@@ -258,9 +258,12 @@ mca_rcache_base_registration_t *mca_rcache_base_vma_tree_find (mca_rcache_base_v
258258    mca_rcache_base_vma_item_t  * vma ;
259259    mca_rcache_base_vma_reg_list_item_t  * item ;
260260
261+     opal_mutex_lock  (& vma_module -> vma_lock );
262+ 
261263    vma  =  (mca_rcache_base_vma_item_t  * ) opal_rb_tree_find_with  (& vma_module -> rb_tree , base ,
262264                                                                 mca_rcache_base_vma_tree_node_compare_search );
263265    if  (!vma ) {
266+         opal_mutex_unlock  (& vma_module -> vma_lock );
264267        return  NULL ;
265268    }
266269
@@ -269,12 +272,18 @@ mca_rcache_base_registration_t *mca_rcache_base_vma_tree_find (mca_rcache_base_v
269272            continue ;
270273        }
271274
272-         if (item -> reg -> bound  >= bound )
275+         if (item -> reg -> bound  >= bound ) {
276+             opal_mutex_unlock  (& vma_module -> vma_lock );
273277            return  item -> reg ;
274-         if (!(item -> reg -> flags  &  MCA_RCACHE_FLAGS_PERSIST ))
278+         }
279+ 
280+         if (!(item -> reg -> flags  &  MCA_RCACHE_FLAGS_PERSIST )) {
275281            break ;
282+         }
276283    }
277284
285+     opal_mutex_unlock  (& vma_module -> vma_lock );
286+ 
278287    return  NULL ;
279288}
280289
@@ -299,6 +308,8 @@ int mca_rcache_base_vma_tree_find_all (mca_rcache_base_vma_module_t *vma_module,
299308    if (opal_list_get_size (& vma_module -> vma_list ) ==  0 )
300309        return  cnt ;
301310
311+     opal_mutex_lock  (& vma_module -> vma_lock );
312+ 
302313    do  {
303314        mca_rcache_base_vma_item_t  * vma ;
304315        mca_rcache_base_vma_reg_list_item_t  * vma_item ;
@@ -316,25 +327,23 @@ int mca_rcache_base_vma_tree_find_all (mca_rcache_base_vma_module_t *vma_module,
316327        }
317328
318329        OPAL_LIST_FOREACH (vma_item , & vma -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
319-             if  (( vma_item -> reg -> flags  &  MCA_RCACHE_FLAGS_INVALID )  || 
330+             if  (vma_item -> reg -> flags  &  MCA_RCACHE_FLAGS_INVALID  || 
320331                is_reg_in_array  (regs , cnt , vma_item -> reg )) {
321332                continue ;
322333            }
323334            regs [cnt ++ ] =  vma_item -> reg ;
324335            if  (cnt  ==  reg_cnt ) {
336+                 opal_mutex_unlock  (& vma_module -> vma_lock );
325337                return  cnt ; /* no space left in the provided array */ 
326338            }
327339        }
328340
329341        base  =  (unsigned char   * )vma -> end  +  1 ;
330-     } while (bound  >= base );
342+     } while   (bound  >= base );
331343
332-     return  cnt ;
333- }
344+     opal_mutex_unlock  (& vma_module -> vma_lock );
334345
335- static  inline  int  mca_rcache_base_vma_can_insert  (mca_rcache_base_vma_module_t  * vma_module , size_t  nbytes , size_t  limit )
336- {
337-     return  (0  ==  limit  ||  vma_module -> reg_cur_cache_size  +  nbytes  <= limit );
346+     return  cnt ;
338347}
339348
340349static  inline  void  mca_rcache_base_vma_update_byte_count  (mca_rcache_base_vma_module_t  * vma_module ,
@@ -343,12 +352,74 @@ static inline void mca_rcache_base_vma_update_byte_count (mca_rcache_base_vma_mo
343352    vma_module -> reg_cur_cache_size  +=  nbytes ;
344353}
345354
355+ int  mca_rcache_base_vma_tree_iterate  (mca_rcache_base_vma_module_t  * vma_module , unsigned char   * base ,
356+                                       size_t  size , int  (* callback_fn ) (struct  mca_rcache_base_registration_t  * , void  * ),
357+                                       void  * ctx )
358+ {
359+     unsigned char   * bound  =  base  +  size  -  1 ;
360+     mca_rcache_base_vma_item_t  * vma ;
361+     int  rc  =  OPAL_SUCCESS ;
362+ 
363+     if  (opal_list_get_size (& vma_module -> vma_list ) ==  0 ) {
364+         /* nothin to do */ 
365+         return  OPAL_SUCCESS ;
366+     }
367+ 
368+     opal_mutex_lock  (& vma_module -> vma_lock );
369+ 
370+     do  {
371+         mca_rcache_base_vma_reg_list_item_t  * vma_item , * next ;
372+         vma  =  (mca_rcache_base_vma_item_t  * ) opal_rb_tree_find_with  (& vma_module -> rb_tree , base ,
373+                                                                      mca_rcache_base_vma_tree_node_compare_closest );
374+ 
375+         if  (NULL  ==  vma ) {
376+             /* base is bigger than any registered memory */ 
377+             break ;
378+         }
379+ 
380+         if  (base  <  (unsigned char   * ) vma -> start ) {
381+             base  =  (unsigned char   * ) vma -> start ;
382+             continue ;
383+         }
384+ 
385+         base  =  (unsigned char   * )vma -> end  +  1 ;
386+ 
387+         /* all the registrations in the vma may be deleted by the callback so keep a 
388+          * reference until we are done with it. */ 
389+         OBJ_RETAIN (vma );
390+ 
391+         OPAL_LIST_FOREACH_SAFE (vma_item , next , & vma -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
392+             rc  =  callback_fn  (vma_item -> reg , ctx );
393+             if  (OPAL_SUCCESS  !=  rc ) {
394+                 break ;
395+             }
396+         }
397+ 
398+         OBJ_RELEASE (vma );
399+ 
400+         if  (OPAL_SUCCESS  !=  rc ) {
401+             break ;
402+         }
403+     } while  (bound  >= base );
404+ 
405+     opal_mutex_unlock  (& vma_module -> vma_lock );
406+ 
407+     return  rc ;
408+ }
409+ 
410+ static  inline  int  mca_rcache_base_vma_can_insert  (mca_rcache_base_vma_module_t  * vma_module , size_t  nbytes , size_t  limit )
411+ {
412+     return  (0  ==  limit  ||  vma_module -> reg_cur_cache_size  +  nbytes  <= limit );
413+ }
414+ 
346415int  mca_rcache_base_vma_tree_insert  (mca_rcache_base_vma_module_t  * vma_module ,
347416                                     mca_rcache_base_registration_t  * reg , size_t  limit )
348417{
349418    mca_rcache_base_vma_item_t  * i ;
350419    uintptr_t  begin  =  (uintptr_t )reg -> base , end  =  (uintptr_t )reg -> bound ;
351420
421+     opal_mutex_lock  (& vma_module -> vma_lock );
422+ 
352423    i  =  (mca_rcache_base_vma_item_t  * ) opal_rb_tree_find_with  (& vma_module -> rb_tree ,
353424            (void  * ) begin , mca_rcache_base_vma_tree_node_compare_closest );
354425
@@ -373,6 +444,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
373444            opal_list_append (& vma_module -> vma_list , & vma -> super );
374445            begin  =  vma -> end  +  1 ;
375446            mca_rcache_base_vma_add_reg  (vma , reg );
447+             opal_mutex_unlock  (& vma_module -> vma_lock );
376448            return  OPAL_SUCCESS ;
377449        }
378450
@@ -434,10 +506,14 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
434506        i  =  (mca_rcache_base_vma_item_t  * ) opal_list_get_next  (& i -> super );
435507    }
436508
509+     opal_mutex_unlock  (& vma_module -> vma_lock );
510+ 
437511    return  OPAL_SUCCESS ;
438512
439513remove :
440514    mca_rcache_base_vma_tree_delete  (vma_module , reg );
515+     opal_mutex_unlock  (& vma_module -> vma_lock );
516+ 
441517    return  OPAL_ERR_TEMP_OUT_OF_RESOURCE ;
442518}
443519
@@ -453,17 +529,23 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
453529                                     mca_rcache_base_registration_t  * reg )
454530{
455531    mca_rcache_base_vma_item_t  * vma ;
532+     opal_list_t  deleted_vmas ;
533+ 
534+     opal_mutex_lock  (& vma_module -> vma_lock );
456535
457536    vma  =  (mca_rcache_base_vma_item_t  * )
458537        opal_rb_tree_find_with  (& vma_module -> rb_tree , reg -> base ,
459538                                mca_rcache_base_vma_tree_node_compare_search );
460539
461540    if  (!vma ) {
541+         opal_mutex_unlock  (& vma_module -> vma_lock );
462542        return  OPAL_ERROR ;
463543    }
464544
545+     OBJ_CONSTRUCT (& deleted_vmas , opal_list_t );
546+ 
465547    while  (vma  !=  (mca_rcache_base_vma_item_t  * ) opal_list_get_end  (& vma_module -> vma_list )
466-              &&  vma -> start  <= (uintptr_t ) reg -> bound ) {
548+            &&  vma -> start  <= (uintptr_t ) reg -> bound ) {
467549        mca_rcache_base_vma_remove_reg (vma , reg );
468550
469551        if (opal_list_is_empty (& vma -> reg_list )) {
@@ -473,7 +555,7 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
473555            mca_rcache_base_vma_update_byte_count  (vma_module ,
474556                                                   vma -> start  -  vma -> end  -  1 );
475557            opal_list_remove_item  (& vma_module -> vma_list , & vma -> super );
476-             OBJ_RELEASE ( vma );
558+             opal_list_append  ( & deleted_vmas ,  & vma -> super );
477559            vma  =  next ;
478560        } else  {
479561            int  merged ;
@@ -491,7 +573,7 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
491573                    prev -> end  =  vma -> end ;
492574                    opal_list_remove_item (& vma_module -> vma_list , & vma -> super );
493575                    opal_rb_tree_delete (& vma_module -> rb_tree , vma );
494-                     OBJ_RELEASE ( vma );
576+                     opal_list_append  ( & deleted_vmas ,  & vma -> super );
495577                    vma  =  prev ;
496578                    merged  =  1 ;
497579                }
@@ -505,7 +587,7 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
505587                    vma -> end  =  next -> end ;
506588                    opal_list_remove_item (& vma_module -> vma_list , & next -> super );
507589                    opal_rb_tree_delete (& vma_module -> rb_tree , next );
508-                     OBJ_RELEASE ( next );
590+                     opal_list_append  ( & deleted_vmas ,  & next -> super );
509591                    merged  =  1 ;
510592                }
511593            } while  (merged );
@@ -514,6 +596,11 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
514596        }
515597    }
516598
599+     opal_mutex_unlock  (& vma_module -> vma_lock );
600+ 
601+     /* actually free vmas now that the lock has been dropped */ 
602+     OPAL_LIST_DESTRUCT (& deleted_vmas );
603+ 
517604    return  0 ;
518605}
519606
@@ -558,7 +645,7 @@ void mca_rcache_base_vma_tree_dump_range (mca_rcache_base_vma_module_t *vma_modu
558645        OPAL_LIST_FOREACH (vma_item , & vma -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
559646            reg  =  vma_item -> reg ;
560647            opal_output (0 , "    reg: base=%p, bound=%p, ref_count=%d, flags=0x%x" ,
561-                         reg -> base , reg -> bound , reg -> ref_count , reg -> flags );
648+                         ( void   * )  reg -> base , ( void   * )  reg -> bound , reg -> ref_count , reg -> flags );
562649        }
563650        base  =  (unsigned char   * )vma -> end  +  1 ;
564651    } while  (bound  >= base );
0 commit comments