From fb1951204c9972d0a4364e24a6f2cd5900b7f2f2 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Sat, 8 Aug 2015 17:40:12 -0700 Subject: [PATCH 1/2] etcdserver: move atomics to make etcd work on arm64 Follow the simple rule in the atomic package: "On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically. The first word in a global variable or in an allocated struct or slice can be relied upon to be 64-bit aligned." Tested on a system with /proc/cpuinfo reporting: processor : 0 model name : ARMv7 Processor rev 1 (v7l) Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc0d CPU revision : 1 --- etcdserver/raft.go | 12 +++++++----- etcdserver/server.go | 6 ++++-- store/watcher_hub.go | 6 +++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/etcdserver/raft.go b/etcdserver/raft.go index 711c8fe61..16838af03 100644 --- a/etcdserver/raft.go +++ b/etcdserver/raft.go @@ -79,6 +79,13 @@ type apply struct { } type raftNode struct { + // Cache of the latest raft index and raft term the server has seen. + // These three unit64 fields must be the first elements to keep 64-bit + // alignment for atomic access to the fields. + index uint64 + term uint64 + lead uint64 + raft.Node // a chan to send out apply @@ -99,11 +106,6 @@ type raftNode struct { // If transport is nil, server will panic. transport rafthttp.Transporter - // Cache of the latest raft index and raft term the server has seen - index uint64 - term uint64 - lead uint64 - stopped chan struct{} done chan struct{} } diff --git a/etcdserver/server.go b/etcdserver/server.go index 330029bda..dce70c6f0 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -141,11 +141,13 @@ type Server interface { // EtcdServer is the production implementation of the Server interface type EtcdServer struct { + // r must be the first element to keep 64-bit alignment for atomic + // access to fields + r raftNode + cfg *ServerConfig snapCount uint64 - r raftNode - w wait.Wait stop chan struct{} done chan struct{} diff --git a/store/watcher_hub.go b/store/watcher_hub.go index d27ace06b..d573eb331 100644 --- a/store/watcher_hub.go +++ b/store/watcher_hub.go @@ -31,9 +31,13 @@ import ( // event happens between the end of the first watch command and the start // of the second command. type watcherHub struct { + // count must be the first element to keep 64-bit alignment for atomic + // access + + count int64 // current number of watchers. + mutex sync.Mutex watchers map[string]*list.List - count int64 // current number of watchers. EventHistory *EventHistory } From 1b894c6b0b8c0689c8c276c0d29367b52cd702de Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Sat, 8 Aug 2015 17:45:13 -0700 Subject: [PATCH 2/2] test: race detector doesn't work on armv7l Test fails without this fix on armv7l: go test: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64 --- test | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test b/test index 9eb0b23c6..88c23a9b7 100755 --- a/test +++ b/test @@ -45,7 +45,13 @@ split=(${NO_RACE_TEST// / }) NO_RACE_TEST=${split[@]/#/${REPO_PATH}/} echo "Running tests..." -go test -timeout 3m ${COVER} $@ ${TEST} --race -cpu 1,2,4 + +MACHINE_TYPE=$(uname -m) +if [ $MACHINE_TYPE != "armv7l" ]; then + RACE="--race" +fi + +go test -timeout 3m ${COVER} $@ ${TEST} ${RACE} -cpu 1,2,4 go test -timeout 3m ${COVER} $@ ${NO_RACE_TEST} -cpu 1,2,4 if [ -n "$INTEGRATION" ]; then