Skip to content

Commit c7a16bf

Browse files
committed
RRC: fix DC crasher on interleaved leg handovers (orphaned NR-leg entities)
Root cause of the long-standing test_numerology MultiCell-CBR-DL crasher ("second establishment path during interleaved leg handovers" noted in 361b471; also failed under v1.4.3-1.4.5, never baselined). Traced with per-UE event logging: ue[4] (LTE 1029 / NR 2053), crash at t=10.05s. Two defects, both on the teardown side: 1. HandoverController: orphaned NR-leg entities at the DC secondary. Data-driven flow establishment (Binder::establishUnidirectionalDataConnection) provisions NR-leg entities (MAC connection, RLC entities, bypass PDCP) for the UE at the master's secondary gNB regardless of whether the UE's NR leg is attached to it. If the LTE leg then hands over while the NR leg is detached, deleteOldBuffers() cleaned only the master -- the secondary's per-UE state was orphaned (t=5.075 provisioning, t=6.05 orphaning in the trace). When the UE later returned to that master, re-establishment of the same DRBs collided with the leftovers: duplicate-CID ASSERT in LteMacBase::createOutgoingConnection (debug) / duplicate rlc-um-tx module error (release) at t=10.05s. Fix: deleteOldBuffers() now also cleans the old serving node's secondary (via the NR leg's controller) when the NR leg is detached; the attached case was already handled by the forced-detachment path. Also pass the servingNodeId argument through to the UE-side deleteQueues()/deleteLocalPdcpEntities() calls instead of the member (identical for all pre-existing call sites, required for the new cross-leg call where the NR leg's member is NODEID_NONE). 2. BearerManagement::deleteLocalPdcpEntities() wiped ALL PDCP entities at any UE, but at an NR UE this single module holds the entities of BOTH legs (keyed by peer node). An NR-leg detach thus also deleted the LTE leg's PDCP RX entities, leaving the LTE RLC RX entities forwarding to a dangling gate: "Gate 'out' not connected" in UmRxEntity at t=15.03s (exposed only after fix 1 let the run get past 10.05s). Fix: keyed (per-node) deletion at eNBs and NR-capable UEs, wipe-all only at plain LTE UEs -- exactly the pre-flattening per-class semantics (LtePdcpEnb/NrPdcpUe keyed with the "delete connections related to the given master nodeB only" comment, LtePdcpUe wipe-all). Verified: test_numerology MultiCell-CBR-DL and MultiCell-CBR-UL now run the full 50s in both debug and release with zero errors. Fingerprints: full suite re-run has zero errors and exactly two justified moves, re-recorded here: - test_numerology/MultiCell-CBR-DL: interval extended 5s -> 20s (deferred from 1886a06, blocked on this crasher); all ingredients move with the longer window, which now covers the interleaved DC handovers. - dualConnectivity_multicell/SplitBearer-CBR-DL: tplx/tilx/sz moved, ~tNl byte-identical -- the keyed PDCP cleanup changes the entity-deletion event trajectory around handovers, while the application packet stream is unchanged. All other rows (incl. all other DC, handover, D2D, and MEC configs) byte-identical.
1 parent 1886a06 commit c7a16bf

3 files changed

Lines changed: 28 additions & 8 deletions

File tree

src/simu5g/stack/rrc/BearerManagement.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,17 @@ void BearerManagement::deleteLocalPdcpEntities(MacNodeId nodeId)
390390

391391
bool isEnb = (registration_->getNodeType() == NODEB);
392392

393+
// Per-node (keyed) deletion at eNBs/gNBs and at NR-capable UEs; wipe-all only at plain
394+
// LTE UEs. This mirrors the pre-flattening per-class behavior (LtePdcpEnb and NrPdcpUe
395+
// deleted entities keyed by node, LtePdcpUe deleted all). At an NR UE this single module
396+
// holds the PDCP entities of BOTH legs (keyed by the peer node): a one-leg detach must
397+
// not delete the other leg's entities, otherwise that leg's RLC RX entities are left
398+
// forwarding to a dangling gate, and later re-establishment collides with its leftovers.
399+
bool keyed = isEnb || registration_->getNrNodeId() != NODEID_NONE;
400+
393401
// Delete PDCP TX entities
394402
for (auto it = pdcpTxEntities_.begin(); it != pdcpTxEntities_.end(); ) {
395-
if (isEnb ? it->first.getNodeId() == nodeId : true) {
403+
if (!keyed || it->first.getNodeId() == nodeId) {
396404
pdcpMux->unregisterTxEntity(it->first);
397405
it->second->deleteModule();
398406
it = pdcpTxEntities_.erase(it);
@@ -401,7 +409,7 @@ void BearerManagement::deleteLocalPdcpEntities(MacNodeId nodeId)
401409

402410
// Delete PDCP RX entities
403411
for (auto it = pdcpRxEntities_.begin(); it != pdcpRxEntities_.end(); ) {
404-
if (isEnb ? it->first.getNodeId() == nodeId : true) {
412+
if (!keyed || it->first.getNodeId() == nodeId) {
405413
it->second->deleteModule();
406414
it = pdcpRxEntities_.erase(it);
407415
} else ++it;
@@ -410,7 +418,7 @@ void BearerManagement::deleteLocalPdcpEntities(MacNodeId nodeId)
410418
// Delete bypass TX entities (eNB-only)
411419
ASSERT(pdcpBypassTxEntities_.empty() || pdcpDcMux != nullptr);
412420
for (auto it = pdcpBypassTxEntities_.begin(); it != pdcpBypassTxEntities_.end(); ) {
413-
if (isEnb ? it->first.getNodeId() == nodeId : true) {
421+
if (!keyed || it->first.getNodeId() == nodeId) {
414422
pdcpDcMux->unregisterBypassTxEntity(it->first);
415423
it->second->deleteModule();
416424
it = pdcpBypassTxEntities_.erase(it);
@@ -419,7 +427,7 @@ void BearerManagement::deleteLocalPdcpEntities(MacNodeId nodeId)
419427

420428
// Delete bypass RX entities
421429
for (auto it = pdcpBypassRxEntities_.begin(); it != pdcpBypassRxEntities_.end(); ) {
422-
if (isEnb ? it->first.getNodeId() == nodeId : true) {
430+
if (!keyed || it->first.getNodeId() == nodeId) {
423431
it->second->deleteModule();
424432
it = pdcpBypassRxEntities_.erase(it);
425433
} else ++it;

src/simu5g/stack/rrc/HandoverController.cc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ void HandoverController::deleteOldBuffers(MacNodeId servingNodeId)
490490
servingNodeMac->deleteQueues(nodeId_);
491491

492492
// delete queues for serving node at this UE
493-
mac_->deleteQueues(servingNodeId_);
493+
mac_->deleteQueues(servingNodeId);
494494

495495
// Delete RLC UM Buffers
496496

@@ -515,7 +515,19 @@ void HandoverController::deleteOldBuffers(MacNodeId servingNodeId)
515515
servingBm->deleteLocalPdcpEntities(nodeId_);
516516

517517
// delete PDCP entities for serving node at this UE
518-
bearerManagement_->deleteLocalPdcpEntities(servingNodeId_);
518+
bearerManagement_->deleteLocalPdcpEntities(servingNodeId);
519+
520+
// Flow establishment (Binder::establishUnidirectionalDataConnection) provisions NR-leg
521+
// entities for this UE at the serving node's DC secondary regardless of whether the UE's
522+
// NR leg is attached to it. If the NR leg is attached, its own (forced) detachment cleans
523+
// them up; if it is detached now, remove them together with the master-side state --
524+
// otherwise they are orphaned here, and a later re-establishment collides with them when
525+
// the UE returns to this master (duplicate MAC CID assert / duplicate module errors).
526+
if (otherHandoverController_ != nullptr && otherHandoverController_->getServingNodeId() == NODEID_NONE) {
527+
MacNodeId secondaryNodeId = binder_->getSecondaryNode(servingNodeId);
528+
if (secondaryNodeId != NODEID_NONE)
529+
otherHandoverController_->deleteOldBuffers(secondaryNodeId);
530+
}
519531
}
520532

521533
LteAmc *HandoverController::getAmcModule(MacNodeId nodeId)

tests/fingerprint/simulations.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
/simulations/nr/dualConnectivity_multicell/, -f omnetpp.ini -c DoubleConnection-CBR-UL -r 0, 40s, 05c6-61aa/tplx;d0f2-6422/tilx;3944-e298/~tNl;3c35-155e/sz, PASS,
7373
/simulations/nr/dualConnectivity_multicell/, -f omnetpp.ini -c SingleConnection-CBR-DL -r 0, 40s, f85c-f458/tplx;9b59-7b8b/tilx;44af-6cd8/~tNl;34d9-dab2/sz, PASS,
7474
/simulations/nr/dualConnectivity_multicell/, -f omnetpp.ini -c SingleConnection-CBR-UL -r 0, 40s, 1e43-8b02/tplx;c59a-41a0/tilx;39c2-5c6b/~tNl;c0f8-dd1a/sz, PASS,
75-
/simulations/nr/dualConnectivity_multicell/, -f omnetpp.ini -c SplitBearer-CBR-DL -r 0, 40s, b45c-c106/tplx;14cc-a55a/tilx;e332-82db/~tNl;33e0-ab8f/sz, PASS,
75+
/simulations/nr/dualConnectivity_multicell/, -f omnetpp.ini -c SplitBearer-CBR-DL -r 0, 40s, daf2-a2d8/tplx;bea5-8ebb/tilx;e332-82db/~tNl;4765-2a49/sz, PASS,
7676
/simulations/nr/dualConnectivity/, -f omnetpp.ini -c DualConn-MasterOnly-DL -r 0, 5s, 27da-87eb/tplx;dbfe-88dd/tilx;7596-fd84/~tNl;3cbd-e6df/sz, PASS,
7777
/simulations/nr/dualConnectivity/, -f omnetpp.ini -c DualConn-MasterOnly-UL -r 0, 5s, 6c5c-3dd7/tplx;ce67-3b2e/tilx;02a2-0a09/~tNl;575a-4aaf/sz, PASS,
7878
/simulations/nr/dualConnectivity/, -f omnetpp.ini -c DualConn-MasterPlusSecondary-DL -r 0, 5s, 1544-1cc7/tplx;a006-c15a/tilx;ea4a-5e6e/~tNl;bbf0-0344/sz, PASS,
@@ -115,7 +115,7 @@
115115
/simulations/nr/test_multiCarrier/, -f omnetpp.ini -c MultiCarrier-CBR-UL -r 0, 5s, 2cdd-48da/tplx;bfa7-1cf0/tilx;8d1b-cbd7/~tNl;c822-5817/sz, PASS,
116116
/simulations/nr/test_multiCarrier/, -f omnetpp.ini -c SingleCarrier-CBR-DL -r 0, 5s, 3439-c327/tplx;d254-3b41/tilx;87df-bb05/~tNl;836c-a2bd/sz, PASS,
117117
/simulations/nr/test_multiCarrier/, -f omnetpp.ini -c SingleCarrier-CBR-UL -r 0, 5s, 4e36-f5e0/tplx;e3af-85cb/tilx;1400-0221/~tNl;5a3f-ae80/sz, PASS,
118-
/simulations/nr/test_numerology/, -f omnetpp.ini -c MultiCell-CBR-DL -r 0, 5s, b433-bcd7/tplx;1ae8-9e78/tilx;6284-1d6c/~tNl;d4eb-f413/sz, PASS,
118+
/simulations/nr/test_numerology/, -f omnetpp.ini -c MultiCell-CBR-DL -r 0, 20s, 5b20-53f9/tplx;eaad-b1a5/tilx;def6-7c78/~tNl;e0cc-0380/sz, PASS,
119119
/simulations/nr/test_numerology/, -f omnetpp.ini -c MultiCell-CBR-UL -r 0, 20s, f09a-c9bb/tplx;a8c5-5c41/tilx;1221-b278/~tNl;627c-015e/sz, PASS,
120120
/simulations/nr/test_numerology/, -f omnetpp.ini -c SingleCell-CBR-DL -r 0, 10s, 7168-a79d/tplx;d8f5-b1b2/tilx;662f-87d8/~tNl;718b-31ac/sz, PASS,
121121
/simulations/nr/test_numerology/, -f omnetpp.ini -c SingleCell-CBR-UL -r 0, 10s, 9a96-9c9d/tplx;2f0b-ad1d/tilx;cf96-908e/~tNl;e1be-7696/sz, PASS,

0 commit comments

Comments
 (0)