From 36120264ca8f43078f8748e022faeb9471edcb36 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 17 Oct 2007 12:50:29 -0700 Subject: Bug #11870: FreeBSD hardware lock cleanup fix with multiple opens by a process. Previously, the lock would get released on the first close by the X Server (during AIGLX setup), and the Radeon driver would then hang in initialization due to unexpected failure in DRM calls that required the lock to be held. Based on a patch by Kostik Belousov. --- bsd-core/drm_drv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bsd-core/drm_drv.c b/bsd-core/drm_drv.c index c36b78aa..d6868b9c 100644 --- a/bsd-core/drm_drv.c +++ b/bsd-core/drm_drv.c @@ -538,6 +538,7 @@ static int drm_load(drm_device_t *dev) if (dev->driver.load != NULL) { DRM_LOCK(); + /* Shared code returns -errno. */ retcode = -dev->driver.load(dev, dev->id_entry->driver_private); DRM_UNLOCK(); @@ -720,6 +721,9 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) return EINVAL; } + if (--file_priv->refs != 0) + goto done; + if (dev->driver.preclose != NULL) dev->driver.preclose(dev, file_priv); @@ -795,17 +799,16 @@ int drm_close(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p) dev->buf_pgid = 0; #endif /* __NetBSD__ || __OpenBSD__ */ - if (--file_priv->refs == 0) { - if (dev->driver.postclose != NULL) - dev->driver.postclose(dev, file_priv); - TAILQ_REMOVE(&dev->files, file_priv, link); - free(file_priv, M_DRM); - } + if (dev->driver.postclose != NULL) + dev->driver.postclose(dev, file_priv); + TAILQ_REMOVE(&dev->files, file_priv, link); + free(file_priv, M_DRM); /* ======================================================== * End inline drm_release */ +done: atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); #ifdef __FreeBSD__ device_unbusy(dev->device); -- cgit v1.2.3 From e7523d337997018a86530266a8f3f88dd061c138 Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 17 Oct 2007 13:20:46 -0700 Subject: Fix a race in the auth test where client prevents server from being master. --- tests/auth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auth.c b/tests/auth.c index 4160d1de..9b6fca94 100644 --- a/tests/auth.c +++ b/tests/auth.c @@ -69,10 +69,10 @@ static void client() int drmfd, ret; /* XXX: Should make sure we open the same DRM as the master */ - drmfd = drm_open_any(); - wait_event(0, SERVER_READY); + drmfd = drm_open_any(); + /* Get a client magic number and pass it to the master for auth. */ auth.magic = 0; /* Quiet valgrind */ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth); -- cgit v1.2.3 From 2c5c18fbd394f419a9cf650720a1187440c643cd Mon Sep 17 00:00:00 2001 From: Robert Noland Date: Wed, 17 Oct 2007 13:25:31 -0700 Subject: Bug #12838: Fix lock test client vs. server master race and misplaced closes. --- tests/lock.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/lock.c b/tests/lock.c index 3f627558..86caa281 100644 --- a/tests/lock.c +++ b/tests/lock.c @@ -87,8 +87,6 @@ client_auth(int drmfd) struct drm_auth auth; int ret; - wait_event(0, SERVER_READY); - /* Get a client magic number and pass it to the master for auth. */ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth); if (ret == -1) @@ -172,8 +170,6 @@ static void test_open_close_locked(drmfd) ret = drmUnlock(drmfd, lock1); if (ret != 0) errx(1, "lock lost during open/close by same pid"); - - close(drmfd); } static void client() @@ -181,6 +177,8 @@ static void client() int drmfd, ret; unsigned int time; + wait_event(0, SERVER_READY); + /* XXX: Should make sure we open the same DRM as the master */ drmfd = drm_open_any(); @@ -201,6 +199,7 @@ static void client() send_event(0, CLIENT_LOCKED); ret = write(commfd[0], &time, sizeof(time)); + close(drmfd); exit(0); } @@ -238,6 +237,8 @@ static void server() if (client_time < unlock_time) errx(1, "Client took lock before server released it"); + + close(drmfd); } int main(int argc, char **argv) -- cgit v1.2.3 From 22883ff26b8a45ab2bec60accc4b822cf6b4f214 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 22 Oct 2007 11:54:41 +1100 Subject: i915: split reloc execution into separate function --- shared-core/i915_dma.c | 65 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 5a51f6ef..d0d65f8c 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -873,6 +873,43 @@ out: return ret; } +static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, + drm_handle_t buf_reloc_handle, + struct drm_buffer_object **buffers, + uint32_t buf_count) +{ + struct drm_device *dev = file_priv->head->dev; + struct i915_relocatee_info relocatee; + int ret = 0; + + memset(&relocatee, 0, sizeof(relocatee)); + + mutex_lock(&dev->struct_mutex); + relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); + mutex_unlock(&dev->struct_mutex); + if (!relocatee.buf) { + DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); + ret = -EINVAL; + goto out_err; + } + + while (buf_reloc_handle) { + ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); + if (ret) { + DRM_ERROR("process relocs failed\n"); + break; + } + } + + drm_bo_kunmap(&relocatee.kmap); + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(&relocatee.buf); + mutex_unlock(&dev->struct_mutex); + +out_err: + return ret; +} + /* * Validate, add fence and relocate a block of bos from a userspace list */ @@ -889,7 +926,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned buf_count = 0; struct drm_device *dev = file_priv->head->dev; uint32_t buf_reloc_handle, buf_handle; - struct i915_relocatee_info relocatee; + do { if (buf_count >= *num_buffers) { @@ -950,33 +987,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_count++; if (buf_reloc_handle) { - memset(&relocatee, 0, sizeof(relocatee)); - - mutex_lock(&dev->struct_mutex); - relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); - mutex_unlock(&dev->struct_mutex); - if (!relocatee.buf) { - DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle); - ret = -EINVAL; - goto out_err; - } - - while (buf_reloc_handle) { - ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count); - if (ret) { - DRM_ERROR("process relocs failed\n"); - break; - } - } - - drm_bo_kunmap(&relocatee.kmap); - mutex_lock(&dev->struct_mutex); - drm_bo_usage_deref_locked(&relocatee.buf); - mutex_unlock(&dev->struct_mutex); - + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); if (ret) goto out_err; - } } while (next != 0); *num_buffers = buf_count; -- cgit v1.2.3 From 9a115080e870f8196adef4a19598343e63e61e45 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 23 Oct 2007 02:18:56 +0200 Subject: nouveau: fix IGP --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index e2f0b38d..448b69d3 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -223,7 +223,7 @@ void nouveau_mem_close(struct drm_device *dev) static uint32_t nouveau_mem_fb_amount_igp(struct drm_device *dev) { -#if defined(LINUX) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) +#if defined(__linux__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) struct drm_nouveau_private *dev_priv = dev->dev_private; struct pci_dev *bridge; uint32_t mem; -- cgit v1.2.3 From a294aa724a1e932fb6017383e08532bfcc914df0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Oct 2007 17:54:07 +1000 Subject: i915: require mfence before submitting batchbuffer --- shared-core/i915_dma.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index d0d65f8c..f0fd6037 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1044,6 +1044,9 @@ static int i915_execbuffer(struct drm_device *dev, void *data, if (ret) goto out_free; + /* make sure all previous memory operations have passed */ + asm volatile("mfence":::"memory"); + /* submit buffer */ batch->start = buffers[num_buffers-1]->offset; -- cgit v1.2.3 From fd7c24753c4020a0022aaa183cfe8fc04a307abd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Oct 2007 11:13:15 +1100 Subject: i915: use a drm memory barrier define --- shared-core/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index f0fd6037..9bc7431d 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1045,7 +1045,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, goto out_free; /* make sure all previous memory operations have passed */ - asm volatile("mfence":::"memory"); + DRM_MEMORYBARRIER(); /* submit buffer */ batch->start = buffers[num_buffers-1]->offset; -- cgit v1.2.3 From 83199c257ea68a7cc0c6928109ff77bf25131819 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 24 Oct 2007 16:27:46 -0700 Subject: Fix missing \n on some DRM_ERROR in i915_dma.c --- shared-core/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 9bc7431d..eb8c9153 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -494,7 +494,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, int i = 0, count, ret; if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); + DRM_ERROR("alignment\n"); return -EINVAL; } @@ -532,7 +532,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, RING_LOCALS; if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); + DRM_ERROR("alignment\n"); return -EINVAL; } -- cgit v1.2.3 From 07abc3384e24356d1302459e2e5c4699ed7b0072 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 25 Oct 2007 10:24:55 +1000 Subject: missing mutex unlock bug --- linux-core/sis_mm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-core/sis_mm.c b/linux-core/sis_mm.c index 7e162a8e..9222b08d 100644 --- a/linux-core/sis_mm.c +++ b/linux-core/sis_mm.c @@ -133,6 +133,7 @@ static int sis_drm_alloc(struct drm_device * dev, struct drm_file *file_priv, dev_priv->agp_initialized)) { DRM_ERROR ("Attempt to allocate from uninitialized memory manager.\n"); + mutex_unlock(&dev->struct_mutex); return -EINVAL; } -- cgit v1.2.3 From c5f158abbe97492f56eb60ac54679945e9d6ddae Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 25 Oct 2007 16:52:33 +1000 Subject: i915: remove relocatee kernel mapping sooner stops mutex taking during sleep --- shared-core/i915_dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index eb8c9153..acbb41dc 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -864,6 +864,9 @@ int i915_process_relocs(struct drm_file *file_priv, } while (reloc_offset != reloc_end); out: + drm_bo_kunmap(&relocatee->kmap); + relocatee->data_page = NULL; + drm_bo_kunmap(&reloc_kmap); mutex_lock(&dev->struct_mutex); @@ -901,7 +904,6 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, } } - drm_bo_kunmap(&relocatee.kmap); mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(&relocatee.buf); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From a70fe82baf0ca2be98e02680cff489f90b0ea3de Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 25 Oct 2007 16:53:18 +1000 Subject: i915: relocate buffers before validation add memory barrier between two --- shared-core/i915_dma.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index acbb41dc..1e15e7ce 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -964,6 +964,13 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_handle = req->bo_req.handle; buf_reloc_handle = arg.reloc_handle; + if (buf_reloc_handle) { + ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); + if (ret) + goto out_err; + DRM_MEMORYBARRIER(); + } + rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle, req->bo_req.fence_class, req->bo_req.flags, @@ -988,11 +995,6 @@ int i915_validate_buffer_list(struct drm_file *file_priv, data = next; buf_count++; - if (buf_reloc_handle) { - ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count); - if (ret) - goto out_err; - } } while (next != 0); *num_buffers = buf_count; return 0; -- cgit v1.2.3