diff options
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_execbuf_util.c')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_execbuf_util.c | 78 |
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 | ||
85 | static 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 | |||
101 | void ttm_eu_backoff_reservation(struct list_head *list) | 85 | void 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 | ||
148 | retry: | ||
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 | ||
135 | retry: | ||
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 | ||
155 | retry_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 | |||
200 | err: | ||
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 | } |
198 | EXPORT_SYMBOL(ttm_eu_reserve_buffers); | 206 | EXPORT_SYMBOL(ttm_eu_reserve_buffers); |
199 | 207 | ||