@@ -372,6 +372,8 @@ static uint64_t &nextXferId() {
372372#define gXferMutex xferMutex ()
373373#define gNextXferId nextXferId ()
374374
375+ static pthread_mutex_t gMrLifecycleMutex = PTHREAD_MUTEX_INITIALIZER;
376+
375377struct FlagcxSliceCache {
376378 static constexpr size_t kCap = 4096 ;
377379 std::vector<FlagcxSlice *> ring;
@@ -2098,15 +2100,17 @@ void flagcxP2pEngineDestroy(FlagcxP2pEngine *engine) {
20982100 }
20992101
21002102 {
2101- /* Phase 1: collect P2P mhandle info under write lock */
2103+ pthread_mutex_lock (&gMrLifecycleMutex );
2104+
2105+ /* Phase 1: collect P2P mhandle info under read lock */
21022106 struct P2pDeregInfo {
21032107 int ibDevN;
21042108 void *mhandle;
21052109 uintptr_t baseAddr;
21062110 };
21072111 std::vector<P2pDeregInfo> deregList;
21082112
2109- flagcxMrRegistryWrLock (flagcxGlobalMrRegistry);
2113+ flagcxMrRegistryRdLock (flagcxGlobalMrRegistry);
21102114 int count = flagcxMrRegistryCount (flagcxGlobalMrRegistry);
21112115 struct flagcxMrEntry *entries =
21122116 flagcxMrRegistryEntries (flagcxGlobalMrRegistry);
@@ -2119,7 +2123,7 @@ void flagcxP2pEngineDestroy(FlagcxP2pEngine *engine) {
21192123 info.baseAddr = entries[i].baseAddr ;
21202124 deregList.push_back (info);
21212125 }
2122- flagcxMrRegistryWrUnlock (flagcxGlobalMrRegistry);
2126+ flagcxMrRegistryRdUnlock (flagcxGlobalMrRegistry);
21232127
21242128 /* Phase 2: deregister from registry first (atomically removes from lookup)
21252129 */
@@ -2135,6 +2139,8 @@ void flagcxP2pEngineDestroy(FlagcxP2pEngine *engine) {
21352139 } devCtx = {info.ibDevN };
21362140 engine->adaptor ->deregMr (&devCtx, info.mhandle );
21372141 }
2142+
2143+ pthread_mutex_unlock (&gMrLifecycleMutex );
21382144 }
21392145
21402146 /* Release P2P engine's refcount on the global MR registry */
@@ -2477,6 +2483,8 @@ int flagcxP2pEngineReg(FlagcxP2pEngine *engine, uintptr_t data, size_t size,
24772483 if (engine == NULL || data == 0 )
24782484 return -1 ;
24792485
2486+ pthread_mutex_lock (&gMrLifecycleMutex );
2487+
24802488 /* Check for existing exact-match registration (dedup) */
24812489 {
24822490 struct flagcxMrEntry existing;
@@ -2490,9 +2498,11 @@ int flagcxP2pEngineReg(FlagcxP2pEngine *engine, uintptr_t data, size_t size,
24902498 WARN (" P2P Reg: addr 0x%lx size mismatch: existing %zu vs requested "
24912499 " %zu" ,
24922500 (unsigned long )data, existing.size , size);
2501+ pthread_mutex_unlock (&gMrLifecycleMutex );
24932502 return -1 ;
24942503 }
24952504 mrId = p2pExt.p2p .mrId ;
2505+ pthread_mutex_unlock (&gMrLifecycleMutex );
24962506 return 0 ;
24972507 }
24982508 }
@@ -2520,6 +2530,7 @@ int flagcxP2pEngineReg(FlagcxP2pEngine *engine, uintptr_t data, size_t size,
25202530 ptrType, FLAGCX_NET_MR_FLAG_NONE ,
25212531 &mhandle) != flagcxSuccess ||
25222532 mhandle == NULL ) {
2533+ pthread_mutex_unlock (&gMrLifecycleMutex );
25232534 return -1 ;
25242535 }
25252536
@@ -2528,6 +2539,7 @@ int flagcxP2pEngineReg(FlagcxP2pEngine *engine, uintptr_t data, size_t size,
25282539 (struct flagcxMrP2pExt *)calloc (1 , sizeof (struct flagcxMrP2pExt ));
25292540 if (p2pExt == NULL ) {
25302541 engine->adaptor ->deregMr (&devCtx, mhandle);
2542+ pthread_mutex_unlock (&gMrLifecycleMutex );
25312543 return -1 ;
25322544 }
25332545 /* mrId=0 signals registry to assign from its monotonic counter */
@@ -2544,34 +2556,48 @@ int flagcxP2pEngineReg(FlagcxP2pEngine *engine, uintptr_t data, size_t size,
25442556 if (res != flagcxSuccess) {
25452557 engine->adaptor ->deregMr (&devCtx, mhandle);
25462558 free (p2pExt);
2559+ pthread_mutex_unlock (&gMrLifecycleMutex );
25472560 return -1 ;
25482561 }
25492562
25502563 mrId = assignedId;
2564+ pthread_mutex_unlock (&gMrLifecycleMutex );
25512565 return 0 ;
25522566}
25532567
25542568void flagcxP2pEngineMrDestroy (FlagcxP2pEngine *engine, FlagcxP2pMr mr) {
25552569 if (engine == NULL )
25562570 return ;
25572571
2572+ pthread_mutex_lock (&gMrLifecycleMutex );
2573+
25582574 /* Find entry by mrId to get baseAddr for deregister */
25592575 struct flagcxMrEntry mrEntry;
25602576 if (flagcxMrRegistryLookupById (flagcxGlobalMrRegistry, mr, &mrEntry, NULL ) !=
2561- flagcxSuccess)
2577+ flagcxSuccess) {
2578+ pthread_mutex_unlock (&gMrLifecycleMutex );
25622579 return ;
2580+ }
25632581
25642582 /* Remove from registry first — prevents concurrent readers from finding it */
25652583 void *removedExt = NULL ;
2566- flagcxMrRegistryDeregister (flagcxGlobalMrRegistry, mrEntry.baseAddr ,
2567- FLAGCX_MR_OWNER_P2P , NULL , &removedExt);
2568- free (removedExt);
2569-
2570- /* Now safe to deregister the adaptor handle */
2584+ flagcxResult_t res;
25712585 struct {
25722586 int ibDevN;
25732587 } devCtx = {mrEntry.ibDevN };
2588+ FLAGCXCHECKGOTO (
2589+ flagcxMrRegistryDeregister (flagcxGlobalMrRegistry, mrEntry.baseAddr ,
2590+ FLAGCX_MR_OWNER_P2P , NULL , &removedExt),
2591+ res, fail);
2592+ free (removedExt);
2593+
2594+ /* Now safe to deregister the adaptor handle */
25742595 engine->adaptor ->deregMr (&devCtx, mrEntry.mhandles [FLAGCX_MR_OWNER_IDX_P2P ]);
2596+ pthread_mutex_unlock (&gMrLifecycleMutex );
2597+ return ;
2598+
2599+ fail:
2600+ pthread_mutex_unlock (&gMrLifecycleMutex );
25752601}
25762602
25772603int flagcxP2pEnginePrepareDesc (FlagcxP2pEngine *engine, FlagcxP2pMr mr,
@@ -2616,6 +2642,23 @@ int flagcxP2pEnginePrepareDesc(FlagcxP2pEngine *engine, FlagcxP2pMr mr,
26162642 return -1 ;
26172643 }
26182644
2645+ /* Verify (data, size) falls within registered MR region (overflow-safe) */
2646+ uintptr_t dataAddr = (uintptr_t )data;
2647+ if (dataAddr < entries[idx].baseAddr ) {
2648+ flagcxMrRegistryWrUnlock (flagcxGlobalMrRegistry);
2649+ return -1 ;
2650+ }
2651+ size_t offset = (size_t )(dataAddr - entries[idx].baseAddr );
2652+ if (offset > entries[idx].size || size > entries[idx].size - offset) {
2653+ flagcxMrRegistryWrUnlock (flagcxGlobalMrRegistry);
2654+ return -1 ;
2655+ }
2656+
2657+ if (size > UINT32_MAX ) {
2658+ flagcxMrRegistryWrUnlock (flagcxGlobalMrRegistry);
2659+ return -1 ;
2660+ }
2661+
26192662 FlagcxP2pRdmaDesc desc;
26202663 memset (&desc, 0 , sizeof (desc));
26212664 desc.addr = (uint64_t )(uintptr_t )data;
0 commit comments