@@ -586,31 +586,59 @@ static size_t uct_cuda_copy_md_get_total_device_mem(CUdevice cuda_device)
586586 return 1 ; /* return 1 byte to avoid division by zero */
587587}
588588
589+ struct uct_cuda_copy_md_query_ctx {
590+ CUcontext cuda_ctx ; /* memory's owning context, or NULL */
591+ CUdevice cuda_device ; /* owning device, or CU_DEVICE_INVALID */
592+ CUcontext pushed_cuda_ctx ; /* context pushed by this query, if any */
593+ CUdevice pushed_cuda_device ; /* device whose primary ctx was pushed */
594+ };
595+
589596static ucs_status_t
590- uct_cuda_copy_md_push_ctx ( CUcontext cuda_ctx , CUdevice cuda_device )
597+ uct_cuda_copy_md_ensure_ctx_pushed ( uct_cuda_copy_md_query_ctx_t * query_ctx )
591598{
592- if (cuda_ctx == NULL ) {
593- return uct_cuda_ctx_primary_push (cuda_device , 0 , UCS_LOG_LEVEL_ERROR );
599+ ucs_status_t status ;
600+
601+ if ((query_ctx == NULL ) ||
602+ ((query_ctx -> cuda_ctx == NULL ) &&
603+ (query_ctx -> cuda_device == CU_DEVICE_INVALID ))) {
604+ return UCS_OK ;
605+ }
606+
607+ if ((query_ctx -> pushed_cuda_ctx != NULL ) ||
608+ (query_ctx -> pushed_cuda_device != CU_DEVICE_INVALID )) {
609+ return UCS_OK ;
610+ }
611+
612+ if (query_ctx -> cuda_ctx == NULL ) {
613+ status = uct_cuda_ctx_primary_push (query_ctx -> cuda_device , 0 ,
614+ UCS_LOG_LEVEL_ERROR );
615+ if (status == UCS_OK ) {
616+ query_ctx -> pushed_cuda_device = query_ctx -> cuda_device ;
617+ }
618+ } else {
619+ status = UCT_CUDADRV_FUNC_LOG_ERR (
620+ cuCtxPushCurrent (query_ctx -> cuda_ctx ));
621+ if (status == UCS_OK ) {
622+ query_ctx -> pushed_cuda_ctx = query_ctx -> cuda_ctx ;
623+ }
594624 }
595625
596- return UCT_CUDADRV_FUNC_LOG_ERR ( cuCtxPushCurrent ( cuda_ctx )) ;
626+ return status ;
597627}
598628
599629static void
600- uct_cuda_copy_md_pop_ctx (CUcontext cuda_ctx , CUdevice cuda_device )
630+ uct_cuda_copy_md_pop_ctx (uct_cuda_copy_md_query_ctx_t * query_ctx )
601631{
602- CUcontext tmp_ctx ;
603-
604- UCT_CUDADRV_FUNC_LOG_WARN (cuCtxPopCurrent (& tmp_ctx ));
605- if (cuda_ctx == NULL ) {
606- UCT_CUDADRV_FUNC_LOG_WARN (cuDevicePrimaryCtxRelease (cuda_device ));
607- }
632+ uct_cuda_ctx_pop_and_release (query_ctx -> pushed_cuda_device ,
633+ query_ctx -> pushed_cuda_ctx );
634+ query_ctx -> pushed_cuda_device = CU_DEVICE_INVALID ;
635+ query_ctx -> pushed_cuda_ctx = NULL ;
608636}
609637
610638static void uct_cuda_copy_md_sync_memops_get_address_range (
611639 const uct_cuda_copy_md_t * md , CUdeviceptr address , size_t length ,
612- CUcontext cuda_ctx , CUdevice cuda_device , int is_vmm ,
613- ucs_memory_info_t * mem_info )
640+ int is_vmm , ucs_memory_info_t * mem_info ,
641+ uct_cuda_copy_md_query_ctx_t * query_ctx )
614642{
615643 CUdeviceptr base_address ;
616644 size_t alloc_length ;
@@ -619,50 +647,47 @@ static void uct_cuda_copy_md_sync_memops_get_address_range(
619647 mem_info -> base_address = (void * )address ;
620648 mem_info -> alloc_length = length ;
621649
622- if (uct_cuda_copy_md_push_ctx (cuda_ctx , cuda_device ) != UCS_OK ) {
650+ /* sync memops and cuMemGetAddressRange below need a current context */
651+ if (uct_cuda_copy_md_ensure_ctx_pushed (query_ctx ) != UCS_OK ) {
623652 return ;
624653 }
625654
626- /* Wrapped the method by push/pop CUDA context since it sets
627- CU_CTX_SYNC_MEMOPS flag for the current context */
628655 uct_cuda_copy_sync_memops (address , is_vmm );
629656
630657 if (md -> config .alloc_whole_reg == UCS_CONFIG_OFF ) {
631658 /* Extending the registration range is disable by configuration */
632- goto out_ctx_pop ;
659+ return ;
633660 }
634661
635662 if (UCT_CUDADRV_FUNC_LOG_DEBUG (
636663 cuMemGetAddressRange (& base_address , & alloc_length , address )) !=
637664 UCS_OK ) {
638- goto out_ctx_pop ;
665+ return ;
639666 }
640667
641668 ucs_trace ("query address 0x%llx: 0x%llx..0x%llx length %zu" , address ,
642669 base_address , base_address + alloc_length , alloc_length );
643670
644671 if (md -> config .alloc_whole_reg == UCS_CONFIG_AUTO ) {
645- total_bytes = uct_cuda_copy_md_get_total_device_mem (cuda_device );
672+ total_bytes = uct_cuda_copy_md_get_total_device_mem (
673+ query_ctx -> cuda_device );
646674 if (alloc_length > (total_bytes * md -> config .max_reg_ratio )) {
647- goto out_ctx_pop ;
675+ return ;
648676 }
649677 } else {
650678 ucs_assert (md -> config .alloc_whole_reg == UCS_CONFIG_ON );
651679 }
652680
653681 mem_info -> base_address = (void * )base_address ;
654682 mem_info -> alloc_length = alloc_length ;
655-
656- out_ctx_pop :
657- uct_cuda_copy_md_pop_ctx (cuda_ctx , cuda_device );
658683}
659684
660685static ucs_status_t
661686uct_cuda_copy_md_query_attributes (const uct_cuda_copy_md_t * md ,
662687 const void * address , size_t length ,
663688 ucs_memory_info_t * mem_info ,
664- int * is_async_managed , CUcontext * cuda_ctx_p ,
665- CUdevice * cuda_device_p )
689+ int * is_async_managed ,
690+ uct_cuda_copy_md_query_ctx_t * query_ctx )
666691{
667692#define UCT_CUDA_MEM_QUERY_NUM_ATTRS 4
668693 CUmemorytype cuda_mem_type = CU_MEMORYTYPE_HOST ;
@@ -677,16 +702,14 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
677702 ucs_status_t status ;
678703
679704 * is_async_managed = 0 ;
680- * cuda_ctx_p = NULL ;
681- * cuda_device_p = CU_DEVICE_INVALID ;
682705
683706 is_vmm = uct_cuda_copy_detect_vmm (address , & mem_info -> type , & cuda_device );
684707 if (is_vmm ) {
685708 if (mem_info -> type == UCS_MEMORY_TYPE_UNKNOWN ) {
686709 return UCS_ERR_INVALID_ADDR ;
687710 }
688711
689- * cuda_device_p = cuda_device ;
712+ query_ctx -> cuda_device = cuda_device ;
690713 } else {
691714 attr_type [0 ] = CU_POINTER_ATTRIBUTE_MEMORY_TYPE ;
692715 attr_data [0 ] = & cuda_mem_type ;
@@ -711,8 +734,8 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
711734 return UCS_ERR_INVALID_ADDR ;
712735 }
713736
714- * cuda_ctx_p = cuda_mem_ctx ;
715- * cuda_device_p = cuda_device ;
737+ query_ctx -> cuda_ctx = cuda_mem_ctx ;
738+ query_ctx -> cuda_device = cuda_device ;
716739
717740 if (is_managed ) {
718741 /* cuMemGetAddress range does not support managed memory so use
@@ -769,9 +792,8 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
769792 }
770793
771794 uct_cuda_copy_md_sync_memops_get_address_range (md , (CUdeviceptr )address ,
772- length , cuda_mem_ctx ,
773- cuda_device , is_vmm ,
774- mem_info );
795+ length , is_vmm , mem_info ,
796+ query_ctx );
775797 return UCS_OK ;
776798
777799out_default_range :
@@ -780,8 +802,9 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
780802 return UCS_OK ;
781803}
782804
783- static int uct_cuda_copy_md_get_dmabuf_fd (uintptr_t address , size_t length ,
784- ucs_sys_device_t sys_dev )
805+ static int uct_cuda_copy_md_get_dmabuf_fd (
806+ uintptr_t address , size_t length , ucs_sys_device_t sys_dev ,
807+ uct_cuda_copy_md_query_ctx_t * query_ctx )
785808{
786809#if CUDA_VERSION >= 11070
787810 unsigned long long flags = 0 ;
@@ -826,6 +849,10 @@ static int uct_cuda_copy_md_get_dmabuf_fd(uintptr_t address, size_t length,
826849 }
827850#endif
828851
852+ if (uct_cuda_copy_md_ensure_ctx_pushed (query_ctx ) != UCS_OK ) {
853+ return UCT_DMABUF_FD_INVALID ;
854+ }
855+
829856 cu_err = get_handle_func ((void * )& fd , address , length ,
830857 CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD , flags );
831858 if (cu_err == CUDA_SUCCESS ) {
@@ -842,9 +869,10 @@ static int uct_cuda_copy_md_get_dmabuf_fd(uintptr_t address, size_t length,
842869 return UCT_DMABUF_FD_INVALID ;
843870}
844871
845- uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf (const void * address ,
846- size_t length ,
847- ucs_sys_device_t sys_dev )
872+ uct_cuda_copy_md_dmabuf_t
873+ uct_cuda_copy_md_get_dmabuf (const void * address , size_t length ,
874+ ucs_sys_device_t sys_dev ,
875+ uct_cuda_copy_md_query_ctx_t * query_ctx )
848876{
849877 uct_cuda_copy_md_dmabuf_t dmabuf ;
850878 uintptr_t base_address , aligned_start , aligned_end ;
@@ -854,7 +882,7 @@ uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf(const void *address,
854882 aligned_end = ucs_align_up_pow2 (base_address + length , ucs_get_page_size ());
855883 dmabuf .fd = uct_cuda_copy_md_get_dmabuf_fd (aligned_start ,
856884 aligned_end - aligned_start ,
857- sys_dev );
885+ sys_dev , query_ctx );
858886 dmabuf .offset = base_address - aligned_start ;
859887 return dmabuf ;
860888}
@@ -863,7 +891,8 @@ static uint8_t
863891uct_cuda_copy_md_detect_mem_flags (uct_cuda_copy_md_t * md ,
864892 const ucs_memory_info_t * mem_info ,
865893 int is_async_managed ,
866- const uct_cuda_copy_md_dmabuf_t * dmabuf )
894+ const uct_cuda_copy_md_dmabuf_t * dmabuf ,
895+ uct_cuda_copy_md_query_ctx_t * query_ctx )
867896{
868897 int close_dmabuf = 0 ;
869898 uct_cuda_copy_md_dmabuf_t local_dmabuf ;
@@ -883,7 +912,8 @@ uct_cuda_copy_md_detect_mem_flags(uct_cuda_copy_md_t *md,
883912 if (dmabuf == NULL ) {
884913 local_dmabuf = uct_cuda_copy_md_get_dmabuf (mem_info -> base_address ,
885914 mem_info -> alloc_length ,
886- mem_info -> sys_dev );
915+ mem_info -> sys_dev ,
916+ query_ctx );
887917 dmabuf = & local_dmabuf ;
888918 close_dmabuf = 1 ;
889919 }
@@ -914,11 +944,14 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
914944 .fd = UCT_DMABUF_FD_INVALID ,
915945 .offset = 0
916946 };
917- int dmabuf_queried = 0 ;
918- int is_async_managed = 0 ;
919- CUcontext cuda_ctx = NULL ;
920- CUdevice cuda_device = CU_DEVICE_INVALID ;
921- int ctx_pushed = 0 ;
947+ uct_cuda_copy_md_query_ctx_t query_ctx = {
948+ .cuda_ctx = NULL ,
949+ .cuda_device = CU_DEVICE_INVALID ,
950+ .pushed_cuda_ctx = NULL ,
951+ .pushed_cuda_device = CU_DEVICE_INVALID
952+ };
953+ int dmabuf_queried = 0 ;
954+ int is_async_managed = 0 ;
922955 ucs_memory_info_t cached_mem_info ;
923956 ucs_memory_info_t addr_mem_info ;
924957 ucs_status_t cache_status ;
@@ -940,9 +973,10 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
940973 & cached_mem_info );
941974 status = uct_cuda_copy_md_query_attributes (md , address , length ,
942975 & addr_mem_info ,
943- & is_async_managed , & cuda_ctx ,
944- & cuda_device );
976+ & is_async_managed ,
977+ & query_ctx );
945978 if (status != UCS_OK ) {
979+ uct_cuda_copy_md_pop_ctx (& query_ctx );
946980 return status ;
947981 }
948982
@@ -972,20 +1006,11 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
9721006 mem_attr -> alloc_length = addr_mem_info .alloc_length ;
9731007 }
9741008
975- /* mem_flags detection requires a current context; push one if needed */
976- if ((cuda_device != CU_DEVICE_INVALID ) &&
977- ((mem_attr -> field_mask & (UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD |
978- UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_OFFSET )) ||
979- !is_async_managed )) {
980- ctx_pushed = (uct_cuda_copy_md_push_ctx (cuda_ctx , cuda_device ) ==
981- UCS_OK );
982- }
983-
9841009 if ((mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD ) ||
9851010 (mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_OFFSET )) {
9861011 dmabuf = uct_cuda_copy_md_get_dmabuf (addr_mem_info .base_address ,
9871012 addr_mem_info .alloc_length ,
988- addr_mem_info .sys_dev );
1013+ addr_mem_info .sys_dev , & query_ctx );
9891014 dmabuf_queried = 1 ;
9901015 if (mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD ) {
9911016 mem_attr -> dmabuf_fd = dmabuf .fd ;
@@ -1000,7 +1025,7 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
10001025 if (address != NULL ) {
10011026 addr_mem_info .mem_flags = uct_cuda_copy_md_detect_mem_flags (
10021027 md , & addr_mem_info , is_async_managed ,
1003- dmabuf_queried ? & dmabuf : NULL );
1028+ dmabuf_queried ? & dmabuf : NULL , & query_ctx );
10041029 ucs_memtype_cache_update (addr_mem_info .base_address ,
10051030 addr_mem_info .alloc_length , addr_mem_info .type ,
10061031 addr_mem_info .sys_dev ,
@@ -1021,10 +1046,7 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
10211046 ucs_close_fd (& dmabuf .fd );
10221047 }
10231048
1024- if (ctx_pushed ) {
1025- uct_cuda_copy_md_pop_ctx (cuda_ctx , cuda_device );
1026- }
1027-
1049+ uct_cuda_copy_md_pop_ctx (& query_ctx );
10281050 return UCS_OK ;
10291051}
10301052
0 commit comments