aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-11-21 03:46:56 -0500
committerDave Airlie <airlied@redhat.com>2013-11-21 03:46:56 -0500
commit27946e97108de281e0e9310965ac9a83a4aaa6fe (patch)
treebc0b2f03c5f25683128a0e2fec3f3a8bced0500e
parent28adb3026d01da3f6acded3cec817e1a3ba37f44 (diff)
parentc58f009e01c918717379c206a63baa66f56a77f9 (diff)
Merge branch 'ttm-fixes-3.13' of git://people.freedesktop.org/~thomash/linux into drm-fixes
The set_need_resched() removal fix and yet another fix in ttm_bo_move_memcpy(). * 'ttm-fixes-3.13' of git://people.freedesktop.org/~thomash/linux: drm/ttm: Remove set_need_resched from the ttm fault handler drm/ttm: Don't move non-existing data
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c35
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c7
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c26
-rw-r--r--include/drm/ttm/ttm_bo_api.h4
4 files changed, 62 insertions, 10 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8d5a646ebe6a..07e02c4bf5a8 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -151,7 +151,7 @@ static void ttm_bo_release_list(struct kref *list_kref)
151 atomic_dec(&bo->glob->bo_count); 151 atomic_dec(&bo->glob->bo_count);
152 if (bo->resv == &bo->ttm_resv) 152 if (bo->resv == &bo->ttm_resv)
153 reservation_object_fini(&bo->ttm_resv); 153 reservation_object_fini(&bo->ttm_resv);
154 154 mutex_destroy(&bo->wu_mutex);
155 if (bo->destroy) 155 if (bo->destroy)
156 bo->destroy(bo); 156 bo->destroy(bo);
157 else { 157 else {
@@ -1123,6 +1123,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev,
1123 INIT_LIST_HEAD(&bo->ddestroy); 1123 INIT_LIST_HEAD(&bo->ddestroy);
1124 INIT_LIST_HEAD(&bo->swap); 1124 INIT_LIST_HEAD(&bo->swap);
1125 INIT_LIST_HEAD(&bo->io_reserve_lru); 1125 INIT_LIST_HEAD(&bo->io_reserve_lru);
1126 mutex_init(&bo->wu_mutex);
1126 bo->bdev = bdev; 1127 bo->bdev = bdev;
1127 bo->glob = bdev->glob; 1128 bo->glob = bdev->glob;
1128 bo->type = type; 1129 bo->type = type;
@@ -1704,3 +1705,35 @@ void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
1704 ; 1705 ;
1705} 1706}
1706EXPORT_SYMBOL(ttm_bo_swapout_all); 1707EXPORT_SYMBOL(ttm_bo_swapout_all);
1708
1709/**
1710 * ttm_bo_wait_unreserved - interruptible wait for a buffer object to become
1711 * unreserved
1712 *
1713 * @bo: Pointer to buffer
1714 */
1715int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo)
1716{
1717 int ret;
1718
1719 /*
1720 * In the absense of a wait_unlocked API,
1721 * Use the bo::wu_mutex to avoid triggering livelocks due to
1722 * concurrent use of this function. Note that this use of
1723 * bo::wu_mutex can go away if we change locking order to
1724 * mmap_sem -> bo::reserve.
1725 */
1726 ret = mutex_lock_interruptible(&bo->wu_mutex);
1727 if (unlikely(ret != 0))
1728 return -ERESTARTSYS;
1729 if (!ww_mutex_is_locked(&bo->resv->lock))
1730 goto out_unlock;
1731 ret = ttm_bo_reserve_nolru(bo, true, false, false, NULL);
1732 if (unlikely(ret != 0))
1733 goto out_unlock;
1734 ww_mutex_unlock(&bo->resv->lock);
1735
1736out_unlock:
1737 mutex_unlock(&bo->wu_mutex);
1738 return ret;
1739}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 4834c463c38b..15b86a94949d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -350,10 +350,13 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
350 goto out2; 350 goto out2;
351 351
352 /* 352 /*
353 * Move nonexistent data. NOP. 353 * Don't move nonexistent data. Clear destination instead.
354 */ 354 */
355 if (old_iomap == NULL && ttm == NULL) 355 if (old_iomap == NULL &&
356 (ttm == NULL || ttm->state == tt_unpopulated)) {
357 memset_io(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
356 goto out2; 358 goto out2;
359 }
357 360
358 /* 361 /*
359 * TTM might be null for moves within the same region. 362 * TTM might be null for moves within the same region.
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index ac617f3ecd0c..b249ab9b1eb2 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -107,13 +107,28 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
107 /* 107 /*
108 * Work around locking order reversal in fault / nopfn 108 * Work around locking order reversal in fault / nopfn
109 * between mmap_sem and bo_reserve: Perform a trylock operation 109 * between mmap_sem and bo_reserve: Perform a trylock operation
110 * for reserve, and if it fails, retry the fault after scheduling. 110 * for reserve, and if it fails, retry the fault after waiting
111 * for the buffer to become unreserved.
111 */ 112 */
112 113 ret = ttm_bo_reserve(bo, true, true, false, NULL);
113 ret = ttm_bo_reserve(bo, true, true, false, 0);
114 if (unlikely(ret != 0)) { 114 if (unlikely(ret != 0)) {
115 if (ret == -EBUSY) 115 if (ret != -EBUSY)
116 set_need_resched(); 116 return VM_FAULT_NOPAGE;
117
118 if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
119 if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
120 up_read(&vma->vm_mm->mmap_sem);
121 (void) ttm_bo_wait_unreserved(bo);
122 }
123
124 return VM_FAULT_RETRY;
125 }
126
127 /*
128 * If we'd want to change locking order to
129 * mmap_sem -> bo::reserve, we'd use a blocking reserve here
130 * instead of retrying the fault...
131 */
117 return VM_FAULT_NOPAGE; 132 return VM_FAULT_NOPAGE;
118 } 133 }
119 134
@@ -123,7 +138,6 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
123 case 0: 138 case 0:
124 break; 139 break;
125 case -EBUSY: 140 case -EBUSY:
126 set_need_resched();
127 case -ERESTARTSYS: 141 case -ERESTARTSYS:
128 retval = VM_FAULT_NOPAGE; 142 retval = VM_FAULT_NOPAGE;
129 goto out_unlock; 143 goto out_unlock;
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 751eaffbf0d5..ee127ec33c60 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -169,6 +169,7 @@ struct ttm_tt;
169 * @offset: The current GPU offset, which can have different meanings 169 * @offset: The current GPU offset, which can have different meanings
170 * depending on the memory type. For SYSTEM type memory, it should be 0. 170 * depending on the memory type. For SYSTEM type memory, it should be 0.
171 * @cur_placement: Hint of current placement. 171 * @cur_placement: Hint of current placement.
172 * @wu_mutex: Wait unreserved mutex.
172 * 173 *
173 * Base class for TTM buffer object, that deals with data placement and CPU 174 * Base class for TTM buffer object, that deals with data placement and CPU
174 * mappings. GPU mappings are really up to the driver, but for simpler GPUs 175 * mappings. GPU mappings are really up to the driver, but for simpler GPUs
@@ -250,6 +251,7 @@ struct ttm_buffer_object {
250 251
251 struct reservation_object *resv; 252 struct reservation_object *resv;
252 struct reservation_object ttm_resv; 253 struct reservation_object ttm_resv;
254 struct mutex wu_mutex;
253}; 255};
254 256
255/** 257/**
@@ -702,5 +704,5 @@ extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
702 size_t count, loff_t *f_pos, bool write); 704 size_t count, loff_t *f_pos, bool write);
703 705
704extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev); 706extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
705 707extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo);
706#endif 708#endif