From aacc33bb47aa8019c1a20b867d3722c241f7f93a Mon Sep 17 00:00:00 2001 From: Seema Khowala Date: Fri, 25 Jan 2019 11:09:52 -0800 Subject: [PATCH] gpu: nvgpu: do not use raw spinlock for ch->timeout.lock With PREEMPT_RT kernel, regular spinlocks are mapped onto sleeping spinlocks (rt_mutex locks), and raw spinlocks retain their behaviour. Schedule while atomic can occur in gk20a_channel_timeout_start, as it acquires ch->timeout.lock raw spinlock, and then calls functions that acquire ch->ch_timedout_lock regular spinlock. Bug 200484795 Change-Id: Iacc63195d8ee6a2d571c998da1b4b5d396f49439 Signed-off-by: Seema Khowala Reviewed-on: https://git-master.nvidia.com/r/2004100 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/channel.c | 28 +++++++++++------------ drivers/gpu/nvgpu/include/nvgpu/channel.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index 5331e48da..3c846d0e0 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c @@ -1526,14 +1526,14 @@ static void gk20a_channel_timeout_start(struct channel_gk20a *ch) return; } - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); if (ch->timeout.running) { - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); return; } __gk20a_channel_timeout_start(ch); - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); } /** @@ -1551,10 +1551,10 @@ static bool gk20a_channel_timeout_stop(struct channel_gk20a *ch) { bool was_running; - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); was_running = ch->timeout.running; ch->timeout.running = false; - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); return was_running; } @@ -1569,9 +1569,9 @@ static bool gk20a_channel_timeout_stop(struct channel_gk20a *ch) */ static void gk20a_channel_timeout_continue(struct channel_gk20a *ch) { - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); ch->timeout.running = true; - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); } /** @@ -1586,11 +1586,11 @@ static void gk20a_channel_timeout_continue(struct channel_gk20a *ch) */ static void gk20a_channel_timeout_rewind(struct channel_gk20a *ch) { - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); if (ch->timeout.running) { __gk20a_channel_timeout_start(ch); } - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); } /** @@ -1645,10 +1645,10 @@ static void gk20a_channel_timeout_handler(struct channel_gk20a *ch) } /* Get status but keep timer running */ - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); gp_get = ch->timeout.gp_get; pb_get = ch->timeout.pb_get; - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); new_gp_get = g->ops.fifo.userd_gp_get(ch->g, ch); new_pb_get = g->ops.fifo.userd_pb_get(ch->g, ch); @@ -1688,9 +1688,9 @@ static void gk20a_channel_timeout_check(struct channel_gk20a *ch) { bool running; - nvgpu_raw_spinlock_acquire(&ch->timeout.lock); + nvgpu_spinlock_acquire(&ch->timeout.lock); running = ch->timeout.running; - nvgpu_raw_spinlock_release(&ch->timeout.lock); + nvgpu_spinlock_release(&ch->timeout.lock); if (running) { gk20a_channel_timeout_handler(ch); @@ -2343,7 +2343,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid) nvgpu_spinlock_init(&c->ref_actions_lock); #endif nvgpu_spinlock_init(&c->joblist.dynamic.lock); - nvgpu_raw_spinlock_init(&c->timeout.lock); + nvgpu_spinlock_init(&c->timeout.lock); nvgpu_init_list_node(&c->joblist.dynamic.jobs); nvgpu_init_list_node(&c->dbg_s_list); diff --git a/drivers/gpu/nvgpu/include/nvgpu/channel.h b/drivers/gpu/nvgpu/include/nvgpu/channel.h index 6b5f44ee7..b6ea5b520 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/channel.h +++ b/drivers/gpu/nvgpu/include/nvgpu/channel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -168,7 +168,7 @@ struct channel_gk20a_joblist { struct channel_gk20a_timeout { /* lock protects the running timer state */ - struct nvgpu_raw_spinlock lock; + struct nvgpu_spinlock lock; struct nvgpu_timeout timer; bool running; u32 gp_get;