From 6a2c18b943951a382b4c04f346af5057089aec1b Mon Sep 17 00:00:00 2001 From: Arihant Jejani Date: Thu, 29 Feb 2024 12:27:14 +0000 Subject: [PATCH] misc: nvscic2c-pcie: fix leak/lock in deinit - Fix missing leak for epc_ctx when probe() fails nvscic2c-pcie-epc - Fix mutex lock/unlock for syncpoint fence operations. Bug 4539983 Change-Id: I18272f991d6d9821ff1a7e13e9b4807cef20d92f Signed-off-by: Arihant Jejani Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3087303 Reviewed-by: Deepak Kumar Badgaiyan Reviewed-by: Vipin Kumar GVS: Gerrit_Virtual_Submit --- drivers/misc/nvscic2c-pcie/comm-channel.c | 5 +++-- drivers/misc/nvscic2c-pcie/endpoint.c | 6 ++++-- drivers/misc/nvscic2c-pcie/epc/module.c | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/misc/nvscic2c-pcie/comm-channel.c b/drivers/misc/nvscic2c-pcie/comm-channel.c index ecc97efe..45977929 100644 --- a/drivers/misc/nvscic2c-pcie/comm-channel.c +++ b/drivers/misc/nvscic2c-pcie/comm-channel.c @@ -414,8 +414,10 @@ fence_do_work(struct work_struct *work) mutex_lock(&syncpt->lock); /* If deinit triggered, no need to proceed. */ - if (syncpt->fence_release) + if (syncpt->fence_release) { + mutex_unlock(&syncpt->lock); return; + } if (syncpt->fence) { dma_fence_put(syncpt->fence); @@ -425,7 +427,6 @@ fence_do_work(struct work_struct *work) ret = allocate_fence(syncpt); if (ret != 0) { - mutex_unlock(&syncpt->lock); pr_err("allocate_fence failed with: %d\n", ret); return; } diff --git a/drivers/misc/nvscic2c-pcie/endpoint.c b/drivers/misc/nvscic2c-pcie/endpoint.c index f84f5ff9..6f7d764b 100644 --- a/drivers/misc/nvscic2c-pcie/endpoint.c +++ b/drivers/misc/nvscic2c-pcie/endpoint.c @@ -598,6 +598,7 @@ allocate_fence(struct syncpt_t *syncpt) mutex_lock(&syncpt->lock); ret = dma_fence_add_callback(fence, &syncpt->fence_cb, host1x_cb_func); if (ret != 0) { + /* If already expired. */ if (ret == -ENOENT) { ret = 0; schedule_work(&syncpt->work); @@ -626,8 +627,10 @@ fence_do_work(struct work_struct *work) mutex_lock(&syncpt->lock); /* If deinit triggered, no need to proceed. */ - if (syncpt->fence_release) + if (syncpt->fence_release) { + mutex_unlock(&syncpt->lock); return; + } if (syncpt->fence) { dma_fence_put(syncpt->fence); syncpt->fence = NULL; @@ -636,7 +639,6 @@ fence_do_work(struct work_struct *work) ret = allocate_fence(syncpt); if (ret != 0) { - mutex_unlock(&syncpt->lock); pr_err("allocate_fence failed with: %d\n", ret); return; } diff --git a/drivers/misc/nvscic2c-pcie/epc/module.c b/drivers/misc/nvscic2c-pcie/epc/module.c index 78c7b164..4dacf120 100644 --- a/drivers/misc/nvscic2c-pcie/epc/module.c +++ b/drivers/misc/nvscic2c-pcie/epc/module.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include @@ -491,6 +491,7 @@ err_enable_device: err_dt_parse: pci_set_drvdata(pdev, NULL); + kfree(drv_ctx->epc_ctx); kfree_const(drv_ctx->drv_name); kfree(drv_ctx); return ret;