Re: kcmp implementation for mesa
- Reply: Konstantin Belousov : "Re: kcmp implementation for mesa"
- In reply to: Michael Zhilin : "Re: kcmp implementation for mesa"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 19 Jan 2024 18:40:32 UTC
instead of messing with code like this it's probably time to implement kcmp in the kernel On 1/19/24, Michael Zhilin <mizhka@gmail.com> wrote: > 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 >> >> >> > -- Mateusz Guzik <mjguzik gmail.com>