diff --git a/SOURCES/0001-i965-bufmgr-Handle-NULL-bufmgr-in-brw_bufmgr_get_for.patch b/SOURCES/0001-i965-bufmgr-Handle-NULL-bufmgr-in-brw_bufmgr_get_for.patch new file mode 100644 index 0000000..243f385 --- /dev/null +++ b/SOURCES/0001-i965-bufmgr-Handle-NULL-bufmgr-in-brw_bufmgr_get_for.patch @@ -0,0 +1,36 @@ +From 735971d5a22a55b43f043f70cf5e973354d53852 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Tue, 27 Oct 2020 11:40:05 +0100 +Subject: [PATCH] i965/bufmgr: Handle NULL bufmgr in brw_bufmgr_get_for_fd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +brw_bufmgr_create can return NULL, in which case we'd crash in +list_addtail. + +Reported by Coverity/clang. + +Fixes: 4094558e8643 ("i965: share buffer managers across screens") +Signed-off-by: Michel Dänzer +--- + src/mesa/drivers/dri/i965/brw_bufmgr.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c +index 5a8680704eb..04cb2448a3e 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c +@@ -1916,7 +1916,8 @@ brw_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd, bool bo_reuse) + } + + bufmgr = brw_bufmgr_create(devinfo, fd, bo_reuse); +- list_addtail(&bufmgr->link, &global_bufmgr_list); ++ if (bufmgr) ++ list_addtail(&bufmgr->link, &global_bufmgr_list); + + unlock: + mtx_unlock(&global_bufmgr_list_mutex); +-- +2.28.0 + diff --git a/SOURCES/0001-i965-initialize-bo_reuse-when-creating-brw_bufmgr.patch b/SOURCES/0001-i965-initialize-bo_reuse-when-creating-brw_bufmgr.patch new file mode 100644 index 0000000..23c59e9 --- /dev/null +++ b/SOURCES/0001-i965-initialize-bo_reuse-when-creating-brw_bufmgr.patch @@ -0,0 +1,154 @@ +From 453530d58df83fac6f7191f56e75ddb00ec855d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tapani=20P=C3=A4lli?= +Date: Wed, 28 Aug 2019 14:29:53 +0300 +Subject: [PATCH 1/8] i965: initialize bo_reuse when creating brw_bufmgr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes a possible data race spotted while debugging on other EGL +related failures where glFinish and eglCreateContext are going on at +the same time: + + ==11558== Possible data race during read of size 1 at 0x5E78CD0 by thread #23 + ==11558== Locks held: 1, at address 0x5E77CA8 + ==11558== at 0x61B71D4: bo_alloc_internal (brw_bufmgr.c:639) + ==11558== by 0x61B7328: brw_bo_alloc (brw_bufmgr.c:669) + ==11558== by 0x61EF975: recreate_growing_buffer (intel_batchbuffer.c:231) + ==11558== by 0x61EFAAE: intel_batchbuffer_reset (intel_batchbuffer.c:255) + ==11558== by 0x61EFB85: intel_batchbuffer_reset_and_clear_render_cache (intel_batchbuffer.c:280) + ==11558== by 0x61F0507: brw_new_batch (intel_batchbuffer.c:551) + ==11558== by 0x61F12C1: _intel_batchbuffer_flush_fence (intel_batchbuffer.c:888) + ==11558== by 0x61BDD6B: intel_glFlush (brw_context.c:296) + ==11558== by 0x61BDDB9: intel_finish (brw_context.c:307) + ==11558== by 0x623831B: _mesa_Finish (context.c:1906) + ==11558== by 0x46D556: deqp::egl::GLES2ThreadTest::Operation::execute(tcu::ThreadUtil::Thread&) + ==11558== by 0x721502: tcu::ThreadUtil::Thread::run() + ==11558== + ==11558== This conflicts with a previous write of size 1 by thread #26 + ==11558== Locks held: 1, at address 0x5D09878 + ==11558== at 0x61B98A9: brw_bufmgr_enable_reuse (brw_bufmgr.c:1541) + ==11558== by 0x61BF09D: brw_process_driconf_options (brw_context.c:854) + ==11558== by 0x61BF6CA: brwCreateContext (brw_context.c:993) + ==11558== by 0x621181F: driCreateContextAttribs (dri_util.c:473) + ==11558== by 0x53FE87B: dri2_create_context (egl_dri2.c:1388) + ==11558== by 0x53EE7BE: eglCreateContext (eglapi.c:807) + ==11558== by 0x5C8AB9: eglw::FuncPtrLibrary::createContext(void*, void*, void*, int const*) const + ==11558== by 0x46E027: deqp::egl::GLES2ThreadTest::CreateContext::exec(tcu::ThreadUtil::Thread&) + +Signed-off-by: Tapani Pälli +Reviewed-by: Lionel Landwerlin +Reviewed-by: Kenneth Graunke +(cherry picked from commit b65de51dcf7d5e6d1a6ccdb5121c385f5360de00) +--- + src/mesa/drivers/dri/i965/brw_bufmgr.c | 16 ++-------------- + src/mesa/drivers/dri/i965/brw_bufmgr.h | 4 ++-- + src/mesa/drivers/dri/i965/brw_context.c | 9 --------- + src/mesa/drivers/dri/i965/intel_screen.c | 12 +++++++++++- + 4 files changed, 15 insertions(+), 26 deletions(-) + +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c +index f1675b191c1..e676fbd9d18 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c +@@ -1529,19 +1529,6 @@ brw_bo_flink(struct brw_bo *bo, uint32_t *name) + return 0; + } + +-/** +- * Enables unlimited caching of buffer objects for reuse. +- * +- * This is potentially very memory expensive, as the cache at each bucket +- * size is only bounded by how many buffers of that size we've managed to have +- * in flight at once. +- */ +-void +-brw_bufmgr_enable_reuse(struct brw_bufmgr *bufmgr) +-{ +- bufmgr->bo_reuse = true; +-} +- + static void + add_bucket(struct brw_bufmgr *bufmgr, int size) + { +@@ -1684,7 +1671,7 @@ brw_using_softpin(struct brw_bufmgr *bufmgr) + * \param fd File descriptor of the opened DRM device. + */ + struct brw_bufmgr * +-brw_bufmgr_init(struct gen_device_info *devinfo, int fd) ++brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse) + { + struct brw_bufmgr *bufmgr; + +@@ -1714,6 +1701,7 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd) + + bufmgr->has_llc = devinfo->has_llc; + bufmgr->has_mmap_wc = gem_param(fd, I915_PARAM_MMAP_VERSION) > 0; ++ bufmgr->bo_reuse = bo_reuse; + + const uint64_t _4GB = 4ull << 30; + +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h +index 32fc7a553c9..a85c8f37bef 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h +@@ -343,11 +343,11 @@ int brw_bo_busy(struct brw_bo *bo); + int brw_bo_madvise(struct brw_bo *bo, int madv); + + /* drm_bacon_bufmgr_gem.c */ +-struct brw_bufmgr *brw_bufmgr_init(struct gen_device_info *devinfo, int fd); ++struct brw_bufmgr *brw_bufmgr_init(struct gen_device_info *devinfo, int fd, ++ bool bo_reuse); + struct brw_bo *brw_bo_gem_create_from_name(struct brw_bufmgr *bufmgr, + const char *name, + unsigned int handle); +-void brw_bufmgr_enable_reuse(struct brw_bufmgr *bufmgr); + + int brw_bo_wait(struct brw_bo *bo, int64_t timeout_ns); + +diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c +index 6ba64e4e06d..6d218e49754 100644 +--- a/src/mesa/drivers/dri/i965/brw_context.c ++++ b/src/mesa/drivers/dri/i965/brw_context.c +@@ -822,15 +822,6 @@ brw_process_driconf_options(struct brw_context *brw) + brw->driContext->driScreenPriv->myNum, + "i965", NULL); + +- int bo_reuse_mode = driQueryOptioni(options, "bo_reuse"); +- switch (bo_reuse_mode) { +- case DRI_CONF_BO_REUSE_DISABLED: +- break; +- case DRI_CONF_BO_REUSE_ALL: +- brw_bufmgr_enable_reuse(brw->bufmgr); +- break; +- } +- + if (INTEL_DEBUG & DEBUG_NO_HIZ) { + brw->has_hiz = false; + /* On gen6, you can only do separate stencil with HIZ. */ +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index c3bd30f7837..1feaf18219c 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -1870,7 +1870,17 @@ intel_init_bufmgr(struct intel_screen *screen) + if (getenv("INTEL_NO_HW") != NULL) + screen->no_hw = true; + +- screen->bufmgr = brw_bufmgr_init(&screen->devinfo, dri_screen->fd); ++ bool bo_reuse = false; ++ int bo_reuse_mode = driQueryOptioni(&screen->optionCache, "bo_reuse"); ++ switch (bo_reuse_mode) { ++ case DRI_CONF_BO_REUSE_DISABLED: ++ break; ++ case DRI_CONF_BO_REUSE_ALL: ++ bo_reuse = true; ++ break; ++ } ++ ++ screen->bufmgr = brw_bufmgr_init(&screen->devinfo, dri_screen->fd, bo_reuse); + if (screen->bufmgr == NULL) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); +-- +2.23.0 + diff --git a/SOURCES/0002-i965-store-DRM-fd-on-intel_screen.patch b/SOURCES/0002-i965-store-DRM-fd-on-intel_screen.patch new file mode 100644 index 0000000..c53f5b7 --- /dev/null +++ b/SOURCES/0002-i965-store-DRM-fd-on-intel_screen.patch @@ -0,0 +1,307 @@ +From 649c8ed3f369aa11e3bdbb4784b61d2e6000cb6a Mon Sep 17 00:00:00 2001 +From: Lionel Landwerlin +Date: Fri, 6 Mar 2020 16:56:25 +0200 +Subject: [PATCH 2/8] i965: store DRM fd on intel_screen + +v2: Fix storing of drm fd (Ajax) + +[mustard: backport to 18.3.4 - ajax] + +Signed-off-by: Lionel Landwerlin +(cherry picked from commit b9d3d93769a96d973e379673e712a11b408f7712) +--- + .../drivers/dri/i965/brw_performance_query.c | 27 +++++++------------ + src/mesa/drivers/dri/i965/brw_reset.c | 6 ++--- + src/mesa/drivers/dri/i965/intel_batchbuffer.c | 6 ++--- + src/mesa/drivers/dri/i965/intel_screen.c | 14 +++++----- + src/mesa/drivers/dri/i965/intel_screen.h | 3 +++ + 5 files changed, 22 insertions(+), 34 deletions(-) + +diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c +index 10e3d024f17..703c79c4f97 100644 +--- a/src/mesa/drivers/dri/i965/brw_performance_query.c ++++ b/src/mesa/drivers/dri/i965/brw_performance_query.c +@@ -1103,7 +1103,6 @@ brw_begin_perf_query(struct gl_context *ctx, + + /* If the OA counters aren't already on, enable them. */ + if (brw->perfquery.oa_stream_fd == -1) { +- __DRIscreen *screen = brw->screen->driScrnPriv; + const struct gen_device_info *devinfo = &brw->screen->devinfo; + + /* The period_exponent gives a sampling period as follows: +@@ -1163,7 +1162,7 @@ brw_begin_perf_query(struct gl_context *ctx, + metric_id, + query->oa_format, + period_exponent, +- screen->fd, /* drm fd */ ++ brw->screen->fd, /* drm fd */ + brw->hw_ctx)) + return false; + } else { +@@ -1847,8 +1846,6 @@ enumerate_sysfs_metrics(struct brw_context *brw) + static bool + kernel_has_dynamic_config_support(struct brw_context *brw) + { +- __DRIscreen *screen = brw->screen->driScrnPriv; +- + hash_table_foreach(brw->perfquery.oa_metrics_table, entry) { + struct brw_perf_query_info *query = entry->data; + char config_path[280]; +@@ -1859,7 +1856,7 @@ kernel_has_dynamic_config_support(struct brw_context *brw) + + /* Look for the test config, which we know we can't replace. */ + if (read_file_uint64(config_path, &config_id) && config_id == 1) { +- return drmIoctl(screen->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, ++ return drmIoctl(brw->screen->fd, DRM_IOCTL_I915_PERF_REMOVE_CONFIG, + &config_id) < 0 && errno == ENOENT; + } + } +@@ -1870,8 +1867,6 @@ kernel_has_dynamic_config_support(struct brw_context *brw) + static void + init_oa_configs(struct brw_context *brw) + { +- __DRIscreen *screen = brw->screen->driScrnPriv; +- + hash_table_foreach(brw->perfquery.oa_metrics_table, entry) { + const struct brw_perf_query_info *query = entry->data; + struct drm_i915_perf_oa_config config; +@@ -1902,7 +1897,7 @@ init_oa_configs(struct brw_context *brw) + config.n_flex_regs = query->n_flex_regs; + config.flex_regs_ptr = (uintptr_t) query->flex_regs; + +- ret = drmIoctl(screen->fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &config); ++ ret = drmIoctl(brw->screen->fd, DRM_IOCTL_I915_PERF_ADD_CONFIG, &config); + if (ret < 0) { + DBG("Failed to load \"%s\" (%s) metrics set in kernel: %s\n", + query->name, query->guid, strerror(errno)); +@@ -1917,7 +1912,6 @@ init_oa_configs(struct brw_context *brw) + static bool + query_topology(struct brw_context *brw) + { +- __DRIscreen *screen = brw->screen->driScrnPriv; + struct drm_i915_query_item item = { + .query_id = DRM_I915_QUERY_TOPOLOGY_INFO, + }; +@@ -1926,14 +1920,14 @@ query_topology(struct brw_context *brw) + .items_ptr = (uintptr_t) &item, + }; + +- if (drmIoctl(screen->fd, DRM_IOCTL_I915_QUERY, &query)) ++ if (drmIoctl(brw->screen->fd, DRM_IOCTL_I915_QUERY, &query)) + return false; + + struct drm_i915_query_topology_info *topo_info = + (struct drm_i915_query_topology_info *) calloc(1, item.length); + item.data_ptr = (uintptr_t) topo_info; + +- if (drmIoctl(screen->fd, DRM_IOCTL_I915_QUERY, &query) || ++ if (drmIoctl(brw->screen->fd, DRM_IOCTL_I915_QUERY, &query) || + item.length <= 0) + return false; + +@@ -1948,21 +1942,20 @@ query_topology(struct brw_context *brw) + static bool + getparam_topology(struct brw_context *brw) + { +- __DRIscreen *screen = brw->screen->driScrnPriv; + drm_i915_getparam_t gp; + int ret; + + int slice_mask = 0; + gp.param = I915_PARAM_SLICE_MASK; + gp.value = &slice_mask; +- ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp); ++ ret = drmIoctl(brw->screen->fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) + return false; + + int subslice_mask = 0; + gp.param = I915_PARAM_SUBSLICE_MASK; + gp.value = &subslice_mask; +- ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp); ++ ret = drmIoctl(brw->screen->fd, DRM_IOCTL_I915_GETPARAM, &gp); + if (ret) + return false; + +@@ -2013,7 +2006,6 @@ init_oa_sys_vars(struct brw_context *brw) + { + const struct gen_device_info *devinfo = &brw->screen->devinfo; + uint64_t min_freq_mhz = 0, max_freq_mhz = 0; +- __DRIscreen *screen = brw->screen->driScrnPriv; + + if (!read_sysfs_drm_device_file_uint64(brw, "gt_min_freq_mhz", &min_freq_mhz)) + return false; +@@ -2041,7 +2033,7 @@ init_oa_sys_vars(struct brw_context *brw) + brw->perfquery.sys_vars.gt_min_freq = min_freq_mhz * 1000000; + brw->perfquery.sys_vars.gt_max_freq = max_freq_mhz * 1000000; + brw->perfquery.sys_vars.timestamp_frequency = devinfo->timestamp_frequency; +- brw->perfquery.sys_vars.revision = intel_device_get_revision(screen->fd); ++ brw->perfquery.sys_vars.revision = intel_device_get_revision(brw->screen->fd); + compute_topology_builtins(brw); + + return true; +@@ -2050,7 +2042,6 @@ init_oa_sys_vars(struct brw_context *brw) + static bool + get_sysfs_dev_dir(struct brw_context *brw) + { +- __DRIscreen *screen = brw->screen->driScrnPriv; + struct stat sb; + int min, maj; + DIR *drmdir; +@@ -2059,7 +2050,7 @@ get_sysfs_dev_dir(struct brw_context *brw) + + brw->perfquery.sysfs_dev_dir[0] = '\0'; + +- if (fstat(screen->fd, &sb)) { ++ if (fstat(brw->screen->fd, &sb)) { + DBG("Failed to stat DRM fd\n"); + return false; + } +diff --git a/src/mesa/drivers/dri/i965/brw_reset.c b/src/mesa/drivers/dri/i965/brw_reset.c +index ad8c44f2d1c..90518780eb8 100644 +--- a/src/mesa/drivers/dri/i965/brw_reset.c ++++ b/src/mesa/drivers/dri/i965/brw_reset.c +@@ -35,7 +35,6 @@ GLenum + brw_get_graphics_reset_status(struct gl_context *ctx) + { + struct brw_context *brw = brw_context(ctx); +- __DRIscreen *dri_screen = brw->screen->driScrnPriv; + struct drm_i915_reset_stats stats = { .ctx_id = brw->hw_ctx }; + + /* If hardware contexts are not being used (or +@@ -51,7 +50,7 @@ brw_get_graphics_reset_status(struct gl_context *ctx) + if (brw->reset_count != 0) + return GL_NO_ERROR; + +- if (drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats) != 0) ++ if (drmIoctl(brw->screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats) != 0) + return GL_NO_ERROR; + + /* A reset was observed while a batch from this context was executing. +@@ -77,10 +76,9 @@ brw_get_graphics_reset_status(struct gl_context *ctx) + void + brw_check_for_reset(struct brw_context *brw) + { +- __DRIscreen *dri_screen = brw->screen->driScrnPriv; + struct drm_i915_reset_stats stats = { .ctx_id = brw->hw_ctx }; + +- if (drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats) != 0) ++ if (drmIoctl(brw->screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats) != 0) + return; + + if (stats.batch_active > 0 || stats.batch_pending > 0) +diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c +index 6207de5a06f..7237e51ab5a 100644 +--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c ++++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c +@@ -683,8 +683,7 @@ throttle(struct brw_context *brw) + } + + if (brw->need_flush_throttle) { +- __DRIscreen *dri_screen = brw->screen->driScrnPriv; +- drmCommandNone(dri_screen->fd, DRM_I915_GEM_THROTTLE); ++ drmCommandNone(brw->screen->fd, DRM_I915_GEM_THROTTLE); + brw->need_flush_throttle = false; + } + } +@@ -749,7 +748,6 @@ execbuffer(int fd, + static int + submit_batch(struct brw_context *brw, int in_fence_fd, int *out_fence_fd) + { +- __DRIscreen *dri_screen = brw->screen->driScrnPriv; + struct intel_batchbuffer *batch = &brw->batch; + int ret = 0; + +@@ -816,7 +814,7 @@ submit_batch(struct brw_context *brw, int in_fence_fd, int *out_fence_fd) + batch->exec_bos[index] = tmp_bo; + } + +- ret = execbuffer(dri_screen->fd, batch, brw->hw_ctx, ++ ret = execbuffer(brw->screen->fd, batch, brw->hw_ctx, + 4 * USED_BATCH(*batch), + in_fence_fd, out_fence_fd, flags); + +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index 1feaf18219c..3e02c11700c 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -1636,7 +1636,7 @@ intel_get_param(struct intel_screen *screen, int param, int *value) + gp.param = param; + gp.value = value; + +- if (drmIoctl(screen->driScrnPriv->fd, DRM_IOCTL_I915_GETPARAM, &gp) == -1) { ++ if (drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp) == -1) { + ret = -errno; + if (ret != -EINVAL) + _mesa_warning(NULL, "drm_i915_getparam: %d", ret); +@@ -1865,8 +1865,6 @@ err_out: + static bool + intel_init_bufmgr(struct intel_screen *screen) + { +- __DRIscreen *dri_screen = screen->driScrnPriv; +- + if (getenv("INTEL_NO_HW") != NULL) + screen->no_hw = true; + +@@ -1880,7 +1878,7 @@ intel_init_bufmgr(struct intel_screen *screen) + break; + } + +- screen->bufmgr = brw_bufmgr_init(&screen->devinfo, dri_screen->fd, bo_reuse); ++ screen->bufmgr = brw_bufmgr_init(&screen->devinfo, screen->fd, bo_reuse); + if (screen->bufmgr == NULL) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); +@@ -2038,8 +2036,7 @@ intel_detect_pipelined_register(struct intel_screen *screen, + /* Don't bother with error checking - if the execbuf fails, the + * value won't be written and we'll just report that there's no access. + */ +- __DRIscreen *dri_screen = screen->driScrnPriv; +- drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); ++ drmIoctl(screen->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); + + /* Check whether the value got written. */ + void *results_map = brw_bo_map(NULL, results, MAP_READ); +@@ -2475,6 +2472,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen) + screen->driScrnPriv = dri_screen; + dri_screen->driverPrivate = (void *) screen; + ++ screen->fd = dri_screen->fd; + screen->deviceID = gen_get_pci_device_id_override(); + if (screen->deviceID < 0) + screen->deviceID = intel_get_integer(screen, I915_PARAM_CHIPSET_ID); +@@ -2531,7 +2529,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen) + screen->max_gtt_map_object_size = gtt_size / 4; + } + +- screen->aperture_threshold = get_aperture_size(dri_screen->fd) * 3 / 4; ++ screen->aperture_threshold = get_aperture_size(screen->fd) * 3 / 4; + + screen->hw_has_swizzling = intel_detect_swizzling(screen); + screen->hw_has_timestamp = intel_detect_timestamp(screen); +@@ -2720,7 +2718,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen) + struct drm_i915_reset_stats stats; + memset(&stats, 0, sizeof(stats)); + +- const int ret = drmIoctl(dri_screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats); ++ const int ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GET_RESET_STATS, &stats); + + screen->has_context_reset_notification = + (ret != -1 || errno != EINVAL); +diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h +index 8d56fcd9e7a..6145afd56c5 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.h ++++ b/src/mesa/drivers/dri/i965/intel_screen.h +@@ -56,6 +56,9 @@ struct intel_screen + /** Bytes of aperture usage beyond which execbuf is likely to fail. */ + uint64_t aperture_threshold; + ++ /** DRM fd associated with this screen. Not owned by this object. Do not close. */ ++ int fd; ++ + bool no_hw; + bool hw_has_swizzling; + bool has_exec_fence; /**< I915_PARAM_HAS_EXEC_FENCE */ +-- +2.23.0 + diff --git a/SOURCES/0003-i965-share-buffer-managers-across-screens.patch b/SOURCES/0003-i965-share-buffer-managers-across-screens.patch new file mode 100644 index 0000000..bca965a --- /dev/null +++ b/SOURCES/0003-i965-share-buffer-managers-across-screens.patch @@ -0,0 +1,239 @@ +From f2ccb19e3e15a04fda47f8b0fcb08e32903031a1 Mon Sep 17 00:00:00 2001 +From: Lionel Landwerlin +Date: Fri, 6 Mar 2020 17:06:25 +0200 +Subject: [PATCH 3/8] i965: share buffer managers across screens + +Signed-off-by: Lionel Landwerlin +--- + src/mesa/drivers/dri/i965/brw_bufmgr.c | 84 ++++++++++++++++++++++-- + src/mesa/drivers/dri/i965/brw_bufmgr.h | 11 ++-- + src/mesa/drivers/dri/i965/intel_screen.c | 7 +- + 3 files changed, 92 insertions(+), 10 deletions(-) + +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c +index e676fbd9d18..32758f2b9ff 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c +@@ -139,6 +139,10 @@ struct bo_cache_bucket { + }; + + struct brw_bufmgr { ++ uint32_t refcount; ++ ++ struct list_head link; ++ + int fd; + + mtx_t lock; +@@ -160,6 +164,12 @@ struct brw_bufmgr { + uint64_t initial_kflags; + }; + ++static mtx_t global_bufmgr_list_mutex = _MTX_INITIALIZER_NP; ++static struct list_head global_bufmgr_list = { ++ .next = &global_bufmgr_list, ++ .prev = &global_bufmgr_list, ++}; ++ + static int bo_set_tiling_internal(struct brw_bo *bo, uint32_t tiling_mode, + uint32_t stride); + +@@ -1292,8 +1302,19 @@ brw_bo_wait(struct brw_bo *bo, int64_t timeout_ns) + } + + void +-brw_bufmgr_destroy(struct brw_bufmgr *bufmgr) ++brw_bufmgr_unref(struct brw_bufmgr *bufmgr) + { ++ mtx_lock(&global_bufmgr_list_mutex); ++ if (p_atomic_dec_zero(&bufmgr->refcount)) { ++ list_del(&bufmgr->link); ++ } else { ++ bufmgr = NULL; ++ } ++ mtx_unlock(&global_bufmgr_list_mutex); ++ ++ if (!bufmgr) ++ return; ++ + mtx_destroy(&bufmgr->lock); + + /* Free any cached buffer objects we were going to reuse */ +@@ -1322,6 +1343,9 @@ brw_bufmgr_destroy(struct brw_bufmgr *bufmgr) + } + } + ++ close(bufmgr->fd); ++ bufmgr->fd = -1; ++ + free(bufmgr); + } + +@@ -1664,14 +1688,21 @@ brw_using_softpin(struct brw_bufmgr *bufmgr) + return bufmgr->initial_kflags & EXEC_OBJECT_PINNED; + } + ++static struct brw_bufmgr * ++brw_bufmgr_ref(struct brw_bufmgr *bufmgr) ++{ ++ p_atomic_inc(&bufmgr->refcount); ++ return bufmgr; ++} ++ + /** + * Initializes the GEM buffer manager, which uses the kernel to allocate, map, + * and manage map buffer objections. + * + * \param fd File descriptor of the opened DRM device. + */ +-struct brw_bufmgr * +-brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse) ++static struct brw_bufmgr * ++brw_bufmgr_create(struct gen_device_info *devinfo, int fd, bool bo_reuse) + { + struct brw_bufmgr *bufmgr; + +@@ -1688,9 +1719,16 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse) + * Don't do this! Ensure that each library/bufmgr has its own device + * fd so that its namespace does not clash with another. + */ +- bufmgr->fd = fd; ++ bufmgr->fd = dup(fd); ++ if (bufmgr->fd < 0) { ++ free(bufmgr); ++ return NULL; ++ } ++ ++ p_atomic_set(&bufmgr->refcount, 1); + + if (mtx_init(&bufmgr->lock, mtx_plain) != 0) { ++ close(bufmgr->fd); + free(bufmgr); + return NULL; + } +@@ -1725,6 +1763,7 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse) + * might actually mean requiring 4.14. + */ + fprintf(stderr, "i965 requires softpin (Kernel 4.5) on Gen10+."); ++ close(bufmgr->fd); + free(bufmgr); + return NULL; + } +@@ -1739,3 +1778,40 @@ brw_bufmgr_init(struct gen_device_info *devinfo, int fd, bool bo_reuse) + + return bufmgr; + } ++ ++struct brw_bufmgr * ++brw_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd, bool bo_reuse) ++{ ++ struct stat st; ++ ++ if (fstat(fd, &st)) ++ return NULL; ++ ++ struct brw_bufmgr *bufmgr = NULL; ++ ++ mtx_lock(&global_bufmgr_list_mutex); ++ list_for_each_entry(struct brw_bufmgr, iter_bufmgr, &global_bufmgr_list, link) { ++ struct stat iter_st; ++ if (fstat(iter_bufmgr->fd, &iter_st)) ++ continue; ++ ++ if (st.st_rdev == iter_st.st_rdev) { ++ bufmgr = brw_bufmgr_ref(iter_bufmgr); ++ goto unlock; ++ } ++ } ++ ++ bufmgr = brw_bufmgr_create(devinfo, fd, bo_reuse); ++ list_addtail(&bufmgr->link, &global_bufmgr_list); ++ ++ unlock: ++ mtx_unlock(&global_bufmgr_list_mutex); ++ ++ return bufmgr; ++} ++ ++int ++brw_bufmgr_get_fd(struct brw_bufmgr *bufmgr) ++{ ++ return bufmgr->fd; ++} +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h +index a85c8f37bef..3d8729da487 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h +@@ -300,9 +300,9 @@ int brw_bo_subdata(struct brw_bo *bo, uint64_t offset, + void brw_bo_wait_rendering(struct brw_bo *bo); + + /** +- * Tears down the buffer manager instance. ++ * Unref a buffer manager instance. + */ +-void brw_bufmgr_destroy(struct brw_bufmgr *bufmgr); ++void brw_bufmgr_unref(struct brw_bufmgr *bufmgr); + + /** + * Get the current tiling (and resulting swizzling) mode for the bo. +@@ -343,8 +343,9 @@ int brw_bo_busy(struct brw_bo *bo); + int brw_bo_madvise(struct brw_bo *bo, int madv); + + /* drm_bacon_bufmgr_gem.c */ +-struct brw_bufmgr *brw_bufmgr_init(struct gen_device_info *devinfo, int fd, +- bool bo_reuse); ++struct brw_bufmgr *brw_bufmgr_get_for_fd(struct gen_device_info *devinfo, int fd, ++ bool bo_reuse); ++ + struct brw_bo *brw_bo_gem_create_from_name(struct brw_bufmgr *bufmgr, + const char *name, + unsigned int handle); +@@ -359,6 +360,8 @@ int brw_hw_context_set_priority(struct brw_bufmgr *bufmgr, + + void brw_destroy_hw_context(struct brw_bufmgr *bufmgr, uint32_t ctx_id); + ++int brw_bufmgr_get_fd(struct brw_bufmgr *bufmgr); ++ + int brw_bo_gem_export_to_prime(struct brw_bo *bo, int *prime_fd); + struct brw_bo *brw_bo_gem_create_from_prime(struct brw_bufmgr *bufmgr, + int prime_fd); +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index 3e02c11700c..c374837c4a1 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -1668,7 +1668,7 @@ intelDestroyScreen(__DRIscreen * sPriv) + { + struct intel_screen *screen = sPriv->driverPrivate; + +- brw_bufmgr_destroy(screen->bufmgr); ++ brw_bufmgr_unref(screen->bufmgr); + driDestroyOptionInfo(&screen->optionCache); + + disk_cache_destroy(screen->disk_cache); +@@ -1865,6 +1865,8 @@ err_out: + static bool + intel_init_bufmgr(struct intel_screen *screen) + { ++ __DRIscreen *dri_screen = screen->driScrnPriv; ++ + if (getenv("INTEL_NO_HW") != NULL) + screen->no_hw = true; + +@@ -1878,12 +1880,13 @@ intel_init_bufmgr(struct intel_screen *screen) + break; + } + +- screen->bufmgr = brw_bufmgr_init(&screen->devinfo, screen->fd, bo_reuse); ++ screen->bufmgr = brw_bufmgr_get_for_fd(&screen->devinfo, dri_screen->fd, bo_reuse); + if (screen->bufmgr == NULL) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); + return false; + } ++ screen->fd = brw_bufmgr_get_fd(screen->bufmgr); + + if (!intel_get_boolean(screen, I915_PARAM_HAS_EXEC_NO_RELOC)) { + fprintf(stderr, "[%s: %u] Kernel 3.9 required.\n", __func__, __LINE__); +-- +2.23.0 + diff --git a/SOURCES/0004-util-Add-os_same_file_description-helper.patch b/SOURCES/0004-util-Add-os_same_file_description-helper.patch new file mode 100644 index 0000000..c5c2474 --- /dev/null +++ b/SOURCES/0004-util-Add-os_same_file_description-helper.patch @@ -0,0 +1,273 @@ +From cd24e64b088c692c74f4383241df8d48d1007b31 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Mon, 6 Jan 2020 18:24:52 +0100 +Subject: [PATCH 4/8] util: Add os_same_file_description helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Acked-by: Pierre-Eric Pelloux-Prayer +Part-of: + +(cherry picked from commit f76cbc7901f7d500f5a4f74aedfd29970d1efd00) + +Signed-off-by: Michel Dänzer +--- + src/util/Makefile.sources | 2 + + src/util/meson.build | 1 + + src/util/os_file.c | 165 ++++++++++++++++++++++++++++++++++++++ + src/util/os_file.h | 45 +++++++++++ + 4 files changed, 213 insertions(+) + create mode 100644 src/util/os_file.c + create mode 100644 src/util/os_file.h + +diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources +index b4d23947ab7..02e7a5e598b 100644 +--- a/src/util/Makefile.sources ++++ b/src/util/Makefile.sources +@@ -27,6 +27,8 @@ MESA_UTIL_FILES := \ + mesa-sha1.h \ + os_time.c \ + os_time.h \ ++ os_file.c \ ++ os_file.h \ + os_misc.c \ + os_misc.h \ + u_process.c \ +diff --git a/src/util/meson.build b/src/util/meson.build +index 156621aff65..d612e31952d 100644 +--- a/src/util/meson.build ++++ b/src/util/meson.build +@@ -51,6 +51,7 @@ files_mesa_util = files( + 'mesa-sha1.h', + 'os_time.c', + 'os_time.h', ++ 'os_file.c', + 'os_misc.c', + 'os_misc.h', + 'u_process.c', +diff --git a/src/util/os_file.c b/src/util/os_file.c +new file mode 100644 +index 00000000000..b502ff4b0ef +--- /dev/null ++++ b/src/util/os_file.c +@@ -0,0 +1,165 @@ ++/* ++ * Copyright 2019 Intel Corporation ++ * SPDX-License-Identifier: MIT ++ */ ++ ++#include "os_file.h" ++ ++#include ++#include ++#include ++#include ++ ++ ++#if defined(WIN32) ++#include ++#define open _open ++#define fdopen _fdopen ++#define O_CREAT _O_CREAT ++#define O_EXCL _O_EXCL ++#define O_WRONLY _O_WRONLY ++#endif ++ ++ ++FILE * ++os_file_create_unique(const char *filename, int filemode) ++{ ++ int fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, filemode); ++ if (fd == -1) ++ return NULL; ++ return fdopen(fd, "w"); ++} ++ ++ ++#if defined(__linux__) ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++static ssize_t ++readN(int fd, char *buf, size_t len) ++{ ++ int err = -ENODATA; ++ size_t total = 0; ++ do { ++ ssize_t ret = read(fd, buf + total, len - total); ++ ++ if (ret < 0) ++ ret = -errno; ++ ++ if (ret == -EINTR || ret == -EAGAIN) ++ continue; ++ ++ if (ret <= 0) { ++ err = ret; ++ break; ++ } ++ ++ total += ret; ++ } while (total != len); ++ ++ return total ? (ssize_t)total : err; ++} ++ ++char * ++os_read_file(const char *filename) ++{ ++ /* Note that this also serves as a slight margin to avoid a 2x grow when ++ * the file is just a few bytes larger when we read it than when we ++ * fstat'ed it. ++ * The string's NULL terminator is also included in here. ++ */ ++ size_t len = 64; ++ ++ int fd = open(filename, O_RDONLY); ++ if (fd == -1) { ++ /* errno set by open() */ ++ return NULL; ++ } ++ ++ /* Pre-allocate a buffer at least the size of the file if we can read ++ * that information. ++ */ ++ struct stat stat; ++ if (fstat(fd, &stat) == 0) ++ len += stat.st_size; ++ ++ char *buf = malloc(len); ++ if (!buf) { ++ close(fd); ++ errno = -ENOMEM; ++ return NULL; ++ } ++ ++ ssize_t actually_read; ++ size_t offset = 0, remaining = len - 1; ++ while ((actually_read = readN(fd, buf + offset, remaining)) == (ssize_t)remaining) { ++ char *newbuf = realloc(buf, 2 * len); ++ if (!newbuf) { ++ free(buf); ++ close(fd); ++ errno = -ENOMEM; ++ return NULL; ++ } ++ ++ buf = newbuf; ++ len *= 2; ++ offset += actually_read; ++ remaining = len - offset - 1; ++ } ++ ++ close(fd); ++ ++ if (actually_read > 0) ++ offset += actually_read; ++ ++ /* Final resize to actual size */ ++ len = offset + 1; ++ char *newbuf = realloc(buf, len); ++ if (!newbuf) { ++ free(buf); ++ errno = -ENOMEM; ++ return NULL; ++ } ++ buf = newbuf; ++ ++ buf[offset] = '\0'; ++ ++ return buf; ++} ++ ++bool ++os_same_file_description(int fd1, int fd2) ++{ ++ pid_t pid = getpid(); ++ ++ return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2) == 0; ++} ++ ++#else ++ ++#include "u_debug.h" ++ ++char * ++os_read_file(const char *filename) ++{ ++ errno = -ENOSYS; ++ return NULL; ++} ++ ++bool ++os_same_file_description(int fd1, int fd2) ++{ ++ if (fd1 == fd2) ++ return true; ++ ++ debug_warn_once("Can't tell if different file descriptors reference the same" ++ " file description, false negatives might cause trouble!\n"); ++ return false; ++} ++ ++#endif +diff --git a/src/util/os_file.h b/src/util/os_file.h +new file mode 100644 +index 00000000000..1972beba32b +--- /dev/null ++++ b/src/util/os_file.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright 2019 Intel Corporation ++ * SPDX-License-Identifier: MIT ++ * ++ * File operations helpers ++ */ ++ ++#ifndef _OS_FILE_H_ ++#define _OS_FILE_H_ ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* ++ * Create a new file and opens it for writing-only. ++ * If the given filename already exists, nothing is done and NULL is returned. ++ * `errno` gets set to the failure reason; if that is not EEXIST, the caller ++ * might want to do something other than trying again. ++ */ ++FILE * ++os_file_create_unique(const char *filename, int filemode); ++ ++/* ++ * Read a file. ++ * Returns a char* that the caller must free(), or NULL and sets errno. ++ */ ++char * ++os_read_file(const char *filename); ++ ++/* ++ * Returns true if the two file descriptors passed in can be determined to ++ * reference the same file description, false otherwise ++ */ ++bool ++os_same_file_description(int fd1, int fd2); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _OS_FILE_H_ */ +-- +2.26.2 + diff --git a/SOURCES/0005-util-remove-the-dependency-on-kcmp.h.patch b/SOURCES/0005-util-remove-the-dependency-on-kcmp.h.patch new file mode 100644 index 0000000..534be6d --- /dev/null +++ b/SOURCES/0005-util-remove-the-dependency-on-kcmp.h.patch @@ -0,0 +1,43 @@ +From a75e8b98e0c043d02df7014b63520063c8191a62 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= +Date: Tue, 18 Feb 2020 16:12:23 -0500 +Subject: [PATCH 5/8] util: remove the dependency on kcmp.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: f76cbc7901f7 "util: Add os_same_file_description helper" + +Acked-by: Eric Engestrom +Reviewed-by: Michel Dänzer +Tested-by: Marge Bot +Part-of: + +(cherry picked from commit f7bfb10c69dfe48a91e35523cb5ee641bdbf6988) + +Signed-off-by: Michel Dänzer +--- + src/util/os_file.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util/os_file.c b/src/util/os_file.c +index b502ff4b0ef..128fe872db1 100644 +--- a/src/util/os_file.c ++++ b/src/util/os_file.c +@@ -34,11 +34,12 @@ os_file_create_unique(const char *filename, int filemode) + #if defined(__linux__) + + #include +-#include + #include + #include + #include + ++/* copied from */ ++#define KCMP_FILE 0 + + static ssize_t + readN(int fd, char *buf, size_t len) +-- +2.26.2 + diff --git a/SOURCES/0006-util-Change-os_same_file_description-return-type-fro.patch b/SOURCES/0006-util-Change-os_same_file_description-return-type-fro.patch new file mode 100644 index 0000000..8d38ebe --- /dev/null +++ b/SOURCES/0006-util-Change-os_same_file_description-return-type-fro.patch @@ -0,0 +1,99 @@ +From 0de5ad2f5083fcf19e579f5a70641e0da0e70dc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Tue, 18 Feb 2020 19:04:00 +0100 +Subject: [PATCH 6/8] util: Change os_same_file_description return type from + bool to int +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows communicating that it wasn't possible to determine whether +the two file descriptors reference the same file description. When +that's the case, log a warning in the amdgpu winsys. + +In turn, remove the corresponding debugging output from the fallback +os_same_file_description implementation. It depends on the caller if +false negatives are problematic or not. + +Reviewed-by: Eric Engestrom +Reviewed-by: Marek Olšák +Tested-by: Marge Bot +Part-of: + +(cherry picked from commit f5a8958910f53d924d062cbf024cebe4134f757a) + +Signed-off-by: Michel Dänzer +--- + src/util/os_file.c | 18 +++++++++++------- + src/util/os_file.h | 10 +++++++--- + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/util/os_file.c b/src/util/os_file.c +index 128fe872db1..228f1e823c5 100644 +--- a/src/util/os_file.c ++++ b/src/util/os_file.c +@@ -133,12 +133,16 @@ os_read_file(const char *filename) + return buf; + } + +-bool ++int + os_same_file_description(int fd1, int fd2) + { + pid_t pid = getpid(); + +- return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2) == 0; ++ /* Same file descriptor trivially implies same file description */ ++ if (fd1 == fd2) ++ return 0; ++ ++ return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2); + } + + #else +@@ -152,15 +156,15 @@ os_read_file(const char *filename) + return NULL; + } + +-bool ++int + os_same_file_description(int fd1, int fd2) + { ++ /* Same file descriptor trivially implies same file description */ + if (fd1 == fd2) +- return true; ++ return 0; + +- debug_warn_once("Can't tell if different file descriptors reference the same" +- " file description, false negatives might cause trouble!\n"); +- return false; ++ /* Otherwise we can't tell */ ++ return -1; + } + + #endif +diff --git a/src/util/os_file.h b/src/util/os_file.h +index 1972beba32b..58639476f60 100644 +--- a/src/util/os_file.h ++++ b/src/util/os_file.h +@@ -32,10 +32,14 @@ char * + os_read_file(const char *filename); + + /* +- * Returns true if the two file descriptors passed in can be determined to +- * reference the same file description, false otherwise ++ * Try to determine if two file descriptors reference the same file description ++ * ++ * Return values: ++ * - 0: They reference the same file description ++ * - > 0: They do not reference the same file description ++ * - < 0: Unable to determine whether they reference the same file description + */ +-bool ++int + os_same_file_description(int fd1, int fd2); + + #ifdef __cplusplus +-- +2.26.2 + diff --git a/SOURCES/0007-i965-don-t-forget-to-set-screen-on-duped-image.patch b/SOURCES/0007-i965-don-t-forget-to-set-screen-on-duped-image.patch new file mode 100644 index 0000000..bf11827 --- /dev/null +++ b/SOURCES/0007-i965-don-t-forget-to-set-screen-on-duped-image.patch @@ -0,0 +1,38 @@ +From 7680f8685e8b5dccc58babecf451ceab77fd373b Mon Sep 17 00:00:00 2001 +From: Lionel Landwerlin +Date: Tue, 2 Jun 2020 11:52:35 +0300 +Subject: [PATCH 7/8] i965: don't forget to set screen on duped image +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We'll start using this field more for querying image properties. +Without it we run into a crash. + +Signed-off-by: Lionel Landwerlin +Cc: +Reviewed-by: Kenneth Graunke +Part-of: + +(cherry picked from commit e41e820648b1cb662cbe938c73d755331d48c6db) + +Signed-off-by: Michel Dänzer +--- + src/mesa/drivers/dri/i965/intel_screen.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index 93f0f8ef401..9c8b0814506 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -943,6 +943,7 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate) + return NULL; + + brw_bo_reference(orig_image->bo); ++ image->screen = orig_image->screen; + image->bo = orig_image->bo; + image->internal_format = orig_image->internal_format; + image->planar_format = orig_image->planar_format; +-- +2.26.2 + diff --git a/SOURCES/0008-i965-fix-export-of-GEM-handles.patch b/SOURCES/0008-i965-fix-export-of-GEM-handles.patch new file mode 100644 index 0000000..5c02f7e --- /dev/null +++ b/SOURCES/0008-i965-fix-export-of-GEM-handles.patch @@ -0,0 +1,342 @@ +From dfadbfc2c4c6dae3e2d21bfcccabb704d2fa6705 Mon Sep 17 00:00:00 2001 +From: Lionel Landwerlin +Date: Sat, 2 May 2020 16:59:19 +0300 +Subject: [PATCH 8/8] i965: fix export of GEM handles +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We reuse DRM file descriptors internally. Therefore when we export a +GEM handle we must do so in the file descriptor used externally. + +v2: Fix dmabuf leak + Fix GEM handle leaks by tracking exported handles + +v3: Check os_same_file_description error (Michel) + Don't create multiple exports for a given GEM table + +v4: Add WARN_ONCE (Ken) + +v5: Remove blank line (Ian) + Remove unused field (Ian) + +Signed-off-by: Lionel Landwerlin +Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2882 +Fixes: 4094558e8643 ("i965: share buffer managers across screens") +Tested-by: Eric Engestrom +Tested-by: Tapani Pälli +Reviewed-by: Kenneth Graunke +Part-of: + +(cherry picked from commit 57e4d0aa1c16d3be36ccee4065c55901cb6fad43) + +Signed-off-by: Michel Dänzer +--- + src/mesa/drivers/dri/i965/brw_bufmgr.c | 120 +++++++++++++++++- + src/mesa/drivers/dri/i965/brw_bufmgr.h | 20 +++ + src/mesa/drivers/dri/i965/intel_batchbuffer.c | 6 + + src/mesa/drivers/dri/i965/intel_screen.c | 11 +- + 4 files changed, 152 insertions(+), 5 deletions(-) + +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c +index 72e61b6bee7..c64878c1275 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c +@@ -61,6 +61,7 @@ + #include "util/macros.h" + #include "util/hash_table.h" + #include "util/list.h" ++#include "util/os_file.h" + #include "util/u_dynarray.h" + #include "util/vma.h" + #include "brw_bufmgr.h" +@@ -77,6 +78,20 @@ + #define VG(x) + #endif + ++/* Bufmgr is not aware of brw_context. */ ++#undef WARN_ONCE ++#define WARN_ONCE(cond, fmt...) do { \ ++ if (unlikely(cond)) { \ ++ static bool _warned = false; \ ++ if (!_warned) { \ ++ fprintf(stderr, "WARNING: "); \ ++ fprintf(stderr, fmt); \ ++ _warned = true; \ ++ } \ ++ } \ ++} while (0) ++ ++ + /* VALGRIND_FREELIKE_BLOCK unfortunately does not actually undo the earlier + * VALGRIND_MALLOCLIKE_BLOCK but instead leaves vg convinced the memory is + * leaked. All because it does not call VG(cli_free) from its +@@ -138,6 +153,16 @@ struct bo_cache_bucket { + struct util_dynarray vma_list[BRW_MEMZONE_COUNT]; + }; + ++struct bo_export { ++ /** File descriptor associated with a handle export. */ ++ int drm_fd; ++ ++ /** GEM handle in drm_fd */ ++ uint32_t gem_handle; ++ ++ struct list_head link; ++}; ++ + struct brw_bufmgr { + uint32_t refcount; + +@@ -496,6 +521,18 @@ brw_bo_cache_purge_bucket(struct brw_bufmgr *bufmgr, + } + } + ++static struct brw_bo * ++bo_calloc(void) ++{ ++ struct brw_bo *bo = calloc(1, sizeof(*bo)); ++ if (!bo) ++ return NULL; ++ ++ list_inithead(&bo->exports); ++ ++ return bo; ++} ++ + static struct brw_bo * + bo_alloc_internal(struct brw_bufmgr *bufmgr, + const char *name, +@@ -569,6 +606,7 @@ retry: + } + + if (alloc_from_cache) { ++ assert(list_empty(&bo->exports)); + if (!brw_bo_madvise(bo, I915_MADV_WILLNEED)) { + bo_free(bo); + brw_bo_cache_purge_bucket(bufmgr, bucket); +@@ -601,7 +639,7 @@ retry: + bo->gtt_offset = 0ull; + } + } else { +- bo = calloc(1, sizeof(*bo)); ++ bo = bo_calloc(); + if (!bo) + goto err; + +@@ -772,11 +810,12 @@ brw_bo_gem_create_from_name(struct brw_bufmgr *bufmgr, + */ + bo = hash_find_bo(bufmgr->handle_table, open_arg.handle); + if (bo) { ++ assert(list_empty(&bo->exports)); + brw_bo_reference(bo); + goto out; + } + +- bo = calloc(1, sizeof(*bo)); ++ bo = bo_calloc(); + if (!bo) + goto out; + +@@ -846,6 +885,8 @@ bo_free(struct brw_bo *bo) + + entry = _mesa_hash_table_search(bufmgr->handle_table, &bo->gem_handle); + _mesa_hash_table_remove(bufmgr->handle_table, entry); ++ } else { ++ assert(list_empty(&bo->exports)); + } + + /* Close this object */ +@@ -895,6 +936,14 @@ bo_unreference_final(struct brw_bo *bo, time_t time) + + DBG("bo_unreference final: %d (%s)\n", bo->gem_handle, bo->name); + ++ list_for_each_entry_safe(struct bo_export, export, &bo->exports, link) { ++ struct drm_gem_close close = { .handle = export->gem_handle }; ++ drmIoctl(export->drm_fd, DRM_IOCTL_GEM_CLOSE, &close); ++ ++ list_del(&export->link); ++ free(export); ++ } ++ + bucket = bucket_for_size(bufmgr, bo->size); + /* Put the buffer into our internal cache for reuse if we can. */ + if (bufmgr->bo_reuse && bo->reusable && bucket != NULL && +@@ -1414,11 +1463,12 @@ brw_bo_gem_create_from_prime_internal(struct brw_bufmgr *bufmgr, int prime_fd, + */ + bo = hash_find_bo(bufmgr->handle_table, handle); + if (bo) { ++ assert(list_empty(&bo->exports)); + brw_bo_reference(bo); + goto out; + } + +- bo = calloc(1, sizeof(*bo)); ++ bo = bo_calloc(); + if (!bo) + goto out; + +@@ -1553,6 +1603,70 @@ brw_bo_flink(struct brw_bo *bo, uint32_t *name) + return 0; + } + ++int ++brw_bo_export_gem_handle_for_device(struct brw_bo *bo, int drm_fd, ++ uint32_t *out_handle) ++{ ++ struct brw_bufmgr *bufmgr = bo->bufmgr; ++ ++ /* Only add the new GEM handle to the list of export if it belongs to a ++ * different GEM device. Otherwise we might close the same buffer multiple ++ * times. ++ */ ++ int ret = os_same_file_description(drm_fd, bufmgr->fd); ++ WARN_ONCE(ret < 0, ++ "Kernel has no file descriptor comparison support: %s\n", ++ strerror(errno)); ++ if (ret == 0) { ++ *out_handle = brw_bo_export_gem_handle(bo); ++ return 0; ++ } ++ ++ struct bo_export *export = calloc(1, sizeof(*export)); ++ if (!export) ++ return -ENOMEM; ++ ++ export->drm_fd = drm_fd; ++ ++ int dmabuf_fd = -1; ++ int err = brw_bo_gem_export_to_prime(bo, &dmabuf_fd); ++ if (err) { ++ free(export); ++ return err; ++ } ++ ++ mtx_lock(&bufmgr->lock); ++ err = drmPrimeFDToHandle(drm_fd, dmabuf_fd, &export->gem_handle); ++ close(dmabuf_fd); ++ if (err) { ++ mtx_unlock(&bufmgr->lock); ++ free(export); ++ return err; ++ } ++ ++ bool found = false; ++ list_for_each_entry(struct bo_export, iter, &bo->exports, link) { ++ if (iter->drm_fd != drm_fd) ++ continue; ++ /* Here we assume that for a given DRM fd, we'll always get back the ++ * same GEM handle for a given buffer. ++ */ ++ assert(iter->gem_handle == export->gem_handle); ++ free(export); ++ export = iter; ++ found = true; ++ break; ++ } ++ if (!found) ++ list_addtail(&export->link, &bo->exports); ++ ++ mtx_unlock(&bufmgr->lock); ++ ++ *out_handle = export->gem_handle; ++ ++ return 0; ++} ++ + static void + add_bucket(struct brw_bufmgr *bufmgr, int size) + { +diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h +index 65508195d95..d1fd4ccdc6c 100644 +--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h ++++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h +@@ -39,6 +39,7 @@ + #include + #include + ++#include "c11/threads.h" + #include "util/u_atomic.h" + #include "util/list.h" + +@@ -179,6 +180,13 @@ struct brw_bo { + /** BO cache list */ + struct list_head head; + ++ /** ++ * List of GEM handle exports of this buffer (bo_export). ++ * ++ * Hold bufmgr->lock when using this list. ++ */ ++ struct list_head exports; ++ + /** + * Boolean of whether this buffer can be re-used + */ +@@ -372,6 +380,18 @@ struct brw_bo *brw_bo_gem_create_from_prime_tiled(struct brw_bufmgr *bufmgr, + + uint32_t brw_bo_export_gem_handle(struct brw_bo *bo); + ++/** ++ * Exports a bo as a GEM handle into a given DRM file descriptor ++ * \param bo Buffer to export ++ * \param drm_fd File descriptor where the new handle is created ++ * \param out_handle Pointer to store the new handle ++ * ++ * Returns 0 if the buffer was successfully exported, a non zero error code ++ * otherwise. ++ */ ++int brw_bo_export_gem_handle_for_device(struct brw_bo *bo, int drm_fd, ++ uint32_t *out_handle); ++ + int brw_reg_read(struct brw_bufmgr *bufmgr, uint32_t offset, + uint64_t *result); + +diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c +index 7237e51ab5a..c8a7f238831 100644 +--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c ++++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c +@@ -513,11 +513,17 @@ grow_buffer(struct brw_context *brw, + new_bo->refcount = bo->refcount; + bo->refcount = 1; + ++ assert(list_empty(&bo->exports)); ++ assert(list_empty(&new_bo->exports)); ++ + struct brw_bo tmp; + memcpy(&tmp, bo, sizeof(struct brw_bo)); + memcpy(bo, new_bo, sizeof(struct brw_bo)); + memcpy(new_bo, &tmp, sizeof(struct brw_bo)); + ++ list_inithead(&bo->exports); ++ list_inithead(&new_bo->exports); ++ + grow->partial_bo = new_bo; /* the one reference of the OLD bo */ + grow->partial_bytes = existing_bytes; + } +diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c +index 9c8b0814506..db97dcaabcb 100644 +--- a/src/mesa/drivers/dri/i965/intel_screen.c ++++ b/src/mesa/drivers/dri/i965/intel_screen.c +@@ -864,9 +864,16 @@ intel_query_image(__DRIimage *image, int attrib, int *value) + case __DRI_IMAGE_ATTRIB_STRIDE: + *value = image->pitch; + return true; +- case __DRI_IMAGE_ATTRIB_HANDLE: +- *value = brw_bo_export_gem_handle(image->bo); ++ case __DRI_IMAGE_ATTRIB_HANDLE: { ++ __DRIscreen *dri_screen = image->screen->driScrnPriv; ++ uint32_t handle; ++ if (brw_bo_export_gem_handle_for_device(image->bo, ++ dri_screen->fd, ++ &handle)) ++ return false; ++ *value = handle; + return true; ++ } + case __DRI_IMAGE_ATTRIB_NAME: + return !brw_bo_flink(image->bo, (uint32_t *) value); + case __DRI_IMAGE_ATTRIB_FORMAT: +-- +2.26.2 + diff --git a/SPECS/mesa.spec b/SPECS/mesa.spec index 184c701..6c18e42 100644 --- a/SPECS/mesa.spec +++ b/SPECS/mesa.spec @@ -61,7 +61,7 @@ Summary: Mesa graphics libraries Name: mesa Version: 18.3.4 -Release: 10%{?dist} +Release: 12%{?dist} License: MIT Group: System Environment/Libraries URL: http://www.mesa3d.org @@ -97,6 +97,17 @@ Patch21: 0001-pkgconfig-Fix-gl.pc-when-glvnd-is-enabled.patch Patch31: 0001-llvmpipe-use-ppc64le-ppc64-Large-code-model-for-JIT-.patch +# i965 multi-screen fix +Patch40: 0001-i965-initialize-bo_reuse-when-creating-brw_bufmgr.patch +Patch41: 0002-i965-store-DRM-fd-on-intel_screen.patch +Patch42: 0003-i965-share-buffer-managers-across-screens.patch +Patch43: 0004-util-Add-os_same_file_description-helper.patch +Patch44: 0005-util-remove-the-dependency-on-kcmp.h.patch +Patch45: 0006-util-Change-os_same_file_description-return-type-fro.patch +Patch46: 0007-i965-don-t-forget-to-set-screen-on-duped-image.patch +Patch47: 0008-i965-fix-export-of-GEM-handles.patch +Patch48: 0001-i965-bufmgr-Handle-NULL-bufmgr-in-brw_bufmgr_get_for.patch + BuildRequires: pkgconfig autoconf automake libtool %if %{with_hardware} BuildRequires: kernel-headers @@ -358,6 +369,16 @@ grep -q ^/ src/gallium/auxiliary/vl/vl_decoder.c && exit 1 #%patch21 -p1 -b .glpc %patch31 -p1 -b .codemodel +%patch40 -p1 -b .multi965.1 +%patch41 -p1 -b .multi965.2 +%patch42 -p1 -b .multi965.3 +%patch43 -p1 -b .util-Add-os_same_file_description-helper +%patch44 -p1 -b .util-remove-the-dependency-on-kcmp.h +%patch45 -p1 -b .util-Change-os_same_file_description-return-type-fro +%patch46 -p1 -b .i965-don-t-forget-to-set-screen-on-duped-image +%patch47 -p1 -b .i965-fix-export-of-GEM-handles +%patch48 -p1 -b .i965-bufmgr-Handle-NULL-bufmgr-in-brw_bufmgr_get_for + %if 0%{with_private_llvm} sed -i 's/\[llvm-config\]/\[llvm-private-config-%{__isa_bits}\]/g' configure.ac sed -i 's/`$LLVM_CONFIG --version`/$LLVM_VERSION_MAJOR.$LLVM_VERSION_MINOR-rhel/' configure.ac @@ -673,6 +694,12 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Tue Oct 27 2020 Michel Dänzer - 18.3.4-12 +- Fix for defect reported by Coverity/clang (#1803811) + +* Fri Oct 23 2020 Michel Dänzer - 18.3.4-11 +- Backport upstream i965 multi-screen fixes (#1803811) + * Thu Jun 18 2020 Adam Jackson - 18.3.4-10 - Revert the previous fix due to regressions in Firefox, Chrome, etc.