[Linaro-mm-sig] [RFC] dma-shared-buf: Add buffer sharing framework
Daniel Vetter
daniel at ffwll.ch
Thu Sep 1 13:19:33 UTC 2011
On Thu, Aug 11, 2011 at 05:02:21AM -0500, Clark, Rob wrote:
> On Wed, Aug 10, 2011 at 7:11 AM, Sumit Semwal <sumit.semwal at ti.com> wrote:
> >
> > +/**
> > + * struct dma_buf_ops - operations possible on struct dmabuf
> > + * @get_scatterlist: returns list of scatter pages allocated, increases
> > + * usecount of the buffer
> > + * @put_scatterlist: decreases usecount of buffer, might deallocate scatter
> > + * pages
> > + * @mmap: map this buffer
> > + * @read: read from this buffer
> > + * @write: write to this buffer
> > + * @release: release this buffer; to be called after the last dma_buf_put
> > + * @sync_sg_for_cpu: sync the sg list for cpu
> > + * @sync_sg_for_device: synch the sg list for device
> > + */
> > +struct dma_buf_ops {
> > + /* allow buffer to not be pinned when DMA is not happening */
> > + struct scatterlist * (*get_scatterlist)(struct dma_buf *);
> > + void (*put_scatterlist)(struct dma_buf *, struct scatterlist *);
>
> One thought, {get,put}_scatterlist() gives the allocating driver half
> of what it needs to implement a sync object.. ie. if receiving driver
> does a "get" before DMA, and "put" on completion, this tells the
> allocating driver that the buffer is in use. If we added an 'op' to
> get_scatterlist which was READ &/| WRITE this would even tell the
> allocator the nature of the DMA which could later be used to implement
> a wait(op).
>
> Another thought.. at the risk of re-opening a can of worms.. an
> 'attrib' flag/mask as a param to get_scatterlist() could allow the
> allocator to defer backing the buffer w/ real memory until the first
> get_scatterlist() call, for now attrib flag could be discontig,
> contig, and weird (as Hans suggested) and we can try to define more
> precisely "weird" later but for now can have platform specific meaning
> perhaps. This gives a sort of "poor mans negotiation" which might
> help on some platforms for now..
You've probably discussed this all at the recent summit I've totally
missed, but why not add a struct device * pointer argument to
get_scatterlist? This way we could shovel all the platform specific
complexity into platform specific code.
For devices that have different dma requirements depending upon function
(i.e. contigous for scanout, iommu-mapped with large pages for overlay
image) we could use a bunch of subdevices to map all the different
requirements.
Another similar idea could also solve the backing storage negotiation
problem: A dma_buf object is at first just an abstract handle (with a
fixed size), then you can attach users with dma_buf_attach_device.
Then, after all users have themselves attached, the first get_scatterlist
call actually allocates the backing storage for the buffer. A subsequent
attach_device would then return -EBUSY.
This way we don't have a special device that allocates a buffer but
instead all the knowledge about dma buffer handling sits in the platform
specific dma code. With that design get_scatterlist should imo then also
return an already mapped sg list, i.e. what dma_map_sg would return.
Probably rename them to dma_map_buffer/dma_unmap_buffer.
In short, I imagine an api like this (neglecting the actual buffer sharing
part and reference counting boiler plate):
struct dma_buf * dma_buf_create(size_t size);
int dma_buf_attach_device(struct dma_buf *buf, struct device *device);
/* might return -EBUSY to signal that the backing storage is
* already allocated and incompatible with the device's
* requirements */
struct scatterlist *dma_buf_map(struct dma_buf *buf, struct device *device, int *ents);
/* not allowed without a preceeding attach_device */
void dma_buf_unmap(struct dma_buf *buf, struct device *device,
struct scatterlist *sg, int ents);
Yours, Daniel
--
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48
More information about the Linaro-mm-sig
mailing list