Skip to content

Commit be6bdd2

Browse files
committed
UCT/CUDA_COPY: Track pushed context
And fix CR comments
1 parent 65d1073 commit be6bdd2

4 files changed

Lines changed: 127 additions & 90 deletions

File tree

src/uct/cuda/cuda_copy/cuda_copy_md.c

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
589596
static 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

599629
static 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

610638
static 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

660685
static ucs_status_t
661686
uct_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

777799
out_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
863891
uct_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

src/uct/cuda/cuda_copy/cuda_copy_md.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ typedef struct {
7272
} uct_cuda_copy_md_dmabuf_t;
7373

7474

75+
/**
76+
* CUDA context state for a single memory query
77+
*/
78+
typedef struct uct_cuda_copy_md_query_ctx uct_cuda_copy_md_query_ctx_t;
79+
80+
7581
ucs_status_t uct_cuda_copy_md_detect_memory_type(uct_md_h md,
7682
const void *address,
7783
size_t length,
@@ -98,10 +104,14 @@ int uct_cuda_copy_md_is_dmabuf_supported();
98104
file descriptor can be used by a Direct NIC. If sys_dev
99105
is UCS_SYS_DEVICE_ID_UNKNOWN, the file descriptor can
100106
be used by any device.
107+
* @param query_ctx [inout] Optional context state (see
108+
* uct_cuda_copy_md_query_ctx_t); NULL relies on the
109+
* caller's current context.
101110
* @return The dmabuf file descriptor and offset
102111
*/
103-
uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf(const void *address,
104-
size_t length,
105-
ucs_sys_device_t sys_dev);
112+
uct_cuda_copy_md_dmabuf_t
113+
uct_cuda_copy_md_get_dmabuf(const void *address, size_t length,
114+
ucs_sys_device_t sys_dev,
115+
uct_cuda_copy_md_query_ctx_t *query_ctx);
106116

107117
#endif

src/uct/ib/mlx5/gdaki/gdaki.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static int uct_gdaki_check_umem_dmabuf(const uct_ib_md_t *md)
152152
}
153153

154154
dmabuf = uct_cuda_copy_md_get_dmabuf((void*)buff, 1,
155-
UCS_SYS_DEVICE_ID_UNKNOWN);
155+
UCS_SYS_DEVICE_ID_UNKNOWN, NULL);
156156
if (dmabuf.fd == UCT_DMABUF_FD_INVALID) {
157157
goto out_free;
158158
}
@@ -337,7 +337,7 @@ uct_rc_gdaki_umem_reg(const uct_ib_md_t *md, struct ibv_context *ibv_context,
337337

338338
if (uct_gdaki_get_driver_features(md) & UCT_GDAKI_DMABUF_UMEM) {
339339
dmabuf = uct_cuda_copy_md_get_dmabuf(address, length,
340-
UCS_SYS_DEVICE_ID_UNKNOWN);
340+
UCS_SYS_DEVICE_ID_UNKNOWN, NULL);
341341
}
342342

343343
if (dmabuf.fd == UCT_DMABUF_FD_INVALID) {

0 commit comments

Comments
 (0)