Skip to content

Commit e6f2789

Browse files
committed
MB-48819: Change Cookie::engine_storage to be atomic
As seen on cluster_run built with TSan, the following race is seen aborting a timed-out SyncWrite: WARNING: ThreadSanitizer: data race (pid=46769) Write of size 8 at 0x7b5400291698 by thread T60 (mutexes: read M542537949550136824, write M360774, read M541974810616805208, write M1133353977207195360): #0 Cookie::setEngineStorage(void*) kv_engine/daemon/cookie.h:432 (memcached+0x66a6e1) #1 EventuallyPersistentEngine::storeEngineSpecific(CookieIface const*, void*) kv_engine/engines/ep/src/ep_engine.cc:1841 (memcached+0x7c4162) #2 operator() kv_engine/engines/ep/src/kv_bucket.cc:2756 (memcached+0xa65268) #3 __invoke_impl<void, KVBucket::makeSyncWriteCompleteCB()::<...> /usr/include/c++/10/bits/invoke.h:60 (memcached+0xa65268) #4 __invoke_r<void, KVBucket::makeSyncWriteCompleteCB()::<...> /usr/include/c++/10/bits/invoke.h:110 (memcached+0xa65268) #5 _M_invoke /usr/include/c++/10/bits/std_function.h:291 (memcached+0xa65268) #6 std::function<void (CookieIface const*, cb::engine_errc)>::operator()(...) const /usr/include/c++/10/bits/std_function.h:622 (memcached+0x9bf920) #7 VBucket::notifyClientOfSyncWriteComplete(CookieIface const*, cb::engine_errc) kv_engine/engines/ep/src/vbucket.cc:1041 (memcached+0x9bf920) ... Previous write of size 8 at 0x7b5400291698 by thread T18 (mutexes: write M3809): #0 Cookie::setEngineStorage(void*) /home/daver/repos/couchbase/server/kv_engine/daemon/cookie.h:432 (memcached+0x66a6e1) #1 EventuallyPersistentEngine::storeEngineSpecific(...) kv_engine/engines/ep/src/ep_engine.cc:1841 (memcached+0x7bb0c2) #2 EventuallyPersistentEngine::storeIfInner(...) kv_engine/engines/ep/src/ep_engine.cc:2539 (memcached+0x7de96a) #3 EventuallyPersistentEngine::store_if(...) kv_engine/engines/ep/src/ep_engine.cc:478 (memcached+0x7debed) #4 bucket_store_if(...) kv_engine/daemon/protocol/mcbp/engine_wrapper.cc:148 (memcached+0x7517bd) #5 MutationCommandContext::storeItem() kv_engine/daemon/protocol/mcbp/mutation_context.cc:288 (memcached+0x733f6d) #6 MutationCommandContext::step() kv_engine/daemon/protocol/mcbp/mutation_context.cc:54 (memcached+0x7385f7) ... When setEngineStorage is called from EventuallyPersistentEngine::store_if (when issueing a SyncWrite) from the frontend thread, the per-frontend thread mutex is held when modifying Cookie:engine_storage. However when the background thread later modifies Cookie:engine_storage the front-end thread mutex is not held. Address this by making Cookie::engine_storage atomic. We could have added a mutex around it, but that would add additional space requirements for each Cookie (of which there are potentially many), so atomic_ptr suffices for the time being. Change-Id: I62e25b6a74d47c2da6b500cb3dc20d7ad2b01e03 Reviewed-on: http://review.couchbase.org/c/kv_engine/+/163278 Tested-by: Build Bot <[email protected]> Reviewed-by: Paolo Cocchi <[email protected]>
1 parent c7ca055 commit e6f2789

File tree

3 files changed

+5
-3
lines changed

3 files changed

+5
-3
lines changed

daemon/cookie.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ nlohmann::json Cookie::toJSON() const {
6868
ret["ewouldblock"] = ewouldblock;
6969
ret["aiostat"] = to_string(cb::engine_errc(aiostat));
7070
ret["refcount"] = uint32_t(refcount);
71-
ret["engine_storage"] = cb::to_hex(uint64_t(engine_storage));
71+
ret["engine_storage"] = cb::to_hex(uint64_t(engine_storage.load()));
7272
return ret;
7373
}
7474

daemon/cookie.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,10 @@ class Cookie : public CookieIface {
687687
* Pointer to engine-specific data which the engine has requested the server
688688
* to persist for the life of the connection.
689689
* See SERVER_COOKIE_API::{get,store}_engine_specific()
690+
* Atomic so it can safely be read / updated from engine background threads
691+
* in addition to front-end threads.
690692
*/
691-
void* engine_storage{nullptr};
693+
std::atomic<void*> engine_storage{nullptr};
692694

693695
/**
694696
* Log a preformatted response text

programs/engine_testapp/mock_cookie.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class MockCookie : public CookieIface {
144144
protected:
145145
static CheckPrivilegeFunction checkPrivilegeFunction;
146146

147-
void* engine_data{nullptr};
147+
std::atomic<void*> engine_data{nullptr};
148148
uint32_t sfd{};
149149
bool handle_ewouldblock{true};
150150
bool handle_mutation_extras{true};

0 commit comments

Comments
 (0)