All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] DRM dumb buffer file descriptors
@ 2015-04-15 19:39 Tommi Rantala
  0 siblings, 0 replies; only message in thread
From: Tommi Rantala @ 2015-04-15 19:39 UTC (permalink / raw)
  To: davej; +Cc: trinity, Tommi Rantala

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

diff --git a/fd-drm.c b/fd-drm.c
new file mode 100644
index 0000000..7772c6a
--- /dev/null
+++ b/fd-drm.c
@@ -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,
+};
diff --git a/fds.c b/fds.c
index fbb2bba..a3a70f9 100644
--- a/fds.c
+++ b/fds.c
@@ -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);
 }
diff --git a/include/drm_fds.h b/include/drm_fds.h
new file mode 100644
index 0000000..3c70b33
--- /dev/null
+++ b/include/drm_fds.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "fd.h"
+struct fd_provider drm_fd_provider;
+
+#define MAX_DRM_FDS 8
diff --git a/include/shm.h b/include/shm.h
index 16a5994..673ed1b 100644
--- a/include/shm.h
+++ b/include/shm.h
@@ -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;
diff --git a/params.c b/params.c
index 53861a5..96c737c 100644
--- a/params.c
+++ b/params.c
@@ -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)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-04-15 19:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-15 19:39 [PATCH] DRM dumb buffer file descriptors Tommi Rantala

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.