From patchwork Fri Oct 10 20:07:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sumit Semwal X-Patchwork-Id: 26394 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1XcgUl-0005lI-K9; Fri, 10 Oct 2014 22:08:59 +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.72/mailfrontend-7) with esmtp id 1XcgUh-00070z-2R; Fri, 10 Oct 2014 22:08:57 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754981AbaJJUIk (ORCPT + 1 other); Fri, 10 Oct 2014 16:08:40 -0400 Received: from mail-pd0-f173.google.com ([209.85.192.173]:63912 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754916AbaJJUIi (ORCPT ); Fri, 10 Oct 2014 16:08:38 -0400 Received: by mail-pd0-f173.google.com with SMTP id g10so2238708pdj.32 for ; Fri, 10 Oct 2014 13:08:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nVYyYAhvizR3BI9UADDC2EFPbFkmJPQtPHSVSDUVmO4=; b=V9ZJfjd+DAsDirr9/RpfdiaO8vgD7VI4eL4nf5fcjP9NE+V7hFlq+ySzUBytKRNu0/ m4Q9bd7+gb0QhCtNqIwRx/6q/coH8k06hPf/GPPx5HC9bgiRIqSGyBfuJfZGZkYaH634 Sc5hPKGWdGNYVEbSk/R99LU2kBH5HOAKrEpdVHs0bRaX5Yh26rYSo492JK5cRruMV97d n14Ct43ZlN/C+gjmAhaPBiWiZEE1egIZEYdrcCiUi6rpVZ240XW02cwcWKYKyEKy9FuJ JSEpezIQYfbZjTBmTGZ5+goPuK5gXysiRd5OL2c3zxSWnYjN2wWqzwhS1+EDrn5MPAlf mWGA== X-Gm-Message-State: ALoCoQl35g2GS68OpGhSdJ4DI0OUYued/Mfc5uC1aRUK6XW5STRK30dm0X6sY+VmwGM1gigxhkSm X-Received: by 10.70.53.202 with SMTP id d10mr7636746pdp.60.1412971718176; Fri, 10 Oct 2014 13:08:38 -0700 (PDT) Received: from localhost.localdomain ([103.227.99.153]) by mx.google.com with ESMTPSA id ap5sm4365463pad.22.2014.10.10.13.08.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Oct 2014 13:08:37 -0700 (PDT) From: Sumit Semwal To: linux-kernel@vger.kernel.org Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linaro-kernel@lists.linaro.org, Sumit Semwal , Greg Kroah-Hartman Subject: [RFC 1/4] dma-buf: Add constraints sharing information Date: Sat, 11 Oct 2014 01:37:55 +0530 Message-Id: <1412971678-4457-2-git-send-email-sumit.semwal@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1412971678-4457-1-git-send-email-sumit.semwal@linaro.org> References: <1412971678-4457-1-git-send-email-sumit.semwal@linaro.org> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2014.10.10.195720 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __STOCK_PHRASE_7 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS , __YOUTUBE_RCVD 0' At present, struct device lacks a mechanism of exposing memory access constraints for the device. Consequently, there is also no mechanism to share these constraints while sharing buffers using dma-buf. If we add support for sharing such constraints, we could use that to try to collect requirements of different buffer-sharing devices to allocate buffers from a pool that satisfies requirements of all such devices. This is an attempt to add this support; at the moment, only a bitmask is added, but if post discussion, we realise we need more information, we could always extend the definition of constraint. A new dma-buf op is also added, to allow exporters to interpret or decide on constraint-masks on their own. A default implementation is provided to just AND (&) all the constraint-masks. What constitutes a constraint-mask could be left for interpretation on a per-platform basis, while defining some common masks. Signed-off-by: Sumit Semwal Cc: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org --- drivers/dma-buf/dma-buf.c | 50 ++++++++++++++++++++++++++++++++++++++++++----- include/linux/device.h | 7 ++++++- include/linux/dma-buf.h | 14 +++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index f3014c4..33bdb6a 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -264,6 +264,30 @@ static inline int is_dma_buf_file(struct file *file) return file->f_op == &dma_buf_fops; } +/* + * def_calc_access_constraints - default implementation of constraint checking + */ +static int def_calc_access_constraints(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) +{ + unsigned long access_mask; + + access_mask = attach->dev->dma_parms->access_constraints_mask; + + if (!access_mask) { + pr_warn("%s dev has no access_constraints_mask; using default\n", + dev_name(attach->dev)); + access_mask = DMA_BUF_ALL_MEMORY_ACCESS_MASK; + } + + dmabuf->access_constraints_mask &= access_mask; + + if (!dmabuf->access_constraints_mask) + return -EINVAL; + + return 0; +} + /** * dma_buf_export_named - Creates a new dma_buf, and associates an anon file * with this buffer, so it can be exported. @@ -313,6 +337,8 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, dmabuf->ops = ops; dmabuf->size = size; dmabuf->exp_name = exp_name; + dmabuf->access_constraints_mask = DMA_BUF_ALL_MEMORY_ACCESS_MASK; + init_waitqueue_head(&dmabuf->poll); dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll; dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0; @@ -410,8 +436,10 @@ void dma_buf_put(struct dma_buf *dmabuf) EXPORT_SYMBOL_GPL(dma_buf_put); /** - * dma_buf_attach - Add the device to dma_buf's attachments list; optionally, - * calls attach() of dma_buf_ops to allow device-specific attach functionality + * dma_buf_attach - Add the device to dma_buf's attachments list; + * calculates access_constraints and throws error if constraints aren't + * satisfied. Optionally, calls attach() of dma_buf_ops to allow + * device-specific attach functionality. * @dmabuf: [in] buffer to attach device to. * @dev: [in] device to be attached. * @@ -436,11 +464,20 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, mutex_lock(&dmabuf->lock); + if (!dmabuf->ops->calc_access_constraints) + ret = def_calc_access_constraints(dmabuf, attach); + else + ret = dmabuf->ops->calc_access_constraints(dmabuf, attach); + + if (ret) + goto err_attach; + if (dmabuf->ops->attach) { ret = dmabuf->ops->attach(dmabuf, dev, attach); if (ret) goto err_attach; } + list_add(&attach->node, &dmabuf->attachments); mutex_unlock(&dmabuf->lock); @@ -785,7 +822,7 @@ static int dma_buf_describe(struct seq_file *s) return ret; seq_puts(s, "\nDma-buf Objects:\n"); - seq_puts(s, "size\tflags\tmode\tcount\texp_name\n"); + seq_puts(s, "size\tflags\tmode\tcount\tconstraints\texp_name\n"); list_for_each_entry(buf_obj, &db_list.head, list_node) { ret = mutex_lock_interruptible(&buf_obj->lock); @@ -796,10 +833,11 @@ static int dma_buf_describe(struct seq_file *s) continue; } - seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", + seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%08lx\t%s\n", buf_obj->size, buf_obj->file->f_flags, buf_obj->file->f_mode, (long)(buf_obj->file->f_count.counter), + buf_obj->access_constraints_mask, buf_obj->exp_name); seq_puts(s, "\tAttached Devices:\n"); @@ -808,7 +846,9 @@ static int dma_buf_describe(struct seq_file *s) list_for_each_entry(attach_obj, &buf_obj->attachments, node) { seq_puts(s, "\t"); - seq_printf(s, "%s\n", dev_name(attach_obj->dev)); + seq_printf(s, "%s\t:%lx\n", + dev_name(attach_obj->dev), + attach_obj->dev->dma_parms->access_constraints_mask); attach_count++; } diff --git a/include/linux/device.h b/include/linux/device.h index a608e23..f9aefa2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -647,6 +647,11 @@ struct device_dma_parameters { */ unsigned int max_segment_size; unsigned long segment_boundary_mask; + /* + * access_constraints_mask: this would be used to share constraints + * about memories that this device can access. + */ + unsigned long access_constraints_mask; }; struct acpi_device; @@ -696,7 +701,7 @@ struct acpi_dev_node { * such descriptors. * @dma_pfn_offset: offset of DMA memory range relatively of RAM * @dma_parms: A low level driver may set these to teach IOMMU code about - * segment limitations. + * segment limitations, and access constraints. * @dma_pools: Dma pools (if dma'ble device). * @dma_mem: Internal for coherent mem override. * @cma_area: Contiguous memory area for dma allocations diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 694e1fe..8429a38 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -37,6 +37,8 @@ struct device; struct dma_buf; struct dma_buf_attachment; +#define DMA_BUF_ALL_MEMORY_ACCESS_MASK ((unsigned long)-1) + /** * struct dma_buf_ops - operations possible on struct dma_buf * @attach: [optional] allows different devices to 'attach' themselves to the @@ -44,6 +46,12 @@ struct dma_buf_attachment; * is already allocated and incompatible with the requirements * of requesting device. * @detach: [optional] detach a given device from this buffer. + * @calc_access_constraints(): [optional] will be called at the end of each + * attach - to calculate and set the constraints for this dma_buf + * according to this attachment's access_constraint_mask in + * dev->dma_parms. + * A default implementation is provided, but exporters are free to + * provide custom version if needed. * @map_dma_buf: returns list of scatter pages allocated, increases usecount * of the buffer. Requires atleast one attach to be called * before. Returned sg list should already be mapped into @@ -77,6 +85,9 @@ struct dma_buf_ops { void (*detach)(struct dma_buf *, struct dma_buf_attachment *); + int (*calc_access_constraints)(struct dma_buf *, + struct dma_buf_attachment *); + /* For {map,unmap}_dma_buf below, any specific buffer attributes * required should get added to device_dma_parameters accessible * via dev->dma_params. @@ -86,6 +97,7 @@ struct dma_buf_ops { void (*unmap_dma_buf)(struct dma_buf_attachment *, struct sg_table *, enum dma_data_direction); + /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY * if the call would block. */ @@ -116,6 +128,7 @@ struct dma_buf_ops { * @ops: dma_buf_ops associated with this buffer object. * @exp_name: name of the exporter; useful for debugging. * @list_node: node for dma_buf accounting and debugging. + * @access_constraints_mask: mask to share access constraints. * @priv: exporter specific private data for this buffer object. * @resv: reservation object linked to this dma-buf */ @@ -130,6 +143,7 @@ struct dma_buf { void *vmap_ptr; const char *exp_name; struct list_head list_node; + unsigned long access_constraints_mask; void *priv; struct reservation_object *resv;