From patchwork Tue Jan 15 12:34:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 14047 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 1556D23F81 for ; Tue, 15 Jan 2013 12:34:40 +0000 (UTC) Received: from mail-vb0-f44.google.com (mail-vb0-f44.google.com [209.85.212.44]) by fiordland.canonical.com (Postfix) with ESMTP id 896D9A182DD for ; Tue, 15 Jan 2013 12:34:39 +0000 (UTC) Received: by mail-vb0-f44.google.com with SMTP id fc26so34843vbb.17 for ; Tue, 15 Jan 2013 04:34:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:dkim-signature:x-received:from:to:date:message-id :x-mailer:in-reply-to:references:cc:subject:x-beenthere :x-mailman-version:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-gm-message-state; bh=E6JslNKrLabC5yJkBJOzykoC5ZbubzTS2R8OJHlETWI=; b=BQMD/WQZVmyKLJ8pyjimJPTY689x5R1odwptLGgXEcS3e88VB3Yn958NFRFFIutI6X 9qKKtSHy9jm35Mct7IJSPffEsc25+I2g6VBDSQJnQPONmpH0SJGXif9Y6ufMRzBnAQfI X35hgHjkXvDUftK841EBFqUu1EBnKLxsGg9GaFaW+2T+R7NeD5WG0zmMWXBFfMhxaC6z PlUVplXRC6syCsvZRFd0ukzaFNyhHHJfmOYQlgmzU7u1T9WCTz/uQygtLaKWv+AE2E2f tPPJpyCWt3Jbr4jn/otg+Fgbuj7fPHBgTrHQZQB+08YNGg+gdHUoQlErNjHYrEK6p2Wj ciCA== X-Received: by 10.58.74.196 with SMTP id w4mr13497789vev.7.1358253279038; Tue, 15 Jan 2013 04:34:39 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp109694veb; Tue, 15 Jan 2013 04:34:38 -0800 (PST) X-Received: by 10.204.133.219 with SMTP id g27mr40164877bkt.65.1358253276788; Tue, 15 Jan 2013 04:34:36 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id gg18si26895786bkc.88.2013.01.15.04.34.34; Tue, 15 Jan 2013 04:34:36 -0800 (PST) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org; dkim=neutral (body hash did not verify) header.i=@gmail.com Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Tv5ir-0003OZ-Tn; Tue, 15 Jan 2013 12:34:33 +0000 Received: from mail-wi0-f178.google.com ([209.85.212.178]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Tv5iq-0003O6-Fq for linaro-mm-sig@lists.linaro.org; Tue, 15 Jan 2013 12:34:32 +0000 Received: by mail-wi0-f178.google.com with SMTP id hn3so39106wib.11 for ; Tue, 15 Jan 2013 04:34:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=lTGuJEjk664CGs+tS2AMk+ShGHgl9mZUmKSh5BOwUSQ=; b=pa3ZhsLYf9HOmkvIaLdWxyv4V1QDM8OQjOuT8vD1wUHkSMA+bxRJVKZb+jApSXDacg qhAXhS+s/tJdUq0I8tPEG5UfTllBNy55galKaWZWRYaxkzIJpO/5DL8GGfEVYmOYBxL8 1cQJb0DnHzzl7pAgZ+wy18/zfH7eX1ceWUesuL87iKLgJTPfDBIqzusO42iK71BUaH4Z nzROvvd0VNukKAopS8YPZXRAOaJZQ/Ac4F90zuokg79Alxdzg9eFnYyITssd+ohiMnWp rSftC7Y35Ok9JFfk6T2UIpSMSyg4T3mUkB30E60PjKGqe49qpEGVpsHGAVUqKWhsj/6f FgQg== X-Received: by 10.180.78.66 with SMTP id z2mr3433353wiw.23.1358253272346; Tue, 15 Jan 2013 04:34:32 -0800 (PST) Received: from localhost (5ED48CEF.cm-7-5c.dynamic.ziggo.nl. [94.212.140.239]) by mx.google.com with ESMTPS id g2sm3615969wiy.0.2013.01.15.04.34.30 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 15 Jan 2013 04:34:31 -0800 (PST) Received: by localhost (sSMTP sendmail emulation); Tue, 15 Jan 2013 13:34:29 +0100 From: Maarten Lankhorst To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org Date: Tue, 15 Jan 2013 13:34:02 +0100 Message-Id: <1358253244-11453-6-git-send-email-maarten.lankhorst@canonical.com> X-Mailer: git-send-email 1.8.0.3 In-Reply-To: <1358253244-11453-1-git-send-email-maarten.lankhorst@canonical.com> References: <1358253244-11453-1-git-send-email-maarten.lankhorst@canonical.com> Cc: Maarten Lankhorst Subject: [Linaro-mm-sig] [PATCH 5/7] seqno-fence: Hardware dma-buf implementation of fencing (v4) X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQnSBsnXJfPbx4L9CS+bvAIvwAknS9lS9JLzoZnPHHx4o5NRH3eq0+0k9l0rLoOemFeB/+Rr This type of fence can be used with hardware synchronization for simple hardware that can block execution until the condition (dma_buf[offset] - value) >= 0 has been met. A software fallback still has to be provided in case the fence is used with a device that doesn't support this mechanism. It is useful to expose this for graphics cards that have an op to support this. Some cards like i915 can export those, but don't have an option to wait, so they need the software fallback. I extended the original patch by Rob Clark. v1: Original v2: Renamed from bikeshed to seqno, moved into dma-fence.c since not much was left of the file. Lots of documentation added. v3: Use fence_ops instead of custom callbacks. Moved to own file to avoid circular dependency between dma-buf.h and fence.h v4: Add spinlock pointer to seqno_fence_init Signed-off-by: Maarten Lankhorst --- Documentation/DocBook/device-drivers.tmpl | 1 + drivers/base/fence.c | 38 +++++++++++ include/linux/seqno-fence.h | 105 ++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 include/linux/seqno-fence.h diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 6f53fc0..ad14396 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -128,6 +128,7 @@ X!Edrivers/base/interface.c !Edrivers/base/dma-buf.c !Edrivers/base/fence.c !Iinclude/linux/fence.h +!Iinclude/linux/seqno-fence.h !Edrivers/base/dma-coherent.c !Edrivers/base/dma-mapping.c diff --git a/drivers/base/fence.c b/drivers/base/fence.c index 28e5ffd..1d3f29c 100644 --- a/drivers/base/fence.c +++ b/drivers/base/fence.c @@ -24,6 +24,7 @@ #include #include #include +#include atomic_t fence_context_counter = ATOMIC_INIT(0); EXPORT_SYMBOL(fence_context_counter); @@ -284,3 +285,40 @@ out: return ret; } EXPORT_SYMBOL(fence_default_wait); + +static bool seqno_enable_signaling(struct fence *fence) +{ + struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->enable_signaling(fence); +} + +static bool seqno_signaled(struct fence *fence) +{ + struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence); +} + +static void seqno_release(struct fence *fence) +{ + struct seqno_fence *f = to_seqno_fence(fence); + + dma_buf_put(f->sync_buf); + if (f->ops->release) + f->ops->release(fence); + else + kfree(f); +} + +static long seqno_wait(struct fence *fence, bool intr, signed long timeout) +{ + struct seqno_fence *f = to_seqno_fence(fence); + return f->ops->wait(fence, intr, timeout); +} + +const struct fence_ops seqno_fence_ops = { + .enable_signaling = seqno_enable_signaling, + .signaled = seqno_signaled, + .wait = seqno_wait, + .release = seqno_release +}; +EXPORT_SYMBOL_GPL(seqno_fence_ops); diff --git a/include/linux/seqno-fence.h b/include/linux/seqno-fence.h new file mode 100644 index 0000000..603adc0 --- /dev/null +++ b/include/linux/seqno-fence.h @@ -0,0 +1,105 @@ +/* + * seqno-fence, using a dma-buf to synchronize fencing + * + * Copyright (C) 2012 Texas Instruments + * Copyright (C) 2012 Canonical Ltd + * Authors: + * Rob Clark + * Maarten Lankhorst + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __LINUX_SEQNO_FENCE_H +#define __LINUX_SEQNO_FENCE_H + +#include +#include + +struct seqno_fence { + struct fence base; + + const struct fence_ops *ops; + struct dma_buf *sync_buf; + uint32_t seqno_ofs; +}; + +extern const struct fence_ops seqno_fence_ops; + +/** + * to_seqno_fence - cast a fence to a seqno_fence + * @fence: fence to cast to a seqno_fence + * + * Returns NULL if the fence is not a seqno_fence, + * or the seqno_fence otherwise. + */ +static inline struct seqno_fence * +to_seqno_fence(struct fence *fence) +{ + if (fence->ops != &seqno_fence_ops) + return NULL; + return container_of(fence, struct seqno_fence, base); +} + +/** + * seqno_fence_init - initialize a seqno fence + * @fence: seqno_fence to initialize + * @lock: pointer to spinlock to use for fence + * @sync_buf: buffer containing the memory location to signal on + * @context: the execution context this fence is a part of + * @seqno_ofs: the offset within @sync_buf + * @seqno: the sequence # to signal on + * @ops: the fence_ops for operations on this seqno fence + * + * This function initializes a struct seqno_fence with passed parameters, + * and takes a reference on sync_buf which is released on fence destruction. + * + * A seqno_fence is a dma_fence which can complete in software when + * enable_signaling is called, but it also completes when + * (s32)((sync_buf)[seqno_ofs] - seqno) >= 0 is true + * + * The seqno_fence will take a refcount on the sync_buf until it's + * destroyed, but actual lifetime of sync_buf may be longer if one of the + * callers take a reference to it. + * + * Certain hardware have instructions to insert this type of wait condition + * in the command stream, so no intervention from software would be needed. + * This type of fence can be destroyed before completed, however a reference + * on the sync_buf dma-buf can be taken. It is encouraged to re-use the same + * dma-buf for sync_buf, since mapping or unmapping the sync_buf to the + * device's vm can be expensive. + * + * It is recommended for creators of seqno_fence to call fence_signal + * before destruction. This will prevent possible issues from wraparound at + * time of issue vs time of check, since users can check fence_is_signaled + * before submitting instructions for the hardware to wait on the fence. + * However, when ops.enable_signaling is not called, it doesn't have to be + * done as soon as possible, just before there's any real danger of seqno + * wraparound. + */ +static inline void +seqno_fence_init(struct seqno_fence *fence, spinlock_t *lock, + struct dma_buf *sync_buf, uint32_t context, uint32_t seqno_ofs, + uint32_t seqno, const struct fence_ops *ops) +{ + BUG_ON(!fence || !sync_buf || !ops->enable_signaling || !ops->wait); + + __fence_init(&fence->base, &seqno_fence_ops, lock, context, seqno); + + get_dma_buf(sync_buf); + fence->ops = ops; + fence->sync_buf = sync_buf; + fence->seqno_ofs = seqno_ofs; +} + +#endif /* __LINUX_SEQNO_FENCE_H */