aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-02-28 02:27:17 -0500
committerIngo Molnar <mingo@kernel.org>2019-02-28 02:27:17 -0500
commit9ed8f1a6e7670aadd5aef30456a90b456ed1b185 (patch)
treeb93479f7f70187b68d29b747ce02c720ddb11f42 /drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
parent43f4e6279f05eefac058a3524e184cecae463bfe (diff)
parent7d762d69145a54d169f58e56d6dac57a5508debc (diff)
Merge branch 'linus' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 71913a18d142..a38e0fb4a6fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -38,6 +38,7 @@
38#include "amdgpu_gem.h" 38#include "amdgpu_gem.h"
39#include <drm/amdgpu_drm.h> 39#include <drm/amdgpu_drm.h>
40#include <linux/dma-buf.h> 40#include <linux/dma-buf.h>
41#include <linux/dma-fence-array.h>
41 42
42/** 43/**
43 * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table 44 * amdgpu_gem_prime_get_sg_table - &drm_driver.gem_prime_get_sg_table
@@ -187,6 +188,48 @@ error:
187 return ERR_PTR(ret); 188 return ERR_PTR(ret);
188} 189}
189 190
191static int
192__reservation_object_make_exclusive(struct reservation_object *obj)
193{
194 struct dma_fence **fences;
195 unsigned int count;
196 int r;
197
198 if (!reservation_object_get_list(obj)) /* no shared fences to convert */
199 return 0;
200
201 r = reservation_object_get_fences_rcu(obj, NULL, &count, &fences);
202 if (r)
203 return r;
204
205 if (count == 0) {
206 /* Now that was unexpected. */
207 } else if (count == 1) {
208 reservation_object_add_excl_fence(obj, fences[0]);
209 dma_fence_put(fences[0]);
210 kfree(fences);
211 } else {
212 struct dma_fence_array *array;
213
214 array = dma_fence_array_create(count, fences,
215 dma_fence_context_alloc(1), 0,
216 false);
217 if (!array)
218 goto err_fences_put;
219
220 reservation_object_add_excl_fence(obj, &array->base);
221 dma_fence_put(&array->base);
222 }
223
224 return 0;
225
226err_fences_put:
227 while (count--)
228 dma_fence_put(fences[count]);
229 kfree(fences);
230 return -ENOMEM;
231}
232
190/** 233/**
191 * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation 234 * amdgpu_gem_map_attach - &dma_buf_ops.attach implementation
192 * @dma_buf: Shared DMA buffer 235 * @dma_buf: Shared DMA buffer
@@ -218,16 +261,16 @@ static int amdgpu_gem_map_attach(struct dma_buf *dma_buf,
218 261
219 if (attach->dev->driver != adev->dev->driver) { 262 if (attach->dev->driver != adev->dev->driver) {
220 /* 263 /*
221 * Wait for all shared fences to complete before we switch to future 264 * We only create shared fences for internal use, but importers
222 * use of exclusive fence on this prime shared bo. 265 * of the dmabuf rely on exclusive fences for implicitly
266 * tracking write hazards. As any of the current fences may
267 * correspond to a write, we need to convert all existing
268 * fences on the reservation object into a single exclusive
269 * fence.
223 */ 270 */
224 r = reservation_object_wait_timeout_rcu(bo->tbo.resv, 271 r = __reservation_object_make_exclusive(bo->tbo.resv);
225 true, false, 272 if (r)
226 MAX_SCHEDULE_TIMEOUT);
227 if (unlikely(r < 0)) {
228 DRM_DEBUG_PRIME("Fence wait failed: %li\n", r);
229 goto error_unreserve; 273 goto error_unreserve;
230 }
231 } 274 }
232 275
233 /* pin buffer into GTT */ 276 /* pin buffer into GTT */