@@ -168,7 +168,7 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
168
168
ompi_osc_rdma_handle_t * rdma_region_handle ;
169
169
osc_rdma_counter_t region_count ;
170
170
osc_rdma_counter_t region_id ;
171
- intptr_t bound , aligned_base , aligned_bound ;
171
+ intptr_t aligned_base , aligned_bound ;
172
172
intptr_t page_size = opal_getpagesize ();
173
173
int region_index , ret ;
174
174
size_t aligned_len ;
@@ -185,6 +185,7 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
185
185
OSC_RDMA_VERBOSE (MCA_BASE_VERBOSE_TRACE , "attach: %s, %p, %lu" , win -> w_name , base , (unsigned long ) len );
186
186
187
187
OPAL_THREAD_LOCK (& module -> lock );
188
+ ompi_osc_rdma_lock_acquire_exclusive (module , my_peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
188
189
189
190
region_count = module -> state -> region_count & 0xffffffffL ;
190
191
region_id = module -> state -> region_count >> 32 ;
@@ -197,7 +198,6 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
197
198
198
199
/* it is wasteful to register less than a page. this may allow the remote side to access more
199
200
* memory but the MPI standard covers this with calling the calling behavior erroneous */
200
- bound = (intptr_t ) base + len ;
201
201
aligned_bound = OPAL_ALIGN ((intptr_t ) base + len , page_size , intptr_t );
202
202
aligned_base = (intptr_t ) base & ~(page_size - 1 );
203
203
aligned_len = (size_t )(aligned_bound - aligned_base );
@@ -209,16 +209,11 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
209
209
/* validates that the region does not overlap with an existing region even if they are on the same page */
210
210
ret = ompi_osc_rdma_add_attachment (module -> dynamic_handles [region_index ], (intptr_t ) base , len );
211
211
OPAL_THREAD_UNLOCK (& module -> lock );
212
+ ompi_osc_rdma_lock_release_exclusive (module , my_peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
212
213
/* no need to invalidate remote caches */
213
214
return ret ;
214
215
}
215
216
216
- /* region is in flux */
217
- module -> state -> region_count = -1 ;
218
- opal_atomic_wmb ();
219
-
220
- ompi_osc_rdma_lock_acquire_exclusive (module , my_peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
221
-
222
217
/* do a binary seach for where the region should be inserted */
223
218
if (region_count ) {
224
219
region = find_insertion_point ((ompi_osc_rdma_region_t * ) module -> state -> regions , 0 , region_count - 1 ,
@@ -239,7 +234,7 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
239
234
region -> len = aligned_len ;
240
235
241
236
OSC_RDMA_VERBOSE (MCA_BASE_VERBOSE_DEBUG , "attaching dynamic memory region {%p, %p} aligned {%p, %p}, at index %d" ,
242
- base , (void * ) bound , (void * ) aligned_base , (void * ) aligned_bound , region_index );
237
+ base , (void * ) (( intptr_t ) base + len ) , (void * ) aligned_base , (void * ) aligned_bound , region_index );
243
238
244
239
/* add RDMA region handle to track this region */
245
240
rdma_region_handle = OBJ_NEW (ompi_osc_rdma_handle_t );
@@ -253,6 +248,7 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
253
248
if (OPAL_UNLIKELY (OMPI_SUCCESS != ret )) {
254
249
OPAL_THREAD_UNLOCK (& module -> lock );
255
250
OBJ_RELEASE (rdma_region_handle );
251
+ ompi_osc_rdma_lock_release_exclusive (module , my_peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
256
252
return OMPI_ERR_RMA_ATTACH ;
257
253
}
258
254
@@ -275,9 +271,9 @@ int ompi_osc_rdma_attach (struct ompi_win_t *win, void *base, size_t len)
275
271
}
276
272
#endif
277
273
278
- opal_atomic_mb ();
279
274
/* the region state has changed */
280
275
module -> state -> region_count = ((region_id + 1 ) << 32 ) | (region_count + 1 );
276
+ opal_atomic_wmb ();
281
277
282
278
ompi_osc_rdma_lock_release_exclusive (module , my_peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
283
279
OPAL_THREAD_UNLOCK (& module -> lock );
@@ -304,6 +300,9 @@ int ompi_osc_rdma_detach (struct ompi_win_t *win, const void *base)
304
300
305
301
OPAL_THREAD_LOCK (& module -> lock );
306
302
303
+ /* lock the region so it can't change while a peer is reading it */
304
+ ompi_osc_rdma_lock_acquire_exclusive (module , & my_peer -> super , offsetof (ompi_osc_rdma_state_t , regions_lock ));
305
+
307
306
/* the upper 4 bytes of the region count are an instance counter */
308
307
region_count = module -> state -> region_count & 0xffffffffL ;
309
308
region_id = module -> state -> region_count >> 32 ;
@@ -327,23 +326,22 @@ int ompi_osc_rdma_detach (struct ompi_win_t *win, const void *base)
327
326
if (region_index == region_count ) {
328
327
OSC_RDMA_VERBOSE (MCA_BASE_VERBOSE_INFO , "could not find dynamic memory attachment for %p" , base );
329
328
OPAL_THREAD_UNLOCK (& module -> lock );
329
+ ompi_osc_rdma_lock_release_exclusive (module , & my_peer -> super , offsetof (ompi_osc_rdma_state_t , regions_lock ));
330
330
return OMPI_ERR_BASE ;
331
331
}
332
332
333
333
if (!opal_list_is_empty (& rdma_region_handle -> attachments )) {
334
334
/* another region is referencing this attachment */
335
+ OPAL_THREAD_UNLOCK (& module -> lock );
336
+ ompi_osc_rdma_lock_release_exclusive (module , & my_peer -> super , offsetof (ompi_osc_rdma_state_t , regions_lock ));
335
337
return OMPI_SUCCESS ;
336
338
}
337
339
338
- /* lock the region so it can't change while a peer is reading it */
339
- ompi_osc_rdma_lock_acquire_exclusive (module , & my_peer -> super , offsetof (ompi_osc_rdma_state_t , regions_lock ));
340
-
341
340
OSC_RDMA_VERBOSE (MCA_BASE_VERBOSE_DEBUG , "detaching dynamic memory region {%p, %p} from index %d" ,
342
341
base , (void * )((intptr_t ) base + region -> len ), region_index );
343
342
344
343
if (module -> selected_btl -> btl_register_mem ) {
345
344
ompi_osc_rdma_deregister (module , rdma_region_handle -> btl_handle );
346
-
347
345
}
348
346
349
347
if (region_index < region_count - 1 ) {
@@ -358,6 +356,7 @@ int ompi_osc_rdma_detach (struct ompi_win_t *win, const void *base)
358
356
module -> dynamic_handles [region_count - 1 ] = NULL ;
359
357
360
358
module -> state -> region_count = ((region_id + 1 ) << 32 ) | (region_count - 1 );
359
+ opal_atomic_wmb ();
361
360
362
361
ompi_osc_rdma_lock_release_exclusive (module , & my_peer -> super , offsetof (ompi_osc_rdma_state_t , regions_lock ));
363
362
@@ -461,14 +460,18 @@ int ompi_osc_rdma_find_dynamic_region (ompi_osc_rdma_module_t *module, ompi_osc_
461
460
ompi_osc_rdma_peer_dynamic_t * dy_peer = (ompi_osc_rdma_peer_dynamic_t * ) peer ;
462
461
intptr_t bound = (intptr_t ) base + len ;
463
462
ompi_osc_rdma_region_t * regions ;
464
- int ret , region_count ;
463
+ int ret = OMPI_SUCCESS , region_count ;
465
464
466
465
OSC_RDMA_VERBOSE (MCA_BASE_VERBOSE_TRACE , "locating dynamic memory region matching: {%" PRIx64 ", %" PRIx64 "}"
467
466
" (len %lu)" , base , base + len , (unsigned long ) len );
468
467
468
+ OPAL_THREAD_LOCK (& module -> lock );
469
+ // Make sure region isn't being touched.
470
+ ompi_osc_rdma_lock_acquire_exclusive (module , peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
469
471
if (!ompi_osc_rdma_peer_local_state (peer )) {
470
472
ret = ompi_osc_rdma_refresh_dynamic_region (module , dy_peer );
471
473
if (OMPI_SUCCESS != ret ) {
474
+ ompi_osc_rdma_lock_release_exclusive (module , peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
472
475
return ret ;
473
476
}
474
477
@@ -482,9 +485,11 @@ int ompi_osc_rdma_find_dynamic_region (ompi_osc_rdma_module_t *module, ompi_osc_
482
485
483
486
* region = ompi_osc_rdma_find_region_containing (regions , 0 , region_count - 1 , (intptr_t ) base , bound , module -> region_size , NULL );
484
487
if (!* region ) {
485
- return OMPI_ERR_RMA_RANGE ;
488
+ ret = OMPI_ERR_RMA_RANGE ;
486
489
}
490
+ OPAL_THREAD_UNLOCK (& module -> lock );
491
+ ompi_osc_rdma_lock_release_exclusive (module , peer , offsetof (ompi_osc_rdma_state_t , regions_lock ));
487
492
488
493
/* round a matching region */
489
- return OMPI_SUCCESS ;
494
+ return ret ;
490
495
}
0 commit comments