From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E4CEC433E6 for ; Fri, 8 Jan 2021 09:43:55 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A96B8235DD for ; Fri, 8 Jan 2021 09:43:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A96B8235DD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 213946E7EC; Fri, 8 Jan 2021 09:43:49 +0000 (UTC) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7F8AA6E7EA for ; Fri, 8 Jan 2021 09:43:45 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 0EF9EAD2B; Fri, 8 Jan 2021 09:43:44 +0000 (UTC) From: Thomas Zimmermann To: sumit.semwal@linaro.org, christian.koenig@amd.com, airlied@redhat.com, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, kraxel@redhat.com, hdegoede@redhat.com, sean@poorly.run, eric@anholt.net, sam@ravnborg.org Subject: [PATCH v4 01/13] dma-buf: Add vmap_local and vnumap_local operations Date: Fri, 8 Jan 2021 10:43:28 +0100 Message-Id: <20210108094340.15290-2-tzimmermann@suse.de> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210108094340.15290-1-tzimmermann@suse.de> References: <20210108094340.15290-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Vetter , dri-devel@lists.freedesktop.org, virtualization@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org, Thomas Zimmermann , linux-media@vger.kernel.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The existing dma-buf calls dma_buf_vmap() and dma_buf_vunmap() are allowed to pin the buffer or acquire the buffer's reservation object lock. This is a problem for callers that only require a short-term mapping of the buffer without the pinning, or callers that have special locking requirements. These may suffer from unnecessary overhead or interfere with regular pin operations. The new interfaces dma_buf_vmap_local(), dma_buf_vunmapo_local(), and their rsp callbacks in struct dma_buf_ops provide an alternative without pinning or reservation locking. Callers are responsible for these operations. v4: * update documentation (Daniel) Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Suggested-by: Daniel Vetter --- drivers/dma-buf/dma-buf.c | 81 +++++++++++++++++++++++++++++++++++++++ include/linux/dma-buf.h | 34 ++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index b8465243eca2..01f9c74d97fa 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -1295,6 +1295,87 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) } EXPORT_SYMBOL_GPL(dma_buf_vunmap); +/** + * dma_buf_vmap_local - Create virtual mapping for the buffer object into kernel + * address space. + * @dmabuf: [in] buffer to vmap + * @map: [out] returns the vmap pointer + * + * Unlike dma_buf_vmap() this is a short term mapping and will not pin + * the buffer. The struct dma_resv for the @dmabuf must be locked until + * dma_buf_vunmap_local() is called. + * + * Returns: + * 0 on success, or a negative errno code otherwise. + */ +int dma_buf_vmap_local(struct dma_buf *dmabuf, struct dma_buf_map *map) +{ + struct dma_buf_map ptr; + int ret = 0; + + dma_buf_map_clear(map); + + if (WARN_ON(!dmabuf)) + return -EINVAL; + + dma_resv_assert_held(dmabuf->resv); + + if (!dmabuf->ops->vmap_local) + return -EINVAL; + + mutex_lock(&dmabuf->lock); + if (dmabuf->vmapping_counter) { + dmabuf->vmapping_counter++; + BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); + *map = dmabuf->vmap_ptr; + goto out_unlock; + } + + BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr)); + + ret = dmabuf->ops->vmap_local(dmabuf, &ptr); + if (WARN_ON_ONCE(ret)) + goto out_unlock; + + dmabuf->vmap_ptr = ptr; + dmabuf->vmapping_counter = 1; + + *map = dmabuf->vmap_ptr; + +out_unlock: + mutex_unlock(&dmabuf->lock); + return ret; +} +EXPORT_SYMBOL_GPL(dma_buf_vmap_local); + +/** + * dma_buf_vunmap_local - Unmap a vmap obtained by dma_buf_vmap_local. + * @dmabuf: [in] buffer to vunmap + * @map: [in] vmap pointer to vunmap + * + * Release a mapping established with dma_buf_vmap_local(). + */ +void dma_buf_vunmap_local(struct dma_buf *dmabuf, struct dma_buf_map *map) +{ + if (WARN_ON(!dmabuf)) + return; + + dma_resv_assert_held(dmabuf->resv); + + BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr)); + BUG_ON(dmabuf->vmapping_counter == 0); + BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map)); + + mutex_lock(&dmabuf->lock); + if (--dmabuf->vmapping_counter == 0) { + if (dmabuf->ops->vunmap_local) + dmabuf->ops->vunmap_local(dmabuf, map); + dma_buf_map_clear(&dmabuf->vmap_ptr); + } + mutex_unlock(&dmabuf->lock); +} +EXPORT_SYMBOL_GPL(dma_buf_vunmap_local); + #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 628681bf6c99..aeed754b5467 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -264,6 +264,38 @@ struct dma_buf_ops { int (*vmap)(struct dma_buf *dmabuf, struct dma_buf_map *map); void (*vunmap)(struct dma_buf *dmabuf, struct dma_buf_map *map); + + /** + * @vmap_local: + * + * Creates a virtual mapping for the buffer into kernel address space. + * + * This callback establishes short-term mappings for situations where + * callers only use the buffer for a bounded amount of time; such as + * updates to the framebuffer or reading back contained information. + * In contrast to the regular @vmap callback, vmap_local does never pin + * the buffer to a specific domain or acquire the buffer's reservation + * lock. + * + * This is called with the &dma_buf.resv object locked. Callers must hold + * the lock until after removing the mapping with @vunmap_local. + * + * This callback is optional. + * + * Returns: + * + * 0 on success or a negative error code on failure. + */ + int (*vmap_local)(struct dma_buf *dmabuf, struct dma_buf_map *map); + + /** + * @vunmap_local: + * + * Removes a virtual mapping that was established by @vmap_local. + * + * This callback is optional. + */ + void (*vunmap_local)(struct dma_buf *dmabuf, struct dma_buf_map *map); }; /** @@ -501,4 +533,6 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map); void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map); +int dma_buf_vmap_local(struct dma_buf *dmabuf, struct dma_buf_map *map); +void dma_buf_vunmap_local(struct dma_buf *dmabuf, struct dma_buf_map *map); #endif /* __DMA_BUF_H__ */ -- 2.29.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel