Fix URMA polling shutdown lifetime by BGQ99 · Pull Request #3634 · apache/brpc · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions src/brpc/urma/urma_endpoint.cpp
4 changes: 3 additions & 1 deletion src/brpc/urma/urma_endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ class BAIDU_CACHELINE_ALIGNMENT UrmaEndpoint : public SocketUser {
std::function<void()> init_fn,
std::function<void()> release_fn);
static void PollingModeRelease(bthread_tag_t tag);
// Stop every polling group without releasing the global IOBuf pool.
static void GlobalPollingModeRelease();

// ---- Handshake IO helpers (also used by urma_handshake.cpp) ----
// Read at most @len bytes from the TCP fd into @data; waits on _read_butex
Expand Down Expand Up @@ -338,7 +340,7 @@ class BAIDU_CACHELINE_ALIGNMENT UrmaEndpoint : public SocketUser {
std::vector<Poller> pollers;
butil::atomic<bool> running;
};
static std::vector<PollerGroup> _poller_groups;
static std::vector<PollerGroup>& PollerGroups();
bthread_tag_t _poller_tag{0};

DISALLOW_COPY_AND_ASSIGN(UrmaEndpoint);
Expand Down
21 changes: 16 additions & 5 deletions src/brpc/urma/urma_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,13 @@ static void GlobalRelease() {
g_device = nullptr;
}

static void ReleasePollingModeAtExit() {
// Match RDMA's shutdown ordering for pollers, but deliberately leave the
// URMA IOBuf pool mapped because thread-local IOBuf blocks may outlive
// atexit handlers.
UrmaEndpoint::GlobalPollingModeRelease();
}

// ============================================================================
// Global initialization.
// ============================================================================
Expand Down Expand Up @@ -620,12 +627,16 @@ static bool GlobalUrmaInitializeImpl() {
return false;
}

if (FLAGS_urma_use_polling) {
atexit(ReleasePollingModeAtExit);
}
Comment on lines +630 to +632

g_urma_available.store(true, butil::memory_order_release);
// Do not register GlobalRelease with atexit. IOBuf keeps blocks in
// thread-local chains whose destructors may run after atexit handlers.
// Unmapping the registered pool here would leave those TLS chains
// pointing into unmapped memory. The process reclaims global URMA
// resources on exit; GlobalRelease remains available for init rollback.
// Register only the polling shutdown above, not GlobalRelease. IOBuf keeps
// blocks in thread-local chains whose destructors may run after atexit
// handlers. Unmapping the registered pool here would leave those TLS
// chains pointing into unmapped memory. The process reclaims the remaining
// global URMA resources; GlobalRelease remains available for init rollback.
LOG(INFO) << "URMA initialized: device=" << device_name
<< " bonding=" << g_is_bonding_device
<< " max_sge=" << g_max_sge
Expand Down
154 changes: 154 additions & 0 deletions test/brpc_urma_unittest.cpp
Loading