diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 05:53:15 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-17 16:08:02 -0500 |
commit | bcffc3faa692d6b2ef734e4f0c8f097175284db6 (patch) | |
tree | 84633b4990a2e826b5cf7c8dcd745b658318c8cd | |
parent | 3b96eff447b4ca34ca8ccd42e2651be2955f34b4 (diff) |
drm/i915: Move the execbuffer objects list from the stack into the tracker
Instead of passing around the eb-objects hashtable and a separate object
list, we can include the object list into the eb-objects structure for
convenience.
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 | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index da103c179e3f..386677f8fd38 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/dma_remapping.h> | 34 | #include <linux/dma_remapping.h> |
35 | 35 | ||
36 | struct eb_objects { | 36 | struct eb_objects { |
37 | struct list_head objects; | ||
37 | int and; | 38 | int and; |
38 | struct hlist_head buckets[0]; | 39 | struct hlist_head buckets[0]; |
39 | }; | 40 | }; |
@@ -53,6 +54,7 @@ eb_create(int size) | |||
53 | return eb; | 54 | return eb; |
54 | 55 | ||
55 | eb->and = count - 1; | 56 | eb->and = count - 1; |
57 | INIT_LIST_HEAD(&eb->objects); | ||
56 | return eb; | 58 | return eb; |
57 | } | 59 | } |
58 | 60 | ||
@@ -73,8 +75,7 @@ static int | |||
73 | eb_lookup_objects(struct eb_objects *eb, | 75 | eb_lookup_objects(struct eb_objects *eb, |
74 | struct drm_i915_gem_exec_object2 *exec, | 76 | struct drm_i915_gem_exec_object2 *exec, |
75 | int count, | 77 | int count, |
76 | struct drm_file *file, | 78 | struct drm_file *file) |
77 | struct list_head *objects) | ||
78 | { | 79 | { |
79 | int i; | 80 | int i; |
80 | 81 | ||
@@ -98,7 +99,7 @@ eb_lookup_objects(struct eb_objects *eb, | |||
98 | } | 99 | } |
99 | 100 | ||
100 | drm_gem_object_reference(&obj->base); | 101 | drm_gem_object_reference(&obj->base); |
101 | list_add_tail(&obj->exec_list, objects); | 102 | list_add_tail(&obj->exec_list, &eb->objects); |
102 | 103 | ||
103 | obj->exec_handle = exec[i].handle; | 104 | obj->exec_handle = exec[i].handle; |
104 | obj->exec_entry = &exec[i]; | 105 | obj->exec_entry = &exec[i]; |
@@ -129,6 +130,15 @@ eb_get_object(struct eb_objects *eb, unsigned long handle) | |||
129 | static void | 130 | static void |
130 | eb_destroy(struct eb_objects *eb) | 131 | eb_destroy(struct eb_objects *eb) |
131 | { | 132 | { |
133 | while (!list_empty(&eb->objects)) { | ||
134 | struct drm_i915_gem_object *obj; | ||
135 | |||
136 | obj = list_first_entry(&eb->objects, | ||
137 | struct drm_i915_gem_object, | ||
138 | exec_list); | ||
139 | list_del_init(&obj->exec_list); | ||
140 | drm_gem_object_unreference(&obj->base); | ||
141 | } | ||
132 | kfree(eb); | 142 | kfree(eb); |
133 | } | 143 | } |
134 | 144 | ||
@@ -328,8 +338,7 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, | |||
328 | 338 | ||
329 | static int | 339 | static int |
330 | i915_gem_execbuffer_relocate(struct drm_device *dev, | 340 | i915_gem_execbuffer_relocate(struct drm_device *dev, |
331 | struct eb_objects *eb, | 341 | struct eb_objects *eb) |
332 | struct list_head *objects) | ||
333 | { | 342 | { |
334 | struct drm_i915_gem_object *obj; | 343 | struct drm_i915_gem_object *obj; |
335 | int ret = 0; | 344 | int ret = 0; |
@@ -342,7 +351,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, | |||
342 | * lockdep complains vehemently. | 351 | * lockdep complains vehemently. |
343 | */ | 352 | */ |
344 | pagefault_disable(); | 353 | pagefault_disable(); |
345 | list_for_each_entry(obj, objects, exec_list) { | 354 | list_for_each_entry(obj, &eb->objects, exec_list) { |
346 | ret = i915_gem_execbuffer_relocate_object(obj, eb); | 355 | ret = i915_gem_execbuffer_relocate_object(obj, eb); |
347 | if (ret) | 356 | if (ret) |
348 | break; | 357 | break; |
@@ -531,7 +540,6 @@ static int | |||
531 | i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | 540 | i915_gem_execbuffer_relocate_slow(struct drm_device *dev, |
532 | struct drm_file *file, | 541 | struct drm_file *file, |
533 | struct intel_ring_buffer *ring, | 542 | struct intel_ring_buffer *ring, |
534 | struct list_head *objects, | ||
535 | struct eb_objects *eb, | 543 | struct eb_objects *eb, |
536 | struct drm_i915_gem_exec_object2 *exec, | 544 | struct drm_i915_gem_exec_object2 *exec, |
537 | int count) | 545 | int count) |
@@ -542,8 +550,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
542 | int i, total, ret; | 550 | int i, total, ret; |
543 | 551 | ||
544 | /* We may process another execbuffer during the unlock... */ | 552 | /* We may process another execbuffer during the unlock... */ |
545 | while (!list_empty(objects)) { | 553 | while (!list_empty(&eb->objects)) { |
546 | obj = list_first_entry(objects, | 554 | obj = list_first_entry(&eb->objects, |
547 | struct drm_i915_gem_object, | 555 | struct drm_i915_gem_object, |
548 | exec_list); | 556 | exec_list); |
549 | list_del_init(&obj->exec_list); | 557 | list_del_init(&obj->exec_list); |
@@ -590,15 +598,15 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
590 | 598 | ||
591 | /* reacquire the objects */ | 599 | /* reacquire the objects */ |
592 | eb_reset(eb); | 600 | eb_reset(eb); |
593 | ret = eb_lookup_objects(eb, exec, count, file, objects); | 601 | ret = eb_lookup_objects(eb, exec, count, file); |
594 | if (ret) | 602 | if (ret) |
595 | goto err; | 603 | goto err; |
596 | 604 | ||
597 | ret = i915_gem_execbuffer_reserve(ring, file, objects); | 605 | ret = i915_gem_execbuffer_reserve(ring, file, &eb->objects); |
598 | if (ret) | 606 | if (ret) |
599 | goto err; | 607 | goto err; |
600 | 608 | ||
601 | list_for_each_entry(obj, objects, exec_list) { | 609 | list_for_each_entry(obj, &eb->objects, exec_list) { |
602 | int offset = obj->exec_entry - exec; | 610 | int offset = obj->exec_entry - exec; |
603 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, | 611 | ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, |
604 | reloc + reloc_offset[offset]); | 612 | reloc + reloc_offset[offset]); |
@@ -756,7 +764,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
756 | struct drm_i915_gem_exec_object2 *exec) | 764 | struct drm_i915_gem_exec_object2 *exec) |
757 | { | 765 | { |
758 | drm_i915_private_t *dev_priv = dev->dev_private; | 766 | drm_i915_private_t *dev_priv = dev->dev_private; |
759 | struct list_head objects; | ||
760 | struct eb_objects *eb; | 767 | struct eb_objects *eb; |
761 | struct drm_i915_gem_object *batch_obj; | 768 | struct drm_i915_gem_object *batch_obj; |
762 | struct drm_clip_rect *cliprects = NULL; | 769 | struct drm_clip_rect *cliprects = NULL; |
@@ -899,28 +906,26 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
899 | } | 906 | } |
900 | 907 | ||
901 | /* Look up object handles */ | 908 | /* Look up object handles */ |
902 | INIT_LIST_HEAD(&objects); | 909 | ret = eb_lookup_objects(eb, exec, args->buffer_count, file); |
903 | ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects); | ||
904 | if (ret) | 910 | if (ret) |
905 | goto err; | 911 | goto err; |
906 | 912 | ||
907 | /* take note of the batch buffer before we might reorder the lists */ | 913 | /* take note of the batch buffer before we might reorder the lists */ |
908 | batch_obj = list_entry(objects.prev, | 914 | batch_obj = list_entry(eb->objects.prev, |
909 | struct drm_i915_gem_object, | 915 | struct drm_i915_gem_object, |
910 | exec_list); | 916 | exec_list); |
911 | 917 | ||
912 | /* Move the objects en-masse into the GTT, evicting if necessary. */ | 918 | /* Move the objects en-masse into the GTT, evicting if necessary. */ |
913 | ret = i915_gem_execbuffer_reserve(ring, file, &objects); | 919 | ret = i915_gem_execbuffer_reserve(ring, file, &eb->objects); |
914 | if (ret) | 920 | if (ret) |
915 | goto err; | 921 | goto err; |
916 | 922 | ||
917 | /* The objects are in their final locations, apply the relocations. */ | 923 | /* The objects are in their final locations, apply the relocations. */ |
918 | ret = i915_gem_execbuffer_relocate(dev, eb, &objects); | 924 | ret = i915_gem_execbuffer_relocate(dev, eb); |
919 | if (ret) { | 925 | if (ret) { |
920 | if (ret == -EFAULT) { | 926 | if (ret == -EFAULT) { |
921 | ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, | 927 | ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, |
922 | &objects, eb, | 928 | eb, exec, |
923 | exec, | ||
924 | args->buffer_count); | 929 | args->buffer_count); |
925 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 930 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
926 | } | 931 | } |
@@ -943,7 +948,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
943 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) | 948 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) |
944 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); | 949 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); |
945 | 950 | ||
946 | ret = i915_gem_execbuffer_move_to_gpu(ring, &objects); | 951 | ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects); |
947 | if (ret) | 952 | if (ret) |
948 | goto err; | 953 | goto err; |
949 | 954 | ||
@@ -997,20 +1002,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
997 | 1002 | ||
998 | trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); | 1003 | trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); |
999 | 1004 | ||
1000 | i915_gem_execbuffer_move_to_active(&objects, ring); | 1005 | i915_gem_execbuffer_move_to_active(&eb->objects, ring); |
1001 | i915_gem_execbuffer_retire_commands(dev, file, ring); | 1006 | i915_gem_execbuffer_retire_commands(dev, file, ring); |
1002 | 1007 | ||
1003 | err: | 1008 | err: |
1004 | eb_destroy(eb); | 1009 | eb_destroy(eb); |
1005 | while (!list_empty(&objects)) { | ||
1006 | struct drm_i915_gem_object *obj; | ||
1007 | |||
1008 | obj = list_first_entry(&objects, | ||
1009 | struct drm_i915_gem_object, | ||
1010 | exec_list); | ||
1011 | list_del_init(&obj->exec_list); | ||
1012 | drm_gem_object_unreference(&obj->base); | ||
1013 | } | ||
1014 | 1010 | ||
1015 | mutex_unlock(&dev->struct_mutex); | 1011 | mutex_unlock(&dev->struct_mutex); |
1016 | 1012 | ||