@@ -589,110 +589,71 @@ static size_t uct_cuda_copy_md_get_total_device_mem(CUdevice cuda_device)
589589 return 1 ; /* return 1 byte to avoid division by zero */
590590}
591591
592- struct uct_cuda_copy_md_query_ctx {
593- CUcontext cuda_ctx ; /* memory's owning context, or NULL */
594- CUdevice cuda_device ; /* owning device, or CU_DEVICE_INVALID */
595- CUcontext pushed_cuda_ctx ; /* context pushed by this query, if any */
596- CUdevice pushed_cuda_device ; /* device whose primary ctx was pushed */
597- };
598-
599- static ucs_status_t
600- uct_cuda_copy_md_ensure_ctx_pushed (uct_cuda_copy_md_query_ctx_t * query_ctx ,
601- ucs_log_level_t log_level )
602- {
603- ucs_status_t status ;
604-
605- if ((query_ctx == NULL ) ||
606- ((query_ctx -> cuda_ctx == NULL ) &&
607- (query_ctx -> cuda_device == CU_DEVICE_INVALID ))) {
608- return UCS_OK ;
609- }
610-
611- if ((query_ctx -> pushed_cuda_ctx != NULL ) ||
612- (query_ctx -> pushed_cuda_device != CU_DEVICE_INVALID )) {
613- return UCS_OK ;
614- }
615-
616- if (query_ctx -> cuda_ctx == NULL ) {
617- status = uct_cuda_ctx_primary_push (query_ctx -> cuda_device , 0 ,
618- log_level );
619- if (status == UCS_OK ) {
620- query_ctx -> pushed_cuda_device = query_ctx -> cuda_device ;
621- }
622- } else {
623- status = UCT_CUDADRV_FUNC (cuCtxPushCurrent (query_ctx -> cuda_ctx ),
624- log_level );
625- if (status == UCS_OK ) {
626- query_ctx -> pushed_cuda_ctx = query_ctx -> cuda_ctx ;
627- }
628- }
629-
630- return status ;
631- }
632-
633- static void
634- uct_cuda_copy_md_pop_ctx (uct_cuda_copy_md_query_ctx_t * query_ctx )
635- {
636- uct_cuda_ctx_pop_and_release (query_ctx -> pushed_cuda_device ,
637- query_ctx -> pushed_cuda_ctx );
638- query_ctx -> pushed_cuda_device = CU_DEVICE_INVALID ;
639- query_ctx -> pushed_cuda_ctx = NULL ;
640- }
641-
642592static void uct_cuda_copy_md_sync_memops_get_address_range (
643593 const uct_cuda_copy_md_t * md , CUdeviceptr address , size_t length ,
644- int is_vmm , ucs_memory_info_t * mem_info ,
645- uct_cuda_copy_md_query_ctx_t * query_ctx )
594+ CUcontext cuda_ctx , CUdevice cuda_device , int is_vmm ,
595+ ucs_memory_info_t * mem_info )
646596{
597+ CUcontext tmp_ctx ;
647598 CUdeviceptr base_address ;
648599 size_t alloc_length ;
649600 size_t total_bytes ;
601+ ucs_status_t status ;
650602
651603 mem_info -> base_address = (void * )address ;
652604 mem_info -> alloc_length = length ;
653605
654- /* sync memops and cuMemGetAddressRange below need a current context */
655- if (uct_cuda_copy_md_ensure_ctx_pushed (query_ctx , UCS_LOG_LEVEL_ERROR ) !=
656- UCS_OK ) {
606+ if (cuda_ctx == NULL ) {
607+ status = uct_cuda_ctx_primary_push (cuda_device , 0 , UCS_LOG_LEVEL_ERROR );
608+ } else {
609+ status = UCT_CUDADRV_FUNC_LOG_ERR (cuCtxPushCurrent (cuda_ctx ));
610+ }
611+ if (status != UCS_OK ) {
657612 return ;
658613 }
659614
615+ /* Wrapped the method by push/pop CUDA context since it sets
616+ CU_CTX_SYNC_MEMOPS flag for the current context */
660617 uct_cuda_copy_sync_memops (address , is_vmm );
661618
662619 if (md -> config .alloc_whole_reg == UCS_CONFIG_OFF ) {
663620 /* Extending the registration range is disable by configuration */
664- return ;
621+ goto out_ctx_pop ;
665622 }
666623
667624 if (UCT_CUDADRV_FUNC_LOG_DEBUG (
668625 cuMemGetAddressRange (& base_address , & alloc_length , address )) !=
669626 UCS_OK ) {
670- return ;
627+ goto out_ctx_pop ;
671628 }
672629
673630 ucs_trace ("query address 0x%llx: 0x%llx..0x%llx length %zu" , address ,
674631 base_address , base_address + alloc_length , alloc_length );
675632
676633 if (md -> config .alloc_whole_reg == UCS_CONFIG_AUTO ) {
677- total_bytes = uct_cuda_copy_md_get_total_device_mem (
678- query_ctx -> cuda_device );
634+ total_bytes = uct_cuda_copy_md_get_total_device_mem (cuda_device );
679635 if (alloc_length > (total_bytes * md -> config .max_reg_ratio )) {
680- return ;
636+ goto out_ctx_pop ;
681637 }
682638 } else {
683639 ucs_assert (md -> config .alloc_whole_reg == UCS_CONFIG_ON );
684640 }
685641
686642 mem_info -> base_address = (void * )base_address ;
687643 mem_info -> alloc_length = alloc_length ;
644+
645+ out_ctx_pop :
646+ UCT_CUDADRV_FUNC_LOG_WARN (cuCtxPopCurrent (& tmp_ctx ));
647+ if (cuda_ctx == NULL ) {
648+ UCT_CUDADRV_FUNC_LOG_WARN (cuDevicePrimaryCtxRelease (cuda_device ));
649+ }
688650}
689651
690652static ucs_status_t
691653uct_cuda_copy_md_query_attributes (const uct_cuda_copy_md_t * md ,
692654 const void * address , size_t length ,
693655 ucs_memory_info_t * mem_info ,
694- int * is_async_managed , int * is_host_located ,
695- uct_cuda_copy_md_query_ctx_t * query_ctx )
656+ int * is_async_managed , int * is_host_located )
696657{
697658#define UCT_CUDA_MEM_QUERY_NUM_ATTRS 4
698659 CUmemorytype cuda_mem_type = CU_MEMORYTYPE_HOST ;
@@ -715,8 +676,6 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
715676 if (mem_info -> type == UCS_MEMORY_TYPE_UNKNOWN ) {
716677 return UCS_ERR_INVALID_ADDR ;
717678 }
718-
719- query_ctx -> cuda_device = cuda_device ;
720679 } else {
721680 attr_type [0 ] = CU_POINTER_ATTRIBUTE_MEMORY_TYPE ;
722681 attr_data [0 ] = & cuda_mem_type ;
@@ -741,9 +700,6 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
741700 return UCS_ERR_INVALID_ADDR ;
742701 }
743702
744- query_ctx -> cuda_ctx = cuda_mem_ctx ;
745- query_ctx -> cuda_device = cuda_device ;
746-
747703 if (is_managed ) {
748704 /* cuMemGetAddress range does not support managed memory so use
749705 * provided address and length as base address and alloc length
@@ -799,8 +755,9 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
799755 }
800756
801757 uct_cuda_copy_md_sync_memops_get_address_range (md , (CUdeviceptr )address ,
802- length , is_vmm , mem_info ,
803- query_ctx );
758+ length , cuda_mem_ctx ,
759+ cuda_device , is_vmm ,
760+ mem_info );
804761 return UCS_OK ;
805762
806763out_default_range :
@@ -809,9 +766,8 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
809766 return UCS_OK ;
810767}
811768
812- static int uct_cuda_copy_md_get_dmabuf_fd (
813- uintptr_t address , size_t length , ucs_sys_device_t sys_dev ,
814- uct_cuda_copy_md_query_ctx_t * query_ctx )
769+ static int uct_cuda_copy_md_get_dmabuf_fd (uintptr_t address , size_t length ,
770+ ucs_sys_device_t sys_dev )
815771{
816772#if CUDA_VERSION >= 11070
817773 unsigned long long flags = 0 ;
@@ -856,10 +812,6 @@ static int uct_cuda_copy_md_get_dmabuf_fd(
856812 }
857813#endif
858814
859- /* Best-effort. If the push fails, still attempt the export with
860- * whatever context is current. */
861- (void )uct_cuda_copy_md_ensure_ctx_pushed (query_ctx , UCS_LOG_LEVEL_DEBUG );
862-
863815 cu_err = get_handle_func ((void * )& fd , address , length ,
864816 CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD , flags );
865817 if (cu_err == CUDA_SUCCESS ) {
@@ -876,10 +828,9 @@ static int uct_cuda_copy_md_get_dmabuf_fd(
876828 return UCT_DMABUF_FD_INVALID ;
877829}
878830
879- uct_cuda_copy_md_dmabuf_t
880- uct_cuda_copy_md_get_dmabuf (const void * address , size_t length ,
881- ucs_sys_device_t sys_dev ,
882- uct_cuda_copy_md_query_ctx_t * query_ctx )
831+ uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf (const void * address ,
832+ size_t length ,
833+ ucs_sys_device_t sys_dev )
883834{
884835 uct_cuda_copy_md_dmabuf_t dmabuf ;
885836 uintptr_t base_address , aligned_start , aligned_end ;
@@ -889,7 +840,7 @@ uct_cuda_copy_md_get_dmabuf(const void *address, size_t length,
889840 aligned_end = ucs_align_up_pow2 (base_address + length , ucs_get_page_size ());
890841 dmabuf .fd = uct_cuda_copy_md_get_dmabuf_fd (aligned_start ,
891842 aligned_end - aligned_start ,
892- sys_dev , query_ctx );
843+ sys_dev );
893844 dmabuf .offset = base_address - aligned_start ;
894845 return dmabuf ;
895846}
@@ -898,8 +849,7 @@ static uint8_t
898849uct_cuda_copy_md_detect_mem_flags (uct_cuda_copy_md_t * md ,
899850 const ucs_memory_info_t * mem_info ,
900851 int is_async_managed , int is_host_located ,
901- const uct_cuda_copy_md_dmabuf_t * dmabuf ,
902- uct_cuda_copy_md_query_ctx_t * query_ctx )
852+ const uct_cuda_copy_md_dmabuf_t * dmabuf )
903853{
904854 int close_dmabuf = 0 ;
905855 uct_cuda_copy_md_dmabuf_t local_dmabuf ;
@@ -924,8 +874,7 @@ uct_cuda_copy_md_detect_mem_flags(uct_cuda_copy_md_t *md,
924874 if (dmabuf == NULL ) {
925875 local_dmabuf = uct_cuda_copy_md_get_dmabuf (mem_info -> base_address ,
926876 mem_info -> alloc_length ,
927- mem_info -> sys_dev ,
928- query_ctx );
877+ mem_info -> sys_dev );
929878 dmabuf = & local_dmabuf ;
930879 close_dmabuf = 1 ;
931880 }
@@ -956,15 +905,11 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
956905 .fd = UCT_DMABUF_FD_INVALID ,
957906 .offset = 0
958907 };
959- uct_cuda_copy_md_query_ctx_t query_ctx = {
960- .cuda_ctx = NULL ,
961- .cuda_device = CU_DEVICE_INVALID ,
962- .pushed_cuda_ctx = NULL ,
963- .pushed_cuda_device = CU_DEVICE_INVALID
964- };
965- int dmabuf_queried = 0 ;
966- int is_async_managed = 0 ;
967- int is_host_located = 0 ;
908+ int dmabuf_queried = 0 ;
909+ int is_async_managed = 0 ;
910+ int is_host_located = 0 ;
911+ CUdevice cur_cuda_device = CU_DEVICE_INVALID ;
912+ CUdevice avail_cuda_device = CU_DEVICE_INVALID ;
968913 ucs_memory_info_t cached_mem_info ;
969914 ucs_memory_info_t addr_mem_info ;
970915 ucs_status_t cache_status ;
@@ -987,10 +932,8 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
987932 status = uct_cuda_copy_md_query_attributes (md , address , length ,
988933 & addr_mem_info ,
989934 & is_async_managed ,
990- & is_host_located ,
991- & query_ctx );
935+ & is_host_located );
992936 if (status != UCS_OK ) {
993- uct_cuda_copy_md_pop_ctx (& query_ctx );
994937 return status ;
995938 }
996939
@@ -1020,11 +963,22 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
1020963 mem_attr -> alloc_length = addr_mem_info .alloc_length ;
1021964 }
1022965
966+ /* dmabuf export and mem_flags detection require a current context on the
967+ * memory's device; reuse the current one if suitable, otherwise push it */
968+ if (addr_mem_info .sys_dev != UCS_SYS_DEVICE_ID_UNKNOWN ) {
969+ if (uct_cuda_ctx_primary_push_avail (0 , addr_mem_info .sys_dev ,
970+ & cur_cuda_device , & avail_cuda_device ,
971+ UCS_LOG_LEVEL_DEBUG ) != UCS_OK ) {
972+ /* best-effort: continue with whatever context is current */
973+ avail_cuda_device = cur_cuda_device ;
974+ }
975+ }
976+
1023977 if ((mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD ) ||
1024978 (mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_OFFSET )) {
1025979 dmabuf = uct_cuda_copy_md_get_dmabuf (addr_mem_info .base_address ,
1026980 addr_mem_info .alloc_length ,
1027- addr_mem_info .sys_dev , & query_ctx );
981+ addr_mem_info .sys_dev );
1028982 dmabuf_queried = 1 ;
1029983 if (mem_attr -> field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD ) {
1030984 mem_attr -> dmabuf_fd = dmabuf .fd ;
@@ -1039,7 +993,7 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
1039993 if (address != NULL ) {
1040994 addr_mem_info .mem_flags = uct_cuda_copy_md_detect_mem_flags (
1041995 md , & addr_mem_info , is_async_managed , is_host_located ,
1042- dmabuf_queried ? & dmabuf : NULL , & query_ctx );
996+ dmabuf_queried ? & dmabuf : NULL );
1043997 ucs_memtype_cache_update (addr_mem_info .base_address ,
1044998 addr_mem_info .alloc_length , addr_mem_info .type ,
1045999 addr_mem_info .sys_dev ,
@@ -1060,7 +1014,10 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
10601014 ucs_close_fd (& dmabuf .fd );
10611015 }
10621016
1063- uct_cuda_copy_md_pop_ctx (& query_ctx );
1017+ if (cur_cuda_device != avail_cuda_device ) {
1018+ uct_cuda_ctx_primary_pop_and_release (avail_cuda_device );
1019+ }
1020+
10641021 return UCS_OK ;
10651022}
10661023
0 commit comments