gpu: nvgpu: move resetup_ramfc() out of sync_lock

We currently have this sequence :
- acquire sync_lock
- sync_create
- resetup_ramfc()
- release sync_lock

but this can lead to deadlock in case resetup_ramfc()
triggers below stack :
- resetup_ramfc()
  - channel_preempt() - preemption fails
  - trigger recovery
  - channel_abort()
    - acquire sync_lock

Fix this by moving resetup_ramfc() out of sync_lock.

resetup_ramfc() is still protected by submit_lock and
hence we cannot free sync after allocation and
before resetup

Bug 200165811

Change-Id: Iebf74d950d6f6902b6d180c2cd8cd2d50493062c
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/931726
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2016-01-12 21:00:10 +05:30
committed by Terje Bergstrom
parent 3c6b40c762
commit cd09ac26c7

View File

@@ -1936,6 +1936,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
bool skip_buffer_refcounting = (flags &
NVGPU_SUBMIT_GPFIFO_FLAGS_SKIP_BUFFER_REFCOUNTING);
bool need_sync_fence = false;
bool new_sync_created = false;
/*
* If user wants to allocate sync_fence_fd always, then respect that;
@@ -2033,16 +2034,22 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
c->sync = gk20a_channel_sync_create(c);
if (!c->sync) {
err = -ENOMEM;
mutex_unlock(&c->sync_lock);
mutex_unlock(&c->submit_lock);
goto clean_up;
}
if (g->ops.fifo.resetup_ramfc)
err = g->ops.fifo.resetup_ramfc(c);
if (err)
return err;
new_sync_created = true;
}
mutex_unlock(&c->sync_lock);
if (g->ops.fifo.resetup_ramfc && new_sync_created) {
err = g->ops.fifo.resetup_ramfc(c);
if (err) {
mutex_unlock(&c->submit_lock);
goto clean_up;
}
}
/*
* optionally insert syncpt wait in the beginning of gpfifo submission
* when user requested and the wait hasn't expired.