dla: kmd: fix race between reset and submission

[1] Prior to this commit, the reset may happen in parallel with the
    submissions. This results in timeout during the falcon boot.
[2] This commit manages the availability status to ensure that,
    the submissions fail gracefully when the reset is in progress.

Bug 4252264

Change-Id: I499fbb742165f0584cafed00fd0c9f8a0ef47e65
Signed-off-by: Arvind M <am@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3046052
(cherry picked from commit ed8345cf3dd8942ef680e9c9bb63ea145dfb517b)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3182574
Reviewed-by: Ken Adams <kadams@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Akshata Bhat <akshatab@nvidia.com>
This commit is contained in:
Arvind M
2024-01-04 07:30:16 -08:00
committed by Jon Hunter
parent 17ef98bafa
commit cd5a44401b
2 changed files with 28 additions and 3 deletions

View File

@@ -310,6 +310,15 @@ int nvdla_send_cmd(struct platform_device *pdev,
mutex_lock(&nvdla_dev->cmd_lock); mutex_lock(&nvdla_dev->cmd_lock);
/**
* If device is unavailable, then error out to retry after some time.
**/
if (!nvdla_dev->available) {
nvdla_dbg_err(pdev, "Command failed: device unavailable\n");
mutex_unlock(&nvdla_dev->cmd_lock);
return -EAGAIN;
}
/* /*
* enable notification for command completion or error if * enable notification for command completion or error if
* wait if required * wait if required
@@ -650,6 +659,13 @@ int nvhost_nvdla_finalize_poweron(struct platform_device *pdev)
nvdla_dev->fw_version = fw_ver_read_bin; nvdla_dev->fw_version = fw_ver_read_bin;
/**
* At this point, the falcon & hardware is available to use.
**/
mutex_lock(&nvdla_dev->cmd_lock);
nvdla_dev->available = true;
mutex_unlock(&nvdla_dev->cmd_lock);
ret = nvdla_alloc_dump_region(pdev); ret = nvdla_alloc_dump_region(pdev);
if (ret) { if (ret) {
nvdla_dbg_err(pdev, "fail alloc dump region\n"); nvdla_dbg_err(pdev, "fail alloc dump region\n");
@@ -676,8 +692,16 @@ int nvhost_nvdla_prepare_poweroff(struct platform_device *pdev)
{ {
int ret; int ret;
struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
struct nvdla_device *nvdla_dev = pdata->private_data;
nvdla_dbg_fn(pdev, ""); nvdla_dbg_fn(pdev, "");
/* Mark the device to be unavailable. */
mutex_lock(&nvdla_dev->cmd_lock);
nvdla_dev->available = false;
mutex_unlock(&nvdla_dev->cmd_lock);
ret = nvhost_flcn_prepare_poweroff(pdev); ret = nvhost_flcn_prepare_poweroff(pdev);
if (ret) { if (ret) {
nvdla_dbg_err(pdev, "failed to poweroff\n"); nvdla_dbg_err(pdev, "failed to poweroff\n");

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: LicenseRef-NvidiaProprietary */
/* /* SPDX-FileCopyrightText: Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* Copyright (c) 2016-2023 NVIDIA Corporation. All rights reserved.
* *
* Tegra Graphics Host NVDLA * Tegra Graphics Host NVDLA
*/ */
@@ -279,6 +278,7 @@ enum nvdla_submit_mode {
* @window_mem_va virtual address of window size buffer * @window_mem_va virtual address of window size buffer
* @is_suspended flag to check if module is in suspend state. * @is_suspended flag to check if module is in suspend state.
* @ping_lock lock to synchronize the ping operation requests. * @ping_lock lock to synchronize the ping operation requests.
* @avaiable flag to check if device is available to use.
*/ */
struct nvdla_device { struct nvdla_device {
struct device *dev; struct device *dev;
@@ -312,6 +312,7 @@ struct nvdla_device {
bool is_suspended; bool is_suspended;
#endif #endif
struct mutex ping_lock; struct mutex ping_lock;
bool available;
}; };
/** /**