Intel produces fairly beefy Xeon servers on which it would be nice to be able to run shader-db to get some results pretty fast. Unfortunately those don't ship with any intel graphics IP (only ancient Matrox cards).
This new script stubs a bunch of ioctls so that we can run shader-db on hardware that doesn't have a /dev/dri/renderD128. Example : ./intel_run -j70 -pskl -oi965 shaders Signed-off-by: Lionel Landwerlin <[email protected]> --- Makefile | 10 ++- intel_run | 5 ++ intel_stub.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+), 1 deletion(-) create mode 100755 intel_run create mode 100644 intel_stub.c diff --git a/Makefile b/Makefile index 9422b32..52a764f 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,15 @@ CFLAGS ?= -g -O2 -march=native -pipe CFLAGS += -std=gnu99 -fopenmp LDLIBS = -lepoxy -lgbm +INTEL_STUB_CFLAGS = -g -fPIC -shared -Wall `pkg-config libdrm_intel --cflags` +INTEL_STUB_LIBS = -ldl + +all: intel_stub.so run + +intel_stub.so: intel_stub.c + gcc $(INTEL_STUB_CFLAGS) $< -o $@ $(INTEL_STUB_LIBS) + run: clean: - rm -f run + rm -f intel_stub.so run diff --git a/intel_run b/intel_run new file mode 100755 index 0000000..10114ff --- /dev/null +++ b/intel_run @@ -0,0 +1,5 @@ +#!/bin/bash +# -*- mode: sh -*- + +LD_PRELOAD=${PWD}/intel_stub.so${LD_PPRELOAD:+:${LD_PRELOAD}} \ + exec ./run $@ diff --git a/intel_stub.c b/intel_stub.c new file mode 100644 index 0000000..4917656 --- /dev/null +++ b/intel_stub.c @@ -0,0 +1,237 @@ +/* + * Copyright © 2015-2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#define _GNU_SOURCE /* for RTLD_NEXT */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <dlfcn.h> +#include <i915_drm.h> + +static void *(*libc_mmap)(void *addr, size_t len, int prot, int flags, + int fildes, off_t off); +static int (*libc_open)(const char *pathname, int flags, mode_t mode); +static int (*libc_close)(int fd); +static int (*libc_ioctl)(int fd, unsigned long request, void *argp); +static int (*libc_fstat)(int fd, struct stat *buf); +static int (*libc__fxstat)(int ver, int fd, struct stat *buf); +static int (*libc_fcntl)(int fd, int cmd, int param); +static ssize_t (*libc_readlink)(const char *pathname, char *buf, size_t bufsiz); + +static int drm_fd = 0x0000BEEF; + +#define DRM_MAJOR 226 + +#define SYSFS_PATH "/sys/dev/char/226:0/device/subsystem" + +static int +dispatch_version(int fd, unsigned long request, + struct drm_version *version) +{ + static const char name[] = "i915"; + static const char date[] = "20160919"; + static const char desc[] = "Intel Graphics"; + + version->version_major = 1; + version->version_minor = 6; + version->version_patchlevel = 0; + + if (version->name) + strncpy(version->name, name, version->name_len); + version->name_len = strlen(name); + if (version->date) + strncpy(version->date, date, version->date_len); + version->date_len = strlen(date); + if (version->desc) + strncpy(version->desc, desc, version->desc_len); + version->desc_len = strlen(desc); + + return 0; +} + +__attribute__ ((visibility ("default"))) int +open(const char *path, int flags, ...) +{ + va_list args; + mode_t mode; + + if (strcmp(path, "/dev/dri/renderD128") == 0) + return drm_fd; + + va_start(args, flags); + mode = va_arg(args, int); + va_end(args); + + return libc_open(path, flags, mode); +} + +__attribute__ ((visibility ("default"))) int +close(int fd) +{ + if (fd == drm_fd) + return 0; + + return libc_close(fd); +} + +__attribute__ ((visibility ("default"))) int +fstat(int fd, struct stat *buf) +{ + if (fd == drm_fd) { + buf->st_mode = S_IFCHR | + (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); + buf->st_uid = 0; + buf->st_gid = getgid(); + return 0; + } + + return libc_fstat(fd, buf); +} + +__attribute__ ((visibility ("default"))) int +__fxstat(int ver, int fd, struct stat *buf) +{ + if (fd == drm_fd) { + buf->st_mode = S_IFCHR | + (S_IRWXG | S_IRGRP | S_IRWXU | S_IRUSR); + buf->st_rdev = makedev(DRM_MAJOR, 0); + buf->st_uid = 0; + buf->st_gid = getgid(); + return 0; + } + + return libc__fxstat(ver, fd, buf); +} + +__attribute__ ((visibility ("default"))) int +fcntl(int fd, int cmd, ...) +{ + va_list args; + int param; + + if (fd == drm_fd && cmd == F_DUPFD_CLOEXEC) + return drm_fd; + + va_start(args, cmd); + param = va_arg(args, int); + va_end(args); + + return libc_fcntl(fd, cmd, param); +} + +__attribute__ ((visibility ("default"))) void * +mmap(void *addr, size_t len, int prot, int flags, + int fildes, off_t off) +{ + if (fildes == drm_fd) { + return libc_mmap(NULL, len, prot, flags | MAP_ANONYMOUS, + -1, 0); + } else { + return libc_mmap(addr, len, prot, flags, fildes, off); + } +} + +__attribute__ ((visibility ("default"))) ssize_t +readlink(const char *pathname, char *buf, size_t bufsiz) +{ + if (strcmp(pathname, SYSFS_PATH) == 0) + return snprintf(buf, bufsiz, "../../../bus/pci"); + + return libc_readlink(pathname, buf, bufsiz); +} + +__attribute__ ((visibility ("default"))) int +ioctl(int fd, unsigned long request, ...) +{ + va_list args; + void *argp; + struct stat buf; + + va_start(args, request); + argp = va_arg(args, void *); + va_end(args); + + if (_IOC_TYPE(request) == DRM_IOCTL_BASE && + drm_fd != fd && libc_fstat(fd, &buf) == 0 && + (buf.st_mode & S_IFMT) == S_IFCHR && major(buf.st_rdev) == DRM_MAJOR) { + drm_fd = fd; + } + + if (fd == drm_fd) { + switch (request) { + case DRM_IOCTL_VERSION: + return dispatch_version(fd, request, argp); + + case DRM_IOCTL_I915_GETPARAM: { + struct drm_i915_getparam *getparam = argp; + + if (getparam->param == I915_PARAM_HAS_RELAXED_DELTA) + *getparam->value = 1; + + else if (getparam->param == I915_PARAM_CHIPSET_ID) { + *getparam->value = strtod(getenv("INTEL_DEVID_OVERRIDE"), NULL); + } + + return 0; + } + + case DRM_IOCTL_I915_GEM_GET_APERTURE: { + struct drm_i915_gem_get_aperture *aperture = argp; + aperture->aper_available_size = 128 * 1024 * 1024; + return 0; + } + + case DRM_IOCTL_I915_GEM_MMAP: { + struct drm_i915_gem_mmap *arg = argp; + arg->addr_ptr = (uintptr_t)libc_mmap( + NULL, arg->size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + return 0; + } + default: + return 0; + } + } else { + return libc_ioctl(fd, request, argp); + } +} + +static void __attribute__ ((constructor)) +init(void) +{ + libc_open = dlsym(RTLD_NEXT, "open"); + libc_close = dlsym(RTLD_NEXT, "close"); + libc_fcntl = dlsym(RTLD_NEXT, "fcntl"); + libc_fstat = dlsym(RTLD_NEXT, "fstat"); + libc__fxstat = dlsym(RTLD_NEXT, "__fxstat"); + libc_ioctl = dlsym(RTLD_NEXT, "ioctl"); + libc_mmap = dlsym(RTLD_NEXT, "mmap"); + libc_readlink = dlsym(RTLD_NEXT, "readlink"); +} -- 2.11.0 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
