summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorseshendra <sgadagottu@nvidia.com>2019-09-03 17:20:03 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-09-06 01:39:33 -0400
commit0214511e2e085b8233600467ab2b044f9f826bc8 (patch)
treeae5c87a2ef7b348ca424103665c86690110d8e5d
parent07ddc5aaad9a89a758cb5fe247c06d845b025e65 (diff)
gpu: nvgpu: fix enable/disable fecs trace
- This patch fixes enable/disable fecs trace logic. - Added enable_lock and enable_count to handle multiple enable/disable of fecs trace logic. - If user does trace disable twice, enable_count will become negative and when user tries to re-enable it, fecs trace will not be enabled. Bug 2672760 Bug 200542611 Change-Id: Ic7d4883b899f01dcf43058d0e7c9d1223a716c9b Signed-off-by: seshendra <sgadagottu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2189371 GVS: Gerrit_Virtual_Submit Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Winnie Hsu <whsu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c141
1 files changed, 88 insertions, 53 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
index 11f1169b..ba85e3a3 100644
--- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
@@ -59,6 +59,8 @@ struct gk20a_fecs_trace {
59 struct nvgpu_mutex poll_lock; 59 struct nvgpu_mutex poll_lock;
60 struct nvgpu_thread poll_task; 60 struct nvgpu_thread poll_task;
61 bool init; 61 bool init;
62 struct nvgpu_mutex enable_lock;
63 u32 enable_count;
62}; 64};
63 65
64#ifdef CONFIG_GK20A_CTXSW_TRACE 66#ifdef CONFIG_GK20A_CTXSW_TRACE
@@ -438,15 +440,23 @@ int gk20a_fecs_trace_init(struct gk20a *g)
438 if (err) 440 if (err)
439 goto clean_poll_lock; 441 goto clean_poll_lock;
440 442
443 err = nvgpu_mutex_init(&trace->enable_lock);
444 if (err)
445 goto clean_hash_lock;
446
441 BUG_ON(!is_power_of_2(GK20A_FECS_TRACE_NUM_RECORDS)); 447 BUG_ON(!is_power_of_2(GK20A_FECS_TRACE_NUM_RECORDS));
442 hash_init(trace->pid_hash_table); 448 hash_init(trace->pid_hash_table);
443 449
444 __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true); 450 __nvgpu_set_enabled(g, NVGPU_SUPPORT_FECS_CTXSW_TRACE, true);
445 451
452 trace->enable_count = 0;
446 trace->init = true; 453 trace->init = true;
447 454
448 return 0; 455 return 0;
449 456
457clean_hash_lock:
458 nvgpu_mutex_destroy(&trace->hash_lock);
459
450clean_poll_lock: 460clean_poll_lock:
451 nvgpu_mutex_destroy(&trace->poll_lock); 461 nvgpu_mutex_destroy(&trace->poll_lock);
452clean: 462clean:
@@ -579,11 +589,18 @@ int gk20a_fecs_trace_deinit(struct gk20a *g)
579 if (!trace->init) 589 if (!trace->init)
580 return 0; 590 return 0;
581 591
582 nvgpu_thread_stop(&trace->poll_task); 592 /*
593 * Check if tracer was enabled before attempting to stop the
594 * tracer thread.
595 */
596 if (trace->enable_count > 0) {
597 nvgpu_thread_stop(&trace->poll_task);
598 }
583 gk20a_fecs_trace_free_hash_table(g); 599 gk20a_fecs_trace_free_hash_table(g);
584 600
585 nvgpu_mutex_destroy(&g->fecs_trace->hash_lock); 601 nvgpu_mutex_destroy(&g->fecs_trace->hash_lock);
586 nvgpu_mutex_destroy(&g->fecs_trace->poll_lock); 602 nvgpu_mutex_destroy(&g->fecs_trace->poll_lock);
603 nvgpu_mutex_destroy(&g->fecs_trace->enable_lock);
587 604
588 nvgpu_kfree(g, g->fecs_trace); 605 nvgpu_kfree(g, g->fecs_trace);
589 g->fecs_trace = NULL; 606 g->fecs_trace = NULL;
@@ -613,46 +630,51 @@ int gk20a_fecs_trace_enable(struct gk20a *g)
613 if (!trace) 630 if (!trace)
614 return -EINVAL; 631 return -EINVAL;
615 632
616 if (nvgpu_thread_is_running(&trace->poll_task)) 633 nvgpu_mutex_acquire(&trace->enable_lock);
617 return 0; 634 trace->enable_count++;
618 635
619 /* drop data in hw buffer */ 636 if (trace->enable_count == 1U) {
620 if (g->ops.fecs_trace.flush) 637 /* drop data in hw buffer */
621 g->ops.fecs_trace.flush(g); 638 if (g->ops.fecs_trace.flush)
622 write = gk20a_fecs_trace_get_write_index(g); 639 g->ops.fecs_trace.flush(g);
623 640
624 if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { 641 write = gk20a_fecs_trace_get_write_index(g);
625 /*
626 * For enabling FECS trace support, MAILBOX1's MSB
627 * (Bit 31:31) should be set to 1. Bits 30:0 represents
628 * actual pointer value.
629 */
630 write = write |
631 (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT));
632 }
633 gk20a_fecs_trace_set_read_index(g, write);
634 642
635 /* 643 if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) {
636 * FECS ucode does a priv holdoff around the assertion of 644 /*
637 * context reset. So, pri transactions (e.g. mailbox1 register 645 * For enabling FECS trace support, MAILBOX1's MSB
638 * write) might fail due to this. Hence, do write with ack 646 * (Bit 31:31) should be set to 1. Bits 30:0 represents
639 * i.e. write and read it back to make sure write happened for 647 * actual pointer value.
640 * mailbox1. 648 */
641 */ 649 write = write |
642 while (gk20a_fecs_trace_get_read_index(g) != write) { 650 (BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT));
643 nvgpu_log(g, gpu_dbg_ctxsw, "mailbox1 update failed"); 651 }
644 gk20a_fecs_trace_set_read_index(g, write); 652 gk20a_fecs_trace_set_read_index(g, write);
645 }
646 653
647 err = nvgpu_thread_create(&trace->poll_task, g, 654 /*
648 gk20a_fecs_trace_periodic_polling, __func__); 655 * FECS ucode does a priv holdoff around the assertion of
649 if (err) { 656 * context reset. So, pri transactions (e.g. mailbox1 register
650 nvgpu_warn(g, 657 * write) might fail due to this. Hence, do write with ack
658 * i.e. write and read it back to make sure write happened for
659 * mailbox1.
660 */
661 while (gk20a_fecs_trace_get_read_index(g) != write) {
662 nvgpu_log(g, gpu_dbg_ctxsw, "mailbox1 update failed");
663 gk20a_fecs_trace_set_read_index(g, write);
664 }
665
666 err = nvgpu_thread_create(&trace->poll_task, g,
667 gk20a_fecs_trace_periodic_polling, __func__);
668 if (err) {
669 nvgpu_warn(g,
651 "failed to create FECS polling task"); 670 "failed to create FECS polling task");
652 return err; 671 goto done;
672 }
653 } 673 }
654 674
655 return 0; 675done:
676 nvgpu_mutex_release(&trace->enable_lock);
677 return err;
656} 678}
657 679
658int gk20a_fecs_trace_disable(struct gk20a *g) 680int gk20a_fecs_trace_disable(struct gk20a *g)
@@ -660,32 +682,45 @@ int gk20a_fecs_trace_disable(struct gk20a *g)
660 struct gk20a_fecs_trace *trace = g->fecs_trace; 682 struct gk20a_fecs_trace *trace = g->fecs_trace;
661 int read = 0; 683 int read = 0;
662 684
663 if (nvgpu_thread_is_running(&trace->poll_task)) 685 if (trace == NULL) {
664 nvgpu_thread_stop(&trace->poll_task); 686 return -EINVAL;
687 }
665 688
666 if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) { 689 nvgpu_mutex_acquire(&trace->enable_lock);
667 /* 690 if (trace->enable_count <= 0U) {
668 * For disabling FECS trace support, MAILBOX1's MSB 691 nvgpu_mutex_release(&trace->enable_lock);
669 * (Bit 31:31) should be set to 0. 692 return 0;
670 */ 693 }
671 read = gk20a_fecs_trace_get_read_index(g) & 694 trace->enable_count--;
672 (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT))); 695 if (trace->enable_count == 0U) {
696 if (nvgpu_is_enabled(g, NVGPU_FECS_TRACE_FEATURE_CONTROL)) {
697 /*
698 * For disabling FECS trace support, MAILBOX1's MSB
699 * (Bit 31:31) should be set to 0.
700 */
701 read = gk20a_fecs_trace_get_read_index(g) &
702 (~(BIT32(NVGPU_FECS_TRACE_FEATURE_CONTROL_BIT)));
673 703
674 gk20a_fecs_trace_set_read_index(g, read); 704 gk20a_fecs_trace_set_read_index(g, read);
675 705
676 /* 706 /*
677 * FECS ucode does a priv holdoff around the assertion 707 * FECS ucode does a priv holdoff around the assertion
678 * of context reset. So, pri transactions (e.g. 708 * of context reset. So, pri transactions (e.g.
679 * mailbox1 register write) might fail due to this. 709 * mailbox1 register write) might fail due to this.
680 * Hence, do write with ack i.e. write and read it back 710 * Hence, do write with ack i.e. write and read it back
681 * to make sure write happened for mailbox1. 711 * to make sure write happened for mailbox1.
682 */ 712 */
683 while (gk20a_fecs_trace_get_read_index(g) != read) { 713 while (gk20a_fecs_trace_get_read_index(g) != read) {
684 nvgpu_log(g, gpu_dbg_ctxsw, 714 nvgpu_log(g, gpu_dbg_ctxsw,
685 "mailbox1 update failed"); 715 "mailbox1 update failed");
686 gk20a_fecs_trace_set_read_index(g, read); 716 gk20a_fecs_trace_set_read_index(g, read);
717 }
687 } 718 }
719
720 nvgpu_thread_stop(&trace->poll_task);
721
688 } 722 }
723 nvgpu_mutex_release(&trace->enable_lock);
689 724
690 return -EPERM; 725 return -EPERM;
691} 726}