From 3212cfb965baa09f6e8bbbef2ca2ed7034031343 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Tue, 5 Jul 2022 19:14:24 +0800 Subject: [PATCH] dma-buf: heaps: system_heap: partial sync with sgtable from heap buffer The dma-heap will allocate a scatterlist table at alloc time and store into the heap buffer. Usually a device should attach to the dmabuf and then map the dmabuf with the attachment, a new scatterlist table will be created and set during dma map. In the dma map, the sg_dma_address will be set for the first scatter of the scatterlist table, if the device has a iommu domain, sg_dma_address is set with the iova start address, else it will be set with a physical address. For a dmabuf hasn't been dma mapped, the sg_dma_address is a error value (-1 = DMA_MAPPING_ERROR). The partial sync hits the case that no device mapped to the dmabuf. It's not easy to support both iommu/no iommu devices for partial sync, this patch make the partial sync simple to implement for no iommu case. Signed-off-by: Jianqun Xu Change-Id: Ib5d0715c4bde95bc444d6fbb873456c94755f550 --- drivers/dma-buf/heaps/system_heap.c | 54 +++++++++-------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 6b7f1ad0178b..7bb7723f0cb8 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -272,8 +272,9 @@ system_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, unsigned int len) { struct system_heap_buffer *buffer = dmabuf->priv; - struct dma_heap_attachment *a; - int ret = 0; + struct dma_heap *heap = buffer->heap; + struct sg_table *table = &buffer->sg_table; + int ret; if (direction == DMA_TO_DEVICE) return 0; @@ -282,25 +283,13 @@ system_heap_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, if (buffer->vmap_cnt) invalidate_kernel_vmap_range(buffer->vaddr, buffer->len); - if (buffer->uncached) - goto unlock; - - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - - ret = system_heap_sgl_sync_range(a->dev, a->table, offset, len, - direction, true); + if (buffer->uncached) { + mutex_unlock(&buffer->lock); + return 0; } - if (list_empty(&buffer->attachments)) { - struct dma_heap *heap = buffer->heap; - struct sg_table *table = &buffer->sg_table; - ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table, - offset, len, - direction, true); - } -unlock: + ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table, + offset, len, direction, true); mutex_unlock(&buffer->lock); return ret; @@ -313,32 +302,21 @@ system_heap_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, unsigned int len) { struct system_heap_buffer *buffer = dmabuf->priv; - struct dma_heap_attachment *a; - int ret = 0; + struct dma_heap *heap = buffer->heap; + struct sg_table *table = &buffer->sg_table; + int ret; mutex_lock(&buffer->lock); if (buffer->vmap_cnt) flush_kernel_vmap_range(buffer->vaddr, buffer->len); - if (buffer->uncached) - goto unlock; - - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - - ret = system_heap_sgl_sync_range(a->dev, a->table, offset, len, - direction, false); + if (buffer->uncached) { + mutex_unlock(&buffer->lock); + return 0; } - if (list_empty(&buffer->attachments)) { - struct dma_heap *heap = buffer->heap; - struct sg_table *table = &buffer->sg_table; - ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table, - offset, len, - direction, false); - } -unlock: + ret = system_heap_sgl_sync_range(dma_heap_get_dev(heap), table, + offset, len, direction, false); mutex_unlock(&buffer->lock); return ret;