diff options
-rw-r--r-- | bsd-core/drm_drv.c | 15 | ||||
-rw-r--r-- | shared-core/i915_dma.c | 70 | ||||
-rw-r--r-- | shared-core/nouveau_mem.c | 2 | ||||
-rw-r--r-- | tests/auth.c | 4 | ||||
-rw-r--r-- | tests/lock.c | 9 |
5 files changed, 63 insertions, 37 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); diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 54621d9e..0be48024 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -772,7 +772,9 @@ int i915_process_relocs(struct drm_file *file_priv, memset(&reloc_kmap, 0, sizeof(reloc_kmap)); + mutex_lock(&dev->struct_mutex); reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1); + mutex_unlock(&dev->struct_mutex); if (!reloc_list_object) return -EINVAL; @@ -838,6 +840,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 */ @@ -854,7 +893,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) { @@ -872,7 +911,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (arg.handled) { data = arg.next; + mutex_lock(&dev->struct_mutex); buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + mutex_unlock(&dev->struct_mutex); buf_count++; continue; } @@ -913,31 +954,9 @@ int i915_validate_buffer_list(struct drm_file *file_priv, buf_count++; if (buf_reloc_handle) { - memset(&relocatee, 0, sizeof(relocatee)); - - relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1); - 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; @@ -992,6 +1011,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; 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; 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); 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) |