diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 05:53:14 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-17 16:08:01 -0500 |
commit | 3b96eff447b4ca34ca8ccd42e2651be2955f34b4 (patch) | |
tree | fd93c20b96673370f68d28df9ee7602265e67db3 | |
parent | 419fa72a1973c9ba2fd2c2505dc889f54b857459 (diff) |
drm/i915: Take the handle idr spinlock once for looking up the exec objects
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 986eb98f0d25..da103c179e3f 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -69,6 +69,46 @@ eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj) | |||
69 | &eb->buckets[obj->exec_handle & eb->and]); | 69 | &eb->buckets[obj->exec_handle & eb->and]); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int | ||
73 | eb_lookup_objects(struct eb_objects *eb, | ||
74 | struct drm_i915_gem_exec_object2 *exec, | ||
75 | int count, | ||
76 | struct drm_file *file, | ||
77 | struct list_head *objects) | ||
78 | { | ||
79 | int i; | ||
80 | |||
81 | spin_lock(&file->table_lock); | ||
82 | for (i = 0; i < count; i++) { | ||
83 | struct drm_i915_gem_object *obj; | ||
84 | |||
85 | obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); | ||
86 | if (obj == NULL) { | ||
87 | spin_unlock(&file->table_lock); | ||
88 | DRM_DEBUG("Invalid object handle %d at index %d\n", | ||
89 | exec[i].handle, i); | ||
90 | return -ENOENT; | ||
91 | } | ||
92 | |||
93 | if (!list_empty(&obj->exec_list)) { | ||
94 | spin_unlock(&file->table_lock); | ||
95 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", | ||
96 | obj, exec[i].handle, i); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | drm_gem_object_reference(&obj->base); | ||
101 | list_add_tail(&obj->exec_list, objects); | ||
102 | |||
103 | obj->exec_handle = exec[i].handle; | ||
104 | obj->exec_entry = &exec[i]; | ||
105 | eb_add_object(eb, obj); | ||
106 | } | ||
107 | spin_unlock(&file->table_lock); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
72 | static struct drm_i915_gem_object * | 112 | static struct drm_i915_gem_object * |
73 | eb_get_object(struct eb_objects *eb, unsigned long handle) | 113 | eb_get_object(struct eb_objects *eb, unsigned long handle) |
74 | { | 114 | { |
@@ -550,21 +590,9 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
550 | 590 | ||
551 | /* reacquire the objects */ | 591 | /* reacquire the objects */ |
552 | eb_reset(eb); | 592 | eb_reset(eb); |
553 | for (i = 0; i < count; i++) { | 593 | ret = eb_lookup_objects(eb, exec, count, file, objects); |
554 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | 594 | if (ret) |
555 | exec[i].handle)); | 595 | goto err; |
556 | if (&obj->base == NULL) { | ||
557 | DRM_DEBUG("Invalid object handle %d at index %d\n", | ||
558 | exec[i].handle, i); | ||
559 | ret = -ENOENT; | ||
560 | goto err; | ||
561 | } | ||
562 | |||
563 | list_add_tail(&obj->exec_list, objects); | ||
564 | obj->exec_handle = exec[i].handle; | ||
565 | obj->exec_entry = &exec[i]; | ||
566 | eb_add_object(eb, obj); | ||
567 | } | ||
568 | 596 | ||
569 | ret = i915_gem_execbuffer_reserve(ring, file, objects); | 597 | ret = i915_gem_execbuffer_reserve(ring, file, objects); |
570 | if (ret) | 598 | if (ret) |
@@ -872,31 +900,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
872 | 900 | ||
873 | /* Look up object handles */ | 901 | /* Look up object handles */ |
874 | INIT_LIST_HEAD(&objects); | 902 | INIT_LIST_HEAD(&objects); |
875 | for (i = 0; i < args->buffer_count; i++) { | 903 | ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects); |
876 | struct drm_i915_gem_object *obj; | 904 | if (ret) |
877 | 905 | goto err; | |
878 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | ||
879 | exec[i].handle)); | ||
880 | if (&obj->base == NULL) { | ||
881 | DRM_DEBUG("Invalid object handle %d at index %d\n", | ||
882 | exec[i].handle, i); | ||
883 | /* prevent error path from reading uninitialized data */ | ||
884 | ret = -ENOENT; | ||
885 | goto err; | ||
886 | } | ||
887 | |||
888 | if (!list_empty(&obj->exec_list)) { | ||
889 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", | ||
890 | obj, exec[i].handle, i); | ||
891 | ret = -EINVAL; | ||
892 | goto err; | ||
893 | } | ||
894 | |||
895 | list_add_tail(&obj->exec_list, &objects); | ||
896 | obj->exec_handle = exec[i].handle; | ||
897 | obj->exec_entry = &exec[i]; | ||
898 | eb_add_object(eb, obj); | ||
899 | } | ||
900 | 906 | ||
901 | /* take note of the batch buffer before we might reorder the lists */ | 907 | /* take note of the batch buffer before we might reorder the lists */ |
902 | batch_obj = list_entry(objects.prev, | 908 | batch_obj = list_entry(objects.prev, |