From patchwork Tue Oct 11 09:23:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Semwal, Sumit" X-Patchwork-Id: 8110 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1RDYak-0006SN-NC; Tue, 11 Oct 2011 11:25:44 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-2) with esmtp id 1RDYaj-00053g-I6; Tue, 11 Oct 2011 11:25:42 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754204Ab1JKJZM (ORCPT + 3 others); Tue, 11 Oct 2011 05:25:12 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:40388 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754130Ab1JKJZK (ORCPT ); Tue, 11 Oct 2011 05:25:10 -0400 Received: from dlep33.itg.ti.com ([157.170.170.112]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id p9B9Ops4013213 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 11 Oct 2011 04:24:51 -0500 Received: from DLEE74.ent.ti.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep33.itg.ti.com (8.13.7/8.13.8) with ESMTP id p9B9OpeD002380; Tue, 11 Oct 2011 04:24:51 -0500 (CDT) Received: from dlelxv23.itg.ti.com (172.17.1.198) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Tue, 11 Oct 2011 04:24:50 -0500 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by dlelxv23.itg.ti.com (8.13.8/8.13.8) with ESMTP id p9B9OoZZ003918; Tue, 11 Oct 2011 04:24:50 -0500 Received: from localhost (a0876505ubnlt.apr.dhcp.ti.com [172.24.136.164]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id p9B9Oj023527; Tue, 11 Oct 2011 04:24:45 -0500 (CDT) From: Sumit Semwal To: , , , , , CC: , , , , , , , Sumit Semwal , Sumit Semwal Subject: [RFC 2/2] dma-buf: Documentation for buffer sharing framework Date: Tue, 11 Oct 2011 14:53:53 +0530 Message-ID: <1318325033-32688-3-git-send-email-sumit.semwal@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1318325033-32688-1-git-send-email-sumit.semwal@ti.com> References: <1318325033-32688-1-git-send-email-sumit.semwal@ti.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2011.10.11.91515 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, MSGID_ADDED_BY_MTA 0.05, DOMAIN_OBFU_DOT 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __CT 0, __CT_TEXT_PLAIN 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MULTIPLE_RCPTS_CC_X2 0, __MULTIPLE_RCPTS_TO_X5 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' X-LSpam-Score: 1.0 (+) X-LSpam-Report: No, score=1.0 required=5.0 tests=BAYES_00=-1.9, KB_DATE_CONTAINS_TAB=2.751, RCVD_IN_DNSWL_MED=-2.3, TAB_IN_FROM=2.494 autolearn=no Add documentation for dma buffer sharing framework, explaining the various operations, members and API of the dma buffer sharing framework. Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal --- Documentation/dma-buf-sharing.txt | 210 +++++++++++++++++++++++++++++++++++++ 1 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 Documentation/dma-buf-sharing.txt diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt new file mode 100644 index 0000000..4da6644 --- /dev/null +++ b/Documentation/dma-buf-sharing.txt @@ -0,0 +1,210 @@ + DMA Buffer Sharing API Guide + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Sumit Semwal + + + +This document serves as a guide to device-driver writers on what is the dma-buf +buffer sharing API, how to use it for exporting and using shared buffers. + +Any device driver which wishes to be a part of dma buffer sharing, can do so as +either the 'exporter' of buffers, or the 'user' of buffers. + +Say a driver A wants to use buffers created by driver B, then we call B as the +exporter, and B as buffer-user. + +The exporter +- implements and manages operations[1] for the buffer +- allows other users to share the buffer by using dma_buf sharing APIs, +- manages the details of buffer allocation, +- decides about the actual backing storage where this allocation happens, +- takes care of any migration of scatterlist - for all (shared) users of this + buffer, +- optionally, provides mmap capability for drivers that need it. + +The buffer-user +- is one of (many) sharing users of the buffer. +- doesn't need to worry about how the buffer is allocated, or where. +- needs a mechanism to get access to the scatterlist that makes up this buffer + in memory, mapped into its own address space, so it can access the same area + of memory. + + +The dma_buf buffer sharing API usage contains the following steps: + +1. Exporter announces that it wishes to export a buffer +2. Userspace gets the file descriptor associated with the exported buffer, and + passes it around to potential buffer-users based on use case +3. Each buffer-user 'connects' itself to the buffer +4. When needed, buffer-user requests access to the buffer from exporter +5. When finished with its use, the buffer-user notifies end-of-dma to exporter +6. when buffer-user is done using this buffer completely, it 'disconnects' + itself from the buffer. + + +1. Exporter's announcement of buffer export + + The buffer exporter announces its wish to export a buffer. In this, it + connects its own private buffer data, provides implementation for operations + that can be performed on the exported dma_buf, and flags for the file + associated with this buffer. + + Interface: + struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops, + int flags) + + If this succeeds, dma_buf_export allocates a dma_buf structure, and returns a + pointer to the same. It also associates an anon file with this buffer, so it + can be exported. On failure to allocate the dma_buf object, it returns NULL. + +2. Userspace gets a handle to pass around to potential buffer-users + + Userspace entity requests for a file-descriptor (fd) which is a handle to the + anon file associated with the buffer. It can then share the fd with other + drivers and/or processes. + + Interface: + int dma_buf_fd(struct dma_buf *dmabuf) + + This API installs an fd for the anon file associated with this buffer; + returns either 'fd', or error. + +3. Each buffer-user 'connects' itself to the buffer + + Each buffer-user now gets a reference to the buffer, using the fd passed to + it. + + Interface: + struct dma_buf *dma_buf_get(int fd) + + This API will return a reference to the dma_buf, and increment refcount for + it. + + After this, the buffer-user needs to attach its device with the buffer, which + helps the exporter to know of device buffer constraints. + + Interface: + struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, + struct device *dev) + + This API returns reference to an attachment structure, which is then used + for scatterlist operations. It will optionally call the 'attach' dma_buf + operation, if provided by the exporter. + + The dma-buf sharing framework does the book-keeping bits related to keeping + the list of all attachments to a buffer. + +Till this stage, the buffer-exporter has the option to choose not to actually +allocate the backing storage for this buffer, but wait for the first buffer-user +to request use of buffer for allocation. + + +4. When needed, buffer-user requests access to the buffer + + Whenever a buffer-user wants to use the buffer for any dma, it asks for + access to the buffer using dma_buf->ops->get_scatterlist operation. Atleast + one attach to the buffer should have happened before get_scatterlist can be + called. + + Interface: [member of struct dma_buf_ops] + struct scatterlist * (*get_scatterlist)(struct dma_buf_attachment *, + enum dma_data_direction, + int* nents); + + It is one of the buffer operations that must be implemented by the exporter. + It should return the scatterlist for this buffer, mapped into caller's address + space. + + If this is being called for the first time, the exporter can now choose to + scan through the list of attachments for this buffer, collate the requirements + of the attached devices, and choose an appropriate backing storage for the + buffer. + + Based on enum dma_data_direction, it might be possible to have multiple users + accessing at the same time (for reading, maybe), or any other kind of sharing + that the exporter might wish to make available to buffer-users. + + +5. When finished, the buffer-user notifies end-of-dma to exporter + + Once the dma for the current buffer-user is over, it signals 'end-of-dma' to + the exporter using the dma_buf->ops->put_scatterlist() operation. + + Interface: + void (*put_scatterlist)(struct dma_buf_attachment *, struct scatterlist *, + int nents); + + put_scatterlist signifies the end-of-dma for the attachment provided. + + +6. when buffer-user is done using this buffer, it 'disconnects' itself from the + buffer. + + After the buffer-user has no more interest in using this buffer, it should + disconnect itself from the buffer: + + - it first detaches itself from the buffer. + + Interface: + void dma_buf_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *dmabuf_attach); + + This API removes the attachment from the list in dmabuf, and optionally calls + dma_buf->ops->detach(), if provided by exporter, for any housekeeping bits. + + - Then, the buffer-user returns the buffer reference to exporter. + + Interface: + void dma_buf_put(struct dma_buf *dmabuf); + + This API then reduces the refcount for this buffer. + + If, as a result of this call, the refcount becomes 0, the 'release' file + operation related to this fd is called. It calls the dmabuf->ops->release() + operation in turn, and frees the memory allocated for dmabuf when exported. + +NOTES: +- Importance of attach-detach and {get,put}_scatterlist operation pairs + The attach-detach calls allow the exporter to figure out backing-storage + constraints for the currently-interested devices. This allows preferential + allocation, and/or migration of pages across different types of storage + available, if possible. + + Bracketing of dma access with {get,put}_scatterlist operations is essential + to allow just-in-time backing of storage, and migration mid-way through a + use-case. + +- Migration of backing storage if needed + After + - atleast one get_scatterlist has happened, + - and the backing storage has been allocated for this buffer, + If another new buffer-user intends to attach itself to this buffer, it might + be allowed, if possible for the exporter. + + In case it is allowed by the exporter: + if the new buffer-user has stricter 'backing-storage constraints', and the + exporter can handle these constraints, the exporter can just stall on the + get_scatterlist till all outstanding access is completed (as signalled by + put_scatterlist). + Once all ongoing access is completed, the exporter could potentially move + the buffer to the stricter backing-storage, and then allow further + {get,put}_scatterlist operations from any buffer-user from the migrated + backing-storage. + + If the exporter cannot fulfill the backing-storage constraints of the new + buffer-user device as requested, dma_buf_attach() would return an error to + denote non-compatibility of the new buffer-sharing request with the current + buffer. + + If the exporter chooses not to allow an attach() operation once a + get_scatterlist has been called, it simply returns an error. + +- mmap file operation + An mmap() file operation is provided for the fd associated with the buffer. + If the exporter defines an mmap operation, the mmap() fop calls this to allow + mmap for devices that might need it; if not, it returns an error. + +References: +[1] struct dma_buf_ops in include/linux/dma-buf.h +[2] All interfaces mentioned above defined in include/linux/dma-buf.h