From 8975fb1f4b2d7c7fc01f88a891c48ef86ddbfba8 Mon Sep 17 00:00:00 2001 From: Sanjith T D Date: Mon, 24 Jul 2023 15:35:04 +0000 Subject: [PATCH] virt_storage: Update calling of ivc_reset() Below race condition can happen during boot 1) Server calls sivc_reset() 2) Storage client driver has IVC event handler registered, so it gets the event and it calls ivc_notified() 3) Server gets ivc event, it calls ivc_notified() ( this makes server local state to established ) 4) Storage cliend driver also goes to established state 5) After this, storage client driver continued with probe() and calls ivc_reset() which results in disconnecting the already established connection. To fix this race condition, perform ivc_reset in storage client driver right after tegra_hv_ivc_reserve() before registering the IVC IRQ handler. Bug 4125055 Change-Id: I36e6db3479f34fb649bdb8d890f24b1783d10cb9 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2943766 GVS: Gerrit_Virtual_Submit Reviewed-by: Manish Bhardwaj Reviewed-by: Sanjith T D Reviewed-by: Vipin Kumar Tested-by: Manish Bhardwaj --- drivers/block/tegra_virt_storage/tegra_hv_vblk.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/block/tegra_virt_storage/tegra_hv_vblk.c b/drivers/block/tegra_virt_storage/tegra_hv_vblk.c index bcae36be..ee059700 100644 --- a/drivers/block/tegra_virt_storage/tegra_hv_vblk.c +++ b/drivers/block/tegra_virt_storage/tegra_hv_vblk.c @@ -1439,7 +1439,7 @@ static int tegra_hv_vblk_probe(struct platform_device *pdev) ret = -ENODEV; goto fail; } - + tegra_hv_ivc_channel_reset(vblkdev->ivck); vblkdev->initialized = false; vblkdev->wq = alloc_workqueue("vblk_req_wq%d", @@ -1478,7 +1478,6 @@ static int tegra_hv_vblk_probe(struct platform_device *pdev) } mutex_lock(&vblkdev->ivc_lock); - tegra_hv_ivc_channel_reset(vblkdev->ivck); if (vblk_send_config_cmd(vblkdev)) { dev_err(dev, "Failed to send config cmd\n"); ret = -EACCES; @@ -1558,11 +1557,6 @@ static int tegra_hv_vblk_suspend(struct device *dev) disable_irq(vblkdev->ivck->irq); flush_workqueue(vblkdev->wq); - - /* Reset the channel */ - mutex_lock(&vblkdev->ivc_lock); - tegra_hv_ivc_channel_reset(vblkdev->ivck); - mutex_unlock(&vblkdev->ivc_lock); } return 0;