summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeema Khowala <seemaj@nvidia.com>2017-10-30 17:15:51 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-05-18 22:54:33 -0400
commit982fcfa737be54fd0ab16792faf97a2741e34907 (patch)
tree6c45741a08156d43d2ea09a4136c104609989e42
parentac687c95d383c3fb0165e6535893510409559a8e (diff)
gpu: nvgpu: Add timeouts_disabled_refcount for enabling timeout
-timeouts will be enabled only when timeouts_disabled_refcount will reach 0 -timeouts_enabled debugfs will change from u32 type to file type to avoid race enabling/disabling timeout from debugfs and ioctl -unify setting timeouts_enabled from debugfs and ioctl Bug 1982434 Change-Id: I54bab778f1ae533872146dfb8d80deafd2a685c7 Signed-off-by: Seema Khowala <seemaj@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1588690 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/linux/debug.c58
-rw-r--r--drivers/gpu/nvgpu/common/linux/driver_common.c13
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_dbg.c26
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h12
7 files changed, 91 insertions, 29 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c
index e8c0417a..87b35dc1 100644
--- a/drivers/gpu/nvgpu/common/linux/debug.c
+++ b/drivers/gpu/nvgpu/common/linux/debug.c
@@ -279,6 +279,59 @@ static int gk20a_railgating_debugfs_init(struct gk20a *g)
279 279
280 return 0; 280 return 0;
281} 281}
282static ssize_t timeouts_enabled_read(struct file *file,
283 char __user *user_buf, size_t count, loff_t *ppos)
284{
285 char buf[3];
286 struct gk20a *g = file->private_data;
287
288 if (nvgpu_is_timeouts_enabled(g))
289 buf[0] = 'Y';
290 else
291 buf[0] = 'N';
292 buf[1] = '\n';
293 buf[2] = 0x00;
294 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
295}
296
297static ssize_t timeouts_enabled_write(struct file *file,
298 const char __user *user_buf, size_t count, loff_t *ppos)
299{
300 char buf[3];
301 int buf_size;
302 bool timeouts_enabled;
303 struct gk20a *g = file->private_data;
304
305 buf_size = min(count, (sizeof(buf)-1));
306 if (copy_from_user(buf, user_buf, buf_size))
307 return -EFAULT;
308
309 if (strtobool(buf, &timeouts_enabled) == 0) {
310 nvgpu_mutex_acquire(&g->dbg_sessions_lock);
311 if (timeouts_enabled == false) {
312 /* requesting to disable timeouts */
313 if (g->timeouts_disabled_by_user == false) {
314 nvgpu_atomic_inc(&g->timeouts_disabled_refcount);
315 g->timeouts_disabled_by_user = true;
316 }
317 } else {
318 /* requesting to enable timeouts */
319 if (g->timeouts_disabled_by_user == true) {
320 nvgpu_atomic_dec(&g->timeouts_disabled_refcount);
321 g->timeouts_disabled_by_user = false;
322 }
323 }
324 nvgpu_mutex_release(&g->dbg_sessions_lock);
325 }
326
327 return count;
328}
329
330static const struct file_operations timeouts_enabled_fops = {
331 .open = simple_open,
332 .read = timeouts_enabled_read,
333 .write = timeouts_enabled_write,
334};
282 335
283void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) 336void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink)
284{ 337{
@@ -323,10 +376,11 @@ void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink)
323 S_IRUGO|S_IWUSR, l->debugfs, 376 S_IRUGO|S_IWUSR, l->debugfs,
324 &g->gr_idle_timeout_default); 377 &g->gr_idle_timeout_default);
325 l->debugfs_timeouts_enabled = 378 l->debugfs_timeouts_enabled =
326 debugfs_create_bool("timeouts_enabled", 379 debugfs_create_file("timeouts_enabled",
327 S_IRUGO|S_IWUSR, 380 S_IRUGO|S_IWUSR,
328 l->debugfs, 381 l->debugfs,
329 &g->timeouts_enabled); 382 g,
383 &timeouts_enabled_fops);
330 384
331 l->debugfs_disable_bigpage = 385 l->debugfs_disable_bigpage =
332 debugfs_create_file("disable_bigpage", 386 debugfs_create_file("disable_bigpage",
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c
index 769f7e03..edc8aca8 100644
--- a/drivers/gpu/nvgpu/common/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/common/linux/driver_common.c
@@ -96,12 +96,15 @@ static void nvgpu_init_timeout(struct gk20a *g)
96{ 96{
97 struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g)); 97 struct gk20a_platform *platform = dev_get_drvdata(dev_from_gk20a(g));
98 98
99 g->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; 99 g->timeouts_disabled_by_user = false;
100 if (nvgpu_platform_is_silicon(g)) 100 nvgpu_atomic_set(&g->timeouts_disabled_refcount, 0);
101 g->timeouts_enabled = true; 101
102 else if (nvgpu_platform_is_fpga(g)) { 102 if (nvgpu_platform_is_silicon(g)) {
103 g->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT;
104 } else if (nvgpu_platform_is_fpga(g)) {
103 g->gr_idle_timeout_default = GK20A_TIMEOUT_FPGA; 105 g->gr_idle_timeout_default = GK20A_TIMEOUT_FPGA;
104 g->timeouts_enabled = true; 106 } else {
107 g->gr_idle_timeout_default = (u32)ULONG_MAX;
105 } 108 }
106 g->ch_wdt_timeout_ms = platform->ch_wdt_timeout_ms; 109 g->ch_wdt_timeout_ms = platform->ch_wdt_timeout_ms;
107} 110}
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c
index 2aba2664..31e7e2cb 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_dbg.c
@@ -228,7 +228,7 @@ static int nvgpu_dbg_gpu_ioctl_timeout(struct dbg_session_gk20a *dbg_s,
228 int err; 228 int err;
229 struct gk20a *g = dbg_s->g; 229 struct gk20a *g = dbg_s->g;
230 230
231 nvgpu_log_fn(g, "powergate mode = %d", args->enable); 231 nvgpu_log(g, gpu_dbg_fn, "timeout enable/disable = %d", args->enable);
232 232
233 nvgpu_mutex_acquire(&g->dbg_sessions_lock); 233 nvgpu_mutex_acquire(&g->dbg_sessions_lock);
234 err = nvgpu_dbg_timeout_enable(dbg_s, args->enable); 234 err = nvgpu_dbg_timeout_enable(dbg_s, args->enable);
@@ -385,18 +385,14 @@ static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s,
385 385
386 switch (timeout_mode) { 386 switch (timeout_mode) {
387 case NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE: 387 case NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE:
388 if (dbg_s->is_timeout_disabled && 388 if (dbg_s->is_timeout_disabled == true)
389 --g->dbg_timeout_disabled_refcount == 0) { 389 nvgpu_atomic_dec(&g->timeouts_disabled_refcount);
390 g->timeouts_enabled = true;
391 }
392 dbg_s->is_timeout_disabled = false; 390 dbg_s->is_timeout_disabled = false;
393 break; 391 break;
394 392
395 case NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE: 393 case NVGPU_DBG_GPU_IOCTL_TIMEOUT_DISABLE:
396 if ((dbg_s->is_timeout_disabled == false) && 394 if (dbg_s->is_timeout_disabled == false)
397 (g->dbg_timeout_disabled_refcount++ == 0)) { 395 nvgpu_atomic_inc(&g->timeouts_disabled_refcount);
398 g->timeouts_enabled = false;
399 }
400 dbg_s->is_timeout_disabled = true; 396 dbg_s->is_timeout_disabled = true;
401 break; 397 break;
402 398
@@ -408,9 +404,11 @@ static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s,
408 break; 404 break;
409 } 405 }
410 406
411 nvgpu_log(g, gpu_dbg_gpu_dbg, "Timeouts enabled : %s", 407 if (!err)
412 g->timeouts_enabled ? "Yes" : "No"); 408 nvgpu_log(g, gpu_dbg_gpu_dbg, "dbg is timeout disabled %s, "
413 409 "timeouts disabled refcount %d",
410 dbg_s->is_timeout_disabled ? "true" : "false",
411 nvgpu_atomic_read(&g->timeouts_disabled_refcount));
414 return err; 412 return err;
415} 413}
416 414
@@ -1598,11 +1596,11 @@ static int nvgpu_ioctl_profiler_reserve(struct dbg_session_gk20a *dbg_s,
1598static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s, 1596static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s,
1599 struct nvgpu_dbg_gpu_timeout_args *args) 1597 struct nvgpu_dbg_gpu_timeout_args *args)
1600{ 1598{
1601 int status; 1599 bool status;
1602 struct gk20a *g = dbg_s->g; 1600 struct gk20a *g = dbg_s->g;
1603 1601
1604 nvgpu_mutex_acquire(&g->dbg_sessions_lock); 1602 nvgpu_mutex_acquire(&g->dbg_sessions_lock);
1605 status = g->timeouts_enabled; 1603 status = nvgpu_is_timeouts_enabled(g);
1606 nvgpu_mutex_release(&g->dbg_sessions_lock); 1604 nvgpu_mutex_release(&g->dbg_sessions_lock);
1607 1605
1608 if (status) 1606 if (status)
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
index 5d3598b5..c5572603 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c
@@ -424,7 +424,8 @@ int vgpu_probe(struct platform_device *pdev)
424 dma_set_max_seg_size(dev, UINT_MAX); 424 dma_set_max_seg_size(dev, UINT_MAX);
425 425
426 gk20a->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT; 426 gk20a->gr_idle_timeout_default = NVGPU_DEFAULT_GR_IDLE_TIMEOUT;
427 gk20a->timeouts_enabled = true; 427 gk20a->timeouts_disabled_by_user = false;
428 nvgpu_atomic_set(&gk20a->timeouts_disabled_refcount, 0);
428 429
429 vgpu_create_sysfs(dev); 430 vgpu_create_sysfs(dev);
430 gk20a_init_gr(gk20a); 431 gk20a_init_gr(gk20a);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index a4637b8f..45ce0e77 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -1158,7 +1158,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
1158 } 1158 }
1159 } 1159 }
1160 1160
1161 if (!c->g->timeouts_enabled || !c->timeout.enabled) 1161 if (!nvgpu_is_timeouts_enabled(c->g) || !c->timeout.enabled)
1162 acquire_timeout = 0; 1162 acquire_timeout = 0;
1163 else 1163 else
1164 acquire_timeout = c->timeout.limit_ms; 1164 acquire_timeout = c->timeout.limit_ms;
@@ -1266,7 +1266,7 @@ bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch,
1266 1266
1267 ch->timeout_gpfifo_get = gpfifo_get; 1267 ch->timeout_gpfifo_get = gpfifo_get;
1268 1268
1269 return ch->g->timeouts_enabled && 1269 return nvgpu_is_timeouts_enabled(ch->g) &&
1270 ch->timeout_accumulated_ms > ch->timeout_ms_max; 1270 ch->timeout_accumulated_ms > ch->timeout_ms_max;
1271} 1271}
1272 1272
@@ -1303,7 +1303,7 @@ static void __gk20a_channel_timeout_start(struct channel_gk20a *ch)
1303 */ 1303 */
1304static void gk20a_channel_timeout_start(struct channel_gk20a *ch) 1304static void gk20a_channel_timeout_start(struct channel_gk20a *ch)
1305{ 1305{
1306 if (!ch->g->timeouts_enabled) 1306 if (!nvgpu_is_timeouts_enabled(ch->g))
1307 return; 1307 return;
1308 1308
1309 if (!ch->timeout.enabled) 1309 if (!ch->timeout.enabled)
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 7f4a0948..964ccb03 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -2482,7 +2482,7 @@ unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id,
2482 2482
2483 val &= ~pbdma_acquire_timeout_en_enable_f(); 2483 val &= ~pbdma_acquire_timeout_en_enable_f();
2484 gk20a_writel(g, pbdma_acquire_r(pbdma_id), val); 2484 gk20a_writel(g, pbdma_acquire_r(pbdma_id), val);
2485 if (g->timeouts_enabled) { 2485 if (nvgpu_is_timeouts_enabled(g)) {
2486 rc_type = RC_TYPE_PBDMA_FAULT; 2486 rc_type = RC_TYPE_PBDMA_FAULT;
2487 nvgpu_err(g, 2487 nvgpu_err(g,
2488 "semaphore acquire timeout!"); 2488 "semaphore acquire timeout!");
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 84d3f639..f6318257 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1314,7 +1314,7 @@ struct gk20a {
1314 struct railgate_stats pstats; 1314 struct railgate_stats pstats;
1315#endif 1315#endif
1316 u32 gr_idle_timeout_default; 1316 u32 gr_idle_timeout_default;
1317 bool timeouts_enabled; 1317 bool timeouts_disabled_by_user;
1318 unsigned int ch_wdt_timeout_ms; 1318 unsigned int ch_wdt_timeout_ms;
1319 1319
1320 struct nvgpu_mutex poweron_lock; 1320 struct nvgpu_mutex poweron_lock;
@@ -1376,7 +1376,8 @@ struct gk20a {
1376 /* also prevents debug sessions from attaching until released */ 1376 /* also prevents debug sessions from attaching until released */
1377 struct nvgpu_mutex dbg_sessions_lock; 1377 struct nvgpu_mutex dbg_sessions_lock;
1378 int dbg_powergating_disabled_refcount; /*refcount for pg disable */ 1378 int dbg_powergating_disabled_refcount; /*refcount for pg disable */
1379 int dbg_timeout_disabled_refcount; /*refcount for timeout disable */ 1379 /*refcount for timeout disable */
1380 nvgpu_atomic_t timeouts_disabled_refcount;
1380 1381
1381 /* must have dbg_sessions_lock before use */ 1382 /* must have dbg_sessions_lock before use */
1382 struct nvgpu_dbg_reg_op *dbg_regops_tmp_buf; 1383 struct nvgpu_dbg_reg_op *dbg_regops_tmp_buf;
@@ -1508,9 +1509,14 @@ struct gk20a {
1508 struct nvgpu_list_node boardobjgrp_head; 1509 struct nvgpu_list_node boardobjgrp_head;
1509}; 1510};
1510 1511
1512static inline bool nvgpu_is_timeouts_enabled(struct gk20a *g)
1513{
1514 return nvgpu_atomic_read(&g->timeouts_disabled_refcount) == 0;
1515}
1516
1511static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g) 1517static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g)
1512{ 1518{
1513 return g->timeouts_enabled ? 1519 return nvgpu_is_timeouts_enabled(g) ?
1514 g->gr_idle_timeout_default : ULONG_MAX; 1520 g->gr_idle_timeout_default : ULONG_MAX;
1515} 1521}
1516 1522