DRM dumb buffer file descriptors
PATCH 1/1 DRM dumb buffer file descriptors
Use the DRM_IOCTL_MODE_CREATE_DUMB ioctl to make "dumb" buffers; then use the DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl to get file descriptors.
--- fd-drm.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fds.c | 1 + include/drm_fds.h | 6 +++ include/shm.h | 2 + params.c | 2 +- 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fd-drm.c create mode 100644 include/drm_fds.h
fd-drm.c new file +143 -0
@@ -0,0 +1,143 @@ +/* DRM FDs */ + +#include "config.h" +#include "fd.h" +#include "log.h" +#include "memfd.h" +#include "net.h" +#include "params.h" +#include "pids.h" +#include "random.h" +#include "sanitise.h" +#include "shm.h" +#include "compat.h" +#include "trinity.h" + +static unsigned fd_count; + +#ifdef USE_DRM + +#include <dirent.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <drm/drm.h> + +static int create_dumb(__unused__ int fd) +{ +#if defined(DRM_IOCTL_MODE_CREATE_DUMB ) && defined(DRM_IOCTL_PRIME_HANDLE_TO_FD ) +struct drm_mode_create_dumb create; +struct drm_prime_handle handle_to_fd; + +memset (&create,0 ,sizeof (create)); + create.height =1 <<RAND_RANGE (0 ,10 ); + create.width =1 <<RAND_RANGE (0 ,10 ); + create.bpp =32 ; + +if (ioctl (fd,DRM_IOCTL_MODE_CREATE_DUMB , &create) <0 ) { +return -1 ; + } + +memset (&handle_to_fd,0 ,sizeof (handle_to_fd)); + handle_to_fd.handle = create.handle; +if (RAND_BOOL ()) + handle_to_fd.flags =DRM_CLOEXEC ; + +if (ioctl (fd,DRM_IOCTL_PRIME_HANDLE_TO_FD , &handle_to_fd) <0 ) { +return -1 ; + } + +return handle_to_fd.fd; +#else +return -1 ; +#endif +} + +static int open_drm_fds (void ) +{ +unsigned int i; +int fd, dfd; +DIR *dir; +struct dirent *entry; +char buf[128 ]; + + dir =opendir ("/dev/dri/" ); +if (!dir) + goto done; + +// Open all /dev/dri/*, and try to make FDs from each of them. +while (1 ) { + entry =readdir (dir); +if (!entry) +break ; + +if (strcmp (entry->d_name,"." ) ==0 || +strcmp (entry->d_name,".." ) ==0 ) +continue ; + +snprintf (buf,sizeof (buf),"/dev/dri/%s" , entry->d_name); + buf[sizeof (buf)-1 ] ='\0' ; + + fd =open (buf,O_RDWR ); +if (fd <0 ) { +continue ; + } + shm->drm_fds[fd_count++] = fd; + +if (fd_count >=MAX_DRM_FDS ) +break ; + + dfd =create_dumb (fd); +if (dfd <0 ) { +continue ; + } + shm->drm_fds[fd_count++] = dfd; + +if (fd_count >=MAX_DRM_FDS ) +break ; + } + +if (dir) +closedir (dir); + +for (i =0 ; i <MAX_DRM_FDS ; i++) { +if (shm->drm_fds[i] >0 ) { +output (2 ,"fd[%d] = drm\n" , shm->drm_fds[i]); + } + } + +done: +if (fd_count ==0 ) + drm_fd_provider.enabled = FALSE; + +return TRUE; +} + +#else + +static int open_drm_fds (void ) {return TRUE; } + +#endif /* USE_DRM */ + +static int get_rand_drm_fd (void ) +{ +// We should not be called when fd_count is zero, but avoid div-by-zero +// just in case. +if (fd_count >0 ) +return shm->drm_fds[rand () % fd_count]; +else +return -1 ; +} + +struct fd_provider drm_fd_provider = { + .name ="drm" , + .enabled = TRUE, + .open = &open_drm_fds, + .get = &get_rand_drm_fd, +};
fds.c +1 -0
@@ -56,6 +56,7 @@ void setup_fd_providers(void)add_to_prov_list (&timerfd_fd_provider);add_to_prov_list (&testfile_fd_provider);add_to_prov_list (&memfd_fd_provider); +add_to_prov_list (&drm_fd_provider);output (0 ,"Registered %d fd providers.\n" , num_fd_providers); }
include/drm_fds.h new file +6 -0
@@ -0,0 +1,6 @@ +#pragma once + +#include "fd.h" +struct fd_provider drm_fd_provider; + +#define MAX_DRM_FDS 8
include/shm.h +2 -0
@@ -2,6 +2,7 @@#include "arch.h" #include "child.h" +#include "drm_fds.h" #include "epoll.h" #include "eventfd.h" #include "exit.h"
@@ -61,6 +62,7 @@ struct shm_s {int timerfd_fds[MAX_TIMERFD_FDS ];int testfile_fds[MAX_TESTFILE_FDS ];int memfd_fds[MAX_MEMFD_FDS ]; +int drm_fds[MAX_DRM_FDS ];struct socketinfo sockets[NR_SOCKET_FDS ];int current_fd;unsigned int fd_lifetime;
params.c +1 -1
@@ -60,7 +60,7 @@ char server_addr[INET6_ADDRSTRLEN] = "\0";void enable_disable_fd_usage (void ) { -outputerr (" --enable-fds/--disable-fds= {sockets,pipes,perf,epoll,eventfd,pseudo,timerfd,testfile,memfd}\n" ); +outputerr (" --enable-fds/--disable-fds= {sockets,pipes,perf,epoll,eventfd,pseudo,timerfd,testfile,memfd,drm}\n" ); }static void usage (void )
Signature · 1 line
2.1.0