diff options
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 |
2 files changed, 19 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 92b43c8a..6a69de3e 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -742,8 +742,7 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch, | |||
742 | 742 | ||
743 | dmabuf = dma_buf_get(args->mem); | 743 | dmabuf = dma_buf_get(args->mem); |
744 | 744 | ||
745 | if (ch->error_notifier_ref) | 745 | gk20a_free_error_notifiers(ch); |
746 | gk20a_free_error_notifiers(ch); | ||
747 | 746 | ||
748 | if (IS_ERR(dmabuf)) { | 747 | if (IS_ERR(dmabuf)) { |
749 | pr_err("Invalid handle: %d\n", args->mem); | 748 | pr_err("Invalid handle: %d\n", args->mem); |
@@ -764,16 +763,23 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch, | |||
764 | return -ENOMEM; | 763 | return -ENOMEM; |
765 | } | 764 | } |
766 | 765 | ||
767 | /* set channel notifiers pointer */ | ||
768 | ch->error_notifier_ref = dmabuf; | ||
769 | ch->error_notifier = va + args->offset; | 766 | ch->error_notifier = va + args->offset; |
770 | ch->error_notifier_va = va; | 767 | ch->error_notifier_va = va; |
771 | memset(ch->error_notifier, 0, sizeof(struct nvgpu_notification)); | 768 | memset(ch->error_notifier, 0, sizeof(struct nvgpu_notification)); |
769 | |||
770 | /* set channel notifiers pointer */ | ||
771 | mutex_lock(&ch->error_notifier_mutex); | ||
772 | ch->error_notifier_ref = dmabuf; | ||
773 | mutex_unlock(&ch->error_notifier_mutex); | ||
774 | |||
772 | return 0; | 775 | return 0; |
773 | } | 776 | } |
774 | 777 | ||
775 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error) | 778 | void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error) |
776 | { | 779 | { |
780 | bool notifier_set = false; | ||
781 | |||
782 | mutex_lock(&ch->error_notifier_mutex); | ||
777 | if (ch->error_notifier_ref) { | 783 | if (ch->error_notifier_ref) { |
778 | struct timespec time_data; | 784 | struct timespec time_data; |
779 | u64 nsec; | 785 | u64 nsec; |
@@ -787,13 +793,18 @@ void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error) | |||
787 | ch->error_notifier->info32 = error; | 793 | ch->error_notifier->info32 = error; |
788 | ch->error_notifier->status = 0xffff; | 794 | ch->error_notifier->status = 0xffff; |
789 | 795 | ||
796 | notifier_set = true; | ||
797 | } | ||
798 | mutex_unlock(&ch->error_notifier_mutex); | ||
799 | |||
800 | if (notifier_set) | ||
790 | gk20a_err(dev_from_gk20a(ch->g), | 801 | gk20a_err(dev_from_gk20a(ch->g), |
791 | "error notifier set to %d for ch %d", error, ch->hw_chid); | 802 | "error notifier set to %d for ch %d", error, ch->hw_chid); |
792 | } | ||
793 | } | 803 | } |
794 | 804 | ||
795 | static void gk20a_free_error_notifiers(struct channel_gk20a *ch) | 805 | static void gk20a_free_error_notifiers(struct channel_gk20a *ch) |
796 | { | 806 | { |
807 | mutex_lock(&ch->error_notifier_mutex); | ||
797 | if (ch->error_notifier_ref) { | 808 | if (ch->error_notifier_ref) { |
798 | dma_buf_vunmap(ch->error_notifier_ref, ch->error_notifier_va); | 809 | dma_buf_vunmap(ch->error_notifier_ref, ch->error_notifier_va); |
799 | dma_buf_put(ch->error_notifier_ref); | 810 | dma_buf_put(ch->error_notifier_ref); |
@@ -801,6 +812,7 @@ static void gk20a_free_error_notifiers(struct channel_gk20a *ch) | |||
801 | ch->error_notifier = NULL; | 812 | ch->error_notifier = NULL; |
802 | ch->error_notifier_va = NULL; | 813 | ch->error_notifier_va = NULL; |
803 | } | 814 | } |
815 | mutex_unlock(&ch->error_notifier_mutex); | ||
804 | } | 816 | } |
805 | 817 | ||
806 | /* Returns delta of cyclic integers a and b. If a is ahead of b, delta | 818 | /* Returns delta of cyclic integers a and b. If a is ahead of b, delta |
@@ -2387,6 +2399,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid) | |||
2387 | c->referenceable = false; | 2399 | c->referenceable = false; |
2388 | init_waitqueue_head(&c->ref_count_dec_wq); | 2400 | init_waitqueue_head(&c->ref_count_dec_wq); |
2389 | mutex_init(&c->ioctl_lock); | 2401 | mutex_init(&c->ioctl_lock); |
2402 | mutex_init(&c->error_notifier_mutex); | ||
2390 | spin_lock_init(&c->jobs_lock); | 2403 | spin_lock_init(&c->jobs_lock); |
2391 | raw_spin_lock_init(&c->timeout.lock); | 2404 | raw_spin_lock_init(&c->timeout.lock); |
2392 | mutex_init(&c->sync_lock); | 2405 | mutex_init(&c->sync_lock); |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index a44321bc..f6571b6f 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -177,6 +177,7 @@ struct channel_gk20a { | |||
177 | struct dma_buf *error_notifier_ref; | 177 | struct dma_buf *error_notifier_ref; |
178 | struct nvgpu_notification *error_notifier; | 178 | struct nvgpu_notification *error_notifier; |
179 | void *error_notifier_va; | 179 | void *error_notifier_va; |
180 | struct mutex error_notifier_mutex; | ||
180 | 181 | ||
181 | struct mutex sync_lock; | 182 | struct mutex sync_lock; |
182 | struct gk20a_channel_sync *sync; | 183 | struct gk20a_channel_sync *sync; |