@@ -126,10 +126,15 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
126126 base = opal_min (base , (uintptr_t ) ov_reg -> base );
127127 bound = opal_max (bound , (uintptr_t ) ov_reg -> bound );
128128
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+
133138 mca_smsc_xpmem_unmap_peer_region (ov_reg );
134139 }
135140 }
@@ -142,7 +147,9 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
142147 return NULL ;
143148 }
144149
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 );
146153 reg -> flags = flags ;
147154 reg -> base = (unsigned char * ) base ;
148155 reg -> bound = (unsigned char * ) bound ;
@@ -184,8 +191,14 @@ void *mca_smsc_xpmem_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t fla
184191
185192 opal_memchecker_base_mem_defined (reg -> rcache_context , bound - base + 1 );
186193
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+ }
189202 }
190203
191204 opal_atomic_wmb ();
@@ -202,17 +215,17 @@ void mca_smsc_xpmem_unmap_peer_region(void *ctx)
202215 int32_t ref_count ;
203216
204217 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 )) {
206219 opal_output_verbose (MCA_BASE_VERBOSE_INFO , opal_smsc_base_framework .framework_output ,
207220 "mca_smsc_xpmem_unmap_peer_region: deleting region mapping for "
208221 "endpoint %p address range %p-%p" ,
209222 (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+ }
216229
217230 opal_memchecker_base_mem_noaccess (reg -> rcache_context , (uintptr_t )(reg -> bound - reg -> base + 1 ));
218231 (void ) xpmem_detach (reg -> rcache_context );
@@ -223,6 +236,10 @@ void mca_smsc_xpmem_unmap_peer_region(void *ctx)
223236
224237static int mca_smsc_xpmem_endpoint_rcache_entry_cleanup (mca_rcache_base_registration_t * reg , void * ctx )
225238{
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+
226243 mca_smsc_xpmem_unmap_peer_region (reg );
227244 return OPAL_SUCCESS ;
228245}
@@ -273,7 +290,8 @@ int mca_smsc_xpmem_copy_to(mca_smsc_endpoint_t *endpoint, void *local_address, v
273290 (void ) reg_handle ;
274291
275292 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 );
277295 mca_smsc_xpmem_memmove (remote_ptr , local_address , size );
278296
279297 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,
289307
290308 void * remote_ptr , * ctx ;
291309
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 );
293312 mca_smsc_xpmem_memmove (local_address , remote_ptr , size );
294313
295314 mca_smsc_xpmem_unmap_peer_region (ctx );
0 commit comments