[TENT] Retire stale endpoint on peer reconnect bootstrap - #3188
[TENT] Retire stale endpoint on peer reconnect bootstrap#3188guptaishaan wants to merge 1 commit into
Conversation
When a peer discards its endpoint (store eviction, or resetConnection after a slice failure) and bootstraps again with a fresh QP set, the passive side still holds an EP_READY endpoint under the same key. accept() rejected the bootstrap and left the endpoint EP_READY, so onSetupRdmaConnections never dropped it from the store and every later bootstrap from that peer was rejected too, wedging all transfers to that instance. Call beginDestroyNoLock() on the stale endpoint before returning the error. The lifecycle stays unidirectional, the endpoint is retired rather than reset. The caller then removes it from the store and the peer's next bootstrap gets a newly constructed endpoint. Adds a unit test that drives accept() on an established endpoint with a new peer QP list and asserts the endpoint retires.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
The two failing checks are not caused by this PR.
Supporting evidence:
I could not read the raw job logs (log download needs repo admin), so I cannot |
|
Thank you very much for the fix. I would like to additionally ask when this error is more likely to occur, due to network fluctuations? |
|
@rookiedali Network fluctuation is one way in, but it is not required. What the bug needs is asymmetric teardown: one side throws its endpoint away and bootstraps again with fresh QP numbers, while the other side still holds an Three ways the active side gets there, all ending in a new bootstrap:
The reason it looked permanent rather than like a blip: before this change the reject left the endpoint in If you can still see the affected run, two things would tell us which trigger you hit: roughly how many peer endpoints that context held versus your |
@guptaishaan Thank you very much for your explanation. I understand now. |
Fixes #3173
When a peer drops its endpoint (endpoint store eviction, or
resetConnection()after a slice failure) and bootstraps again with a fresh QP set, the passive side
still holds an
EP_READYendpoint under the same key.accept()saw the samepeer nic path but a different
peer_desc.qp_num, logged "Endpoint alreadyestablished ... cannot accept new connection" and returned an error while leaving
the endpoint
EP_READY.onSetupRdmaConnections()only drops endpoints in aterminal state, so the stale one stayed in the store and rejected every later
bootstrap from that peer, wedging all further transfers to that instance.
The stale endpoint now calls
beginDestroyNoLock()before returning the error.Endpoints keep their unidirectional lifecycle, they are still never reset. The
caller's existing terminal-state branch removes the retired endpoint from the
store, and the peer's next bootstrap (the worker resubmits the slice) is served
by a newly constructed endpoint.
Testing:
EndpointLifecycleTest.BootstrapWithNewPeerQpsRetiresEstablishedEndpoint.It fails before the change (endpoint stays
EP_READY) and passes after.and failover suites.
Not verified: no RDMA hardware was available, so the two-node handshake was not
run end to end. The test drives
accept()on an endpoint with no RdmaContext, sothe verbs work inside
beginDestroyNoLock()(QP transition to ERR, notificationQP unregistration) is not covered by it.
Thanks to @rookiedali for the report and the logs, which pinpointed the rejecting
branch.