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 <jay.xu@rock-chips.com>
Change-Id: Ib5d0715c4bde95bc444d6fbb873456c94755f550
This commit is contained in:
Jianqun Xu
2022-07-05 19:14:24 +08:00
committed by Tao Huang
parent 4925881228
commit 3212cfb965

View File

@@ -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;