From 45a0155889ec181ff6c972b661f3e066f0cc4dfc Mon Sep 17 00:00:00 2001 From: Sanjith T D Date: Mon, 14 Apr 2025 10:41:54 +0000 Subject: [PATCH] vblk: Pass correct direction for DMA map/unmap The tegra_hv_vblk driver use DMA_BIDIRECTIONAL in dma_map/dma_unmap for both read and write. It could add unnecessary CMO for cpu/for device (depends on R/W). Fixed this by passing the correct direction for DMA map/unmap based on read/write operation. Bug 5221800 Change-Id: Ieee50fa66c18a8e1bf23db749eba0c5f2d3745b2 Signed-off-by: Sanjith T D Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3340025 Reviewed-by: mobile promotions Reviewed-by: svcacv Tested-by: mobile promotions GVS: buildbot_gerritrpt Reviewed-by: Vipin Kumar Reviewed-by: Sreenivas Velpula --- drivers/block/tegra_virt_storage/tegra_hv_vblk.c | 15 +++++++++++++-- drivers/block/tegra_virt_storage/tegra_vblk.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/block/tegra_virt_storage/tegra_hv_vblk.c b/drivers/block/tegra_virt_storage/tegra_hv_vblk.c index 7a6ecf79..7382c6e6 100644 --- a/drivers/block/tegra_virt_storage/tegra_hv_vblk.c +++ b/drivers/block/tegra_virt_storage/tegra_hv_vblk.c @@ -360,7 +360,7 @@ end: dma_unmap_sg(vblkdev->device, vsc_req->sg_lst, vsc_req->sg_num_ents, - DMA_BIDIRECTIONAL); + vsc_req->dma_direction); devm_kfree(vblkdev->device, vsc_req->sg_lst); } } @@ -531,6 +531,16 @@ static enum blk_cmd_op cleanup_op_supported(struct vblk_dev *vblkdev, uint32_t o return cleanup_op; } +static enum dma_data_direction get_dma_data_direction(struct request *bio_req) +{ + if (req_op(bio_req) == REQ_OP_READ) + return DMA_FROM_DEVICE; + else if (req_op(bio_req) == REQ_OP_WRITE) + return DMA_TO_DEVICE; + else + return DMA_NONE; +} + /** * submit_bio_req: Fetch a bio request and submit it to * server for processing. @@ -602,8 +612,9 @@ static bool submit_bio_req(struct vblk_dev *vblkdev) vsc_req->sg_lst); #endif vsc_req->sg_num_ents = sg_nents(vsc_req->sg_lst); + vsc_req->dma_direction = get_dma_data_direction(bio_req); if (dma_map_sg(vblkdev->device, vsc_req->sg_lst, - vsc_req->sg_num_ents, DMA_BIDIRECTIONAL) == 0) { + vsc_req->sg_num_ents, vsc_req->dma_direction) == 0) { dev_err(vblkdev->device, "dma_map_sg failed\n"); goto bio_exit; } diff --git a/drivers/block/tegra_virt_storage/tegra_vblk.h b/drivers/block/tegra_virt_storage/tegra_vblk.h index 455ba14b..2f2765d2 100644 --- a/drivers/block/tegra_virt_storage/tegra_vblk.h +++ b/drivers/block/tegra_virt_storage/tegra_vblk.h @@ -70,6 +70,7 @@ struct vsc_request { /* Timer to track bio request completion*/ struct timer_list timer; uint64_t time; + enum dma_data_direction dma_direction; }; enum vblk_queue_state {