Skip to content

Commit 59475d7

Browse files
committed
Update L0 provider to use getpidfd function to open IPC handle from remote process
1 parent 61d5260 commit 59475d7

8 files changed

+91
-77
lines changed

src/provider/provider_level_zero.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,16 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
285285
return UMF_RESULT_ERROR_NOT_SUPPORTED;
286286
}
287287

288+
typedef struct ze_ipc_data_t {
289+
int pid;
290+
ze_ipc_mem_handle_t ze_handle;
291+
} ze_ipc_data_t;
292+
288293
static umf_result_t ze_memory_provider_get_ipc_handle_size(void *provider,
289294
size_t *size) {
290295
(void)provider;
291296
ASSERT(size != NULL);
292-
*size = sizeof(ze_ipc_mem_handle_t);
297+
*size = sizeof(ze_ipc_data_t);
293298
return UMF_RESULT_SUCCESS;
294299
}
295300

@@ -301,17 +306,19 @@ static umf_result_t ze_memory_provider_get_ipc_handle(void *provider,
301306
ASSERT(providerIpcData != NULL);
302307
(void)size;
303308
ze_result_t ze_result;
304-
ze_ipc_mem_handle_t *ze_ipc_handle = (ze_ipc_mem_handle_t *)providerIpcData;
309+
ze_ipc_data_t *ze_ipc_data = (ze_ipc_data_t *)providerIpcData;
305310
struct ze_memory_provider_t *ze_provider =
306311
(struct ze_memory_provider_t *)provider;
307312

308-
ze_result =
309-
g_ze_ops.zeMemGetIpcHandle(ze_provider->context, ptr, ze_ipc_handle);
313+
ze_result = g_ze_ops.zeMemGetIpcHandle(ze_provider->context, ptr,
314+
&ze_ipc_data->ze_handle);
310315
if (ze_result != ZE_RESULT_SUCCESS) {
311316
LOG_ERR("zeMemGetIpcHandle() failed.");
312317
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
313318
}
314319

320+
ze_ipc_data->pid = utils_getpid();
321+
315322
return UMF_RESULT_SUCCESS;
316323
}
317324

@@ -322,7 +329,7 @@ static umf_result_t ze_memory_provider_put_ipc_handle(void *provider,
322329
ze_result_t ze_result;
323330
struct ze_memory_provider_t *ze_provider =
324331
(struct ze_memory_provider_t *)provider;
325-
ze_ipc_mem_handle_t *ze_ipc_handle = (ze_ipc_mem_handle_t *)providerIpcData;
332+
ze_ipc_data_t *ze_ipc_data = (ze_ipc_data_t *)providerIpcData;
326333

327334
if (g_ze_ops.zeMemPutIpcHandle == NULL) {
328335
// g_ze_ops.zeMemPutIpcHandle can be NULL because it was introduced
@@ -331,8 +338,8 @@ static umf_result_t ze_memory_provider_put_ipc_handle(void *provider,
331338
return UMF_RESULT_SUCCESS;
332339
}
333340

334-
ze_result =
335-
g_ze_ops.zeMemPutIpcHandle(ze_provider->context, *ze_ipc_handle);
341+
ze_result = g_ze_ops.zeMemPutIpcHandle(ze_provider->context,
342+
ze_ipc_data->ze_handle);
336343
if (ze_result != ZE_RESULT_SUCCESS) {
337344
LOG_ERR("zeMemPutIpcHandle() failed.");
338345
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
@@ -347,12 +354,28 @@ static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
347354
ASSERT(providerIpcData != NULL);
348355
ASSERT(ptr != NULL);
349356
ze_result_t ze_result;
350-
ze_ipc_mem_handle_t *ze_ipc_handle = (ze_ipc_mem_handle_t *)providerIpcData;
357+
ze_ipc_data_t *ze_ipc_data = (ze_ipc_data_t *)providerIpcData;
351358
struct ze_memory_provider_t *ze_provider =
352359
(struct ze_memory_provider_t *)provider;
360+
int fd_local = -1;
361+
362+
if (ze_ipc_data->pid != utils_getpid()) {
363+
int fd_remote = -1;
364+
memcpy(&fd_remote, &ze_ipc_data->ze_handle, sizeof(fd_remote));
365+
fd_local = utils_duplicate_fd(ze_ipc_data->pid, fd_remote);
366+
if (fd_local == -1) {
367+
LOG_ERR("duplicating file descriptor failed");
368+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
369+
}
370+
memcpy(&ze_ipc_data->ze_handle, &fd_local, sizeof(fd_local));
371+
}
353372

354-
ze_result = g_ze_ops.zeMemOpenIpcHandle(
355-
ze_provider->context, ze_provider->device, *ze_ipc_handle, 0, ptr);
373+
ze_result =
374+
g_ze_ops.zeMemOpenIpcHandle(ze_provider->context, ze_provider->device,
375+
ze_ipc_data->ze_handle, 0, ptr);
376+
if (fd_local != -1) {
377+
utils_close_fd(fd_local);
378+
}
356379
if (ze_result != ZE_RESULT_SUCCESS) {
357380
LOG_ERR("zeMemOpenIpcHandle() failed.");
358381
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;

src/provider/provider_os_memory.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ create_fd_for_mmap(umf_os_memory_provider_params_t *in_params,
326326

327327
err_close_file:
328328
if (provider->fd > 0) {
329-
(void)os_close_fd(provider->fd);
329+
(void)utils_close_fd(provider->fd);
330330
}
331331

332332
return result;
@@ -1243,11 +1243,10 @@ static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
12431243
}
12441244
(void)os_shm_unlink(os_provider->shm_name);
12451245
} else {
1246-
umf_result_t umf_result =
1247-
os_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd, &fd);
1248-
if (umf_result != UMF_RESULT_SUCCESS) {
1249-
LOG_PERR("duplicating file descriptor failed");
1250-
return umf_result;
1246+
fd = utils_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd);
1247+
if (fd == -1) {
1248+
LOG_ERR("duplicating file descriptor failed");
1249+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
12511250
}
12521251
}
12531252

@@ -1259,7 +1258,7 @@ static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
12591258
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
12601259
}
12611260

1262-
(void)os_close_fd(fd);
1261+
(void)utils_close_fd(fd);
12631262

12641263
return ret;
12651264
}

src/provider/provider_os_memory_internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ size_t os_get_page_size(void);
9797

9898
void os_strerror(int errnum, char *buf, size_t buflen);
9999

100-
umf_result_t os_duplicate_fd(int pid, int fd_in, int *fd_out);
101-
102-
umf_result_t os_close_fd(int fd);
103-
104100
#ifdef __cplusplus
105101
}
106102
#endif

src/provider/provider_os_memory_posix.c

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -89,47 +89,3 @@ int os_purge(void *addr, size_t length, int advice) {
8989
void os_strerror(int errnum, char *buf, size_t buflen) {
9090
strerror_r(errnum, buf, buflen);
9191
}
92-
93-
umf_result_t os_duplicate_fd(int pid, int fd_in, int *fd_out) {
94-
// pidfd_getfd(2) is used to obtain a duplicate of another process's file descriptor.
95-
// Permission to duplicate another process's file descriptor
96-
// is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
97-
// that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
98-
// pidfd_getfd(2) is supported since Linux 5.6
99-
// pidfd_open(2) is supported since Linux 5.3
100-
#if defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd)
101-
errno = 0;
102-
int pid_fd = syscall(SYS_pidfd_open, pid, 0);
103-
if (pid_fd == -1) {
104-
LOG_PDEBUG("SYS_pidfd_open");
105-
return UMF_RESULT_ERROR_UNKNOWN;
106-
}
107-
108-
int fd_dup = syscall(SYS_pidfd_getfd, pid_fd, fd_in, 0);
109-
close(pid_fd);
110-
if (fd_dup == -1) {
111-
LOG_PDEBUG("SYS_pidfd_getfd");
112-
return UMF_RESULT_ERROR_UNKNOWN;
113-
}
114-
115-
*fd_out = fd_dup;
116-
117-
return UMF_RESULT_SUCCESS;
118-
#else
119-
// TODO: find another way to obtain a duplicate of another process's file descriptor
120-
(void)pid; // unused
121-
(void)fd_in; // unused
122-
(void)fd_out; // unused
123-
errno = ENOTSUP;
124-
return UMF_RESULT_ERROR_NOT_SUPPORTED; // unsupported
125-
#endif /* defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd) */
126-
}
127-
128-
umf_result_t os_close_fd(int fd) {
129-
if (close(fd)) {
130-
LOG_PERR("close() failed");
131-
return UMF_RESULT_ERROR_UNKNOWN;
132-
}
133-
134-
return UMF_RESULT_SUCCESS;
135-
}

src/provider/provider_os_memory_windows.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,3 @@ size_t os_get_page_size(void) {
139139
void os_strerror(int errnum, char *buf, size_t buflen) {
140140
strerror_s(buf, buflen, errnum);
141141
}
142-
143-
umf_result_t os_duplicate_fd(int pid, int fd_in, int *fd_out) {
144-
(void)pid; // unused
145-
(void)fd_in; // unused
146-
(void)fd_out; // unused
147-
return UMF_RESULT_ERROR_NOT_SUPPORTED; // unsupported
148-
}
149-
150-
umf_result_t os_close_fd(int fd) {
151-
(void)fd; // unused
152-
return UMF_RESULT_ERROR_NOT_SUPPORTED; // unsupported
153-
}

src/utils/utils_common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ int utils_getpid(void);
7777
// get the current thread ID
7878
int utils_gettid(void);
7979

80+
// close file descriptor
81+
int utils_close_fd(int fd);
82+
83+
// obtain a duplicate of another process's file descriptor
84+
int utils_duplicate_fd(int pid, int fd_in);
85+
8086
#ifdef __cplusplus
8187
}
8288
#endif

src/utils/utils_posix_common.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
*
88
*/
99

10+
#include <errno.h>
1011
#include <stdlib.h>
1112
#include <string.h>
1213
#include <sys/syscall.h>
1314
#include <unistd.h>
1415

1516
#include "utils_concurrency.h"
17+
#include "utils_log.h"
1618

1719
static UTIL_ONCE_FLAG Page_size_is_initialized = UTIL_ONCE_FLAG_INIT;
1820
static size_t Page_size;
@@ -38,3 +40,38 @@ int utils_gettid(void) {
3840
return syscall(SYS_gettid);
3941
#endif
4042
}
43+
44+
int utils_close_fd(int fd) { return close(fd); }
45+
46+
int utils_duplicate_fd(int pid, int fd_in) {
47+
// pidfd_getfd(2) is used to obtain a duplicate of another process's file descriptor.
48+
// Permission to duplicate another process's file descriptor
49+
// is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
50+
// that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
51+
// pidfd_getfd(2) is supported since Linux 5.6
52+
// pidfd_open(2) is supported since Linux 5.3
53+
#if defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd)
54+
errno = 0;
55+
int pid_fd = syscall(SYS_pidfd_open, pid, 0);
56+
if (pid_fd == -1) {
57+
LOG_PERR("SYS_pidfd_open");
58+
return -1;
59+
}
60+
61+
int fd_dup = syscall(SYS_pidfd_getfd, pid_fd, fd_in, 0);
62+
close(pid_fd);
63+
if (fd_dup == -1) {
64+
LOG_PERR("SYS_pidfd_getfd");
65+
return -1;
66+
}
67+
68+
return fd_dup;
69+
#else
70+
// TODO: find another way to obtain a duplicate of another process's file descriptor
71+
(void)pid; // unused
72+
(void)fd_in; // unused
73+
errno = ENOTSUP; // unsupported
74+
LOG_ERR("__NR_pidfd_open or __NR_pidfd_getfd not available");
75+
return -1;
76+
#endif /* defined(__NR_pidfd_open) && defined(__NR_pidfd_getfd) */
77+
}

src/utils/utils_windows_common.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,12 @@ size_t util_get_page_size(void) {
3333
int utils_getpid(void) { return GetCurrentProcessId(); }
3434

3535
int utils_gettid(void) { return GetCurrentThreadId(); }
36+
37+
int utils_close_fd(int fd) { return -1; }
38+
39+
int utils_duplicate_fd(int pid, int fd_in) {
40+
// TODO: find another way to obtain a duplicate of another process's file descriptor
41+
(void)pid; // unused
42+
(void)fd_in; // unused
43+
return -1;
44+
}

0 commit comments

Comments
 (0)