Skip to content

Commit 67c657c

Browse files
committed
Update L0 provider to use getpidfd function to open IPC handle from remote process
1 parent d5477ec commit 67c657c

8 files changed

+121
-72
lines changed

src/provider/provider_level_zero.c

Lines changed: 33 additions & 9 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,29 @@ 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+
ze_ipc_mem_handle_t ze_ipc_handle = ze_ipc_data->ze_handle;
362+
363+
if (ze_ipc_data->pid != utils_getpid()) {
364+
int fd_remote = -1;
365+
memcpy(&fd_remote, &ze_ipc_handle, sizeof(fd_remote));
366+
umf_result_t umf_result =
367+
utils_duplicate_fd(ze_ipc_data->pid, fd_remote, &fd_local);
368+
if (umf_result != UMF_RESULT_SUCCESS) {
369+
LOG_PERR("duplicating file descriptor failed");
370+
return umf_result;
371+
}
372+
memcpy(&ze_ipc_handle, &fd_local, sizeof(fd_local));
373+
}
353374

354375
ze_result = g_ze_ops.zeMemOpenIpcHandle(
355-
ze_provider->context, ze_provider->device, *ze_ipc_handle, 0, ptr);
376+
ze_provider->context, ze_provider->device, ze_ipc_handle, 0, ptr);
377+
if (fd_local != -1) {
378+
(void)utils_close_fd(fd_local);
379+
}
356380
if (ze_result != ZE_RESULT_SUCCESS) {
357381
LOG_ERR("zeMemOpenIpcHandle() failed.");
358382
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;

src/provider/provider_os_memory.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ create_fd_for_mmap(umf_os_memory_provider_params_t *in_params,
325325

326326
err_close_file:
327327
if (provider->fd > 0) {
328-
(void)os_close_fd(provider->fd);
328+
(void)utils_close_fd(provider->fd);
329329
}
330330

331331
return result;
@@ -1247,7 +1247,7 @@ static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
12471247
(void)os_shm_unlink(os_provider->shm_name);
12481248
} else {
12491249
umf_result_t umf_result =
1250-
os_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd, &fd);
1250+
utils_duplicate_fd(os_ipc_data->pid, os_ipc_data->fd, &fd);
12511251
if (umf_result != UMF_RESULT_SUCCESS) {
12521252
LOG_PERR("duplicating file descriptor failed");
12531253
return umf_result;
@@ -1262,7 +1262,7 @@ static umf_result_t os_open_ipc_handle(void *provider, void *providerIpcData,
12621262
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
12631263
}
12641264

1265-
(void)os_close_fd(fd);
1265+
(void)utils_close_fd(fd);
12661266

12671267
return ret;
12681268
}

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
@@ -151,15 +151,3 @@ size_t os_get_page_size(void) {
151151
void os_strerror(int errnum, char *buf, size_t buflen) {
152152
strerror_s(buf, buflen, errnum);
153153
}
154-
155-
umf_result_t os_duplicate_fd(int pid, int fd_in, int *fd_out) {
156-
(void)pid; // unused
157-
(void)fd_in; // unused
158-
(void)fd_out; // unused
159-
return UMF_RESULT_ERROR_NOT_SUPPORTED; // unsupported
160-
}
161-
162-
umf_result_t os_close_fd(int fd) {
163-
(void)fd; // unused
164-
return UMF_RESULT_ERROR_NOT_SUPPORTED; // unsupported
165-
}

src/utils/utils_common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <stddef.h>
1515
#include <stdint.h>
1616

17+
#include <umf/base.h>
18+
1719
#ifdef __cplusplus
1820
extern "C" {
1921
#endif
@@ -77,6 +79,12 @@ int utils_getpid(void);
7779
// get the current thread ID
7880
int utils_gettid(void);
7981

82+
// close file descriptor
83+
int utils_close_fd(int fd);
84+
85+
// obtain a duplicate of another process's file descriptor
86+
umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out);
87+
8088
#ifdef __cplusplus
8189
}
8290
#endif

src/utils/utils_posix_common.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,22 @@
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

16+
#include "utils_common.h"
1517
#include "utils_concurrency.h"
18+
#include "utils_log.h"
19+
20+
#ifndef __NR_pidfd_open
21+
#define __NR_pidfd_open 434 /* Syscall id */
22+
#endif
23+
#ifndef __NR_pidfd_getfd
24+
#define __NR_pidfd_getfd 438 /* Syscall id */
25+
#endif
1626

1727
static UTIL_ONCE_FLAG Page_size_is_initialized = UTIL_ONCE_FLAG_INIT;
1828
static size_t Page_size;
@@ -38,3 +48,57 @@ int utils_gettid(void) {
3848
return syscall(SYS_gettid);
3949
#endif
4050
}
51+
52+
int utils_close_fd(int fd) { return close(fd); }
53+
54+
static umf_result_t errno_to_umf_result(int err) {
55+
switch (err) {
56+
case EBADF:
57+
case EINVAL:
58+
case ESRCH:
59+
case EPERM:
60+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
61+
case EMFILE:
62+
case ENOMEM:
63+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
64+
case ENODEV:
65+
case ENOSYS:
66+
case ENOTSUP:
67+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
68+
default:
69+
return UMF_RESULT_ERROR_UNKNOWN;
70+
}
71+
}
72+
73+
umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) {
74+
#ifdef __APPLE__
75+
(void)pid; // unused
76+
(void)fd_in; // unused
77+
(void)fd_out; // unused
78+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
79+
#else
80+
// pidfd_getfd(2) is used to obtain a duplicate of another process's file descriptor.
81+
// Permission to duplicate another process's file descriptor
82+
// is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
83+
// that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
84+
// pidfd_getfd(2) is supported since Linux 5.6
85+
// pidfd_open(2) is supported since Linux 5.3
86+
errno = 0;
87+
int pid_fd = syscall(__NR_pidfd_open, pid, 0);
88+
if (pid_fd == -1) {
89+
LOG_PERR("__NR_pidfd_open");
90+
return errno_to_umf_result(errno);
91+
}
92+
93+
int fd_dup = syscall(__NR_pidfd_getfd, pid_fd, fd_in, 0);
94+
close(pid_fd);
95+
if (fd_dup == -1) {
96+
LOG_PERR("__NR_pidfd_open");
97+
return errno_to_umf_result(errno);
98+
}
99+
100+
*fd_out = fd_dup;
101+
102+
return UMF_RESULT_SUCCESS;
103+
#endif
104+
}

src/utils/utils_windows_common.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <processenv.h>
1313
#include <processthreadsapi.h>
1414

15+
#include "utils_common.h"
1516
#include "utils_concurrency.h"
1617

1718
#define BUFFER_SIZE 1024
@@ -33,3 +34,15 @@ size_t util_get_page_size(void) {
3334
int utils_getpid(void) { return GetCurrentProcessId(); }
3435

3536
int utils_gettid(void) { return GetCurrentThreadId(); }
37+
38+
int utils_close_fd(int fd) {
39+
(void)fd; // unused
40+
return -1;
41+
}
42+
43+
umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) {
44+
(void)pid; // unused
45+
(void)fd_in; // unused
46+
(void)fd_out; // unused
47+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
48+
}

0 commit comments

Comments
 (0)