From patchwork Tue Apr 26 12:46:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 82717 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1njKaf-002cQV-5V; Tue, 26 Apr 2022 12:46:49 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244153AbiDZMtw (ORCPT + 1 other); Tue, 26 Apr 2022 08:49:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244125AbiDZMtt (ORCPT ); Tue, 26 Apr 2022 08:49:49 -0400 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E5ACE16E852 for ; Tue, 26 Apr 2022 05:46:40 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id k2so4878853wrd.5 for ; Tue, 26 Apr 2022 05:46:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=QWJNebhjBBDPg0cwekMSjS6qePRn97Mj0N6BUIsgDy0=; b=fW/mKAflpo7RWGocl/TrgqYK1m+lv3D25HAHRiow7NSCHvmDEw+UGqV2sp0vpmTJ8b ZCsaSg/i2tVNLQzDOMcrbC1IlrgRYG1L3Qj9ucb4cWeM0NvJBSK2ywHMzha5g4HOCDv/ fcgL1aVCu2bEs7rX8/GmOMOWRTK5GoOV8h0+2TnKzK9eRzwSudRRbMxekQ+33+CvHBIY FXZmw7yNFBqi2fEEWLSQZmzwaWmloOIm3jJCLspSRjb98vsXApoSm4YX5usHNb5CXP9V 3ssUP1M+LXFMrcuIqq9ksmQrqAwg1ndl9JAiFncDiNF8kqfsuqQx8bcmrrzcM5LNSLII qzww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=QWJNebhjBBDPg0cwekMSjS6qePRn97Mj0N6BUIsgDy0=; b=uDnDFTPFG5i5iHKvZs/SE8k2jnwUwaSjrv37YcU2w6h2IMecV14g+7bX2UgXWF2fCw g+VQoQEKBX+69YagLygBelUmNk9I3MzRNevgyiKbzifVj8EMtusBGbDoS+BzcYdLBAQi UzOf1dTiglEssagSbe7EWXzwq0RtDpfqRkfCxOmSo4J2riNyYpaM5huAAxj5WGjq7QjL bkKsWTIqsUA0oDAnjwQr2F9hqX7xX8HQbk3nXFTkswF/sGv5atGpntUCbHdapdNv3/+T JPeMsNs55i+HlyZuuncgu+veHZ0RoIMvE+6c0185pKjixAS91DhDKcZtsN2bUBVTSrR5 8mTw== X-Gm-Message-State: AOAM533PoGSh19sNCLzTQvONzjbUOq8ApjDtiSyqaUS19mXkWkgSXxlD iJugQMU5frRVve8+qEiQeQolOWEJ0Js= X-Google-Smtp-Source: ABdhPJy3I6knemy6thzL7TvwKzDO8Xk8r+AeuQt3EcSrgvCK5597hs0se5nJF+0rP6gmxMaGGx9efQ== X-Received: by 2002:adf:e112:0:b0:206:d12:9c3a with SMTP id t18-20020adfe112000000b002060d129c3amr17784718wrz.391.1650977199474; Tue, 26 Apr 2022 05:46:39 -0700 (PDT) Received: from able.fritz.box (p57b0b9e1.dip0.t-ipconnect.de. [87.176.185.225]) by smtp.gmail.com with ESMTPSA id s10-20020adf978a000000b0020ae0154f1esm3641025wrb.5.2022.04.26.05.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 05:46:38 -0700 (PDT) From: " =?utf-8?q?Christian_K=C3=B6nig?= " X-Google-Original-From: =?utf-8?q?Christian_K=C3=B6nig?= To: sumit.semwal@linaro.org, gustavo@padovan.org, daniel.vetter@ffwll.ch Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, =?utf-8?q?Christian_K=C3=B6nig?= Subject: [PATCH 1/3] dma-buf/sync_file: cleanup fence merging a bit Date: Tue, 26 Apr 2022 14:46:35 +0200 Message-Id: <20220426124637.329764-1-christian.koenig@amd.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -2.5 (--) X-LSpam-Report: No, score=-2.5 required=5.0 tests=BAYES_00=-1.9,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,FREEMAIL_FORGED_FROMDOMAIN=0.001,FREEMAIL_FROM=0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1 autolearn=ham autolearn_force=no krealloc_array() ignores attempts to reduce the array size, so the attempt to save memory is completely pointless here. Also move testing for the no fence case into sync_file_set_fence(), this way we don't even touch the fence array when we don't have any fences. Signed-off-by: Christian König Reviewed-by: Daniel Vetter --- drivers/dma-buf/sync_file.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 514d213261df..0fe564539166 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -157,9 +157,15 @@ static int sync_file_set_fence(struct sync_file *sync_file, * we already own a new reference to the fence. For num_fence > 1 * we own the reference of the dma_fence_array creation. */ - if (num_fences == 1) { + + if (num_fences == 0) { + sync_file->fence = dma_fence_get_stub(); + kfree(fences); + + } else if (num_fences == 1) { sync_file->fence = fences[0]; kfree(fences); + } else { array = dma_fence_array_create(num_fences, fences, dma_fence_context_alloc(1), @@ -261,19 +267,6 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, } } - if (index == 0) - fences[index++] = dma_fence_get_stub(); - - if (num_fences > index) { - struct dma_fence **tmp; - - /* Keep going even when reducing the size failed */ - tmp = krealloc_array(fences, index, sizeof(*fences), - GFP_KERNEL); - if (tmp) - fences = tmp; - } - if (sync_file_set_fence(sync_file, fences, index) < 0) goto err_put_fences; From patchwork Tue Apr 26 12:46:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 82716 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1njKae-002cQV-4E; Tue, 26 Apr 2022 12:46:48 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244048AbiDZMtv (ORCPT + 1 other); Tue, 26 Apr 2022 08:49:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244153AbiDZMtu (ORCPT ); Tue, 26 Apr 2022 08:49:50 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 331E3179EB2 for ; Tue, 26 Apr 2022 05:46:42 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id j15so12063015wrb.2 for ; Tue, 26 Apr 2022 05:46:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=h6287YDjDUK+eFsVfJsYvnD1WwPKUDWTtG8h5mAWiqU=; b=Q/wKqMy43pyd0rMHbAGGSJqLuQq10eefnGEe+RKVqDVVWcy/T7efVeg2vJfCTSw87h DezJdj8wOYlHI3dfrQyJAmnSVCUvvu+733kwRNmbhn4OSl4D3dZv7M5hNM45QE1h4PvA Or2Wzv6IysgRLDkJ/d4LL0ZqAQMkpSxk05v9YH7C39cfIvdbUuR0H8q8Vg4HoZ0RvPR5 QTLMAyO/G8NWTIk505ScNAQr9iGrbcGs+971sAK/SKJPgKeZrrgb3uRtx3DPm63Jh3x9 wVgE3A4NGd7Dzt++uWGIIK2fjGTyDfH6DUZy7FbUi4Ec+wPB5t6Bwv44I2MOoc/piy7y Cy7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=h6287YDjDUK+eFsVfJsYvnD1WwPKUDWTtG8h5mAWiqU=; b=eQOMfsRkUH19hPHzfsHuat1nvOcolOX3Z75CRxp0IQUGUuC/jEzXD1uAfcEWIj35YG EfGP7yUJY2uJgSaFHXOIMR7X0KntXw0GMIs1V02EF9LqoAcaod9nmao9PkKmvbznZGER X8aX5Vy3BvpMNIrHrZEyrtxVBoJjDAbtCzPiKoqD05MKwnNOY2wvftp2AbYPpEJAwaW/ 5QbnqK0Sm2jnV0d1C1yFauy8iqc1oD0FBf7lLA2Q+hw60aOm16an7qKK0m7yiw0FvZJ/ n560wv1h1v5KDnYW152JVP4qBmzq+dksWj9+623NOc8Ti5mnH67VtXf9ffXhvYQNEtyW t5dw== X-Gm-Message-State: AOAM530nCY5yBSyECMfvTj5/+huPlEZjb6S8Z2BNDA84DSdi6C9m9Vci OlCDXba8L21HQiYpU0Hw4lg= X-Google-Smtp-Source: ABdhPJwJAK2HiB3ZbgqcCeas8cfbdVCwNeWxWg8zyrszlLjPjzB265V1RDm/hfxYPjIZoAFgHvdCvg== X-Received: by 2002:adf:d1ce:0:b0:20a:e668:8927 with SMTP id b14-20020adfd1ce000000b0020ae6688927mr2335749wrd.508.1650977200608; Tue, 26 Apr 2022 05:46:40 -0700 (PDT) Received: from able.fritz.box (p57b0b9e1.dip0.t-ipconnect.de. [87.176.185.225]) by smtp.gmail.com with ESMTPSA id s10-20020adf978a000000b0020ae0154f1esm3641025wrb.5.2022.04.26.05.46.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 05:46:40 -0700 (PDT) From: " =?utf-8?q?Christian_K=C3=B6nig?= " X-Google-Original-From: =?utf-8?q?Christian_K=C3=B6nig?= To: sumit.semwal@linaro.org, gustavo@padovan.org, daniel.vetter@ffwll.ch Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, =?utf-8?q?Christian_K=C3=B6nig?= Subject: [PATCH 2/3] dma-buf: cleanup dma_fence_unwrap implementation and selftest Date: Tue, 26 Apr 2022 14:46:36 +0200 Message-Id: <20220426124637.329764-2-christian.koenig@amd.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426124637.329764-1-christian.koenig@amd.com> References: <20220426124637.329764-1-christian.koenig@amd.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -2.5 (--) X-LSpam-Report: No, score=-2.5 required=5.0 tests=BAYES_00=-1.9,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,FREEMAIL_FORGED_FROMDOMAIN=0.001,FREEMAIL_FROM=0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1 autolearn=ham autolearn_force=no Move the code from the inline functions into exported functions. While at it also cleanup the the selftests, fix the error handling, remove unused functions and stop leaking memory in failed tests. Signed-off-by: Christian König --- drivers/dma-buf/Makefile | 2 +- drivers/dma-buf/dma-fence-unwrap.c | 59 +++++++++++++++++++++++++++ drivers/dma-buf/st-dma-fence-unwrap.c | 40 ++++++++---------- include/linux/dma-fence-unwrap.h | 52 ++--------------------- 4 files changed, 80 insertions(+), 73 deletions(-) create mode 100644 drivers/dma-buf/dma-fence-unwrap.c diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 4c9eb53ba3f8..70ec901edf2c 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-resv.o + dma-fence-unwrap.o dma-resv.o obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_DMABUF_HEAPS) += heaps/ obj-$(CONFIG_SYNC_FILE) += sync_file.o diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c new file mode 100644 index 000000000000..711be125428c --- /dev/null +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * dma-fence-util: misc functions for dma_fence objects + * + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * Authors: + * Christian König + */ + +#include +#include +#include +#include + +/* Internal helper to start new array iteration, don't use directly */ +static struct dma_fence * +__dma_fence_unwrap_array(struct dma_fence_unwrap *cursor) +{ + cursor->array = dma_fence_chain_contained(cursor->chain); + cursor->index = 0; + return dma_fence_array_first(cursor->array); +} + +/** + * dma_fence_unwrap_first - return the first fence from fence containers + * @head: the entrypoint into the containers + * @cursor: current position inside the containers + * + * Unwraps potential dma_fence_chain/dma_fence_array containers and return the + * first fence. + */ +struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head, + struct dma_fence_unwrap *cursor) +{ + cursor->chain = dma_fence_get(head); + return __dma_fence_unwrap_array(cursor); +} +EXPORT_SYMBOL_GPL(dma_fence_unwrap_first); + +/** + * dma_fence_unwrap_next - return the next fence from a fence containers + * @cursor: current position inside the containers + * + * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return + * the next fence from them. + */ +struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) +{ + struct dma_fence *tmp; + + ++cursor->index; + tmp = dma_fence_array_next(cursor->array, cursor->index); + if (tmp) + return tmp; + + cursor->chain = dma_fence_chain_walk(cursor->chain); + return __dma_fence_unwrap_array(cursor); +} +EXPORT_SYMBOL_GPL(dma_fence_unwrap_next); diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index 039f016b57be..59628add93f5 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -4,27 +4,19 @@ * Copyright (C) 2022 Advanced Micro Devices, Inc. */ +#include +#include +#include #include -#if 0 -#include -#include -#include -#include -#include -#include -#include -#endif #include "selftest.h" #define CHAIN_SZ (4 << 10) -static inline struct mock_fence { +struct mock_fence { struct dma_fence base; spinlock_t lock; -} *to_mock_fence(struct dma_fence *f) { - return container_of(f, struct mock_fence, base); -} +}; static const char *mock_name(struct dma_fence *f) { @@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void) return NULL; spin_lock_init(&f->lock); - dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0); + dma_fence_init(&f->base, &mock_ops, &f->lock, + dma_fence_context_alloc(1), 1); return &f->base; } @@ -113,7 +106,6 @@ static int sanitycheck(void *arg) if (!chain) return -ENOMEM; - dma_fence_signal(f); dma_fence_put(chain); return err; } @@ -154,10 +146,10 @@ static int unwrap_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); + dma_fence_put(f1); + dma_fence_put(f2); dma_fence_put(array); - return 0; + return err; } static int unwrap_chain(void *arg) @@ -196,10 +188,10 @@ static int unwrap_chain(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); + dma_fence_put(f1); + dma_fence_put(f2); dma_fence_put(chain); - return 0; + return err; } static int unwrap_chain_array(void *arg) @@ -242,10 +234,10 @@ static int unwrap_chain_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); + dma_fence_put(f1); + dma_fence_put(f2); dma_fence_put(chain); - return 0; + return err; } int dma_fence_unwrap(void) diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index 77e335a1bcac..e7c219da4ed7 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -1,7 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * fence-chain: chain fences together in a timeline - * * Copyright (C) 2022 Advanced Micro Devices, Inc. * Authors: * Christian König @@ -10,8 +8,7 @@ #ifndef __LINUX_DMA_FENCE_UNWRAP_H #define __LINUX_DMA_FENCE_UNWRAP_H -#include -#include +struct dma_fence; /** * struct dma_fence_unwrap - cursor into the container structure @@ -33,50 +30,9 @@ struct dma_fence_unwrap { unsigned int index; }; -/* Internal helper to start new array iteration, don't use directly */ -static inline struct dma_fence * -__dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) -{ - cursor->array = dma_fence_chain_contained(cursor->chain); - cursor->index = 0; - return dma_fence_array_first(cursor->array); -} - -/** - * dma_fence_unwrap_first - return the first fence from fence containers - * @head: the entrypoint into the containers - * @cursor: current position inside the containers - * - * Unwraps potential dma_fence_chain/dma_fence_array containers and return the - * first fence. - */ -static inline struct dma_fence * -dma_fence_unwrap_first(struct dma_fence *head, struct dma_fence_unwrap *cursor) -{ - cursor->chain = dma_fence_get(head); - return __dma_fence_unwrap_array(cursor); -} - -/** - * dma_fence_unwrap_next - return the next fence from a fence containers - * @cursor: current position inside the containers - * - * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return - * the next fence from them. - */ -static inline struct dma_fence * -dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) -{ - struct dma_fence *tmp; - - ++cursor->index; - tmp = dma_fence_array_next(cursor->array, cursor->index); - if (tmp) - return tmp; - - cursor->chain = dma_fence_chain_walk(cursor->chain); - return __dma_fence_unwrap_array(cursor); -} +struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head, + struct dma_fence_unwrap *cursor); +struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); /** * dma_fence_unwrap_for_each - iterate over all fences in containers From patchwork Tue Apr 26 12:46:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 82718 Received: from vger.kernel.org ([23.128.96.18]) by www.linuxtv.org with esmtp (Exim 4.92) (envelope-from ) id 1njKag-002cQV-0b; Tue, 26 Apr 2022 12:46:50 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244693AbiDZMtx (ORCPT + 1 other); Tue, 26 Apr 2022 08:49:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245570AbiDZMtw (ORCPT ); Tue, 26 Apr 2022 08:49:52 -0400 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE77C17B381 for ; Tue, 26 Apr 2022 05:46:43 -0700 (PDT) Received: by mail-wm1-x32a.google.com with SMTP id y21so11135225wmi.2 for ; Tue, 26 Apr 2022 05:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7BXUq0vj8KoqiCfdmoJA1YRh5B//+tg+SsjJvRIdEH4=; b=iuDsd1y2jI5fQI29K4wTwdDcxoV4P6L6PB/puaNSFy8v84JYzCdxFMY9XlABMkhpbK 1OTW+FEn68QaOsemJ9OfdsPiNgstRQeAHTYsYPYiYcqucst8BFOQIMBcfQZpFTiVsmOt t8vmR1PfDZHEnYfuehOnWe51yLtVhAIrdZtnP84JE1nu8QCauhigUvTGuobG9l6S8tLO 9P1YeSQszZFF6JfGBQ4uB5rgeJ/SR+Q876pfAIcp7Rq5XWoxjfhd5JpIlfcvWB2nMeDT zNRybmlgWxoHJ08m9t2tSuoztXJszO7iK+cWHiAX4/iz72w3H7ERGxq1uT0NUNUiWlKN 2ZMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7BXUq0vj8KoqiCfdmoJA1YRh5B//+tg+SsjJvRIdEH4=; b=AIl9x/dZOPeB+SHk3S9Rb1nTJNNQzwS9WcvP+EJ4/1YyXOHiKV4CZhNCNXG8tIb++k 5lgbVGiUvW+D+VTKIYQVIFQFtiA/AIdDZPFR5SM+frPDhXoKKA5Xcdc66VrOcGhNWVpS vFay+S6pvOlPgeHV0Cn1Kcl6jhNA7gglC1V+Xh/ngETcKQyAsjqhwMuQ0SsE8JHh0Eqk EUqWLwDevbdHWWqz5VKLIH1Jpg/hKP9qKGRw+j9Jm0KczAw+a/t5Wtt5IdYG42gFiT8f B1qx/A51iiBF1SX4sd7mPH0AJm2ekphVma1nKsdpyU53CqZycjVQDz/HcqZwLgcZ8wcY wmmA== X-Gm-Message-State: AOAM530B0rWv3F+11ZVIqgd5H9otSyOZJYQqkvENDPuroaPlSA/ApVru szs8TtK0frplRfs72+c3Iq0= X-Google-Smtp-Source: ABdhPJwKn4CvOBZ/cyMB8CU835KLoTbqBbS3Z43xUVydAp2yc1vsY3UTn8RFvu/8rzTwiQvcOLmpvQ== X-Received: by 2002:a05:600c:2d93:b0:393:fbf7:5a58 with SMTP id i19-20020a05600c2d9300b00393fbf75a58mr894901wmg.101.1650977201897; Tue, 26 Apr 2022 05:46:41 -0700 (PDT) Received: from able.fritz.box (p57b0b9e1.dip0.t-ipconnect.de. [87.176.185.225]) by smtp.gmail.com with ESMTPSA id s10-20020adf978a000000b0020ae0154f1esm3641025wrb.5.2022.04.26.05.46.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Apr 2022 05:46:41 -0700 (PDT) From: " =?utf-8?q?Christian_K=C3=B6nig?= " X-Google-Original-From: =?utf-8?q?Christian_K=C3=B6nig?= To: sumit.semwal@linaro.org, gustavo@padovan.org, daniel.vetter@ffwll.ch Cc: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, =?utf-8?q?Christian_K=C3=B6nig?= Subject: [PATCH 3/3] dma-buf: generalize fence merging Date: Tue, 26 Apr 2022 14:46:37 +0200 Message-Id: <20220426124637.329764-3-christian.koenig@amd.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220426124637.329764-1-christian.koenig@amd.com> References: <20220426124637.329764-1-christian.koenig@amd.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-LSpam-Score: -2.5 (--) X-LSpam-Report: No, score=-2.5 required=5.0 tests=BAYES_00=-1.9,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,FREEMAIL_FORGED_FROMDOMAIN=0.001,FREEMAIL_FROM=0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1 autolearn=ham autolearn_force=no Introduce a dma_fence_merge() macro which allows to unwrap fences which potentially can be containers as well and then merge them back together into a flat dma_fence_array. Signed-off-by: Christian König --- drivers/dma-buf/dma-fence-unwrap.c | 95 ++++++++++++++++++++ drivers/dma-buf/st-dma-fence-unwrap.c | 47 ++++++++++ drivers/dma-buf/sync_file.c | 119 ++------------------------ include/linux/dma-fence-unwrap.h | 24 ++++++ 4 files changed, 172 insertions(+), 113 deletions(-) diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index 711be125428c..c9becc74896d 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -11,6 +11,7 @@ #include #include #include +#include /* Internal helper to start new array iteration, don't use directly */ static struct dma_fence * @@ -57,3 +58,97 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) return __dma_fence_unwrap_array(cursor); } EXPORT_SYMBOL_GPL(dma_fence_unwrap_next); + +/* Implementation for the dma_fence_merge() marco, don't use directly */ +struct dma_fence *__dma_fence_merge(unsigned int num_fences, + struct dma_fence **fences, + struct dma_fence_unwrap *iter) +{ + struct dma_fence_array *result; + struct dma_fence *tmp, **array; + unsigned int i, count; + + count = 0; + for (i = 0; i < num_fences; ++i) { + dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) + if (!dma_fence_is_signaled(tmp)) + ++count; + } + + if (count == 0) + return dma_fence_get_stub(); + + if (count > INT_MAX) + return NULL; + + array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); + if (!array) + return NULL; + + /* + * We can't guarantee that inpute fences are ordered by context, but + * it is still quite likely when this function is used multiple times. + * So attempt to order the fences by context as we pass over them and + * merge fences with the same context. + */ + for (i = 0; i < num_fences; ++i) + fences[i] = dma_fence_unwrap_first(fences[i], &iter[i]); + + count = 0; + do { + unsigned int sel; + +restart: + tmp = NULL; + for (i = 0; i < num_fences; ++i) { + struct dma_fence *next = fences[i]; + + if (!next || dma_fence_is_signaled(next)) + continue; + + if (!tmp || tmp->context > next->context) { + tmp = next; + sel = i; + + } else if (tmp->context < next->context) { + continue; + + } else if (dma_fence_is_later(tmp, next)) { + fences[i] = dma_fence_unwrap_next(&iter[i]); + goto restart; + } else { + fences[sel] = dma_fence_unwrap_next(&iter[sel]); + goto restart; + } + } + + if (tmp) { + array[count++] = dma_fence_get(tmp); + fences[sel] = dma_fence_unwrap_next(&iter[sel]); + } + } while (tmp); + + if (count == 0) { + tmp = dma_fence_get_stub(); + goto return_tmp; + } + + if (count == 1) { + tmp = array[0]; + goto return_tmp; + } + + result = dma_fence_array_create(count, array, + dma_fence_context_alloc(1), + 1, false); + if (!result) { + tmp = NULL; + goto return_tmp; + } + return &result->base; + +return_tmp: + kfree(array); + return tmp; +} +EXPORT_SYMBOL_GPL(__dma_fence_merge); diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index 59628add93f5..23ab134417ed 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -240,6 +240,52 @@ static int unwrap_chain_array(void *arg) return err; } +static int unwrap_merge(void *arg) +{ + struct dma_fence *fence, *f1, *f2, *f3; + struct dma_fence_unwrap iter; + int err = 0; + + f1 = mock_fence(); + if (!f1) + return -ENOMEM; + + f2 = mock_fence(); + if (!f2) { + err = -ENOMEM; + goto error_put_f1; + } + + f3 = dma_fence_merge(f1, f2); + if (!f3) { + err = -ENOMEM; + goto error_put_f2; + } + + dma_fence_unwrap_for_each(fence, &iter, f3) { + if (fence == f1) { + f1 = NULL; + } else if (fence == f2) { + f2 = NULL; + } else { + pr_err("Unexpected fence!\n"); + err = -EINVAL; + } + } + + if (f1 || f2) { + pr_err("Not all fences seen!\n"); + err = -EINVAL; + } + + dma_fence_put(f3); +error_put_f2: + dma_fence_put(f2); +error_put_f1: + dma_fence_put(f1); + return err; +} + int dma_fence_unwrap(void) { static const struct subtest tests[] = { @@ -247,6 +293,7 @@ int dma_fence_unwrap(void) SUBTEST(unwrap_array), SUBTEST(unwrap_chain), SUBTEST(unwrap_chain_array), + SUBTEST(unwrap_merge), }; return subtests(tests, NULL); diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 0fe564539166..fe149d7e3ce2 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -146,50 +146,6 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len) return buf; } -static int sync_file_set_fence(struct sync_file *sync_file, - struct dma_fence **fences, int num_fences) -{ - struct dma_fence_array *array; - - /* - * The reference for the fences in the new sync_file and held - * in add_fence() during the merge procedure, so for num_fences == 1 - * we already own a new reference to the fence. For num_fence > 1 - * we own the reference of the dma_fence_array creation. - */ - - if (num_fences == 0) { - sync_file->fence = dma_fence_get_stub(); - kfree(fences); - - } else if (num_fences == 1) { - sync_file->fence = fences[0]; - kfree(fences); - - } else { - array = dma_fence_array_create(num_fences, fences, - dma_fence_context_alloc(1), - 1, false); - if (!array) - return -ENOMEM; - - sync_file->fence = &array->base; - } - - return 0; -} - -static void add_fence(struct dma_fence **fences, - int *i, struct dma_fence *fence) -{ - fences[*i] = fence; - - if (!dma_fence_is_signaled(fence)) { - dma_fence_get(fence); - (*i)++; - } -} - /** * sync_file_merge() - merge two sync_files * @name: name of new fence @@ -203,84 +159,21 @@ static void add_fence(struct dma_fence **fences, static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, struct sync_file *b) { - struct dma_fence *a_fence, *b_fence, **fences; - struct dma_fence_unwrap a_iter, b_iter; - unsigned int index, num_fences; struct sync_file *sync_file; + struct dma_fence *fence; sync_file = sync_file_alloc(); if (!sync_file) return NULL; - num_fences = 0; - dma_fence_unwrap_for_each(a_fence, &a_iter, a->fence) - ++num_fences; - dma_fence_unwrap_for_each(b_fence, &b_iter, b->fence) - ++num_fences; - - if (num_fences > INT_MAX) - goto err_free_sync_file; - - fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); - if (!fences) - goto err_free_sync_file; - - /* - * We can't guarantee that fences in both a and b are ordered, but it is - * still quite likely. - * - * So attempt to order the fences as we pass over them and merge fences - * with the same context. - */ - - index = 0; - for (a_fence = dma_fence_unwrap_first(a->fence, &a_iter), - b_fence = dma_fence_unwrap_first(b->fence, &b_iter); - a_fence || b_fence; ) { - - if (!b_fence) { - add_fence(fences, &index, a_fence); - a_fence = dma_fence_unwrap_next(&a_iter); - - } else if (!a_fence) { - add_fence(fences, &index, b_fence); - b_fence = dma_fence_unwrap_next(&b_iter); - - } else if (a_fence->context < b_fence->context) { - add_fence(fences, &index, a_fence); - a_fence = dma_fence_unwrap_next(&a_iter); - - } else if (b_fence->context < a_fence->context) { - add_fence(fences, &index, b_fence); - b_fence = dma_fence_unwrap_next(&b_iter); - - } else if (__dma_fence_is_later(a_fence->seqno, b_fence->seqno, - a_fence->ops)) { - add_fence(fences, &index, a_fence); - a_fence = dma_fence_unwrap_next(&a_iter); - b_fence = dma_fence_unwrap_next(&b_iter); - - } else { - add_fence(fences, &index, b_fence); - a_fence = dma_fence_unwrap_next(&a_iter); - b_fence = dma_fence_unwrap_next(&b_iter); - } + fence = dma_fence_merge(a->fence, b->fence); + if (!fence) { + fput(sync_file->file); + return NULL; } - - if (sync_file_set_fence(sync_file, fences, index) < 0) - goto err_put_fences; - + sync_file->fence = fence; strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); return sync_file; - -err_put_fences: - while (index) - dma_fence_put(fences[--index]); - kfree(fences); - -err_free_sync_file: - fput(sync_file->file); - return NULL; } static int sync_file_release(struct inode *inode, struct file *file) diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index e7c219da4ed7..7c0fab318301 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -48,4 +48,28 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); for (fence = dma_fence_unwrap_first(head, cursor); fence; \ fence = dma_fence_unwrap_next(cursor)) +struct dma_fence *__dma_fence_merge(unsigned int num_fences, + struct dma_fence **fences, + struct dma_fence_unwrap *cursors); + +/** + * dma_fence_merge - unwrap and merge fences + * + * All fences given as parameters are unwrapped and merged back together as flat + * dma_fence_array. Useful if multiple containers need to be merged together. + * + * Implemented as a macro to allocate the necessary arrays on the stack and + * account the stack frame size to the caller. + * + * Returns NULL on memory allocation failure, a dma_fence object representing + * all the given fences otherwise. + */ +#define dma_fence_merge(...) \ + ({ \ + struct dma_fence *__f[] = { __VA_ARGS__ }; \ + struct dma_fence_unwrap __c[ARRAY_SIZE(__f)]; \ + \ + __dma_fence_merge(ARRAY_SIZE(__f), __f, __c); \ + }) + #endif