mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: acquire mutex for notifier read
We use &ch->error_notifier_mutex to protect writes and free of error notifier But we currently do not protect reading of notifier in gk20a_fifo_set_ctx_mmu_error() and vgpu_fifo_set_ctx_mmu_error() Add new API gk20a_set_error_notifier_locked() which is same as gk20a_set_error_notifier() but without the locks. In *_fifo_set_ctx_mmu_error() APIs, acquire the mutex explicitly, and then use this new API gk20a_set_error_notifier() will now just call gk20a_set_error_notifier_locked() within a mutex Bug 1824788 Bug 1844312 Change-Id: I1f3831dc63fe1daa761b2e17e4de3c155f505d6f Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1273471 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
f3d2dd4fd2
commit
505b442551
@@ -827,11 +827,12 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
|
||||
/**
|
||||
* gk20a_set_error_notifier_locked()
|
||||
* Should be called with ch->error_notifier_mutex held
|
||||
*/
|
||||
void gk20a_set_error_notifier_locked(struct channel_gk20a *ch, __u32 error)
|
||||
{
|
||||
bool notifier_set = false;
|
||||
|
||||
mutex_lock(&ch->error_notifier_mutex);
|
||||
if (ch->error_notifier_ref) {
|
||||
struct timespec time_data;
|
||||
u64 nsec;
|
||||
@@ -845,14 +846,17 @@ void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
|
||||
ch->error_notifier->info32 = error;
|
||||
ch->error_notifier->status = 0xffff;
|
||||
|
||||
notifier_set = true;
|
||||
}
|
||||
mutex_unlock(&ch->error_notifier_mutex);
|
||||
|
||||
if (notifier_set)
|
||||
gk20a_err(dev_from_gk20a(ch->g),
|
||||
"error notifier set to %d for ch %d", error, ch->hw_chid);
|
||||
}
|
||||
}
|
||||
|
||||
void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
|
||||
{
|
||||
mutex_lock(&ch->error_notifier_mutex);
|
||||
gk20a_set_error_notifier_locked(ch, error);
|
||||
mutex_unlock(&ch->error_notifier_mutex);
|
||||
}
|
||||
|
||||
static void gk20a_free_error_notifiers(struct channel_gk20a *ch)
|
||||
{
|
||||
|
||||
@@ -235,6 +235,7 @@ void gk20a_disable_channel(struct channel_gk20a *ch);
|
||||
void gk20a_channel_abort(struct channel_gk20a *ch, bool channel_preempt);
|
||||
void gk20a_channel_abort_clean_up(struct channel_gk20a *ch);
|
||||
void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error);
|
||||
void gk20a_set_error_notifier_locked(struct channel_gk20a *ch, __u32 error);
|
||||
void gk20a_channel_semaphore_wakeup(struct gk20a *g, bool post_events);
|
||||
int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 size,
|
||||
struct priv_cmd_entry *entry);
|
||||
|
||||
@@ -1219,7 +1219,8 @@ static bool gk20a_fifo_set_ctx_mmu_error(struct gk20a *g,
|
||||
if (!ch)
|
||||
return verbose;
|
||||
|
||||
if (ch->error_notifier) {
|
||||
mutex_lock(&ch->error_notifier_mutex);
|
||||
if (ch->error_notifier_ref) {
|
||||
u32 err = ch->error_notifier->info32;
|
||||
if (ch->error_notifier->status == 0xffff) {
|
||||
/* If error code is already set, this mmu fault
|
||||
@@ -1230,10 +1231,12 @@ static bool gk20a_fifo_set_ctx_mmu_error(struct gk20a *g,
|
||||
if (err == NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT)
|
||||
verbose = ch->timeout_debug_dump;
|
||||
} else {
|
||||
gk20a_set_error_notifier(ch,
|
||||
gk20a_set_error_notifier_locked(ch,
|
||||
NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ch->error_notifier_mutex);
|
||||
|
||||
/* mark channel as faulted */
|
||||
ch->has_timedout = true;
|
||||
wmb();
|
||||
|
||||
@@ -678,17 +678,20 @@ static int vgpu_fifo_force_reset_ch(struct channel_gk20a *ch,
|
||||
static void vgpu_fifo_set_ctx_mmu_error(struct gk20a *g,
|
||||
struct channel_gk20a *ch)
|
||||
{
|
||||
if (ch->error_notifier) {
|
||||
mutex_lock(&ch->error_notifier_mutex);
|
||||
if (ch->error_notifier_ref) {
|
||||
if (ch->error_notifier->status == 0xffff) {
|
||||
/* If error code is already set, this mmu fault
|
||||
* was triggered as part of recovery from other
|
||||
* error condition.
|
||||
* Don't overwrite error flag. */
|
||||
} else {
|
||||
gk20a_set_error_notifier(ch,
|
||||
gk20a_set_error_notifier_locked(ch,
|
||||
NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ch->error_notifier_mutex);
|
||||
|
||||
/* mark channel as faulted */
|
||||
ch->has_timedout = true;
|
||||
wmb();
|
||||
|
||||
Reference in New Issue
Block a user