From c6da5975142af516d445a87af390b9b9e8925339 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Wed, 2 Jul 2025 15:31:37 +0800 Subject: [PATCH] vi5: fix vi5_channel_error_recover memory leak release chan->request_iova and also chan->emb_buf memory Bug 5371485 Change-Id: I6e2642733a222a85b2f7d6814716835afc921948 Signed-off-by: Jerry Chang Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3403484 (cherry picked from commit f7d53151d1ed7536f9c920a5f3b1ad54f9d8fe32) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3443797 GVS: buildbot_gerritrpt Reviewed-by: svcacv Reviewed-by: Narendra Kondapalli --- .../media/platform/tegra/camera/vi/vi5_fops.c | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/media/platform/tegra/camera/vi/vi5_fops.c b/drivers/media/platform/tegra/camera/vi/vi5_fops.c index c68751f8..e458f33d 100644 --- a/drivers/media/platform/tegra/camera/vi/vi5_fops.c +++ b/drivers/media/platform/tegra/camera/vi/vi5_fops.c @@ -626,6 +626,9 @@ rel_buf: vi5_release_buffer(chan, buf); } +static void vi5_unit_get_device_handle(struct platform_device *pdev, + uint32_t csi_stream_id, struct device **dev); + static int vi5_channel_error_recover(struct tegra_channel *chan, bool queue_error) { @@ -644,6 +647,25 @@ static int vi5_channel_error_recover(struct tegra_channel *chan, dev_err(&chan->video->dev, "vi capture release failed\n"); goto done; } + + /* Release capture requests */ + if (chan->request[vi_port] != NULL) { + dma_free_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev, + chan->capture_queue_depth * sizeof(struct capture_descriptor), + chan->request[vi_port], chan->request_iova[vi_port]); + } + chan->request[vi_port] = NULL; + + /* Release emd data buffers */ + if (chan->emb_buf_size > 0) { + struct device *vi_unit_dev; + + vi5_unit_get_device_handle(chan->vi->ndev, chan->port[0], &vi_unit_dev); + dma_free_coherent(vi_unit_dev, chan->emb_buf_size, + chan->emb_buf_addr, chan->emb_buf); + chan->emb_buf_size = 0; + } + vi_channel_close_ex(chan->vi_channel_id[vi_port], chan->tegra_vi_channel[vi_port]); chan->tegra_vi_channel[vi_port] = NULL;