From c386221971ab864c6008ba7bb5ba4ceb36c66413 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Wed, 17 Jan 2018 14:35:59 +0200 Subject: [PATCH] gpu: nvgpu: add g->sw_ready flag Fix a race condition where we'd still be booting up the gpu and/or initializing the driver but elsewhere assume that all is done already. Some userspace APIs to make sure that we're ready by testing g->gr.sw_ready, but this flag is set in the middle of bootup; there are other things after gr initialization. Add a new flag that is enabled after bootup is fully complete at the end of finalize_poweron, and change the checks in user API paths to test the new flag only. These checks are only in the ioctl paths for ctrl, dbg and tsg, and in the ctrl device's opening path. The gr.sw_ready flag is still left there to signify whether just gr has had its bookkeeping initialized. Bug 200370011 Change-Id: I2995500e06de46430d9b835de1e9d60b3f01744e Signed-off-by: Konsta Holtta Reviewed-on: https://git-master.nvidia.com/r/1640136 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 4 ++-- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 2 +- drivers/gpu/nvgpu/gk20a/gk20a.c | 2 ++ drivers/gpu/nvgpu/gk20a/gk20a.h | 1 + drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 1 + drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 2 +- drivers/gpu/nvgpu/vgpu/vgpu.c | 2 ++ 7 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index ff8257dd6..d5c764390 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -73,7 +73,7 @@ int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) */ priv->g = g; - if (!g->gr.sw_ready) { + if (!g->sw_ready) { err = gk20a_busy(g); if (err) goto free_ref; @@ -1387,7 +1387,7 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg return -EFAULT; } - if (!g->gr.sw_ready) { + if (!g->sw_ready) { err = gk20a_busy(g); if (err) return err; diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 1b96d73de..d1402990f 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -959,7 +959,7 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; } - if (!g->gr.sw_ready) { + if (!g->sw_ready) { err = gk20a_busy(g); if (err) return err; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index aca89bae9..8a1af974e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -1109,6 +1109,8 @@ int gk20a_pm_finalize_poweron(struct device *dev) } } + g->sw_ready = true; + done: if (err) g->power_on = false; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 33b7b10f4..229082372 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -891,6 +891,7 @@ struct gk20a { bool gpu_reset_done; bool power_on; bool suspended; + bool sw_ready; struct rw_semaphore busy_lock; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 2ab153578..694ed9a76 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c @@ -798,6 +798,7 @@ static ssize_t tpc_fs_mask_store(struct device *dev, g->gr.ctx_vars.local_golden_image = NULL; g->gr.ctx_vars.golden_image_initialized = false; g->gr.ctx_vars.golden_image_size = 0; + /* Cause next poweron to reinit just gr */ g->gr.sw_ready = false; } diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index bf0cc5d69..3154e3b9b 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c @@ -629,7 +629,7 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; } - if (!g->gr.sw_ready) { + if (!g->sw_ready) { err = gk20a_busy(g); if (err) return err; diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 8f4ecd8d9..135d2bdc3 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -498,6 +498,8 @@ int vgpu_pm_finalize_poweron(struct device *dev) gk20a_sched_ctrl_init(g); gk20a_channel_resume(g); + g->sw_ready = true; + done: return err; }