diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2010-11-17 07:28:30 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-11-21 22:25:20 -0500 |
commit | 95762c2b34069bf4adb7929969f1f5f5fc8a38df (patch) | |
tree | 5c792e65dbdb4e7cb2c04b5a8058a929e8acc23d | |
parent | 702adba22433c175e8429a47760f35ca16caf1cd (diff) |
drm/ttm: Improved fencing of buffer object lists
Drastically reduce the number of spin lock / unlock operations by performing
unreserving and fencing under global locks.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jerome Glisse <j.glisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_execbuf_util.c | 36 | ||||
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 10 | ||||
-rw-r--r-- | include/drm/ttm/ttm_execbuf_util.h | 2 |
4 files changed, 45 insertions, 14 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d93c73b1c471..551a5d31cadf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -299,14 +299,19 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, | |||
299 | return ret; | 299 | return ret; |
300 | } | 300 | } |
301 | 301 | ||
302 | void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo) | ||
303 | { | ||
304 | ttm_bo_add_to_lru(bo); | ||
305 | atomic_set(&bo->reserved, 0); | ||
306 | wake_up_all(&bo->event_queue); | ||
307 | } | ||
308 | |||
302 | void ttm_bo_unreserve(struct ttm_buffer_object *bo) | 309 | void ttm_bo_unreserve(struct ttm_buffer_object *bo) |
303 | { | 310 | { |
304 | struct ttm_bo_global *glob = bo->glob; | 311 | struct ttm_bo_global *glob = bo->glob; |
305 | 312 | ||
306 | spin_lock(&glob->lru_lock); | 313 | spin_lock(&glob->lru_lock); |
307 | ttm_bo_add_to_lru(bo); | 314 | ttm_bo_unreserve_locked(bo); |
308 | atomic_set(&bo->reserved, 0); | ||
309 | wake_up_all(&bo->event_queue); | ||
310 | spin_unlock(&glob->lru_lock); | 315 | spin_unlock(&glob->lru_lock); |
311 | } | 316 | } |
312 | EXPORT_SYMBOL(ttm_bo_unreserve); | 317 | EXPORT_SYMBOL(ttm_bo_unreserve); |
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index c3a2100bace6..b6da65cc502a 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c | |||
@@ -200,22 +200,36 @@ EXPORT_SYMBOL(ttm_eu_reserve_buffers); | |||
200 | void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj) | 200 | void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj) |
201 | { | 201 | { |
202 | struct ttm_validate_buffer *entry; | 202 | struct ttm_validate_buffer *entry; |
203 | struct ttm_buffer_object *bo; | ||
204 | struct ttm_bo_global *glob; | ||
205 | struct ttm_bo_device *bdev; | ||
206 | struct ttm_bo_driver *driver; | ||
203 | 207 | ||
204 | list_for_each_entry(entry, list, head) { | 208 | if (list_empty(list)) |
205 | struct ttm_buffer_object *bo = entry->bo; | 209 | return; |
206 | struct ttm_bo_device *bdev = bo->bdev; | 210 | |
207 | struct ttm_bo_driver *driver = bdev->driver; | 211 | bo = list_first_entry(list, struct ttm_validate_buffer, head)->bo; |
208 | void *old_sync_obj; | 212 | bdev = bo->bdev; |
213 | driver = bdev->driver; | ||
214 | glob = bo->glob; | ||
209 | 215 | ||
210 | spin_lock(&bdev->fence_lock); | 216 | spin_lock(&bdev->fence_lock); |
211 | old_sync_obj = bo->sync_obj; | 217 | spin_lock(&glob->lru_lock); |
218 | |||
219 | list_for_each_entry(entry, list, head) { | ||
220 | bo = entry->bo; | ||
221 | entry->old_sync_obj = bo->sync_obj; | ||
212 | bo->sync_obj = driver->sync_obj_ref(sync_obj); | 222 | bo->sync_obj = driver->sync_obj_ref(sync_obj); |
213 | bo->sync_obj_arg = entry->new_sync_obj_arg; | 223 | bo->sync_obj_arg = entry->new_sync_obj_arg; |
214 | spin_unlock(&bdev->fence_lock); | 224 | ttm_bo_unreserve_locked(bo); |
215 | ttm_bo_unreserve(bo); | ||
216 | entry->reserved = false; | 225 | entry->reserved = false; |
217 | if (old_sync_obj) | 226 | } |
218 | driver->sync_obj_unref(&old_sync_obj); | 227 | spin_unlock(&glob->lru_lock); |
228 | spin_unlock(&bdev->fence_lock); | ||
229 | |||
230 | list_for_each_entry(entry, list, head) { | ||
231 | if (entry->old_sync_obj) | ||
232 | driver->sync_obj_unref(&entry->old_sync_obj); | ||
219 | } | 233 | } |
220 | } | 234 | } |
221 | EXPORT_SYMBOL(ttm_eu_fence_buffer_objects); | 235 | EXPORT_SYMBOL(ttm_eu_fence_buffer_objects); |
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index ca8131e98300..cfb9ca4ec1c4 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -910,6 +910,16 @@ extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, | |||
910 | extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); | 910 | extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); |
911 | 911 | ||
912 | /** | 912 | /** |
913 | * ttm_bo_unreserve_locked | ||
914 | * | ||
915 | * @bo: A pointer to a struct ttm_buffer_object. | ||
916 | * | ||
917 | * Unreserve a previous reservation of @bo. | ||
918 | * Needs to be called with struct ttm_bo_global::lru_lock held. | ||
919 | */ | ||
920 | extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo); | ||
921 | |||
922 | /** | ||
913 | * ttm_bo_wait_unreserved | 923 | * ttm_bo_wait_unreserved |
914 | * | 924 | * |
915 | * @bo: A pointer to a struct ttm_buffer_object. | 925 | * @bo: A pointer to a struct ttm_buffer_object. |
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index fd09b8438977..535ab00407e0 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h | |||
@@ -44,6 +44,7 @@ | |||
44 | * @reserved: Indicates whether @bo has been reserved for validation. | 44 | * @reserved: Indicates whether @bo has been reserved for validation. |
45 | * @removed: Indicates whether @bo has been removed from lru lists. | 45 | * @removed: Indicates whether @bo has been removed from lru lists. |
46 | * @put_count: Number of outstanding references on bo::list_kref. | 46 | * @put_count: Number of outstanding references on bo::list_kref. |
47 | * @old_sync_obj: Pointer to a sync object about to be unreferenced | ||
47 | */ | 48 | */ |
48 | 49 | ||
49 | struct ttm_validate_buffer { | 50 | struct ttm_validate_buffer { |
@@ -53,6 +54,7 @@ struct ttm_validate_buffer { | |||
53 | bool reserved; | 54 | bool reserved; |
54 | bool removed; | 55 | bool removed; |
55 | int put_count; | 56 | int put_count; |
57 | void *old_sync_obj; | ||
56 | }; | 58 | }; |
57 | 59 | ||
58 | /** | 60 | /** |