@@ -126,10 +126,15 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
126
126
base = opal_min (base , (uintptr_t ) ov_reg -> base );
127
127
bound = opal_max (bound , (uintptr_t ) ov_reg -> bound );
128
128
129
- /* Unmap will decrement the ref count and dealloc the attachment if it's
130
- * not in use. Okay to do even though we didn't increment the ref count
131
- * when we found the reg, as there is a superfluous ref present from when
132
- * we initialized ref_count to 2 instead of 1. */
129
+ /* unmap_peer_region will decrement the ref count and dealloc the attachment
130
+ * if it drops to 0. But we didn't increment the ref count when we found the
131
+ * reg as is customary. If PERSIST was set, there is superfluous ref present
132
+ * from when we initialized ref_count to 2 instead of 1, so we good. If not,
133
+ * manually add the missing reference here; otherwise the count would drop to
134
+ * -1, or the reg might be deleted while still in use elsewhere. */
135
+ if (!(MCA_RCACHE_FLAGS_PERSIST & ov_reg -> flags ))
136
+ opal_atomic_add (& ov_reg -> ref_count , 1 );
137
+
133
138
mca_smsc_xpmem_unmap_peer_region (ov_reg );
134
139
}
135
140
}
@@ -142,7 +147,9 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
142
147
return NULL ;
143
148
}
144
149
145
- reg -> ref_count = 2 ;
150
+ // PERSIST is implemented by keeping an extra reference around
151
+ reg -> ref_count = ((flags & MCA_RCACHE_FLAGS_PERSIST )
152
+ && !(flags & MCA_RCACHE_FLAGS_CACHE_BYPASS ) ? 2 : 1 );
146
153
reg -> flags = flags ;
147
154
reg -> base = (unsigned char * ) base ;
148
155
reg -> bound = (unsigned char * ) bound ;
@@ -184,8 +191,14 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
184
191
185
192
opal_memchecker_base_mem_defined (reg -> rcache_context , bound - base + 1 );
186
193
187
- rc = mca_rcache_base_vma_insert (vma_module , reg , 0 );
188
- assert (OPAL_SUCCESS == rc );
194
+ if (!(reg -> flags & MCA_RCACHE_FLAGS_CACHE_BYPASS )) {
195
+ rc = mca_rcache_base_vma_insert (vma_module , reg , 0 );
196
+ assert (OPAL_SUCCESS == rc );
197
+
198
+ if (OPAL_SUCCESS != rc ) {
199
+ reg -> flags |= MCA_RCACHE_FLAGS_CACHE_BYPASS ;
200
+ }
201
+ }
189
202
}
190
203
191
204
opal_atomic_wmb ();
@@ -202,17 +215,17 @@ void mca_smsc_xpmem_unmap_peer_region(void *ctx)
202
215
int32_t ref_count ;
203
216
204
217
ref_count = opal_atomic_add_fetch_32 (& reg -> ref_count , -1 );
205
- if (OPAL_UNLIKELY (0 == ref_count && !( reg -> flags & MCA_RCACHE_FLAGS_PERSIST ) )) {
218
+ if (OPAL_UNLIKELY (0 == ref_count )) {
206
219
opal_output_verbose (MCA_BASE_VERBOSE_INFO , opal_smsc_base_framework .framework_output ,
207
220
"mca_smsc_xpmem_unmap_peer_region: deleting region mapping for "
208
221
"endpoint %p address range %p-%p" ,
209
222
(void * ) endpoint , reg -> base , reg -> bound );
210
- #if OPAL_ENABLE_DEBUG
211
- int ret = mca_rcache_base_vma_delete ( endpoint -> vma_module , reg );
212
- assert ( OPAL_SUCCESS == ret );
213
- #else
214
- (void ) mca_rcache_base_vma_delete ( endpoint -> vma_module , reg ) ;
215
- #endif
223
+
224
+ if (!( reg -> flags & MCA_RCACHE_FLAGS_CACHE_BYPASS )) {
225
+ int ret = mca_rcache_base_vma_delete ( endpoint -> vma_module , reg );
226
+ assert ( OPAL_SUCCESS == ret );
227
+ (void ) ret ;
228
+ }
216
229
217
230
opal_memchecker_base_mem_noaccess (reg -> rcache_context , (uintptr_t )(reg -> bound - reg -> base + 1 ));
218
231
(void ) xpmem_detach (reg -> rcache_context );
@@ -223,6 +236,10 @@ void mca_smsc_xpmem_unmap_peer_region(void *ctx)
223
236
224
237
static int mca_smsc_xpmem_endpoint_rcache_entry_cleanup (mca_rcache_base_registration_t * reg , void * ctx )
225
238
{
239
+ // See respective comment in mca_smsc_xpmem_map_peer_region
240
+ if (!(MCA_RCACHE_FLAGS_PERSIST & reg -> flags ))
241
+ opal_atomic_add (& reg -> ref_count , 1 );
242
+
226
243
mca_smsc_xpmem_unmap_peer_region (reg );
227
244
return OPAL_SUCCESS ;
228
245
}
@@ -273,7 +290,8 @@ int mca_smsc_xpmem_copy_to(mca_smsc_endpoint_t *endpoint, void *local_address, v
273
290
(void ) reg_handle ;
274
291
275
292
void * remote_ptr , * ctx ;
276
- ctx = mca_smsc_xpmem_map_peer_region (endpoint , /*flags=*/ 0 , remote_address , size , & remote_ptr );
293
+ ctx = mca_smsc_xpmem_map_peer_region (endpoint ,
294
+ MCA_RCACHE_FLAGS_PERSIST , remote_address , size , & remote_ptr );
277
295
mca_smsc_xpmem_memmove (remote_ptr , local_address , size );
278
296
279
297
mca_smsc_xpmem_unmap_peer_region (ctx );
@@ -289,7 +307,8 @@ int mca_smsc_xpmem_copy_from(mca_smsc_endpoint_t *endpoint, void *local_address,
289
307
290
308
void * remote_ptr , * ctx ;
291
309
292
- ctx = mca_smsc_xpmem_map_peer_region (endpoint , /*flags=*/ 0 , remote_address , size , & remote_ptr );
310
+ ctx = mca_smsc_xpmem_map_peer_region (endpoint ,
311
+ MCA_RCACHE_FLAGS_PERSIST , remote_address , size , & remote_ptr );
293
312
mca_smsc_xpmem_memmove (local_address , remote_ptr , size );
294
313
295
314
mca_smsc_xpmem_unmap_peer_region (ctx );
0 commit comments