mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-25 10:42:21 +03:00
nvdla: kmd: synchronize PING across many clients
[1] When the multiple clients try to ping at the same time, the
KMD errors out for all clients except one. This behavior
is expected since there is only one command memory and the
KMD errors out when that memory is busy.
[2] This commit fixes the issue by synchronizing the ping operations
across all the clients by introducing a lock.
[3] Alternatively Increasing MAX_COMMANDS_PER_DEVICE will work but
not optimal since,
- the ping is an INIT mode operation.
- the ping operation is inexpensive => the memory is immediately
available even if locked.
- the overall memory allocation will increase.
Considering the use case is rare, the synchronization of ping across
multiple clients is preferred.
Change-Id: I012efd18554a85bb31b79b98bf83386b37251d32
Signed-off-by: Arvind M <am@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2813197
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Amit Sharma (SW-TEGRA) <amisharma@nvidia.com>
Reviewed-by: Ken Adams <kadams@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
c7726fd7d3
commit
103da69059
@@ -838,6 +838,7 @@ static int nvdla_probe(struct platform_device *pdev)
|
||||
mutex_init(&pdata->lock);
|
||||
mutex_init(&nvdla_dev->cmd_lock);
|
||||
init_completion(&nvdla_dev->cmd_completion);
|
||||
mutex_init(&nvdla_dev->ping_lock);
|
||||
pdata->private_data = nvdla_dev;
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
nvdla_dev->dbg_mask = debug_err;
|
||||
@@ -900,6 +901,7 @@ err_client_device_init:
|
||||
nvhost_module_deinit(pdev);
|
||||
err_module_init:
|
||||
err_get_resources:
|
||||
mutex_destroy(&nvdla_dev->ping_lock);
|
||||
devm_kfree(dev, nvdla_dev);
|
||||
err_alloc_nvdla:
|
||||
err_no_ip:
|
||||
@@ -928,7 +930,7 @@ static int __exit nvdla_remove(struct platform_device *pdev)
|
||||
nvdla_queue_deinit(nvdla_dev->pool);
|
||||
nvhost_client_device_release(pdev);
|
||||
nvhost_module_deinit(pdev);
|
||||
|
||||
mutex_destroy(&nvdla_dev->ping_lock);
|
||||
nvdla_free_gcov_region(pdev, false);
|
||||
|
||||
if (nvdla_dev->trace_dump_pa) {
|
||||
|
||||
@@ -243,6 +243,7 @@ enum nvdla_submit_mode {
|
||||
* @gcov_dump_pa physical address of fw gcov buffer
|
||||
* @gcov_dump_va virtual address of fw gcovbuffer
|
||||
* @is_suspended flag to check if module is in suspend state.
|
||||
* @ping_lock lock to synchronize the ping operation requests.
|
||||
*/
|
||||
struct nvdla_device {
|
||||
struct platform_device *pdev;
|
||||
@@ -269,6 +270,7 @@ struct nvdla_device {
|
||||
#ifdef CONFIG_PM
|
||||
bool is_suspended;
|
||||
#endif
|
||||
struct mutex ping_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -258,6 +258,8 @@ static int nvdla_ping(struct platform_device *pdev,
|
||||
{
|
||||
struct nvdla_cmd_mem_info ping_cmd_mem_info;
|
||||
struct nvdla_cmd_data cmd_data;
|
||||
struct nvhost_device_data *pdata = platform_get_drvdata(pdev);
|
||||
struct nvdla_device *nvdla_dev = pdata->private_data;
|
||||
u32 *ping_va;
|
||||
int err = 0;
|
||||
|
||||
@@ -275,6 +277,14 @@ static int nvdla_ping(struct platform_device *pdev,
|
||||
goto fail_to_on;
|
||||
}
|
||||
|
||||
if (nvdla_dev == NULL) {
|
||||
nvdla_dbg_err(pdev, "Invalid nvdla device\n");
|
||||
err = -EINVAL;
|
||||
goto fail_to_get_nvdla_dev;
|
||||
}
|
||||
|
||||
mutex_lock(&nvdla_dev->ping_lock);
|
||||
|
||||
/* assign ping cmd buffer */
|
||||
err = nvdla_get_cmd_memory(pdev, &ping_cmd_mem_info);
|
||||
if (err) {
|
||||
@@ -313,6 +323,8 @@ static int nvdla_ping(struct platform_device *pdev,
|
||||
fail_cmd:
|
||||
nvdla_put_cmd_memory(pdev, ping_cmd_mem_info.index);
|
||||
fail_to_alloc:
|
||||
mutex_unlock(&nvdla_dev->ping_lock);
|
||||
fail_to_get_nvdla_dev:
|
||||
nvhost_module_idle(pdev);
|
||||
fail_to_on:
|
||||
fail_to_get_val_arg:
|
||||
|
||||
Reference in New Issue
Block a user