diff options
author | Jagan Teki | 2020-06-10 21:18:23 +0200 |
---|---|---|
committer | Tom Rini | 2020-06-23 14:43:23 -0400 |
commit | 1a027a90aaa65ea429a55035f0316eadd0d83180 (patch) | |
tree | bf08642f32a7a5f6aed5c72a8ffca869f55d7125 /drivers/nvme | |
parent | ccbda9e68093b0c6019b95596366faec2b19442d (diff) |
nvme: Invalidate dcache before submitting admin cmd
This patch try to avoids eviction of dirty lines during DMA
transfer. The code right now execute the following step:
- allocate the buffer
- start a dma operation using the non-coherent dma buffer
- invalidate cache lines associated with the buffer
- read the buffer
This can lead to reading back not valid information, because the cache
controller could evict dirty cache lines belonging to the buffer *after*
the DMA operation has started to fill the DRAM.
In order to avoid this, a new invalidation is required *before* starting
the DMA operation. The patch just adds an invalidation before submitting
the DMA command.
Example below shows the nvme disk scan result without the following
patch
=> nvme scan
nvme_get_info_from_identify: nn = 544502629, vwc = 100,
sn = dev_0T, mn = `�\�, fr = t_part, mdts = 105
So, invalidating the cache before submitting the admin command,
fix the cpu read.
Cc: André Przywara <andre.przywara@arm.com>
Reported-by: Suniel Mahesh <sunil@amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Tested-by: Suniel Mahesh <sunil@amarulasolutions.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/nvme')
-rw-r--r-- | drivers/nvme/nvme.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 0357aba7f11..fc64d93ab83 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -466,6 +466,9 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid, c.identify.cns = cpu_to_le32(cns); + invalidate_dcache_range(dma_addr, + dma_addr + sizeof(struct nvme_id_ctrl)); + ret = nvme_submit_admin_cmd(dev, &c, NULL); if (!ret) invalidate_dcache_range(dma_addr, |