drm/msm: bigger synchronization hammer
Because we use a list_head in the bo to track it's position in a submit, we need to serialize at a higher layer. Otherwise there are problems when multiple contexts are SUBMIT'ing in parallel cmdstreams referencing a shared bo. Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Родитель
9999f105e7
Коммит
c2703b13a6
|
@ -163,7 +163,7 @@ retry:
|
||||||
|
|
||||||
|
|
||||||
/* if locking succeeded, pin bo: */
|
/* if locking succeeded, pin bo: */
|
||||||
ret = msm_gem_get_iova(&msm_obj->base,
|
ret = msm_gem_get_iova_locked(&msm_obj->base,
|
||||||
submit->gpu->id, &iova);
|
submit->gpu->id, &iova);
|
||||||
|
|
||||||
/* this would break the logic in the fail path.. there is no
|
/* this would break the logic in the fail path.. there is no
|
||||||
|
@ -247,7 +247,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
|
||||||
/* For now, just map the entire thing. Eventually we probably
|
/* For now, just map the entire thing. Eventually we probably
|
||||||
* to do it page-by-page, w/ kmap() if not vmap()d..
|
* to do it page-by-page, w/ kmap() if not vmap()d..
|
||||||
*/
|
*/
|
||||||
ptr = msm_gem_vaddr(&obj->base);
|
ptr = msm_gem_vaddr_locked(&obj->base);
|
||||||
|
|
||||||
if (IS_ERR(ptr)) {
|
if (IS_ERR(ptr)) {
|
||||||
ret = PTR_ERR(ptr);
|
ret = PTR_ERR(ptr);
|
||||||
|
@ -307,14 +307,12 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool fail)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
mutex_lock(&submit->dev->struct_mutex);
|
|
||||||
for (i = 0; i < submit->nr_bos; i++) {
|
for (i = 0; i < submit->nr_bos; i++) {
|
||||||
struct msm_gem_object *msm_obj = submit->bos[i].obj;
|
struct msm_gem_object *msm_obj = submit->bos[i].obj;
|
||||||
submit_unlock_unpin_bo(submit, i);
|
submit_unlock_unpin_bo(submit, i);
|
||||||
list_del_init(&msm_obj->submit_entry);
|
list_del_init(&msm_obj->submit_entry);
|
||||||
drm_gem_object_unreference(&msm_obj->base);
|
drm_gem_object_unreference(&msm_obj->base);
|
||||||
}
|
}
|
||||||
mutex_unlock(&submit->dev->struct_mutex);
|
|
||||||
|
|
||||||
ww_acquire_fini(&submit->ticket);
|
ww_acquire_fini(&submit->ticket);
|
||||||
kfree(submit);
|
kfree(submit);
|
||||||
|
@ -342,6 +340,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||||
if (args->nr_cmds > MAX_CMDS)
|
if (args->nr_cmds > MAX_CMDS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&dev->struct_mutex);
|
||||||
|
|
||||||
submit = submit_create(dev, gpu, args->nr_bos);
|
submit = submit_create(dev, gpu, args->nr_bos);
|
||||||
if (!submit) {
|
if (!submit) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -410,5 +410,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||||
out:
|
out:
|
||||||
if (submit)
|
if (submit)
|
||||||
submit_cleanup(submit, !!ret);
|
submit_cleanup(submit, !!ret);
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,8 +298,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
|
||||||
struct msm_drm_private *priv = dev->dev_private;
|
struct msm_drm_private *priv = dev->dev_private;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
|
||||||
|
|
||||||
submit->fence = ++priv->next_fence;
|
submit->fence = ++priv->next_fence;
|
||||||
|
|
||||||
gpu->submitted_fence = submit->fence;
|
gpu->submitted_fence = submit->fence;
|
||||||
|
@ -331,7 +329,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
|
||||||
msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence);
|
msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence);
|
||||||
}
|
}
|
||||||
hangcheck_timer_reset(gpu);
|
hangcheck_timer_reset(gpu);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче