Hi Laurent, Please refer to the comments below. On 03/22/2012 12:04 PM, Laurent Pinchart wrote: > Hi Tomasz, > > On Tuesday 13 March 2012 11:17:01 Tomasz Stanislawski wrote: >> From: Sumit Semwal <sumit.semwal@xxxxxx> >> >> This patch makes changes for adding dma-contig as a dma_buf user. It >> provides function implementations for the {attach, detach, map, >> unmap}_dmabuf() mem_ops of DMABUF memory type. >> >> Signed-off-by: Sumit Semwal <sumit.semwal@xxxxxx> >> Signed-off-by: Sumit Semwal <sumit.semwal@xxxxxxxxxx> >> [author of the original patch] >> Signed-off-by: Tomasz Stanislawski <t.stanislaws@xxxxxxxxxxx> >> [integration with refactored dma-contig allocator] >> --- >> drivers/media/video/videobuf2-dma-contig.c | 116 >> ++++++++++++++++++++++++++++ 1 files changed, 116 insertions(+), 0 >> deletions(-) >> >> diff --git a/drivers/media/video/videobuf2-dma-contig.c >> b/drivers/media/video/videobuf2-dma-contig.c index c1dc043..746dd5f 100644 >> --- a/drivers/media/video/videobuf2-dma-contig.c >> +++ b/drivers/media/video/videobuf2-dma-contig.c >> @@ -35,6 +35,9 @@ struct vb2_dc_buf { >> >> /* USERPTR related */ >> struct vm_area_struct *vma; >> + >> + /* DMABUF related */ >> + struct dma_buf_attachment *db_attach; >> }; >> >> /*********************************************/ >> @@ -485,6 +488,115 @@ fail_buf: >> } >> >> /*********************************************/ >> +/* callbacks for DMABUF buffers */ >> +/*********************************************/ >> + >> +static int vb2_dc_map_dmabuf(void *mem_priv) >> +{ >> + struct vb2_dc_buf *buf = mem_priv; >> + struct sg_table *sgt; >> + unsigned long contig_size; >> + int ret = 0; >> + >> + if (WARN_ON(!buf->db_attach)) { >> + printk(KERN_ERR "trying to pin a non attached buffer\n"); >> + return -EINVAL; >> + } >> + >> + if (WARN_ON(buf->dma_sgt)) { >> + printk(KERN_ERR "dmabuf buffer is already pinned\n"); >> + return 0; >> + } >> + >> + /* get the associated scatterlist for this buffer */ >> + sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); >> + if (IS_ERR_OR_NULL(sgt)) { >> + printk(KERN_ERR "Error getting dmabuf scatterlist\n"); >> + return -EINVAL; >> + } > > I've checked why dma_map_sg() was missing from here, and then remembered that > the exporter is still responsible for mapping the buffer to the importer's > device address space :-) I'll raise that topic separately. > >> + >> + /* checking if dmabuf is big enough to store contiguous chunk */ >> + contig_size = vb2_dc_get_contiguous_size(sgt); >> + if (contig_size < buf->size) { >> + printk(KERN_ERR "contiguous chunk of dmabuf is too small\n"); >> + ret = -EFAULT; >> + goto fail_map; >> + } >> + >> + buf->dma_addr = sg_dma_address(sgt->sgl); >> + buf->dma_sgt = sgt; >> + >> + return 0; >> + >> +fail_map: >> + dma_buf_unmap_attachment(buf->db_attach, sgt); >> + >> + return ret; >> +} >> + >> +static void vb2_dc_unmap_dmabuf(void *mem_priv) >> +{ >> + struct vb2_dc_buf *buf = mem_priv; >> + struct sg_table *sgt = buf->dma_sgt; >> + >> + if (WARN_ON(!buf->db_attach)) { >> + printk(KERN_ERR "trying to unpin a not attached buffer\n"); >> + return; >> + } >> + >> + if (WARN_ON(!sgt)) { >> + printk(KERN_ERR "dmabuf buffer is already unpinned\n"); >> + return; >> + } >> + >> + dma_buf_unmap_attachment(buf->db_attach, sgt); >> + >> + buf->dma_addr = 0; >> + buf->dma_sgt = NULL; >> +} >> + >> +static void vb2_dc_detach_dmabuf(void *mem_priv) >> +{ >> + struct vb2_dc_buf *buf = mem_priv; >> + >> + if (buf->dma_addr) >> + vb2_dc_unmap_dmabuf(buf); > > Can detach() be called with the buffer still mapped() ? Wouldn't that be a bug > in the caller ? > No, it is not. The functions from vb2_dc_*_dmabuf are called by vb2-core. It is not a part of DMABUF API itself. Therefore usage can be a bit different. Please refer to the function __qbuf_dmabuf function vb2-core. If new DMABUF is passed to in the QBUF then old DMABUF is released by calling detach_dmabuf without unmap. However, this part of code is probably not reachable if the buffer was not dequeued. Detach without unmap may happen in a case of closing a video fd without prior dequeuing of all buffers. Do you think it would be a good idea to move a call map_dmabuf to __enqueue_in_driver and add calling unmap_dmabuf to vb2_buffer_done? >> + >> + /* detach this attachment */ >> + dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach); >> + kfree(buf); >> +} > > There's nothing allocator-specific in the attach/detach operations. Shouldn't > they be moved to the vb2 core ? > Calling dma_buf_attach could be moved to vb2-core. But it gives little gain. First, the pointer of dma_buf_attachment would have to be added to struct vb2_plane. Second, the allocator would have to keep in the copy of this pointer in its context structure for use of vb2_dc_(un)map_dmabuf functions. Third, dma_buf_attach requires a pointer to 'struct device' which is not available in the vb2-core layer. Because of the mentioned reasons I decided to keep attach_dmabuf in allocator-specific code. >> + >> +static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, >> + unsigned long size, int write) >> +{ >> + struct vb2_dc_buf *buf; >> + struct dma_buf_attachment *dba; >> + >> + if (dbuf->size < size) >> + return ERR_PTR(-EFAULT); >> + >> + buf = kzalloc(sizeof *buf, GFP_KERNEL); >> + if (!buf) >> + return ERR_PTR(-ENOMEM); >> + >> + buf->dev = alloc_ctx; >> + /* create attachment for the dmabuf with the user device */ >> + dba = dma_buf_attach(dbuf, buf->dev); >> + if (IS_ERR(dba)) { >> + printk(KERN_ERR "failed to attach dmabuf\n"); >> + kfree(buf); >> + return dba; >> + } >> + >> + buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; >> + buf->size = size; >> + buf->db_attach = dba; >> + >> + return buf; >> +} >> + >> +/*********************************************/ >> /* DMA CONTIG exported functions */ >> /*********************************************/ >> >> @@ -498,6 +610,10 @@ const struct vb2_mem_ops vb2_dma_contig_memops = { >> .put_userptr = vb2_dc_put_userptr, >> .prepare = vb2_dc_prepare, >> .finish = vb2_dc_finish, >> + .map_dmabuf = vb2_dc_map_dmabuf, >> + .unmap_dmabuf = vb2_dc_unmap_dmabuf, >> + .attach_dmabuf = vb2_dc_attach_dmabuf, >> + .detach_dmabuf = vb2_dc_detach_dmabuf, >> .num_users = vb2_dc_num_users, >> }; >> EXPORT_SYMBOL_GPL(vb2_dma_contig_memops); > Best regards, Tomasz Stanislawski _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel