aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_bo.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-05-14 09:42:29 -0400
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-02 11:28:47 -0400
commit472db7ab3093bf2a2999f6b5aa64a030466d6f92 (patch)
tree84b4fd486f1b54cbec662f8840a85065bcbd7f30 /drivers/gpu/drm/ttm/ttm_bo.c
parent5fbad9928faf93f69903c8662ec9874ac4a0754e (diff)
drm/ttm: use rcu in core ttm
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c76
1 files changed, 13 insertions, 63 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 66707be386f7..a11969acfea5 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -467,66 +467,6 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
467 ((HZ / 100) < 1) ? 1 : HZ / 100); 467 ((HZ / 100) < 1) ? 1 : HZ / 100);
468} 468}
469 469
470static int ttm_bo_unreserve_and_wait(struct ttm_buffer_object *bo,
471 bool interruptible)
472{
473 struct ttm_bo_global *glob = bo->glob;
474 struct reservation_object_list *fobj;
475 struct fence *excl = NULL;
476 struct fence **shared = NULL;
477 u32 shared_count = 0, i;
478 int ret = 0;
479
480 fobj = reservation_object_get_list(bo->resv);
481 if (fobj && fobj->shared_count) {
482 shared = kmalloc(sizeof(*shared) * fobj->shared_count,
483 GFP_KERNEL);
484
485 if (!shared) {
486 ret = -ENOMEM;
487 __ttm_bo_unreserve(bo);
488 spin_unlock(&glob->lru_lock);
489 return ret;
490 }
491
492 for (i = 0; i < fobj->shared_count; ++i) {
493 if (!fence_is_signaled(fobj->shared[i])) {
494 fence_get(fobj->shared[i]);
495 shared[shared_count++] = fobj->shared[i];
496 }
497 }
498 if (!shared_count) {
499 kfree(shared);
500 shared = NULL;
501 }
502 }
503
504 excl = reservation_object_get_excl(bo->resv);
505 if (excl && !fence_is_signaled(excl))
506 fence_get(excl);
507 else
508 excl = NULL;
509
510 __ttm_bo_unreserve(bo);
511 spin_unlock(&glob->lru_lock);
512
513 if (excl) {
514 ret = fence_wait(excl, interruptible);
515 fence_put(excl);
516 }
517
518 if (shared_count > 0) {
519 for (i = 0; i < shared_count; ++i) {
520 if (!ret)
521 ret = fence_wait(shared[i], interruptible);
522 fence_put(shared[i]);
523 }
524 kfree(shared);
525 }
526
527 return ret;
528}
529
530/** 470/**
531 * function ttm_bo_cleanup_refs_and_unlock 471 * function ttm_bo_cleanup_refs_and_unlock
532 * If bo idle, remove from delayed- and lru lists, and unref. 472 * If bo idle, remove from delayed- and lru lists, and unref.
@@ -550,9 +490,19 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
550 ret = ttm_bo_wait(bo, false, false, true); 490 ret = ttm_bo_wait(bo, false, false, true);
551 491
552 if (ret && !no_wait_gpu) { 492 if (ret && !no_wait_gpu) {
553 ret = ttm_bo_unreserve_and_wait(bo, interruptible); 493 long lret;
554 if (ret) 494 ww_mutex_unlock(&bo->resv->lock);
555 return ret; 495 spin_unlock(&glob->lru_lock);
496
497 lret = reservation_object_wait_timeout_rcu(bo->resv,
498 true,
499 interruptible,
500 30 * HZ);
501
502 if (lret < 0)
503 return lret;
504 else if (lret == 0)
505 return -EBUSY;
556 506
557 spin_lock(&glob->lru_lock); 507 spin_lock(&glob->lru_lock);
558 ret = __ttm_bo_reserve(bo, false, true, false, NULL); 508 ret = __ttm_bo_reserve(bo, false, true, false, NULL);