diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2026-06-01 16:17:03 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-08-10 09:54:35 -0400 |
| commit | 5b06f706374c37375bdff9d21cc10e61df925a92 (patch) | |
| tree | 8cbf6a2c0f202674d0fc275e3b429fb39dcfafbe /include/linux/workqueue_api.h | |
| parent | 8215892993ea9f5231da4fa9eb42428a286fce8b (diff) | |
rpcrdma: arm rn_done before publishing the notification
rpcrdma_rn_register() inserts @rn into rd_xa with xa_alloc() before
storing the caller's callback in rn->rn_done. The xarray makes @rn
reachable to rpcrdma_remove_one(), which walks rd_xa and invokes
rn->rn_done(rn) for every registered notification. A device removal
that races a fresh registration can therefore observe @rn with
rn_done still NULL, because the notification objects are zero
allocated by their owners, and call through a NULL function pointer.
Store rn->rn_done before xa_alloc() publishes @rn. The xarray's
store-side and load-side ordering then guarantees that any CPU which
finds @rn in rd_xa also observes the armed callback.
rpcrdma_rn_unregister() treats a non-NULL rn_done as the sentinel
for a completed registration, so the early store must not survive a
failed registration. Clear rn_done again when xa_alloc() fails.
Were it left set, the failed-accept cleanup path would call
rpcrdma_rn_unregister() on an @rn that was never inserted, erasing
an unrelated rd_xa slot and underflowing rd_kref.
Fixes: 7e86845a0346 ("rpcrdma: Implement generic device removal")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260601201703.46078-1-cel@kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'include/linux/workqueue_api.h')
0 files changed, 0 insertions, 0 deletions
