summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2016-11-14 00:57:38 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-17 11:15:12 -0500
commitefe0758081f25b39d5bb8b097fc0ae64d0e47c3f (patch)
treef99d333adfb8db97524508d2b81beec1164e9fde /drivers
parent157ff622f3156a68281a5d1c0eb97bc8ad3a5b3b (diff)
gpu: nvgpu: fix pmu->mscg_stat optimization issue
- with help of WRITE_ONCE() & ACCESS_ONCE() make sure variable pmu->mscg_stat read/write goes through without optimization - Added WRITE_ONCE() define for kernel-3.18 version & below to support backward compatibility issue: inconsistencies on getting MSCG to trigger consistently in P5 due to a lack of memory barrier around and volatile accesses to the variable pmu->mscg_stat JIRA DNVGPU-71 Change-Id: I04d30493d42c52710304dbdfb9cb4a1e9a76f2c0 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1252524 (cherry picked from commit 8af7fc68e7ab06a856ba4ef4e44de7336682361b) Reviewed-on: http://git-master/r/1271614 Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c12
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c8
-rw-r--r--drivers/gpu/nvgpu/lpwr/lpwr.c16
4 files changed, 29 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5e2344cf..692f054f 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -64,6 +64,10 @@ struct acr_desc;
64#endif 64#endif
65#include "gm206/bios_gm206.h" 65#include "gm206/bios_gm206.h"
66 66
67#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
68#define WRITE_ONCE(x, val) \
69 x = val
70#endif
67 71
68/* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds. 72/* PTIMER_REF_FREQ_HZ corresponds to a period of 32 nanoseconds.
69 32 ns is the resolution of ptimer. */ 73 32 ns is the resolution of ptimer. */
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
index 9bf6acec..6611b120 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c
@@ -511,15 +511,21 @@ static ssize_t mscg_enable_store(struct device *dev,
511 g->mscg_enabled = true; 511 g->mscg_enabled = true;
512 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g, 512 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
513 PMU_PG_LPWR_FEATURE_MSCG)) { 513 PMU_PG_LPWR_FEATURE_MSCG)) {
514 if (!pmu->mscg_stat) 514 if (!ACCESS_ONCE(pmu->mscg_stat)) {
515 pmu->mscg_stat = PMU_MSCG_ENABLED; 515 WRITE_ONCE(pmu->mscg_stat,
516 PMU_MSCG_ENABLED);
517 /* make status visible */
518 smp_mb();
519 }
516 } 520 }
517 521
518 } else if (!val && g->mscg_enabled) { 522 } else if (!val && g->mscg_enabled) {
519 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g, 523 if (g->ops.pmu.pmu_is_lpwr_feature_supported(g,
520 PMU_PG_LPWR_FEATURE_MSCG)) { 524 PMU_PG_LPWR_FEATURE_MSCG)) {
521 gk20a_pmu_pg_global_enable(g, false); 525 gk20a_pmu_pg_global_enable(g, false);
522 pmu->mscg_stat = PMU_MSCG_DISABLED; 526 WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
527 /* make status visible */
528 smp_mb();
523 g->mscg_enabled = false; 529 g->mscg_enabled = false;
524 if (g->elpg_enabled) 530 if (g->elpg_enabled)
525 gk20a_pmu_pg_global_enable(g, true); 531 gk20a_pmu_pg_global_enable(g, true);
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index ef6a5943..11baa7af 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -3388,7 +3388,9 @@ static void pmu_handle_pg_elpg_msg(struct gk20a *g, struct pmu_msg *msg,
3388 PMU_PG_FEATURE_GR_POWER_GATING_ENABLED) { 3388 PMU_PG_FEATURE_GR_POWER_GATING_ENABLED) {
3389 pmu->initialized = true; 3389 pmu->initialized = true;
3390 pmu->pmu_state = PMU_STATE_STARTED; 3390 pmu->pmu_state = PMU_STATE_STARTED;
3391 pmu->mscg_stat = PMU_MSCG_DISABLED; 3391 WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
3392 /* make status visible */
3393 smp_mb();
3392 } else { 3394 } else {
3393 pmu->pmu_state = PMU_STATE_ELPG_BOOTED; 3395 pmu->pmu_state = PMU_STATE_ELPG_BOOTED;
3394 schedule_work(&pmu->pg_init); 3396 schedule_work(&pmu->pg_init);
@@ -4849,7 +4851,7 @@ int gk20a_pmu_enable_elpg(struct gk20a *g)
4849 pg_engine_id++) { 4851 pg_engine_id++) {
4850 4852
4851 if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS && 4853 if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS &&
4852 pmu->mscg_stat == PMU_MSCG_DISABLED) 4854 ACCESS_ONCE(pmu->mscg_stat) == PMU_MSCG_DISABLED)
4853 continue; 4855 continue;
4854 4856
4855 if (BIT(pg_engine_id) & pg_engine_id_list) 4857 if (BIT(pg_engine_id) & pg_engine_id_list)
@@ -4925,7 +4927,7 @@ int gk20a_pmu_disable_elpg(struct gk20a *g)
4925 pg_engine_id++) { 4927 pg_engine_id++) {
4926 4928
4927 if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS && 4929 if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_MS &&
4928 pmu->mscg_stat == PMU_MSCG_DISABLED) 4930 ACCESS_ONCE(pmu->mscg_stat) == PMU_MSCG_DISABLED)
4929 continue; 4931 continue;
4930 4932
4931 if (BIT(pg_engine_id) & pg_engine_id_list) { 4933 if (BIT(pg_engine_id) & pg_engine_id_list) {
diff --git a/drivers/gpu/nvgpu/lpwr/lpwr.c b/drivers/gpu/nvgpu/lpwr/lpwr.c
index 4f8d2eec..e3483cca 100644
--- a/drivers/gpu/nvgpu/lpwr/lpwr.c
+++ b/drivers/gpu/nvgpu/lpwr/lpwr.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -362,8 +362,11 @@ int nvgpu_lpwr_enable_pg(struct gk20a *g, bool pstate_lock)
362 is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g, 362 is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g,
363 present_pstate); 363 present_pstate);
364 if (is_mscg_supported && g->mscg_enabled) { 364 if (is_mscg_supported && g->mscg_enabled) {
365 if (!pmu->mscg_stat) 365 if (!ACCESS_ONCE(pmu->mscg_stat)) {
366 pmu->mscg_stat = PMU_MSCG_ENABLED; 366 WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_ENABLED);
367 /* make status visible */
368 smp_mb();
369 }
367 } 370 }
368 371
369 is_rppg_supported = nvgpu_lpwr_is_rppg_supported(g, 372 is_rppg_supported = nvgpu_lpwr_is_rppg_supported(g,
@@ -409,8 +412,11 @@ int nvgpu_lpwr_disable_pg(struct gk20a *g, bool pstate_lock)
409 is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g, 412 is_mscg_supported = nvgpu_lpwr_is_mscg_supported(g,
410 present_pstate); 413 present_pstate);
411 if (is_mscg_supported && g->mscg_enabled) { 414 if (is_mscg_supported && g->mscg_enabled) {
412 if (pmu->mscg_stat) 415 if (ACCESS_ONCE(pmu->mscg_stat)) {
413 pmu->mscg_stat = PMU_MSCG_DISABLED; 416 WRITE_ONCE(pmu->mscg_stat, PMU_MSCG_DISABLED);
417 /* make status visible */
418 smp_mb();
419 }
414 } 420 }
415 421
416exit_unlock: 422exit_unlock: