From f2e64d527699751d6b64698495ae1d48eeee6cf7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:56:01 +1000 Subject: nouveau: NV4X PFIFO engtab functions --- linux-core/Makefile.kernel | 1 + linux-core/nv40_fifo.c | 1 + 2 files changed, 2 insertions(+) create mode 120000 linux-core/nv40_fifo.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 6f5b021b..3e78b6d7 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -25,6 +25,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ + nv40_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ nv40_graph.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o diff --git a/linux-core/nv40_fifo.c b/linux-core/nv40_fifo.c new file mode 120000 index 00000000..cc71e7a4 --- /dev/null +++ b/linux-core/nv40_fifo.c @@ -0,0 +1 @@ +../shared-core/nv40_fifo.c \ No newline at end of file -- cgit v1.2.3 From 05d86d950a10b77ffaa708e9d89b2a87c11fed01 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:57:09 +1000 Subject: nouveau: NV04 PFIFO engtab functions --- linux-core/Makefile.kernel | 2 +- linux-core/nv04_fifo.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 120000 linux-core/nv04_fifo.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 3e78b6d7..45d2dc46 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -25,7 +25,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ - nv40_fifo.o \ + nv04_fifo.o nv40_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ nv40_graph.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o diff --git a/linux-core/nv04_fifo.c b/linux-core/nv04_fifo.c new file mode 120000 index 00000000..d10beb19 --- /dev/null +++ b/linux-core/nv04_fifo.c @@ -0,0 +1 @@ +../shared-core/nv04_fifo.c \ No newline at end of file -- cgit v1.2.3 From 341bc7820749024e09275de6e689b10c2908689a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 18:58:14 +1000 Subject: nouveau: NV1X/2X/3X PFIFO engtab functions Earlier NV1X chips use the NV04 code, see previous commits about NV10 RAMFC entry size. --- linux-core/Makefile.kernel | 2 +- linux-core/nv10_fifo.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 120000 linux-core/nv10_fifo.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 45d2dc46..9427a04b 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -25,7 +25,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ - nv04_fifo.o nv40_fifo.o \ + nv04_fifo.o nv10_fifo.o nv40_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ nv40_graph.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o diff --git a/linux-core/nv10_fifo.c b/linux-core/nv10_fifo.c new file mode 120000 index 00000000..8630ad04 --- /dev/null +++ b/linux-core/nv10_fifo.c @@ -0,0 +1 @@ +../shared-core/nv10_fifo.c \ No newline at end of file -- cgit v1.2.3 From 695599f18d907bb277805581bbe208b0e083e7d9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 19:03:35 +1000 Subject: nouveau: Nuke DMA_OBJECT_INIT ioctl (bumps interface to 0.0.7) For various reasons, this ioctl was a bad idea. At channel creation we now automatically create DMA objects covering available VRAM and GART memory, where the client used to do this themselves. However, there is still a need to be able to create DMA objects pointing at specific areas of memory (ie. notifiers). Each channel is now allocated a small amount of memory from which a client can suballocate things (such as notifiers), and have a DMA object created which covers the suballocated area. The NOTIFIER_ALLOC ioctl exposes this functionality. --- linux-core/Makefile.kernel | 2 +- linux-core/nouveau_notifier.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 120000 linux-core/nouveau_notifier.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 9427a04b..6ab17a49 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -21,7 +21,7 @@ i810-objs := i810_drv.o i810_dma.o i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \ i915_buffer.o nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ - nouveau_object.o nouveau_irq.o \ + nouveau_object.o nouveau_irq.o nouveau_notifier.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ diff --git a/linux-core/nouveau_notifier.c b/linux-core/nouveau_notifier.c new file mode 120000 index 00000000..285469c5 --- /dev/null +++ b/linux-core/nouveau_notifier.c @@ -0,0 +1 @@ +../shared-core/nouveau_notifier.c \ No newline at end of file -- cgit v1.2.3 From ce0d528d3ca78348a7c1ad7c402757824fb6cf95 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Jun 2007 20:49:19 +1000 Subject: nouveau/nv50: skeletal backend --- linux-core/Makefile.kernel | 6 +++--- linux-core/nv50_fifo.c | 1 + linux-core/nv50_graph.c | 1 + linux-core/nv50_mc.c | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) create mode 120000 linux-core/nv50_fifo.c create mode 120000 linux-core/nv50_graph.c create mode 120000 linux-core/nv50_mc.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 6ab17a49..478c4df0 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -23,11 +23,11 @@ i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nouveau_object.o nouveau_irq.o nouveau_notifier.o \ nv04_timer.o \ - nv04_mc.o nv40_mc.o \ + nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ - nv04_fifo.o nv10_fifo.o nv40_fifo.o \ + nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ - nv40_graph.o + nv40_graph.o nv50_graph.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o diff --git a/linux-core/nv50_fifo.c b/linux-core/nv50_fifo.c new file mode 120000 index 00000000..4c9990a9 --- /dev/null +++ b/linux-core/nv50_fifo.c @@ -0,0 +1 @@ +../shared-core/nv50_fifo.c \ No newline at end of file diff --git a/linux-core/nv50_graph.c b/linux-core/nv50_graph.c new file mode 120000 index 00000000..03f69e68 --- /dev/null +++ b/linux-core/nv50_graph.c @@ -0,0 +1 @@ +../shared-core/nv50_graph.c \ No newline at end of file diff --git a/linux-core/nv50_mc.c b/linux-core/nv50_mc.c new file mode 120000 index 00000000..f4bb369e --- /dev/null +++ b/linux-core/nv50_mc.c @@ -0,0 +1 @@ +../shared-core/nv50_mc.c \ No newline at end of file -- cgit v1.2.3 From 00f1a66f22d52c212bb9334a0103a4785af69bc1 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 29 Jun 2007 12:50:12 +0200 Subject: Fence object reference / dereference cleanup. Buffer object dereference cleanup. Add a struct drm_device member to fence objects: This can simplify code, particularly in drivers. --- linux-core/drm_bo.c | 109 +++++++++++++++++++----------------------- linux-core/drm_bo_move.c | 6 +-- linux-core/drm_fence.c | 122 +++++++++++++++++++++++++++-------------------- linux-core/drm_objects.h | 21 ++++---- linux-core/drm_vm.c | 3 +- 5 files changed, 134 insertions(+), 127 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index f1ca0b44..ab257825 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -269,31 +269,25 @@ static int drm_bo_handle_move_mem(drm_buffer_object_t * bo, int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals, int no_wait) { - - drm_fence_object_t *fence = bo->fence; int ret; DRM_ASSERT_LOCKED(&bo->mutex); - if (fence) { - drm_device_t *dev = bo->dev; - if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) { - drm_fence_usage_deref_unlocked(dev, fence); - bo->fence = NULL; + if (bo->fence) { + if (drm_fence_object_signaled(bo->fence, bo->fence_type, 0)) { + drm_fence_usage_deref_unlocked(&bo->fence); return 0; } if (no_wait) { return -EBUSY; } ret = - drm_fence_object_wait(dev, fence, lazy, ignore_signals, + drm_fence_object_wait(bo->fence, lazy, ignore_signals, bo->fence_type); if (ret) return ret; - drm_fence_usage_deref_unlocked(dev, fence); - bo->fence = NULL; - + drm_fence_usage_deref_unlocked(&bo->fence); } return 0; } @@ -321,10 +315,8 @@ static int drm_bo_expire_fence(drm_buffer_object_t * bo, int allow_errors) "Evicting buffer.\n"); } } - if (bo->fence) { - drm_fence_usage_deref_unlocked(dev, bo->fence); - bo->fence = NULL; - } + if (bo->fence) + drm_fence_usage_deref_unlocked(&bo->fence); } return 0; } @@ -348,11 +340,9 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all) DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); - if (bo->fence && drm_fence_object_signaled(dev, bo->fence, - bo->fence_type, 0)) { - drm_fence_usage_deref_unlocked(dev, bo->fence); - bo->fence = NULL; - } + if (bo->fence && drm_fence_object_signaled(bo->fence, + bo->fence_type, 0)) + drm_fence_usage_deref_unlocked(&bo->fence); if (bo->fence && remove_all) (void)drm_bo_expire_fence(bo, 0); @@ -383,7 +373,7 @@ static void drm_bo_cleanup_refs(drm_buffer_object_t * bo, int remove_all) } if (list_empty(&bo->ddestroy)) { - drm_fence_object_flush(dev, bo->fence, bo->fence_type); + drm_fence_object_flush(bo->fence, bo->fence_type); list_add_tail(&bo->ddestroy, &bm->ddestroy); schedule_delayed_work(&bm->wq, ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100); @@ -503,12 +493,15 @@ static void drm_bo_delayed_workqueue(struct work_struct *work) mutex_unlock(&dev->struct_mutex); } -void drm_bo_usage_deref_locked(drm_buffer_object_t * bo) +void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo) { - DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); + struct drm_buffer_object *tmp_bo = *bo; + bo = NULL; - if (atomic_dec_and_test(&bo->usage)) { - drm_bo_destroy_locked(bo); + DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex); + + if (atomic_dec_and_test(&tmp_bo->usage)) { + drm_bo_destroy_locked(tmp_bo); } } @@ -520,17 +513,19 @@ static void drm_bo_base_deref_locked(drm_file_t * priv, drm_user_object_t * uo) DRM_ASSERT_LOCKED(&bo->dev->struct_mutex); drm_bo_takedown_vm_locked(bo); - drm_bo_usage_deref_locked(bo); + drm_bo_usage_deref_locked(&bo); } -static void drm_bo_usage_deref_unlocked(drm_buffer_object_t * bo) +static void drm_bo_usage_deref_unlocked(drm_buffer_object_t ** bo) { - drm_device_t *dev = bo->dev; + struct drm_buffer_object *tmp_bo = *bo; + drm_device_t *dev = tmp_bo->dev; - if (atomic_dec_and_test(&bo->usage)) { + *bo = NULL; + if (atomic_dec_and_test(&tmp_bo->usage)) { mutex_lock(&dev->struct_mutex); - if (atomic_read(&bo->usage) == 0) - drm_bo_destroy_locked(bo); + if (atomic_read(&tmp_bo->usage) == 0) + drm_bo_destroy_locked(tmp_bo); mutex_unlock(&dev->struct_mutex); } } @@ -616,16 +611,15 @@ int drm_fence_buffer_objects(drm_file_t * priv, if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) { count++; if (entry->fence) - drm_fence_usage_deref_locked(dev, entry->fence); - entry->fence = fence; - atomic_inc(&fence->usage); + drm_fence_usage_deref_locked(&entry->fence); + entry->fence = drm_fence_reference_locked(fence); DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); DRM_WAKEUP(&entry->event_queue); drm_bo_add_to_lru(entry); } mutex_unlock(&entry->mutex); - drm_bo_usage_deref_locked(entry); + drm_bo_usage_deref_locked(&entry); l = f_list.next; } DRM_DEBUG("Fenced %d buffers\n", count); @@ -742,7 +736,7 @@ static int drm_bo_mem_force_space(drm_device_t * dev, ret = drm_bo_evict(entry, mem_type, no_wait); mutex_unlock(&entry->mutex); - drm_bo_usage_deref_unlocked(entry); + drm_bo_usage_deref_unlocked(&entry); if (ret) return ret; mutex_lock(&dev->struct_mutex); @@ -962,10 +956,8 @@ static int drm_bo_quick_busy(drm_buffer_object_t * bo) BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED); if (fence) { - drm_device_t *dev = bo->dev; - if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) { - drm_fence_usage_deref_unlocked(dev, fence); - bo->fence = NULL; + if (drm_fence_object_signaled(fence, bo->fence_type, 0)) { + drm_fence_usage_deref_unlocked(&bo->fence); return 0; } return 1; @@ -984,16 +976,13 @@ static int drm_bo_busy(drm_buffer_object_t * bo) BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED); if (fence) { - drm_device_t *dev = bo->dev; - if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) { - drm_fence_usage_deref_unlocked(dev, fence); - bo->fence = NULL; + if (drm_fence_object_signaled(fence, bo->fence_type, 0)) { + drm_fence_usage_deref_unlocked(&bo->fence); return 0; } - drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE); - if (drm_fence_object_signaled(dev, fence, bo->fence_type, 0)) { - drm_fence_usage_deref_unlocked(dev, fence); - bo->fence = NULL; + drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE); + if (drm_fence_object_signaled(fence, bo->fence_type, 0)) { + drm_fence_usage_deref_unlocked(&bo->fence); return 0; } return 1; @@ -1190,7 +1179,7 @@ static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle, drm_bo_fill_rep_arg(bo, rep); out: mutex_unlock(&bo->mutex); - drm_bo_usage_deref_unlocked(bo); + drm_bo_usage_deref_unlocked(&bo); return ret; } @@ -1216,7 +1205,7 @@ static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle) } drm_remove_ref_object(priv, ro); - drm_bo_usage_deref_locked(bo); + drm_bo_usage_deref_locked(&bo); out: mutex_unlock(&dev->struct_mutex); return ret; @@ -1512,7 +1501,7 @@ static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle, mutex_unlock(&bo->mutex); - drm_bo_usage_deref_unlocked(bo); + drm_bo_usage_deref_unlocked(&bo); return ret; } @@ -1534,7 +1523,7 @@ static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle, (void)drm_bo_busy(bo); drm_bo_fill_rep_arg(bo, rep); mutex_unlock(&bo->mutex); - drm_bo_usage_deref_unlocked(bo); + drm_bo_usage_deref_unlocked(&bo); return 0; } @@ -1566,7 +1555,7 @@ static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle, out: mutex_unlock(&bo->mutex); - drm_bo_usage_deref_unlocked(bo); + drm_bo_usage_deref_unlocked(&bo); return ret; } @@ -1651,7 +1640,7 @@ int drm_buffer_object_create(drm_device_t *dev, out_err: mutex_unlock(&bo->mutex); - drm_bo_usage_deref_unlocked(bo); + drm_bo_usage_deref_unlocked(&bo); return ret; } @@ -1728,7 +1717,7 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) mask & DRM_BO_FLAG_SHAREABLE); if (rep.ret) - drm_bo_usage_deref_unlocked(entry); + drm_bo_usage_deref_unlocked(&entry); if (rep.ret) break; @@ -1957,7 +1946,7 @@ restart: allow_errors); mutex_lock(&dev->struct_mutex); - drm_bo_usage_deref_locked(entry); + drm_bo_usage_deref_locked(&entry); if (ret) return ret; @@ -1967,10 +1956,8 @@ restart: do_restart = ((next->prev != list) && (next->prev != prev)); - if (nentry != NULL && do_restart) { - drm_bo_usage_deref_locked(nentry); - nentry = NULL; - } + if (nentry != NULL && do_restart) + drm_bo_usage_deref_locked(&nentry); if (do_restart) goto restart; @@ -2365,7 +2352,7 @@ static void drm_bo_takedown_vm_locked(drm_buffer_object_t * bo) drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ); list->map = NULL; list->user_token = 0ULL; - drm_bo_usage_deref_locked(bo); + drm_bo_usage_deref_locked(&bo); } static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo) diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c index 4f752065..8ef2a8ff 100644 --- a/linux-core/drm_bo_move.c +++ b/linux-core/drm_bo_move.c @@ -306,7 +306,7 @@ int drm_buffer_object_transfer(drm_buffer_object_t * bo, INIT_LIST_HEAD(&fbo->p_mm_list); #endif - atomic_inc(&bo->fence->usage); + drm_fence_reference_unlocked(&fbo->fence, bo->fence); fbo->pinned_node = NULL; fbo->mem.mm_node->private = (void *)fbo; atomic_set(&fbo->usage, 1); @@ -339,7 +339,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo, drm_buffer_object_t *old_obj; if (bo->fence) - drm_fence_usage_deref_unlocked(dev, bo->fence); + drm_fence_usage_deref_unlocked(&bo->fence); ret = drm_fence_object_create(dev, fence_class, fence_type, fence_flags | DRM_FENCE_FLAG_EMIT, &bo->fence); @@ -396,7 +396,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t * bo, DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); drm_bo_add_to_lru(old_obj); - drm_bo_usage_deref_locked(old_obj); + drm_bo_usage_deref_locked(&old_obj); mutex_unlock(&dev->struct_mutex); } diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index b5fc2235..ace70d51 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -124,56 +124,76 @@ static void drm_fence_unring(drm_device_t * dev, struct list_head *ring) write_unlock_irqrestore(&fm->lock, flags); } -void drm_fence_usage_deref_locked(drm_device_t * dev, - drm_fence_object_t * fence) +void drm_fence_usage_deref_locked(drm_fence_object_t ** fence) { + struct drm_fence_object *tmp_fence = *fence; + struct drm_device *dev = tmp_fence->dev; drm_fence_manager_t *fm = &dev->fm; DRM_ASSERT_LOCKED(&dev->struct_mutex); - - if (atomic_dec_and_test(&fence->usage)) { - drm_fence_unring(dev, &fence->ring); + *fence = NULL; + if (atomic_dec_and_test(&tmp_fence->usage)) { + drm_fence_unring(dev, &tmp_fence->ring); DRM_DEBUG("Destroyed a fence object 0x%08lx\n", - fence->base.hash.key); + tmp_fence->base.hash.key); atomic_dec(&fm->count); - BUG_ON(!list_empty(&fence->base.list)); - drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE); + BUG_ON(!list_empty(&tmp_fence->base.list)); + drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE); } } -void drm_fence_usage_deref_unlocked(drm_device_t * dev, - drm_fence_object_t * fence) +void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence) { + struct drm_fence_object *tmp_fence = *fence; + struct drm_device *dev = tmp_fence->dev; drm_fence_manager_t *fm = &dev->fm; - if (atomic_dec_and_test(&fence->usage)) { + *fence = NULL; + if (atomic_dec_and_test(&tmp_fence->usage)) { mutex_lock(&dev->struct_mutex); - if (atomic_read(&fence->usage) == 0) { - drm_fence_unring(dev, &fence->ring); + if (atomic_read(&tmp_fence->usage) == 0) { + drm_fence_unring(dev, &tmp_fence->ring); atomic_dec(&fm->count); - BUG_ON(!list_empty(&fence->base.list)); - drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE); + BUG_ON(!list_empty(&tmp_fence->base.list)); + drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE); } mutex_unlock(&dev->struct_mutex); } } -static void drm_fence_object_destroy(drm_file_t * priv, - drm_user_object_t * base) +struct drm_fence_object +*drm_fence_reference_locked(struct drm_fence_object *src) +{ + DRM_ASSERT_LOCKED(&src->dev->struct_mutex); + + atomic_inc(&src->usage); + return src; +} + +void drm_fence_reference_unlocked(struct drm_fence_object **dst, + struct drm_fence_object *src) +{ + mutex_lock(&src->dev->struct_mutex); + *dst = src; + atomic_inc(&src->usage); + mutex_unlock(&src->dev->struct_mutex); +} + + +static void drm_fence_object_destroy(drm_file_t *priv, drm_user_object_t * base) { - drm_device_t *dev = priv->head->dev; drm_fence_object_t *fence = drm_user_object_entry(base, drm_fence_object_t, base); - drm_fence_usage_deref_locked(dev, fence); + drm_fence_usage_deref_locked(&fence); } -int drm_fence_object_signaled(drm_device_t * dev, - drm_fence_object_t * fence, - uint32_t mask, int poke_flush) +int drm_fence_object_signaled(drm_fence_object_t * fence, + uint32_t mask, int poke_flush) { unsigned long flags; int signaled; + struct drm_device *dev = fence->dev; drm_fence_manager_t *fm = &dev->fm; drm_fence_driver_t *driver = dev->driver->fence_driver; @@ -204,10 +224,10 @@ static void drm_fence_flush_exe(drm_fence_class_manager_t * fc, } } -int drm_fence_object_flush(drm_device_t * dev, - drm_fence_object_t * fence, +int drm_fence_object_flush(drm_fence_object_t * fence, uint32_t type) { + struct drm_device *dev = fence->dev; drm_fence_manager_t *fm = &dev->fm; drm_fence_class_manager_t *fc = &fm->class[fence->class]; drm_fence_driver_t *driver = dev->driver->fence_driver; @@ -270,24 +290,23 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t class, uint32_t sequence) mutex_unlock(&dev->struct_mutex); return; } - fence = list_entry(fc->ring.next, drm_fence_object_t, ring); - atomic_inc(&fence->usage); + fence = drm_fence_reference_locked(list_entry(fc->ring.next, drm_fence_object_t, ring)); mutex_unlock(&dev->struct_mutex); diff = (old_sequence - fence->sequence) & driver->sequence_mask; read_unlock_irqrestore(&fm->lock, flags); if (diff < driver->wrap_diff) { - drm_fence_object_flush(dev, fence, fence->type); + drm_fence_object_flush(fence, fence->type); } - drm_fence_usage_deref_unlocked(dev, fence); + drm_fence_usage_deref_unlocked(&fence); } EXPORT_SYMBOL(drm_fence_flush_old); -static int drm_fence_lazy_wait(drm_device_t *dev, - drm_fence_object_t *fence, +static int drm_fence_lazy_wait(drm_fence_object_t *fence, int ignore_signals, uint32_t mask) { + struct drm_device *dev = fence->dev; drm_fence_manager_t *fm = &dev->fm; drm_fence_class_manager_t *fc = &fm->class[fence->class]; int signaled; @@ -296,13 +315,13 @@ static int drm_fence_lazy_wait(drm_device_t *dev, do { DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ, - (signaled = drm_fence_object_signaled(dev, fence, mask, 1))); + (signaled = drm_fence_object_signaled(fence, mask, 1))); if (signaled) return 0; if (time_after_eq(jiffies, _end)) break; } while (ret == -EINTR && ignore_signals); - if (drm_fence_object_signaled(dev, fence, mask, 0)) + if (drm_fence_object_signaled(fence, mask, 0)) return 0; if (time_after_eq(jiffies, _end)) ret = -EBUSY; @@ -317,10 +336,10 @@ static int drm_fence_lazy_wait(drm_device_t *dev, return 0; } -int drm_fence_object_wait(drm_device_t * dev, - drm_fence_object_t * fence, +int drm_fence_object_wait(drm_fence_object_t * fence, int lazy, int ignore_signals, uint32_t mask) { + struct drm_device *dev = fence->dev; drm_fence_driver_t *driver = dev->driver->fence_driver; int ret = 0; unsigned long _end; @@ -332,16 +351,16 @@ int drm_fence_object_wait(drm_device_t * dev, return -EINVAL; } - if (drm_fence_object_signaled(dev, fence, mask, 0)) + if (drm_fence_object_signaled(fence, mask, 0)) return 0; _end = jiffies + 3 * DRM_HZ; - drm_fence_object_flush(dev, fence, mask); + drm_fence_object_flush(fence, mask); if (lazy && driver->lazy_capable) { - ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask); + ret = drm_fence_lazy_wait(fence, ignore_signals, mask); if (ret) return ret; @@ -349,7 +368,7 @@ int drm_fence_object_wait(drm_device_t * dev, if (driver->has_irq(dev, fence->class, DRM_FENCE_TYPE_EXE)) { - ret = drm_fence_lazy_wait(dev, fence, ignore_signals, + ret = drm_fence_lazy_wait(fence, ignore_signals, DRM_FENCE_TYPE_EXE); if (ret) return ret; @@ -357,13 +376,13 @@ int drm_fence_object_wait(drm_device_t * dev, if (driver->has_irq(dev, fence->class, mask & ~DRM_FENCE_TYPE_EXE)) { - ret = drm_fence_lazy_wait(dev, fence, ignore_signals, + ret = drm_fence_lazy_wait(fence, ignore_signals, mask); if (ret) return ret; } } - if (drm_fence_object_signaled(dev, fence, mask, 0)) + if (drm_fence_object_signaled(fence, mask, 0)) return 0; /* @@ -375,7 +394,7 @@ int drm_fence_object_wait(drm_device_t * dev, #endif do { schedule(); - signaled = drm_fence_object_signaled(dev, fence, mask, 1); + signaled = drm_fence_object_signaled(fence, mask, 1); } while (!signaled && !time_after_eq(jiffies, _end)); if (!signaled) @@ -384,9 +403,10 @@ int drm_fence_object_wait(drm_device_t * dev, return 0; } -int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence, +int drm_fence_object_emit(drm_fence_object_t * fence, uint32_t fence_flags, uint32_t class, uint32_t type) { + struct drm_device *dev = fence->dev; drm_fence_manager_t *fm = &dev->fm; drm_fence_driver_t *driver = dev->driver->fence_driver; drm_fence_class_manager_t *fc = &fm->class[fence->class]; @@ -436,9 +456,10 @@ static int drm_fence_object_init(drm_device_t * dev, uint32_t class, fence->submitted_flush = 0; fence->signaled = 0; fence->sequence = 0; + fence->dev = dev; write_unlock_irqrestore(&fm->lock, flags); if (fence_flags & DRM_FENCE_FLAG_EMIT) { - ret = drm_fence_object_emit(dev, fence, fence_flags, + ret = drm_fence_object_emit(fence, fence_flags, fence->class, type); } return ret; @@ -476,7 +497,7 @@ int drm_fence_object_create(drm_device_t * dev, uint32_t class, uint32_t type, return -ENOMEM; ret = drm_fence_object_init(dev, class, type, flags, fence); if (ret) { - drm_fence_usage_deref_unlocked(dev, fence); + drm_fence_usage_deref_unlocked(&fence); return ret; } *c_fence = fence; @@ -533,8 +554,7 @@ drm_fence_object_t *drm_lookup_fence_object(drm_file_t * priv, uint32_t handle) mutex_unlock(&dev->struct_mutex); return NULL; } - fence = drm_user_object_entry(uo, drm_fence_object_t, base); - atomic_inc(&fence->usage); + fence = drm_fence_reference_locked(drm_user_object_entry(uo, drm_fence_object_t, base)); mutex_unlock(&dev->struct_mutex); return fence; } @@ -568,7 +588,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) arg.flags & DRM_FENCE_FLAG_SHAREABLE); if (ret) { - drm_fence_usage_deref_unlocked(dev, fence); + drm_fence_usage_deref_unlocked(&fence); return ret; } arg.handle = fence->base.hash.key; @@ -603,14 +623,14 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) fence = drm_lookup_fence_object(priv, arg.handle); if (!fence) return -EINVAL; - ret = drm_fence_object_flush(dev, fence, arg.type); + ret = drm_fence_object_flush(fence, arg.type); break; case drm_fence_wait: fence = drm_lookup_fence_object(priv, arg.handle); if (!fence) return -EINVAL; ret = - drm_fence_object_wait(dev, fence, + drm_fence_object_wait(fence, arg.flags & DRM_FENCE_FLAG_WAIT_LAZY, 0, arg.type); break; @@ -619,7 +639,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) fence = drm_lookup_fence_object(priv, arg.handle); if (!fence) return -EINVAL; - ret = drm_fence_object_emit(dev, fence, arg.flags, arg.class, + ret = drm_fence_object_emit(fence, arg.flags, arg.class, arg.type); break; case drm_fence_buffers: @@ -647,7 +667,7 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) arg.type = fence->type; arg.signaled = fence->signaled; read_unlock_irqrestore(&fm->lock, flags); - drm_fence_usage_deref_unlocked(dev, fence); + drm_fence_usage_deref_unlocked(&fence); DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg)); return ret; diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 59c8902d..f82d6628 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -141,6 +141,7 @@ extern int drm_user_object_unref(drm_file_t * priv, uint32_t user_token, typedef struct drm_fence_object { drm_user_object_t base; + struct drm_device *dev; atomic_t usage; /* @@ -196,17 +197,15 @@ extern void drm_fence_manager_init(struct drm_device *dev); extern void drm_fence_manager_takedown(struct drm_device *dev); extern void drm_fence_flush_old(struct drm_device *dev, uint32_t class, uint32_t sequence); -extern int drm_fence_object_flush(struct drm_device *dev, - drm_fence_object_t * fence, uint32_t type); -extern int drm_fence_object_signaled(struct drm_device *dev, - drm_fence_object_t * fence, +extern int drm_fence_object_flush(drm_fence_object_t * fence, uint32_t type); +extern int drm_fence_object_signaled(drm_fence_object_t * fence, uint32_t type, int flush); -extern void drm_fence_usage_deref_locked(struct drm_device *dev, - drm_fence_object_t * fence); -extern void drm_fence_usage_deref_unlocked(struct drm_device *dev, - drm_fence_object_t * fence); -extern int drm_fence_object_wait(struct drm_device *dev, - drm_fence_object_t * fence, +extern void drm_fence_usage_deref_locked(drm_fence_object_t ** fence); +extern void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence); +extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src); +extern void drm_fence_reference_unlocked(struct drm_fence_object **dst, + struct drm_fence_object *src); +extern int drm_fence_object_wait(drm_fence_object_t * fence, int lazy, int ignore_signals, uint32_t mask); extern int drm_fence_object_create(struct drm_device *dev, uint32_t type, uint32_t fence_flags, uint32_t class, @@ -441,7 +440,7 @@ extern int drm_bo_pci_offset(struct drm_device *dev, unsigned long *bus_size); extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem); -extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo); +extern void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo); extern int drm_fence_buffer_objects(drm_file_t * priv, struct list_head *list, uint32_t fence_flags, diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index f2c43508..72d63c10 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -840,7 +840,8 @@ static void drm_bo_vm_close(struct vm_area_struct *vma) #ifdef DRM_ODD_MM_COMPAT drm_bo_delete_vma(bo, vma); #endif - drm_bo_usage_deref_locked(bo); + drm_bo_usage_deref_locked((struct drm_buffer_object **) + &vma->vm_private_data); mutex_unlock(&dev->struct_mutex); } return; -- cgit v1.2.3 From a27af4c4a665864df09123f177ca7269e48f6171 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 29 Jun 2007 15:22:28 +0200 Subject: Avoid hitting BUG() for kernel-only fence objects. --- linux-core/drm_fence.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux-core') diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index ace70d51..5215feb6 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -450,6 +450,12 @@ static int drm_fence_object_init(drm_device_t * dev, uint32_t class, write_lock_irqsave(&fm->lock, flags); INIT_LIST_HEAD(&fence->ring); + + /* + * Avoid hitting BUG() for kernel-only fence objects. + */ + + INIT_LIST_HEAD(&fence->base.list); fence->class = class; fence->type = type; fence->flush_mask = 0; -- cgit v1.2.3 From b323ab52aa9ccbfb06dd723ece361a5242d067b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 28 Jun 2007 14:45:26 -0400 Subject: Drop drm_drawable_list and add drm_drawable_info directly to the idr. --- linux-core/drmP.h | 4 ---- linux-core/drm_drawable.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 24 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index dd3a69df..7bcd095a 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -598,10 +598,6 @@ typedef struct ati_pcigart_info { int table_size; } drm_ati_pcigart_info; -struct drm_drawable_list { - drm_drawable_info_t info; -}; - #include "drm_objects.h" /** diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index eb44a189..74f0bb5d 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -44,19 +44,19 @@ int drm_adddraw(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long irqflags; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *draw_info; drm_draw_t draw; int new_id = 0; int ret; - draw_info = drm_calloc(1, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + draw_info = drm_calloc(1, sizeof(*draw_info), DRM_MEM_BUFS); if (!draw_info) return -ENOMEM; again: if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { DRM_ERROR("Out of memory expanding drawable idr\n"); - drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return -ENOMEM; } @@ -86,7 +86,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS) DRM_DEVICE; drm_draw_t draw; unsigned long irqflags; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *draw_info; DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, sizeof(draw)); @@ -100,33 +100,31 @@ int drm_rmdraw(DRM_IOCTL_ARGS) spin_lock_irqsave(&dev->drw_lock, irqflags); idr_remove(&dev->drw_idr, draw.handle); - drm_free(draw_info, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("%d\n", draw.handle); return 0; } -int drm_update_drawable_info(DRM_IOCTL_ARGS) { +int drm_update_drawable_info(DRM_IOCTL_ARGS) +{ DRM_DEVICE; drm_update_draw_t update; unsigned long irqflags; - drm_drawable_info_t *info; drm_clip_rect_t *rects; - struct drm_drawable_list *draw_info; + struct drm_drawable_info *info; int err; DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, sizeof(update)); - draw_info = idr_find(&dev->drw_idr, update.handle); - if (!draw_info) { + info = idr_find(&dev->drw_idr, update.handle); + if (!info) { DRM_ERROR("No such drawable %d\n", update.handle); return DRM_ERR(EINVAL); } - info = &draw_info->info; - switch (update.type) { case DRM_DRAWABLE_CLIPRECTS: if (update.num != info->num_rects) { @@ -184,24 +182,27 @@ error: /** * Caller must hold the drawable spinlock! */ -drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - struct drm_drawable_list *draw_info; - draw_info = idr_find(&dev->drw_idr, id); - if (!draw_info) { +drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) +{ + struct drm_drawable_info *info; + + info = idr_find(&dev->drw_idr, id); + if (!info) { DRM_DEBUG("No such drawable %d\n", id); return NULL; } - return &draw_info->info; + return info; } EXPORT_SYMBOL(drm_get_drawable_info); static int drm_drawable_free(int idr, void *p, void *data) { - struct drm_drawable_list *drw_entry = p; - drm_free(drw_entry->info.rects, drw_entry->info.num_rects * + struct drm_drawable_info *info = p; + + drm_free(info->rects, info->num_rects * sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(drw_entry, sizeof(struct drm_drawable_list), DRM_MEM_BUFS); + drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return 0; } -- cgit v1.2.3 From c9d752ff4fb2b6eee2fef636193fc9ca29abba37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 2 Jul 2007 17:52:07 -0400 Subject: Fix must-check warnings and implement a few error paths. --- linux-core/drm_drv.c | 2 +- linux-core/drm_stub.c | 26 +++++++++++++++++--------- linux-core/drm_sysfs.c | 31 +++++++++++++++++++++++++------ 3 files changed, 43 insertions(+), 16 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index d5eb9713..6bbe7fca 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -311,7 +311,7 @@ int drm_init(struct drm_driver *driver, } if (!drm_fb_loaded) - pci_register_driver(&driver->pci_driver); + return pci_register_driver(&driver->pci_driver); else { for (i = 0; pciidlist[i].vendor != 0; i++) { pid = &pciidlist[i]; diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index f57ed9cc..b96408ab 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -232,18 +232,22 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if (!drm_fb_loaded) { pci_set_drvdata(pdev, dev); - pci_request_regions(pdev, driver->pci_driver.name); + ret = pci_request_regions(pdev, driver->pci_driver.name); + if (ret) + goto err_g1; } - pci_enable_device(pdev); + ret = pci_enable_device(pdev); + if (ret) + goto err_g2; pci_set_master(pdev); if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { printk(KERN_ERR "DRM: fill_in_dev failed\n"); - goto err_g1; + goto err_g3; } if ((ret = drm_get_head(dev, &dev->primary))) - goto err_g1; + goto err_g3; DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, @@ -251,12 +255,16 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, return 0; -err_g1: - if (!drm_fb_loaded) { - pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); + err_g3: + if (!drm_fb_loaded) pci_disable_device(pdev); - } + err_g2: + if (!drm_fb_loaded) + pci_release_regions(pdev); + err_g1: + if (!drm_fb_loaded) + pci_set_drvdata(pdev, NULL); + drm_free(dev, sizeof(*dev), DRM_MEM_STUB); printk(KERN_ERR "DRM: drm_get_dev failed.\n"); return ret; diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index ace0778b..9b2f5dce 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -93,11 +93,15 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) retval = class_register(&cs->class); if (retval) goto error; - class_create_file(&cs->class, &class_attr_version); + retval = class_create_file(&cs->class, &class_attr_version); + if (retval) + goto error_with_class; return cs; - error: + error_with_class: + class_unregister(&cs->class); + error: kfree(cs); return ERR_PTR(retval); } @@ -170,16 +174,31 @@ struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, if (retval) goto error; - class_device_create_file(&s_dev->class_dev, &cs->attr); + retval = class_device_create_file(&s_dev->class_dev, &cs->attr); + if (retval) + goto error_with_device; + class_set_devdata(&s_dev->class_dev, head); - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + retval = class_device_create_file(&s_dev->class_dev, + &class_device_attrs[i]); + if (retval) + goto error_with_files; + } return &s_dev->class_dev; -error: + error_with_files: + while (i > 0) + class_device_remove_file(&s_dev->class_dev, + &class_device_attrs[--i]); + class_device_remove_file(&s_dev->class_dev, &cs->attr); + error_with_device: + class_device_unregister(&s_dev->class_dev); + error: kfree(s_dev); + return ERR_PTR(retval); } -- cgit v1.2.3 From 8d96ba9805316b29e948d7594344feebb17042f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Jul 2007 11:41:44 +0200 Subject: Restore pre-idr semantics for drawable information. There's a difference between a drawable ID not having valid drawable information and not being allocated at all. Not making the distinction would break i915 DRM swap scheduling with older X servers that don't push drawable cliprect information to the DRM. --- linux-core/drm_drawable.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 74f0bb5d..7657e954 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -37,6 +37,8 @@ #include "drmP.h" +#define NO_DRW_INFO (void*)1 + /** * Allocate drawable ID and memory to store information about it. */ @@ -44,24 +46,18 @@ int drm_adddraw(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long irqflags; - struct drm_drawable_info *draw_info; drm_draw_t draw; int new_id = 0; int ret; - draw_info = drm_calloc(1, sizeof(*draw_info), DRM_MEM_BUFS); - if (!draw_info) - return -ENOMEM; - again: if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) { DRM_ERROR("Out of memory expanding drawable idr\n"); - drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); return -ENOMEM; } spin_lock_irqsave(&dev->drw_lock, irqflags); - ret = idr_get_new_above(&dev->drw_idr, draw_info, 1, &new_id); + ret = idr_get_new_above(&dev->drw_idr, NO_DRW_INFO, 1, &new_id); if (ret == -EAGAIN) { spin_unlock_irqrestore(&dev->drw_lock, irqflags); goto again; @@ -86,21 +82,16 @@ int drm_rmdraw(DRM_IOCTL_ARGS) DRM_DEVICE; drm_draw_t draw; unsigned long irqflags; - struct drm_drawable_info *draw_info; DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, sizeof(draw)); - draw_info = idr_find(&dev->drw_idr, draw.handle); - if (!draw_info) { - DRM_DEBUG("No such drawable %d\n", draw.handle); - return -EINVAL; - } - spin_lock_irqsave(&dev->drw_lock, irqflags); + drm_free(drm_get_drawable_info(dev, draw.handle), + sizeof(struct drm_drawable_info), DRM_MEM_BUFS); + idr_remove(&dev->drw_idr, draw.handle); - drm_free(draw_info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); spin_unlock_irqrestore(&dev->drw_lock, irqflags); DRM_DEBUG("%d\n", draw.handle); @@ -125,6 +116,13 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } + if (info == NO_DRW_INFO) { + info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); + if (!info) + return -ENOMEM; + idr_replace(&dev->drw_idr, info, update.handle); + } + switch (update.type) { case DRM_DRAWABLE_CLIPRECTS: if (update.num != info->num_rects) { @@ -187,11 +185,17 @@ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) struct drm_drawable_info *info; info = idr_find(&dev->drw_idr, id); + if (!info) { DRM_DEBUG("No such drawable %d\n", id); return NULL; } + if (info == NO_DRW_INFO) { + DRM_DEBUG("No information for drawable %d\n", id); + return NULL; + } + return info; } EXPORT_SYMBOL(drm_get_drawable_info); @@ -200,9 +204,12 @@ static int drm_drawable_free(int idr, void *p, void *data) { struct drm_drawable_info *info = p; - drm_free(info->rects, info->num_rects * - sizeof(drm_clip_rect_t), DRM_MEM_BUFS); - drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); + if (info != NO_DRW_INFO) { + drm_free(info->rects, info->num_rects * + sizeof(drm_clip_rect_t), DRM_MEM_BUFS); + drm_free(info, sizeof(*info), DRM_MEM_BUFS); + } + return 0; } -- cgit v1.2.3 From ea832a8e555c9e1f90830b55cbd970d0eca0e2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Jul 2007 12:15:15 +0200 Subject: Simplification for previous commit. Dave Airlie pointed out on IRC that idr_replace lets us know if the ID hasn't been allocated, so we don't need a special pointer value for allocated IDs that don't have valid information yet. --- linux-core/drm_drawable.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 7657e954..57b62ca4 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -37,8 +37,6 @@ #include "drmP.h" -#define NO_DRW_INFO (void*)1 - /** * Allocate drawable ID and memory to store information about it. */ @@ -57,7 +55,7 @@ again: } spin_lock_irqsave(&dev->drw_lock, irqflags); - ret = idr_get_new_above(&dev->drw_idr, NO_DRW_INFO, 1, &new_id); + ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id); if (ret == -EAGAIN) { spin_unlock_irqrestore(&dev->drw_lock, irqflags); goto again; @@ -112,15 +110,15 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) info = idr_find(&dev->drw_idr, update.handle); if (!info) { - DRM_ERROR("No such drawable %d\n", update.handle); - return DRM_ERR(EINVAL); - } - - if (info == NO_DRW_INFO) { info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); if (!info) return -ENOMEM; - idr_replace(&dev->drw_idr, info, update.handle); + if (idr_replace(&dev->drw_idr, info, update.handle) == + (void*)-ENOENT) { + DRM_ERROR("No such drawable %d\n", update.handle); + drm_free(info, sizeof(*info), DRM_MEM_BUFS); + return -EINVAL; + } } switch (update.type) { @@ -182,21 +180,7 @@ error: */ drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { - struct drm_drawable_info *info; - - info = idr_find(&dev->drw_idr, id); - - if (!info) { - DRM_DEBUG("No such drawable %d\n", id); - return NULL; - } - - if (info == NO_DRW_INFO) { - DRM_DEBUG("No information for drawable %d\n", id); - return NULL; - } - - return info; + return idr_find(&dev->drw_idr, id); } EXPORT_SYMBOL(drm_get_drawable_info); @@ -204,7 +188,7 @@ static int drm_drawable_free(int idr, void *p, void *data) { struct drm_drawable_info *info = p; - if (info != NO_DRW_INFO) { + if (info) { drm_free(info->rects, info->num_rects * sizeof(drm_clip_rect_t), DRM_MEM_BUFS); drm_free(info, sizeof(*info), DRM_MEM_BUFS); -- cgit v1.2.3 From 1814a829eb65ee53a14fa9b53fc6f3a4196dcaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 3 Jul 2007 10:31:46 -0400 Subject: Don't take dev->struct_mutex twice in drm_setsareactx. --- linux-core/drm_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c index 101a298c..ff08e809 100644 --- a/linux-core/drm_context.c +++ b/linux-core/drm_context.c @@ -245,8 +245,6 @@ int drm_setsareactx(struct inode *inode, struct file *filp, if (!map) goto bad; - mutex_lock(&dev->struct_mutex); - ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id); if (!ctx_sarea) goto bad; -- cgit v1.2.3 From d57b7f02d2e525e5600e5d77370d7ad2b4c9b265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 3 Jul 2007 10:41:48 -0400 Subject: Use idr_replace trick to eliminate struct drm_ctx_sarea_list. --- linux-core/drmP.h | 4 ---- linux-core/drm_context.c | 41 +++++++---------------------------------- linux-core/drm_drawable.c | 3 +-- 3 files changed, 8 insertions(+), 40 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 7bcd095a..c992c8d9 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -570,10 +570,6 @@ typedef struct drm_ctx_list { drm_file_t *tag; /**< associated fd private data */ } drm_ctx_list_t; -struct drm_ctx_sarea_list { - drm_map_t *map; -}; - typedef struct drm_vbl_sig { struct list_head head; unsigned int sequence; diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c index ff08e809..195c7fb5 100644 --- a/linux-core/drm_context.c +++ b/linux-core/drm_context.c @@ -58,17 +58,9 @@ */ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) { - struct drm_ctx_sarea_list *ctx; - mutex_lock(&dev->struct_mutex); - ctx = idr_find(&dev->ctx_idr, ctx_handle); - if (ctx) { - idr_remove(&dev->ctx_idr, ctx_handle); - drm_free(ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST); - } else - DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle); + idr_remove(&dev->ctx_idr, ctx_handle); mutex_unlock(&dev->struct_mutex); - return; } /** @@ -84,20 +76,15 @@ static int drm_ctxbitmap_next(drm_device_t * dev) { int new_id; int ret; - struct drm_ctx_sarea_list *new_ctx; - - new_ctx = drm_calloc(1, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST); - if (!new_ctx) - return -1; again: if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) { DRM_ERROR("Out of memory expanding drawable idr\n"); - drm_free(new_ctx, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST); return -ENOMEM; } mutex_lock(&dev->struct_mutex); - ret = idr_get_new_above(&dev->ctx_idr, new_ctx, DRM_RESERVED_CONTEXTS, &new_id); + ret = idr_get_new_above(&dev->ctx_idr, NULL, + DRM_RESERVED_CONTEXTS, &new_id); if (ret == -EAGAIN) { mutex_unlock(&dev->struct_mutex); goto again; @@ -120,15 +107,6 @@ int drm_ctxbitmap_init(drm_device_t * dev) return 0; } - - -static int drm_ctx_sarea_free(int id, void *p, void *data) -{ - struct drm_ctx_sarea_list *ctx_entry = p; - drm_free(ctx_entry, sizeof(struct drm_ctx_sarea_list), DRM_MEM_CTXLIST); - return 0; -} - /** * Context bitmap cleanup. * @@ -140,7 +118,6 @@ static int drm_ctx_sarea_free(int id, void *p, void *data) void drm_ctxbitmap_cleanup(drm_device_t * dev) { mutex_lock(&dev->struct_mutex); - idr_for_each(&dev->ctx_idr, drm_ctx_sarea_free, NULL); idr_remove_all(&dev->ctx_idr); mutex_unlock(&dev->struct_mutex); } @@ -172,19 +149,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp, drm_ctx_priv_map_t request; drm_map_t *map; drm_map_list_t *_entry; - struct drm_ctx_sarea_list *ctx_sarea; if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; mutex_lock(&dev->struct_mutex); - ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id); - if (!ctx_sarea) { + map = idr_find(&dev->ctx_idr, request.ctx_id); + if (!map) { mutex_unlock(&dev->struct_mutex); return -EINVAL; } - map = ctx_sarea->map; mutex_unlock(&dev->struct_mutex); @@ -224,7 +199,6 @@ int drm_setsareactx(struct inode *inode, struct file *filp, drm_ctx_priv_map_t request; drm_map_t *map = NULL; drm_map_list_t *r_list = NULL; - struct drm_ctx_sarea_list *ctx_sarea; if (copy_from_user(&request, (drm_ctx_priv_map_t __user *) arg, sizeof(request))) @@ -245,12 +219,11 @@ int drm_setsareactx(struct inode *inode, struct file *filp, if (!map) goto bad; - ctx_sarea = idr_find(&dev->ctx_idr, request.ctx_id); - if (!ctx_sarea) + if (IS_ERR(idr_replace(&dev->ctx_idr, map, request.ctx_id))) goto bad; - ctx_sarea->map = map; mutex_unlock(&dev->struct_mutex); + return 0; } diff --git a/linux-core/drm_drawable.c b/linux-core/drm_drawable.c index 57b62ca4..7129980b 100644 --- a/linux-core/drm_drawable.c +++ b/linux-core/drm_drawable.c @@ -113,8 +113,7 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); if (!info) return -ENOMEM; - if (idr_replace(&dev->drw_idr, info, update.handle) == - (void*)-ENOENT) { + if (IS_ERR(idr_replace(&dev->drw_idr, info, update.handle))) { DRM_ERROR("No such drawable %d\n", update.handle); drm_free(info, sizeof(*info), DRM_MEM_BUFS); return -EINVAL; -- cgit v1.2.3 From c806bba4665bb369168ee0b453fa28e2e0bf2a5d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 5 Jul 2007 00:12:33 +1000 Subject: nouveau/nv50: Initial channel/object support Should be OK on G84 for a single channel, multiple channels *almost* work. Untested on G80. --- linux-core/Makefile.kernel | 3 ++- linux-core/nv04_instmem.c | 1 + linux-core/nv50_instmem.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 120000 linux-core/nv04_instmem.c create mode 120000 linux-core/nv50_instmem.c (limited to 'linux-core') diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 478c4df0..be2641c8 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -27,7 +27,8 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nv04_fb.o nv10_fb.o nv40_fb.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \ - nv40_graph.o nv50_graph.o + nv40_graph.o nv50_graph.o \ + nv04_instmem.o nv50_instmem.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o diff --git a/linux-core/nv04_instmem.c b/linux-core/nv04_instmem.c new file mode 120000 index 00000000..e720fb5b --- /dev/null +++ b/linux-core/nv04_instmem.c @@ -0,0 +1 @@ +../shared-core/nv04_instmem.c \ No newline at end of file diff --git a/linux-core/nv50_instmem.c b/linux-core/nv50_instmem.c new file mode 120000 index 00000000..4e45344a --- /dev/null +++ b/linux-core/nv50_instmem.c @@ -0,0 +1 @@ +../shared-core/nv50_instmem.c \ No newline at end of file -- cgit v1.2.3 From 04e4922c0c407a9f0cfe268f62130891e98fc682 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 11 Jul 2007 02:33:12 +0200 Subject: Made drm_sg_alloc accessible from inside the DRM - drm_sg_alloc_ioctl is the ioctl wrapper --- linux-core/drmP.h | 3 ++- linux-core/drm_drv.c | 2 +- linux-core/drm_scatter.c | 49 ++++++++++++++++++++++++++++++------------------ 3 files changed, 34 insertions(+), 20 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c992c8d9..c274f1fa 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1129,8 +1129,9 @@ extern int drm_proc_cleanup(int minor, /* Scatter Gather Support (drm_scatter.h) */ extern void drm_sg_cleanup(drm_sg_mem_t * entry); -extern int drm_sg_alloc(struct inode *inode, struct file *filp, +extern int drm_sg_alloc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int drm_sg_alloc(drm_device_t *dev, drm_scatter_gather_t * request); extern int drm_sg_free(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 6bbe7fca..0d446a12 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -113,7 +113,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, #endif - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, diff --git a/linux-core/drm_scatter.c b/linux-core/drm_scatter.c index e5c9f877..c0d6db24 100644 --- a/linux-core/drm_scatter.c +++ b/linux-core/drm_scatter.c @@ -55,6 +55,7 @@ void drm_sg_cleanup(drm_sg_mem_t * entry) entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES); drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); } +EXPORT_SYMBOL(drm_sg_cleanup); #ifdef _LP64 # define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1))) @@ -62,13 +63,8 @@ void drm_sg_cleanup(drm_sg_mem_t * entry) # define ScatterHandle(x) (unsigned int)(x) #endif -int drm_sg_alloc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_scatter_gather_t __user *argp = (void __user *)arg; - drm_scatter_gather_t request; drm_sg_mem_t *entry; unsigned long pages, i, j; @@ -80,17 +76,13 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, if (dev->sg) return -EINVAL; - if (copy_from_user(&request, argp, sizeof(request))) - return -EFAULT; - entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); if (!entry) return -ENOMEM; memset(entry, 0, sizeof(*entry)); - - pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages); + pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; + DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages); entry->pages = pages; entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), @@ -142,12 +134,7 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, SetPageReserved(entry->pagelist[j]); } - request.handle = entry->handle; - - if (copy_to_user(argp, &request, sizeof(request))) { - drm_sg_cleanup(entry); - return -EFAULT; - } + request->handle = entry->handle; dev->sg = entry; @@ -196,6 +183,32 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, failed: drm_sg_cleanup(entry); return -ENOMEM; + +} +EXPORT_SYMBOL(drm_sg_alloc); + +int drm_sg_alloc_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_scatter_gather_t __user *argp = (void __user *)arg; + drm_scatter_gather_t request; + int ret; + + if (copy_from_user(&request, argp, sizeof(request))) + return -EFAULT; + + ret = drm_sg_alloc(priv->head->dev, &request); + if ( ret ) return ret; + + if (copy_to_user(argp, &request, sizeof(request))) { + drm_sg_cleanup(priv->head->dev->sg); + return -EFAULT; + } + + + return 0; + } int drm_sg_free(struct inode *inode, struct file *filp, -- cgit v1.2.3 From 750371cb6ea9a64c9d4d4d3b9716c3c68d810d48 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 12 Jul 2007 10:15:16 +1000 Subject: nouveau: separate region_offset into map_handle and offset. --- linux-core/drmP.h | 3 +++ linux-core/drm_bufs.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c274f1fa..2bbc6200 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1048,6 +1048,9 @@ extern unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource); extern unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource); +extern drm_map_list_t *drm_find_matching_map(drm_device_t *dev, + drm_local_map_t *map); + /* DMA support (drm_dma.h) */ extern int drm_dma_setup(drm_device_t * dev); diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index a2c8a75e..2f3e4b2a 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -48,8 +48,7 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) } EXPORT_SYMBOL(drm_get_resource_len); -static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, - drm_local_map_t *map) +drm_map_list_t *drm_find_matching_map(drm_device_t *dev, drm_local_map_t *map) { drm_map_list_t *entry; list_for_each_entry(entry, &dev->maplist, head) { @@ -62,6 +61,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, return NULL; } +EXPORT_SYMBOL(drm_find_matching_map); static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, unsigned long user_token, int hashed_handle) -- cgit v1.2.3