gpu: nvgpu: note railgate_allowed in do_idle

The idling and unidling of deterministic channels in the
do_idle/do_unidle path assume that each deterministic channel holds a
power reference. This is no longer the case if railgating has been
allowed for a channel via the deterministic options ioctl which also
causes the channel to drop the power ref that it holds otherwise during
its lifetime.

All this is happening inside the deterministic_busy rwsem, which also
guards the ioctl changing those deterministic option states.

Bug 200327089

Change-Id: I9ce312bbaa459b3cf4a7541fa369186b78c3afdc
Signed-off-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1642310
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Alex Waterman <alexw@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Konsta Holtta
2018-01-19 15:06:50 +02:00
committed by mobile promotions
parent 3ccf5c85fb
commit f6d898656a

View File

@@ -2006,11 +2006,13 @@ void gk20a_channel_deterministic_idle(struct gk20a *g)
if (!gk20a_channel_get(ch))
continue;
if (ch->deterministic) {
if (ch->deterministic && !ch->deterministic_railgate_allowed) {
/*
* Drop the power ref taken when setting deterministic
* flag. deterministic_unidle will put this and the
* channel ref back.
* channel ref back. If railgate is allowed separately
* for this channel, the power ref has already been put
* away.
*
* Hold the channel ref: it must not get freed in
* between. A race could otherwise result in lost
@@ -2045,7 +2047,7 @@ void gk20a_channel_deterministic_unidle(struct gk20a *g)
* Deterministic state changes inside deterministic_busy lock,
* which we took in deterministic_idle.
*/
if (ch->deterministic) {
if (ch->deterministic && !ch->deterministic_railgate_allowed) {
if (gk20a_busy(g))
nvgpu_err(g, "cannot busy() again!");
/* Took this in idle() */