Re: kcmp implementation for mesa
- Reply: Mateusz Guzik : "Re: kcmp implementation for mesa"
- In reply to: Rozhuk Ivan : "kcmp implementation for mesa"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 19 Jan 2024 18:34:31 UTC
Hi Ivan,
Looks good. Could you please put patch on reviews.freebsd.org?
Thx,
Michael
On Fri, 19 Jan 2024, 14:11 Rozhuk Ivan, <rozhuk.im@gmail.com> wrote:
> 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
>
>
>