summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2018-08-08 08:06:01 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-09-20 13:50:25 -0400
commit85c323c3e89d6e1b624b839c3325ae072952e545 (patch)
tree0822589079047c74fb278f512a51f80baff07b85
parent519948a9c664020fd0b37118749faad2dfd73d97 (diff)
gpu: nvgpu: restrict devfreq during active clk_arb set requests
Restrict access to devfreq when there are active set requests in the clk_arbiter. We make the following changes in the patch. 1) Add a global counter in the struct gk20a named clk_arb_global_nr which is used to track the number of active set requests in the system. 2) Anytime a set request is successfully made by the userspace, clk_arb_global_nr is incremented by 1 and during the completion of request(releasing the corresponding file handle), clk_arb_global_nr is decremented by 1. 3) gk20a_scale_target(invoked by devfreq to set the new frequency based on load) atomically checks clk_arb_global_nr. If the value = 0, the code simply continue or else if its > 0, it quits thus making devfreq requests mutually exclusive with the clk_arbiter. Bug 2061372 Change-Id: I5d19de03e45520f4ff8fccb97b1f1589d04c8ab8 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1790002 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c11
-rw-r--r--drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c5
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/clk_arb.h2
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/os/linux/debug_clk_gm20b.c3
-rw-r--r--drivers/gpu/nvgpu/os/linux/driver_common.c3
-rw-r--r--drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c1
-rw-r--r--drivers/gpu/nvgpu/os/linux/scale.c3
-rw-r--r--drivers/gpu/nvgpu/os/posix/clk_arb.c5
9 files changed, 33 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 452d9de3..3d97535d 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -772,6 +772,11 @@ int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
772 return err; 772 return err;
773} 773}
774 774
775bool nvgpu_clk_arb_has_active_req(struct gk20a *g)
776{
777 return (nvgpu_atomic_read(&g->clk_arb_global_nr) > 0);
778}
779
775void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) 780void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g)
776{ 781{
777 nvgpu_clk_arb_schedule_alarm(g, 782 nvgpu_clk_arb_schedule_alarm(g,
@@ -854,10 +859,12 @@ void nvgpu_clk_arb_free_fd(struct nvgpu_ref *refcount)
854 struct nvgpu_clk_dev *dev = container_of(refcount, 859 struct nvgpu_clk_dev *dev = container_of(refcount,
855 struct nvgpu_clk_dev, refcount); 860 struct nvgpu_clk_dev, refcount);
856 struct nvgpu_clk_session *session = dev->session; 861 struct nvgpu_clk_session *session = dev->session;
862 struct gk20a *g = session->g;
857 863
858 nvgpu_clk_notification_queue_free(session->g, &dev->queue); 864 nvgpu_clk_notification_queue_free(g, &dev->queue);
859 865
860 nvgpu_kfree(session->g, dev); 866 nvgpu_atomic_dec(&g->clk_arb_global_nr);
867 nvgpu_kfree(g, dev);
861} 868}
862 869
863void nvgpu_clk_arb_free_session(struct nvgpu_ref *refcount) 870void nvgpu_clk_arb_free_session(struct nvgpu_ref *refcount)
diff --git a/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c
index 4dcc3ca5..78fb1261 100644
--- a/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c
@@ -215,6 +215,9 @@ int gp10b_init_clk_arbiter(struct gk20a *g)
215 goto init_fail; 215 goto init_fail;
216 } 216 }
217 217
218 /* This is set for the duration of the default req */
219 nvgpu_atomic_inc(&g->clk_arb_global_nr);
220
218 nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); 221 nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item);
219 222
220 do { 223 do {
@@ -224,6 +227,8 @@ int gp10b_init_clk_arbiter(struct gk20a *g)
224 nvgpu_atomic_read(&arb->req_nr) != 0, 0); 227 nvgpu_atomic_read(&arb->req_nr) != 0, 0);
225 } while (nvgpu_atomic_read(&arb->req_nr) == 0); 228 } while (nvgpu_atomic_read(&arb->req_nr) == 0);
226 229
230 /* Once the default request is completed, reduce the usage count */
231 nvgpu_atomic_dec(&g->clk_arb_global_nr);
227 232
228 return arb->status; 233 return arb->status;
229 234
diff --git a/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h b/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h
index 81b1df1b..a04e3542 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h
@@ -295,6 +295,8 @@ int nvgpu_clk_arb_worker_init(struct gk20a *g);
295 295
296int nvgpu_clk_arb_init_arbiter(struct gk20a *g); 296int nvgpu_clk_arb_init_arbiter(struct gk20a *g);
297 297
298bool nvgpu_clk_arb_has_active_req(struct gk20a *g);
299
298int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, 300int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain,
299 u16 *min_mhz, u16 *max_mhz); 301 u16 *min_mhz, u16 *max_mhz);
300 302
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
index b8ca5754..5f875707 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
@@ -1596,6 +1596,8 @@ struct gk20a {
1596 1596
1597 struct nvgpu_mutex clk_arb_enable_lock; 1597 struct nvgpu_mutex clk_arb_enable_lock;
1598 1598
1599 nvgpu_atomic_t clk_arb_global_nr;
1600
1599 struct gk20a_ce_app ce_app; 1601 struct gk20a_ce_app ce_app;
1600 1602
1601 bool ltc_intr_en_illegal_compstat; 1603 bool ltc_intr_en_illegal_compstat;
diff --git a/drivers/gpu/nvgpu/os/linux/debug_clk_gm20b.c b/drivers/gpu/nvgpu/os/linux/debug_clk_gm20b.c
index 52eea83f..b8b95fd7 100644
--- a/drivers/gpu/nvgpu/os/linux/debug_clk_gm20b.c
+++ b/drivers/gpu/nvgpu/os/linux/debug_clk_gm20b.c
@@ -17,6 +17,7 @@
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18 18
19#include <nvgpu/io.h> 19#include <nvgpu/io.h>
20#include <nvgpu/clk_arb.h>
20 21
21#include "gm20b/clk_gm20b.h" 22#include "gm20b/clk_gm20b.h"
22#include "os_linux.h" 23#include "os_linux.h"
@@ -33,6 +34,8 @@ static int rate_get(void *data, u64 *val)
33static int rate_set(void *data, u64 val) 34static int rate_set(void *data, u64 val)
34{ 35{
35 struct gk20a *g = (struct gk20a *)data; 36 struct gk20a *g = (struct gk20a *)data;
37 if (nvgpu_clk_arb_has_active_req(g))
38 return 0;
36 return g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, (u32)val); 39 return g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, (u32)val);
37} 40}
38DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, rate_set, "%llu\n"); 41DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, rate_set, "%llu\n");
diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c
index ebd0b40b..0a25cd3f 100644
--- a/drivers/gpu/nvgpu/os/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/os/linux/driver_common.c
@@ -66,6 +66,9 @@ static void nvgpu_init_vars(struct gk20a *g)
66 nvgpu_mutex_init(&g->tpc_pg_lock); 66 nvgpu_mutex_init(&g->tpc_pg_lock);
67 nvgpu_mutex_init(&g->clk_arb_enable_lock); 67 nvgpu_mutex_init(&g->clk_arb_enable_lock);
68 68
69 /* Init the clock req count to 0 */
70 nvgpu_atomic_set(&g->clk_arb_global_nr, 0);
71
69 l->regs_saved = l->regs; 72 l->regs_saved = l->regs;
70 l->bar1_saved = l->bar1; 73 l->bar1_saved = l->bar1;
71 74
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c b/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c
index 2d9946b1..ff1cc00a 100644
--- a/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c
+++ b/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c
@@ -436,6 +436,7 @@ int nvgpu_clk_arb_commit_request_fd(struct gk20a *g,
436 clk_arb_dbg(g, "requested target = %u\n", 436 clk_arb_dbg(g, "requested target = %u\n",
437 (u32)dev->gpc2clk_target_mhz); 437 (u32)dev->gpc2clk_target_mhz);
438 438
439 nvgpu_atomic_inc(&g->clk_arb_global_nr);
439 nvgpu_ref_get(&dev->refcount); 440 nvgpu_ref_get(&dev->refcount);
440 nvgpu_spinlock_acquire(&session->session_lock); 441 nvgpu_spinlock_acquire(&session->session_lock);
441 nvgpu_list_add(&dev->node, &session->targets); 442 nvgpu_list_add(&dev->node, &session->targets);
diff --git a/drivers/gpu/nvgpu/os/linux/scale.c b/drivers/gpu/nvgpu/os/linux/scale.c
index ecc8207a..cbb9fdc5 100644
--- a/drivers/gpu/nvgpu/os/linux/scale.c
+++ b/drivers/gpu/nvgpu/os/linux/scale.c
@@ -25,6 +25,7 @@
25 25
26#include <nvgpu/kmem.h> 26#include <nvgpu/kmem.h>
27#include <nvgpu/log.h> 27#include <nvgpu/log.h>
28#include <nvgpu/clk_arb.h>
28 29
29#include "gk20a/gk20a.h" 30#include "gk20a/gk20a.h"
30#include "platform_gk20a.h" 31#include "platform_gk20a.h"
@@ -154,6 +155,8 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
154 unsigned long rounded_rate; 155 unsigned long rounded_rate;
155 unsigned long min_freq = 0, max_freq = 0; 156 unsigned long min_freq = 0, max_freq = 0;
156 157
158 if (nvgpu_clk_arb_has_active_req(g))
159 return 0;
157 /* 160 /*
158 * Calculate floor and cap frequency values 161 * Calculate floor and cap frequency values
159 * 162 *
diff --git a/drivers/gpu/nvgpu/os/posix/clk_arb.c b/drivers/gpu/nvgpu/os/posix/clk_arb.c
index 63ab0f13..fcba0a26 100644
--- a/drivers/gpu/nvgpu/os/posix/clk_arb.c
+++ b/drivers/gpu/nvgpu/os/posix/clk_arb.c
@@ -52,6 +52,11 @@ int nvgpu_clk_arb_worker_init(struct gk20a *g)
52 return -ENOSYS; 52 return -ENOSYS;
53} 53}
54 54
55bool nvgpu_clk_arb_has_active_req(struct gk20a *g)
56{
57 return false;
58}
59
55int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, 60int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g,
56 u32 api_domain, u16 *actual_mhz) 61 u32 api_domain, u16 *actual_mhz)
57{ 62{