From f6d898656a6d7c197aa27ee53f5f0151fb6dfcf5 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Fri, 19 Jan 2018 15:06:50 +0200 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1642310 Reviewed-by: svc-mobile-coverity Reviewed-by: Alex Waterman GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 64266fe5..371793ef 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -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() */ -- cgit v1.2.2