summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Goyal <dgoyal@nvidia.com>2017-10-23 02:16:09 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-25 07:23:57 -0400
commitc61e21c868246faf7a9ffc812590941fc362af17 (patch)
treecacc1639bcdc48766047dc65a715c67c51682612
parent539c8bff4b501a4ca999290454a210f5d17ba516 (diff)
gpu: nvgpu: Fix race in PMU state transitions.
PMU response(intr callback for messages) can run faster than the kthread posting commands to PMU. This causes the PMU message callback to skip important pmu state change(which happens just after the PMU command is posted). Solution: State change should be triggered from only inside the intr callback. Other places can only update the pmu_state variable. This change also adds error check to print in case command post fails. JIRA GPUT19X-20 Change-Id: Ib0a4275440455342a898c93ea9d86c5822e039a7 Signed-off-by: Deepak Goyal <dgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1583577 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu.c4
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu_ipc.c2
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu_pg.c37
3 files changed, 28 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c
index 95b57e22..3447f40d 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu.c
@@ -367,7 +367,7 @@ static void pmu_setup_hw_enable_elpg(struct gk20a *g)
367 nvgpu_log_fn(g, " "); 367 nvgpu_log_fn(g, " ");
368 368
369 pmu->initialized = true; 369 pmu->initialized = true;
370 nvgpu_pmu_state_change(g, PMU_STATE_STARTED, true); 370 nvgpu_pmu_state_change(g, PMU_STATE_STARTED, false);
371 371
372 if (nvgpu_is_enabled(g, NVGPU_PMU_ZBC_SAVE)) { 372 if (nvgpu_is_enabled(g, NVGPU_PMU_ZBC_SAVE)) {
373 /* Save zbc table after PMU is initialized. */ 373 /* Save zbc table after PMU is initialized. */
@@ -448,8 +448,6 @@ static int nvgpu_pg_init_task(void *arg)
448 case PMU_STATE_LOADING_ZBC: 448 case PMU_STATE_LOADING_ZBC:
449 nvgpu_pmu_dbg(g, "loaded zbc"); 449 nvgpu_pmu_dbg(g, "loaded zbc");
450 pmu_setup_hw_enable_elpg(g); 450 pmu_setup_hw_enable_elpg(g);
451 break;
452 case PMU_STATE_STARTED:
453 nvgpu_pmu_dbg(g, "PMU booted, thread exiting"); 451 nvgpu_pmu_dbg(g, "PMU booted, thread exiting");
454 return 0; 452 return 0;
455 default: 453 default:
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c
index e76ed7df..4c706e57 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c
@@ -640,7 +640,7 @@ int nvgpu_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd,
640 640
641 nvgpu_log_fn(g, "done"); 641 nvgpu_log_fn(g, "done");
642 642
643 return 0; 643 return err;
644 644
645clean_up: 645clean_up:
646 nvgpu_log_fn(g, "fail"); 646 nvgpu_log_fn(g, "fail");
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pmu_pg.c
index b7f2cee8..bf39ce19 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu_pg.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu_pg.c
@@ -370,9 +370,16 @@ static int pmu_pg_init_send(struct gk20a *g, u32 pg_engine_id)
370 struct nvgpu_pmu *pmu = &g->pmu; 370 struct nvgpu_pmu *pmu = &g->pmu;
371 struct pmu_cmd cmd; 371 struct pmu_cmd cmd;
372 u32 seq; 372 u32 seq;
373 int err = 0;
373 374
374 nvgpu_log_fn(g, " "); 375 nvgpu_log_fn(g, " ");
375 376
377 if (pmu->pmu_state == PMU_STATE_INIT_RECEIVED)
378 nvgpu_pmu_state_change(g,
379 PMU_STATE_ELPG_BOOTING, false);
380 else
381 nvgpu_err(g, "PMU INIT not received\n");
382
376 gk20a_pmu_pg_idle_counter_config(g, pg_engine_id); 383 gk20a_pmu_pg_idle_counter_config(g, pg_engine_id);
377 384
378 if (g->ops.pmu.pmu_pg_init_param) 385 if (g->ops.pmu.pmu_pg_init_param)
@@ -387,8 +394,10 @@ static int pmu_pg_init_send(struct gk20a *g, u32 pg_engine_id)
387 cmd.cmd.pg.elpg_cmd.cmd = PMU_PG_ELPG_CMD_INIT; 394 cmd.cmd.pg.elpg_cmd.cmd = PMU_PG_ELPG_CMD_INIT;
388 395
389 nvgpu_pmu_dbg(g, "cmd post PMU_PG_ELPG_CMD_INIT"); 396 nvgpu_pmu_dbg(g, "cmd post PMU_PG_ELPG_CMD_INIT");
390 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, 397 err = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
391 pmu_handle_pg_elpg_msg, pmu, &seq, ~0); 398 pmu_handle_pg_elpg_msg, pmu, &seq, ~0);
399 if (err)
400 nvgpu_err(g, "PMU_PG_ELPG_CMD_INIT cmd failed\n");
392 401
393 /* alloc dmem for powergating state log */ 402 /* alloc dmem for powergating state log */
394 pmu->stat_dmem_offset[pg_engine_id] = 0; 403 pmu->stat_dmem_offset[pg_engine_id] = 0;
@@ -401,8 +410,10 @@ static int pmu_pg_init_send(struct gk20a *g, u32 pg_engine_id)
401 cmd.cmd.pg.stat.data = 0; 410 cmd.cmd.pg.stat.data = 0;
402 411
403 nvgpu_pmu_dbg(g, "cmd post PMU_PG_STAT_CMD_ALLOC_DMEM"); 412 nvgpu_pmu_dbg(g, "cmd post PMU_PG_STAT_CMD_ALLOC_DMEM");
404 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ, 413 err = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
405 pmu_handle_pg_stat_msg, pmu, &seq, ~0); 414 pmu_handle_pg_stat_msg, pmu, &seq, ~0);
415 if (err)
416 nvgpu_err(g, "PMU_PG_STAT_CMD_ALLOC_DMEM cmd failed\n");
406 417
407 /* disallow ELPG initially 418 /* disallow ELPG initially
408 * PMU ucode requires a disallow cmd before allow cmd 419 * PMU ucode requires a disallow cmd before allow cmd
@@ -420,8 +431,10 @@ static int pmu_pg_init_send(struct gk20a *g, u32 pg_engine_id)
420 cmd.cmd.pg.elpg_cmd.cmd = PMU_PG_ELPG_CMD_DISALLOW; 431 cmd.cmd.pg.elpg_cmd.cmd = PMU_PG_ELPG_CMD_DISALLOW;
421 432
422 nvgpu_pmu_dbg(g, "cmd post PMU_PG_ELPG_CMD_DISALLOW"); 433 nvgpu_pmu_dbg(g, "cmd post PMU_PG_ELPG_CMD_DISALLOW");
423 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, 434 err = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
424 pmu_handle_pg_elpg_msg, pmu, &seq, ~0); 435 pmu_handle_pg_elpg_msg, pmu, &seq, ~0);
436 if (err)
437 nvgpu_err(g, "PMU_PG_ELPG_CMD_DISALLOW cmd failed\n");
425 438
426 if (g->ops.pmu.pmu_pg_set_sub_feature_mask) 439 if (g->ops.pmu.pmu_pg_set_sub_feature_mask)
427 g->ops.pmu.pmu_pg_set_sub_feature_mask(g, pg_engine_id); 440 g->ops.pmu.pmu_pg_set_sub_feature_mask(g, pg_engine_id);
@@ -431,7 +444,6 @@ static int pmu_pg_init_send(struct gk20a *g, u32 pg_engine_id)
431 444
432int nvgpu_pmu_init_powergating(struct gk20a *g) 445int nvgpu_pmu_init_powergating(struct gk20a *g)
433{ 446{
434 struct nvgpu_pmu *pmu = &g->pmu;
435 u32 pg_engine_id; 447 u32 pg_engine_id;
436 u32 pg_engine_id_list = 0; 448 u32 pg_engine_id_list = 0;
437 449
@@ -448,9 +460,6 @@ int nvgpu_pmu_init_powergating(struct gk20a *g)
448 460
449 if (BIT(pg_engine_id) & pg_engine_id_list) { 461 if (BIT(pg_engine_id) & pg_engine_id_list) {
450 pmu_pg_init_send(g, pg_engine_id); 462 pmu_pg_init_send(g, pg_engine_id);
451 if (pmu->pmu_state == PMU_STATE_INIT_RECEIVED)
452 nvgpu_pmu_state_change(g,
453 PMU_STATE_ELPG_BOOTING, false);
454 } 463 }
455 } 464 }
456 465
@@ -519,9 +528,12 @@ int nvgpu_pmu_init_bind_fecs(struct gk20a *g)
519 528
520 pmu->buf_loaded = false; 529 pmu->buf_loaded = false;
521 nvgpu_pmu_dbg(g, "cmd post PMU_PG_CMD_ID_ENG_BUF_LOAD PMU_PGENG_GR_BUFFER_IDX_FECS"); 530 nvgpu_pmu_dbg(g, "cmd post PMU_PG_CMD_ID_ENG_BUF_LOAD PMU_PGENG_GR_BUFFER_IDX_FECS");
522 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
523 pmu_handle_pg_buf_config_msg, pmu, &desc, ~0);
524 nvgpu_pmu_state_change(g, PMU_STATE_LOADING_PG_BUF, false); 531 nvgpu_pmu_state_change(g, PMU_STATE_LOADING_PG_BUF, false);
532 err = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
533 pmu_handle_pg_buf_config_msg, pmu, &desc, ~0);
534 if (err)
535 nvgpu_err(g, "cmd LOAD PMU_PGENG_GR_BUFFER_IDX_FECS failed\n");
536
525 return err; 537 return err;
526} 538}
527 539
@@ -531,6 +543,7 @@ void nvgpu_pmu_setup_hw_load_zbc(struct gk20a *g)
531 struct pmu_cmd cmd; 543 struct pmu_cmd cmd;
532 u32 desc; 544 u32 desc;
533 u32 gr_engine_id; 545 u32 gr_engine_id;
546 int err = 0;
534 547
535 gr_engine_id = gk20a_fifo_get_gr_engine_id(g); 548 gr_engine_id = gk20a_fifo_get_gr_engine_id(g);
536 549
@@ -555,9 +568,11 @@ void nvgpu_pmu_setup_hw_load_zbc(struct gk20a *g)
555 568
556 pmu->buf_loaded = false; 569 pmu->buf_loaded = false;
557 nvgpu_pmu_dbg(g, "cmd post PMU_PG_CMD_ID_ENG_BUF_LOAD PMU_PGENG_GR_BUFFER_IDX_ZBC"); 570 nvgpu_pmu_dbg(g, "cmd post PMU_PG_CMD_ID_ENG_BUF_LOAD PMU_PGENG_GR_BUFFER_IDX_ZBC");
558 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
559 pmu_handle_pg_buf_config_msg, pmu, &desc, ~0);
560 nvgpu_pmu_state_change(g, PMU_STATE_LOADING_ZBC, false); 571 nvgpu_pmu_state_change(g, PMU_STATE_LOADING_ZBC, false);
572 err = nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_LPQ,
573 pmu_handle_pg_buf_config_msg, pmu, &desc, ~0);
574 if (err)
575 nvgpu_err(g, "CMD LOAD PMU_PGENG_GR_BUFFER_IDX_ZBC failed\n");
561} 576}
562 577
563/* stats */ 578/* stats */