gpu: nvgpu: retry MMU fault buffer read

When handling MMU faults, retry the first MMU fault buffer read multiple
times until it contains valid data. There may be a delay between the MMU
fault interrupt triggering and the fault buffer containing valid data.

Jira NVGPU-9217

Change-Id: I06b442acaf54a4e036795de65345b423f9b424bf
Signed-off-by: Austin Tajiri <atajiri@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2881909
Reviewed-by: Rajesh Devaraj <rdevaraj@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Austin Tajiri
2023-04-03 20:11:19 +00:00
committed by mobile promotions
parent a321679a5d
commit 7e0351f291

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -49,6 +49,9 @@
#include "hal/fb/fb_mmu_fault_gv11b.h"
#include "hal/mm/mmu_fault/mmu_fault_gv11b.h"
#define NVGPU_MMU_FAULT_BUFFER_READ_DELAY 10U
#define NVGPU_MMU_FAULT_BUFFER_READ_ITERS 20U
#ifdef CONFIG_NVGPU_REPLAYABLE_FAULT
static int gv11b_fb_fix_page_fault(struct gk20a *g,
struct mmu_fault_info *mmufault);
@@ -608,6 +611,34 @@ void gv11b_mm_mmu_fault_handle_nonreplay_replay_fault(struct gk20a *g,
rd32_val = nvgpu_mem_rd32(g, mem,
nvgpu_safe_add_u32(offset, gmmu_fault_buf_entry_valid_w()));
if (!nvgpu_platform_is_silicon(g)) {
/*
* In sim environments, there may be a delay between the MMU
* fault interrupt triggering and the MMU fault buffer containing
* valid data, try reading the fault buffer entry's valid bit
* multiple times until it is set.
*/
u32 iters = NVGPU_MMU_FAULT_BUFFER_READ_ITERS;
do {
if (((rd32_val & gmmu_fault_buf_entry_valid_m()) != 0U)) {
break;
}
if (--iters == 0U) {
break;
}
nvgpu_udelay(NVGPU_MMU_FAULT_BUFFER_READ_DELAY);
rd32_val = nvgpu_mem_rd32(g, mem,
nvgpu_safe_add_u32(offset, gmmu_fault_buf_entry_valid_w()));
} while (true);
if (iters == 0U) {
nvgpu_err(g, "timeout waiting for valid fault buffer entry");
return;
}
}
nvgpu_log(g, gpu_dbg_intr, "entry valid offset val = 0x%x", rd32_val);
gv11b_mm_mmu_fault_handle_buf_valid_entry(g, mem, mmufault,