aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_execbuf_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_execbuf_util.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_execbuf_util.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index cd9e4523dc56..7b90def15674 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -82,22 +82,6 @@ static void ttm_eu_list_ref_sub(struct list_head *list)
82 } 82 }
83} 83}
84 84
85static int ttm_eu_wait_unreserved_locked(struct list_head *list,
86 struct ttm_buffer_object *bo)
87{
88 struct ttm_bo_global *glob = bo->glob;
89 int ret;
90
91 ttm_eu_del_from_lru_locked(list);
92 spin_unlock(&glob->lru_lock);
93 ret = ttm_bo_wait_unreserved(bo, true);
94 spin_lock(&glob->lru_lock);
95 if (unlikely(ret != 0))
96 ttm_eu_backoff_reservation_locked(list);
97 return ret;
98}
99
100
101void ttm_eu_backoff_reservation(struct list_head *list) 85void ttm_eu_backoff_reservation(struct list_head *list)
102{ 86{
103 struct ttm_validate_buffer *entry; 87 struct ttm_validate_buffer *entry;
@@ -145,47 +129,65 @@ int ttm_eu_reserve_buffers(struct list_head *list)
145 entry = list_first_entry(list, struct ttm_validate_buffer, head); 129 entry = list_first_entry(list, struct ttm_validate_buffer, head);
146 glob = entry->bo->glob; 130 glob = entry->bo->glob;
147 131
148retry:
149 spin_lock(&glob->lru_lock); 132 spin_lock(&glob->lru_lock);
150 val_seq = entry->bo->bdev->val_seq++; 133 val_seq = entry->bo->bdev->val_seq++;
151 134
135retry:
152 list_for_each_entry(entry, list, head) { 136 list_for_each_entry(entry, list, head) {
153 struct ttm_buffer_object *bo = entry->bo; 137 struct ttm_buffer_object *bo = entry->bo;
154 138
155retry_this_bo: 139 /* already slowpath reserved? */
156 ret = ttm_bo_reserve_locked(bo, true, true, true, val_seq); 140 if (entry->reserved)
141 continue;
142
143 ret = ttm_bo_reserve_nolru(bo, true, true, true, val_seq);
157 switch (ret) { 144 switch (ret) {
158 case 0: 145 case 0:
159 break; 146 break;
160 case -EBUSY: 147 case -EBUSY:
161 ret = ttm_eu_wait_unreserved_locked(list, bo); 148 ttm_eu_del_from_lru_locked(list);
162 if (unlikely(ret != 0)) { 149 spin_unlock(&glob->lru_lock);
163 spin_unlock(&glob->lru_lock); 150 ret = ttm_bo_reserve_nolru(bo, true, false,
164 ttm_eu_list_ref_sub(list); 151 true, val_seq);
165 return ret; 152 spin_lock(&glob->lru_lock);
166 } 153 if (!ret)
167 goto retry_this_bo; 154 break;
155
156 if (unlikely(ret != -EAGAIN))
157 goto err;
158
159 /* fallthrough */
168 case -EAGAIN: 160 case -EAGAIN:
169 ttm_eu_backoff_reservation_locked(list); 161 ttm_eu_backoff_reservation_locked(list);
162
163 /*
164 * temporarily increase sequence number every retry,
165 * to prevent us from seeing our old reservation
166 * sequence when someone else reserved the buffer,
167 * but hasn't updated the seq_valid/seqno members yet.
168 */
169 val_seq = entry->bo->bdev->val_seq++;
170
170 spin_unlock(&glob->lru_lock); 171 spin_unlock(&glob->lru_lock);
171 ttm_eu_list_ref_sub(list); 172 ttm_eu_list_ref_sub(list);
172 ret = ttm_bo_wait_unreserved(bo, true); 173 ret = ttm_bo_reserve_slowpath_nolru(bo, true, val_seq);
173 if (unlikely(ret != 0)) 174 if (unlikely(ret != 0))
174 return ret; 175 return ret;
176 spin_lock(&glob->lru_lock);
177 entry->reserved = true;
178 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
179 ret = -EBUSY;
180 goto err;
181 }
175 goto retry; 182 goto retry;
176 default: 183 default:
177 ttm_eu_backoff_reservation_locked(list); 184 goto err;
178 spin_unlock(&glob->lru_lock);
179 ttm_eu_list_ref_sub(list);
180 return ret;
181 } 185 }
182 186
183 entry->reserved = true; 187 entry->reserved = true;
184 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) { 188 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
185 ttm_eu_backoff_reservation_locked(list); 189 ret = -EBUSY;
186 spin_unlock(&glob->lru_lock); 190 goto err;
187 ttm_eu_list_ref_sub(list);
188 return -EBUSY;
189 } 191 }
190 } 192 }
191 193
@@ -194,6 +196,12 @@ retry_this_bo:
194 ttm_eu_list_ref_sub(list); 196 ttm_eu_list_ref_sub(list);
195 197
196 return 0; 198 return 0;
199
200err:
201 ttm_eu_backoff_reservation_locked(list);
202 spin_unlock(&glob->lru_lock);
203 ttm_eu_list_ref_sub(list);
204 return ret;
197} 205}
198EXPORT_SYMBOL(ttm_eu_reserve_buffers); 206EXPORT_SYMBOL(ttm_eu_reserve_buffers);
199 207