*/
xprt_wait_for_buffer_space(&r_xprt->rx_xprt);
r_xprt->rx_stats.empty_sendctx_q++;
+
+ /* Recheck: a Send completion between the ring-empty test
+ * and the set_bit could cause its xprt_write_space() to
+ * miss, leaving XPRT_WRITE_SPACE set with a non-full ring.
+ * The smp_mb__after_atomic() pairs with smp_store_release()
+ * in rpcrdma_sendctx_put_locked().
+ */
+ smp_mb__after_atomic();
+ next_head = rpcrdma_sendctx_next(buf, buf->rb_sc_head);
+ if (next_head != READ_ONCE(buf->rb_sc_tail))
+ xprt_write_space(&r_xprt->rx_xprt);
+
return NULL;
}
} while (buf->rb_sc_ctxs[next_tail] != sc);
- /* Paired with READ_ONCE */
+ /* Paired with READ_ONCE in rpcrdma_sendctx_get_locked():
+ * both the fast-path ring-full test and the post-set_bit
+ * recheck in the slow path depend on this store-release.
+ */
smp_store_release(&buf->rb_sc_tail, next_tail);
xprt_write_space(&r_xprt->rx_xprt);