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.c43
1 files changed, 17 insertions, 26 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index efcb734e5543..7392da557be2 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -48,8 +48,7 @@ static void ttm_eu_backoff_reservation_locked(struct list_head *list,
48 entry->removed = false; 48 entry->removed = false;
49 49
50 } else { 50 } else {
51 atomic_set(&bo->reserved, 0); 51 ww_mutex_unlock(&bo->resv->lock);
52 wake_up_all(&bo->event_queue);
53 } 52 }
54 } 53 }
55} 54}
@@ -134,8 +133,6 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
134 glob = entry->bo->glob; 133 glob = entry->bo->glob;
135 134
136 ww_acquire_init(ticket, &reservation_ww_class); 135 ww_acquire_init(ticket, &reservation_ww_class);
137 spin_lock(&glob->lru_lock);
138
139retry: 136retry:
140 list_for_each_entry(entry, list, head) { 137 list_for_each_entry(entry, list, head) {
141 struct ttm_buffer_object *bo = entry->bo; 138 struct ttm_buffer_object *bo = entry->bo;
@@ -144,42 +141,34 @@ retry:
144 if (entry->reserved) 141 if (entry->reserved)
145 continue; 142 continue;
146 143
147 ret = ttm_bo_reserve_nolru(bo, true, true, true, ticket);
148 switch (ret) {
149 case 0:
150 break;
151 case -EBUSY:
152 ttm_eu_del_from_lru_locked(list);
153 spin_unlock(&glob->lru_lock);
154 ret = ttm_bo_reserve_nolru(bo, true, false,
155 true, ticket);
156 spin_lock(&glob->lru_lock);
157
158 if (!ret)
159 break;
160 144
161 if (unlikely(ret != -EAGAIN)) 145 ret = ttm_bo_reserve_nolru(bo, true, false, true, ticket);
162 goto err;
163 146
164 /* fallthrough */ 147 if (ret == -EDEADLK) {
165 case -EAGAIN: 148 /* uh oh, we lost out, drop every reservation and try
149 * to only reserve this buffer, then start over if
150 * this succeeds.
151 */
152 spin_lock(&glob->lru_lock);
166 ttm_eu_backoff_reservation_locked(list, ticket); 153 ttm_eu_backoff_reservation_locked(list, ticket);
167 spin_unlock(&glob->lru_lock); 154 spin_unlock(&glob->lru_lock);
168 ttm_eu_list_ref_sub(list); 155 ttm_eu_list_ref_sub(list);
169 ret = ttm_bo_reserve_slowpath_nolru(bo, true, ticket); 156 ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
170 if (unlikely(ret != 0)) 157 ticket);
158 if (unlikely(ret != 0)) {
159 if (ret == -EINTR)
160 ret = -ERESTARTSYS;
171 goto err_fini; 161 goto err_fini;
162 }
172 163
173 spin_lock(&glob->lru_lock);
174 entry->reserved = true; 164 entry->reserved = true;
175 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) { 165 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
176 ret = -EBUSY; 166 ret = -EBUSY;
177 goto err; 167 goto err;
178 } 168 }
179 goto retry; 169 goto retry;
180 default: 170 } else if (ret)
181 goto err; 171 goto err;
182 }
183 172
184 entry->reserved = true; 173 entry->reserved = true;
185 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) { 174 if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
@@ -189,12 +178,14 @@ retry:
189 } 178 }
190 179
191 ww_acquire_done(ticket); 180 ww_acquire_done(ticket);
181 spin_lock(&glob->lru_lock);
192 ttm_eu_del_from_lru_locked(list); 182 ttm_eu_del_from_lru_locked(list);
193 spin_unlock(&glob->lru_lock); 183 spin_unlock(&glob->lru_lock);
194 ttm_eu_list_ref_sub(list); 184 ttm_eu_list_ref_sub(list);
195 return 0; 185 return 0;
196 186
197err: 187err:
188 spin_lock(&glob->lru_lock);
198 ttm_eu_backoff_reservation_locked(list, ticket); 189 ttm_eu_backoff_reservation_locked(list, ticket);
199 spin_unlock(&glob->lru_lock); 190 spin_unlock(&glob->lru_lock);
200 ttm_eu_list_ref_sub(list); 191 ttm_eu_list_ref_sub(list);