Rozhuk Ivan
2024-01-19 11:10:47 UTC
Hi!
graphics/mesa-* uses SYS_kcmp [1] to compare two fds:
int
os_same_file_description(int fd1, int fd2)
{
pid_t pid = getpid();
/* Same file descriptor trivially implies same file description */
if (fd1 == fd2)
return 0;
return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2);
}
FreeBSD does not implemet this and we got in terminal:
"amdgpu: os_same_file_description couldn't determine if two DRM fds reference the same file description."
Mesa say:
/* DRM file descriptors, file descriptions and buffer sharing.
*
* amdgpu_device_initialize first argument is a file descriptor (fd)
* representing a specific GPU.
* If a fd is duplicated using os_dupfd_cloexec,
* the file description will remain the same (os_same_file_description will
* return 0).
* But if the same device is re-opened, the fd and the file description will
* be different.
*
* amdgpu_screen_winsys's fd tracks the file description which was
* given to amdgpu_winsys_create. This is the fd used by the application
* using the driver and may be used in other ioctl (eg: drmModeAddFB)
*
* amdgpu_winsys's fd is the file description used to initialize the
* device handle in libdrm_amdgpu.
*
* The 2 fds can be different, even in systems with a single GPU, eg: if
* radv is initialized before radeonsi.
*
* This fd tracking is useful for buffer sharing because KMS/GEM handles are
* specific to a DRM file description, i.e. the same handle value may refer
* to different underlying BOs in different DRM file descriptions.
* As an example, if an app wants to use drmModeAddFB it'll need a KMS handle
* valid for its fd (== amdgpu_screen_winsys::fd).
* If both fds are identical, there's nothing to do: bo->u.real.kms_handle
* can be used directly (see amdgpu_bo_get_handle).
* If they're different, the BO has to be exported from the device fd as
* a dma-buf, then imported from the app fd as a KMS handle.
*/
I do few checks with dup() and os_dupfd_cloexec() and code show that fd equal.
Does this implementation will do that mesa expects?
#include <sys/user.h>
#include <fcntl.h>
int
os_same_file_description(int fd1, int fd2) {
struct kinfo_file kif1, kif2;
/* Same file descriptor trivially implies same file description */
if (fd1 == fd2)
return (0);
kif1.kf_structsize = sizeof(kif1);
kif2.kf_structsize = sizeof(kif2);
if (-1 == fcntl(fd1, F_KINFO, &kif1) ||
-1 == fcntl(fd2, F_KINFO, &kif2))
return (-1);
if (kif1.kf_type != kif2.kf_type ||
0 != memcmp(&kif1.kf_path, &kif2.kf_path, sizeof(kif1.kf_path)))
return (3);
switch (kif1.kf_type) {
case KF_TYPE_VNODE:
if (0 == memcmp(&kif1.kf_un.kf_file, &kif2.kf_un.kf_file,
sizeof(kif1.kf_un.kf_file)))
return (0);
return (3);
case KF_TYPE_SOCKET:
if (0 == memcmp(&kif1.kf_un.kf_sock, &kif2.kf_un.kf_sock,
sizeof(kif1.kf_un.kf_sock)))
return (0);
return (3);
case KF_TYPE_PIPE:
if (0 == memcmp(&kif1.kf_un.kf_pipe, &kif2.kf_un.kf_pipe,
sizeof(kif1.kf_un.kf_pipe)))
return (0);
return (3);
//case KF_TYPE_FIFO:
case KF_TYPE_KQUEUE:
if (0 == memcmp(&kif1.kf_un.kf_kqueue, &kif2.kf_un.kf_kqueue,
sizeof(kif1.kf_un.kf_kqueue)))
return (0);
return (3);
//case KF_TYPE_MQUEUE:
//case KF_TYPE_SHM:
case KF_TYPE_SEM:
if (0 == memcmp(&kif1.kf_un.kf_sem, &kif2.kf_un.kf_sem,
sizeof(kif1.kf_un.kf_sem)))
return (0);
return (3);
case KF_TYPE_PTS:
if (0 == memcmp(&kif1.kf_un.kf_pts, &kif2.kf_un.kf_pts,
sizeof(kif1.kf_un.kf_pts)))
return (0);
return (3);
case KF_TYPE_PROCDESC:
if (0 == memcmp(&kif1.kf_un.kf_proc, &kif2.kf_un.kf_proc,
sizeof(kif1.kf_un.kf_proc)))
return (0);
return (3);
//case KF_TYPE_DEV:
case KF_TYPE_EVENTFD:
if (0 == memcmp(&kif1.kf_un.kf_eventfd, &kif2.kf_un.kf_eventfd,
sizeof(kif1.kf_un.kf_eventfd)))
return (0);
return (3);
case KF_TYPE_TIMERFD:
if (0 == memcmp(&kif1.kf_un.kf_timerfd, &kif2.kf_un.kf_timerfd,
sizeof(kif1.kf_un.kf_timerfd)))
return (0);
return (3);
}
/* Otherwise we can't tell */
return (-1);
}
Refs:
1. https://man7.org/linux/man-pages/man2/kcmp.2.html
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
graphics/mesa-* uses SYS_kcmp [1] to compare two fds:
int
os_same_file_description(int fd1, int fd2)
{
pid_t pid = getpid();
/* Same file descriptor trivially implies same file description */
if (fd1 == fd2)
return 0;
return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2);
}
FreeBSD does not implemet this and we got in terminal:
"amdgpu: os_same_file_description couldn't determine if two DRM fds reference the same file description."
Mesa say:
/* DRM file descriptors, file descriptions and buffer sharing.
*
* amdgpu_device_initialize first argument is a file descriptor (fd)
* representing a specific GPU.
* If a fd is duplicated using os_dupfd_cloexec,
* the file description will remain the same (os_same_file_description will
* return 0).
* But if the same device is re-opened, the fd and the file description will
* be different.
*
* amdgpu_screen_winsys's fd tracks the file description which was
* given to amdgpu_winsys_create. This is the fd used by the application
* using the driver and may be used in other ioctl (eg: drmModeAddFB)
*
* amdgpu_winsys's fd is the file description used to initialize the
* device handle in libdrm_amdgpu.
*
* The 2 fds can be different, even in systems with a single GPU, eg: if
* radv is initialized before radeonsi.
*
* This fd tracking is useful for buffer sharing because KMS/GEM handles are
* specific to a DRM file description, i.e. the same handle value may refer
* to different underlying BOs in different DRM file descriptions.
* As an example, if an app wants to use drmModeAddFB it'll need a KMS handle
* valid for its fd (== amdgpu_screen_winsys::fd).
* If both fds are identical, there's nothing to do: bo->u.real.kms_handle
* can be used directly (see amdgpu_bo_get_handle).
* If they're different, the BO has to be exported from the device fd as
* a dma-buf, then imported from the app fd as a KMS handle.
*/
I do few checks with dup() and os_dupfd_cloexec() and code show that fd equal.
Does this implementation will do that mesa expects?
#include <sys/user.h>
#include <fcntl.h>
int
os_same_file_description(int fd1, int fd2) {
struct kinfo_file kif1, kif2;
/* Same file descriptor trivially implies same file description */
if (fd1 == fd2)
return (0);
kif1.kf_structsize = sizeof(kif1);
kif2.kf_structsize = sizeof(kif2);
if (-1 == fcntl(fd1, F_KINFO, &kif1) ||
-1 == fcntl(fd2, F_KINFO, &kif2))
return (-1);
if (kif1.kf_type != kif2.kf_type ||
0 != memcmp(&kif1.kf_path, &kif2.kf_path, sizeof(kif1.kf_path)))
return (3);
switch (kif1.kf_type) {
case KF_TYPE_VNODE:
if (0 == memcmp(&kif1.kf_un.kf_file, &kif2.kf_un.kf_file,
sizeof(kif1.kf_un.kf_file)))
return (0);
return (3);
case KF_TYPE_SOCKET:
if (0 == memcmp(&kif1.kf_un.kf_sock, &kif2.kf_un.kf_sock,
sizeof(kif1.kf_un.kf_sock)))
return (0);
return (3);
case KF_TYPE_PIPE:
if (0 == memcmp(&kif1.kf_un.kf_pipe, &kif2.kf_un.kf_pipe,
sizeof(kif1.kf_un.kf_pipe)))
return (0);
return (3);
//case KF_TYPE_FIFO:
case KF_TYPE_KQUEUE:
if (0 == memcmp(&kif1.kf_un.kf_kqueue, &kif2.kf_un.kf_kqueue,
sizeof(kif1.kf_un.kf_kqueue)))
return (0);
return (3);
//case KF_TYPE_MQUEUE:
//case KF_TYPE_SHM:
case KF_TYPE_SEM:
if (0 == memcmp(&kif1.kf_un.kf_sem, &kif2.kf_un.kf_sem,
sizeof(kif1.kf_un.kf_sem)))
return (0);
return (3);
case KF_TYPE_PTS:
if (0 == memcmp(&kif1.kf_un.kf_pts, &kif2.kf_un.kf_pts,
sizeof(kif1.kf_un.kf_pts)))
return (0);
return (3);
case KF_TYPE_PROCDESC:
if (0 == memcmp(&kif1.kf_un.kf_proc, &kif2.kf_un.kf_proc,
sizeof(kif1.kf_un.kf_proc)))
return (0);
return (3);
//case KF_TYPE_DEV:
case KF_TYPE_EVENTFD:
if (0 == memcmp(&kif1.kf_un.kf_eventfd, &kif2.kf_un.kf_eventfd,
sizeof(kif1.kf_un.kf_eventfd)))
return (0);
return (3);
case KF_TYPE_TIMERFD:
if (0 == memcmp(&kif1.kf_un.kf_timerfd, &kif2.kf_un.kf_timerfd,
sizeof(kif1.kf_un.kf_timerfd)))
return (0);
return (3);
}
/* Otherwise we can't tell */
return (-1);
}
Refs:
1. https://man7.org/linux/man-pages/man2/kcmp.2.html
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de