Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2221947/?format=api
{ "id": 2221947, "url": "http://patchwork.ozlabs.org/api/patches/2221947/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260410-sdxi-base-v1-12-1d184cb5c60a@amd.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260410-sdxi-base-v1-12-1d184cb5c60a@amd.com>", "list_archive_url": null, "date": "2026-04-10T13:07:22", "name": "[12/23] dmaengine: sdxi: Add descriptor ring management", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "0c6ba8e314e67a09686bbf4e1478d12e2ac7ee86", "submitter": { "id": 91626, "url": "http://patchwork.ozlabs.org/api/people/91626/?format=api", "name": "Nathan Lynch via B4 Relay", "email": "devnull+nathan.lynch.amd.com@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260410-sdxi-base-v1-12-1d184cb5c60a@amd.com/mbox/", "series": [ { "id": 499458, "url": "http://patchwork.ozlabs.org/api/series/499458/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=499458", "date": "2026-04-10T13:07:10", "name": "dmaengine: Smart Data Accelerator Interface (SDXI) basic support", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/499458/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2221947/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2221947/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-52323-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=G93lmfVh;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-pci+bounces-52323-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"G93lmfVh\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fsccV5Cyvz1yGS\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 23:10:50 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 12F023058DF4\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 13:07:58 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id A23533AE1AA;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)", "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 793BE3A75A2;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPS id 4939AC4AF14;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)", "from aws-us-west-2-korg-lkml-1.web.codeaurora.org\n (localhost.localdomain [127.0.0.1])\n\tby smtp.lore.kernel.org (Postfix) with ESMTP id 41AA0F4485D;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775826470; cv=none;\n b=Cw8xLos690ShG9WhzNhjrvLYRp5jG5Am+1A0l3MknP6JJXpHOOz9vkGt/PuEezAW+mx/2M1TnHjpYOdLlmNKgoBqKg8lrQNQJ4IqdbkxhDfudAkyG38jqDjvbo+iXoQJzI+ov8Hp0MDrb/U9Xr6NpurJQafP5T29H8a4nPYwrf0=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775826470; c=relaxed/simple;\n\tbh=y2lhqBRmwblDddnugdEB3vFz8AAI/IYZVx7AafENaug=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=ogVgdBDkc9i9Oj4D762w+TgVmDUw4hNl0wx0HCbLD3ri1W6yrNd1rlEJweuDcLiaaU4rjU84KkSZSgVf1DOdZhHG9LWKmLuv/BZKpBGxuCfLJninseZ+MdJ+HKheM2s5WbrxCwteYNJ1mx3sZ5AjJelMpfAfmYWKbpQqABz7IhM=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=G93lmfVh; arc=none smtp.client-ip=10.30.226.201", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1775826470;\n\tbh=y2lhqBRmwblDddnugdEB3vFz8AAI/IYZVx7AafENaug=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;\n\tb=G93lmfVhB0seWhqvYhiGfy0DjzUEorIwvRKuIsn+4tORdrTuR6ICeh6vIjYhnRqL/\n\t OGXSzES3gHgJQW2LC3G90BLAJ+HSqk/SELzLbBa6NN4Q/oTl3UX90Nohx3cAoaLm01\n\t JDLoQmtMQxHAuB7r7LF2jeOilO5uML6WhSJe7Y4J3Ml/XkmmgrilqHejmXKU/qEt5Y\n\t NtkRuEsgMYZqQm+fQG8XklxE1O/KwBRJPQ4W8N8dI5ssAPlItnE8ivHtToqULxUMSz\n\t lyGzm6egXFfiLQRL1RIauwUItRFyUVSpeXa0X8SeFPbv5dXj2N9K0fJSwwDCvKQxPZ\n\t YehHS7EbzO86w==", "From": "Nathan Lynch via B4 Relay <devnull+nathan.lynch.amd.com@kernel.org>", "Date": "Fri, 10 Apr 2026 08:07:22 -0500", "Subject": "[PATCH 12/23] dmaengine: sdxi: Add descriptor ring management", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260410-sdxi-base-v1-12-1d184cb5c60a@amd.com>", "References": "<20260410-sdxi-base-v1-0-1d184cb5c60a@amd.com>", "In-Reply-To": "<20260410-sdxi-base-v1-0-1d184cb5c60a@amd.com>", "To": "Vinod Koul <vkoul@kernel.org>", "Cc": "Wei Huang <wei.huang2@amd.com>,\n Mario Limonciello <mario.limonciello@amd.com>,\n Bjorn Helgaas <bhelgaas@google.com>,\n Jonathan Cameron <jonathan.cameron@huawei.com>,\n Stephen Bates <Stephen.Bates@amd.com>, PradeepVineshReddy.Kodamati@amd.com,\n John.Kariuki@amd.com, linux-pci@vger.kernel.org,\n linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,\n Nathan Lynch <nathan.lynch@amd.com>", "X-Mailer": "b4 0.15.2", "X-Developer-Signature": "v=1; a=ed25519-sha256; t=1775826467; l=9249;\n i=nathan.lynch@amd.com; s=20260410; h=from:subject:message-id;\n bh=U1lYJRGamQ63I3Aze0bJO+juzHNCos3OOr49CuQP8zc=;\n b=1i7IxsLJT2SQfymOvkdyPQsByIsZEiizdFlb6yIXlQpWI0DCSInly6vv8tYZZJv2XvCZhb+9d\n Y/KIYK66kClCA1f1EWpABpNrQ5ilJlP7VpTOybLpFUtEkC5T9dKyQt9", "X-Developer-Key": "i=nathan.lynch@amd.com; a=ed25519;\n pk=PK4ozhq+/z9/2Jl5rgDmvHa9raVomv79qM8p1RAFpEw=", "X-Endpoint-Received": "by B4 Relay for nathan.lynch@amd.com/20260410 with\n auth_id=728", "X-Original-From": "Nathan Lynch <nathan.lynch@amd.com>", "Reply-To": "nathan.lynch@amd.com" }, "content": "From: Nathan Lynch <nathan.lynch@amd.com>\n\nIntroduce a library for managing SDXI descriptor ring state. It\nencapsulates determining the next free space in the ring to deposit\ndescriptors and performing the update of the write index correctly, as\nwell as iterating over slices (reservations) of the ring without\ndealing directly with ring offsets/indexes.\n\nThe central abstraction is sdxi_ring_state, which maintains the write\nindex and a wait queue. An internal spin lock serializes checks for\nspace in the ring and updates to the write index.\n\nReservations (sdxi_ring_resv) are intended to be short-lived on-stack\nobjects representing slices of the ring for callers to populate with\ndescriptors. Both blocking and non-blocking reservation APIs are\nprovided.\n\nDescriptor access within a reservation is provided via\nsdxi_ring_resv_next() and sdxi_ring_resv_foreach().\n\nCompletion handlers must call sdxi_ring_wake_up() when descriptors\nhave been consumed so that blocked reservations can proceed.\n\nCo-developed-by: Wei Huang <wei.huang2@amd.com>\nSigned-off-by: Wei Huang <wei.huang2@amd.com>\nSigned-off-by: Nathan Lynch <nathan.lynch@amd.com>\n---\n drivers/dma/sdxi/Makefile | 3 +-\n drivers/dma/sdxi/ring.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++\n drivers/dma/sdxi/ring.h | 84 ++++++++++++++++++++++++\n 3 files changed, 244 insertions(+), 1 deletion(-)", "diff": "diff --git a/drivers/dma/sdxi/Makefile b/drivers/dma/sdxi/Makefile\nindex 2178f274831c..23536a1defc3 100644\n--- a/drivers/dma/sdxi/Makefile\n+++ b/drivers/dma/sdxi/Makefile\n@@ -3,6 +3,7 @@ obj-$(CONFIG_SDXI) += sdxi.o\n \n sdxi-objs += \\\n \tcontext.o \\\n-\tdevice.o\n+\tdevice.o \\\n+\tring.o\n \n sdxi-$(CONFIG_PCI_MSI) += pci.o\ndiff --git a/drivers/dma/sdxi/ring.c b/drivers/dma/sdxi/ring.c\nnew file mode 100644\nindex 000000000000..d51b9e708a4f\n--- /dev/null\n+++ b/drivers/dma/sdxi/ring.c\n@@ -0,0 +1,158 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * SDXI descriptor ring state management. Handles advancing the write\n+ * index correctly and supplies \"reservations\" i.e. slices of the ring\n+ * to be filled with descriptors.\n+ *\n+ * Copyright Advanced Micro Devices, Inc.\n+ */\n+#include <kunit/visibility.h>\n+#include <linux/io-64-nonatomic-lo-hi.h>\n+#include <linux/lockdep.h>\n+#include <linux/range.h>\n+#include <linux/sched.h>\n+#include <linux/spinlock.h>\n+#include <linux/types.h>\n+#include <linux/wait.h>\n+#include <asm/barrier.h>\n+#include <asm/byteorder.h>\n+#include <asm/div64.h>\n+#include <asm/rwonce.h>\n+\n+#include \"ring.h\"\n+#include \"hw.h\"\n+\n+/*\n+ * Initialize ring management state. Caller is responsible for\n+ * allocating, mapping, and initializing the actual control structures\n+ * shared with hardware: the indexes and ring array.\n+ */\n+void sdxi_ring_state_init(struct sdxi_ring_state *rs, const __le64 *read_index,\n+\t\t\t __le64 *write_index, u32 entries,\n+\t\t\t struct sdxi_desc descs[static SZ_1K])\n+{\n+\tWARN_ON_ONCE(!read_index);\n+\tWARN_ON_ONCE(!write_index);\n+\t/*\n+\t * See SDXI 1.0 Table 3-1 Memory Structure Summary. Minimum\n+\t * descriptor ring size in bytes is 64KB; thus 1024 64-byte\n+\t * entries.\n+\t */\n+\tWARN_ON_ONCE(entries < SZ_1K);\n+\n+\t*rs = (typeof(*rs)) {\n+\t\t.write_index = le64_to_cpu(*write_index),\n+\t\t.write_index_ptr = write_index,\n+\t\t.read_index_ptr = read_index,\n+\t\t.entries = entries,\n+\t\t.entry = descs,\n+\t};\n+\tspin_lock_init(&rs->lock);\n+\tinit_waitqueue_head(&rs->wqh);\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_ring_state_init);\n+\n+static u64 sdxi_ring_state_load_ridx(struct sdxi_ring_state *rs)\n+{\n+\tlockdep_assert_held(&rs->lock);\n+\treturn le64_to_cpu(READ_ONCE(*rs->read_index_ptr));\n+}\n+\n+static void sdxi_ring_state_store_widx(struct sdxi_ring_state *rs, u64 new_widx)\n+{\n+\tlockdep_assert_held(&rs->lock);\n+\t*rs->write_index_ptr = cpu_to_le64(rs->write_index = new_widx);\n+}\n+\n+/* Non-blocking ring reservation. Callers must handle ring full (-EBUSY). */\n+int sdxi_ring_try_reserve(struct sdxi_ring_state *rs, size_t nr,\n+\t\t\t struct sdxi_ring_resv *resv)\n+{\n+\tu64 new_widx;\n+\n+\t/*\n+\t * Caller bug, warn and reject.\n+\t */\n+\tif (WARN_ONCE(nr < 1 || nr > rs->entries,\n+\t\t \"Reservation of size %zu requested from ring of size %u\\n\",\n+\t\t nr, rs->entries))\n+\t\treturn -EINVAL;\n+\n+\tscoped_guard(spinlock_irqsave, &rs->lock) {\n+\t\tu64 ridx = sdxi_ring_state_load_ridx(rs);\n+\n+\t\t/*\n+\t\t * Bug: the read index should never exceed the write index.\n+\t\t * TODO: sdxi_err() or similar; need a reference to\n+\t\t * the device.\n+\t\t */\n+\t\tif (ridx > rs->write_index)\n+\t\t\treturn -EIO;\n+\n+\t\tnew_widx = rs->write_index + nr;\n+\n+\t\t/*\n+\t\t * Not enough space available right now.\n+\t\t * TODO: sdxi_dbg() or tracepoint here.\n+\t\t */\n+\t\tif (new_widx - ridx > rs->entries)\n+\t\t\treturn -EBUSY;\n+\n+\t\tsdxi_ring_state_store_widx(rs, new_widx);\n+\t}\n+\n+\t*resv = (typeof(*resv)) {\n+\t\t.rs = rs,\n+\t\t.range = {\n+\t\t\t.start = new_widx - nr,\n+\t\t\t.end = new_widx - 1,\n+\t\t},\n+\t\t.iter = new_widx - nr,\n+\t};\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_ring_try_reserve);\n+\n+/* Blocking ring reservation. Retries until success or non-transient error. */\n+int sdxi_ring_reserve(struct sdxi_ring_state *rs, size_t nr,\n+\t\t struct sdxi_ring_resv *resv)\n+{\n+\tint ret;\n+\n+\twait_event(rs->wqh,\n+\t\t (ret = sdxi_ring_try_reserve(rs, nr, resv)) != -EBUSY);\n+\n+\treturn ret;\n+}\n+\n+/* Completion code should call this whenever descriptors have been consumed. */\n+void sdxi_ring_wake_up(struct sdxi_ring_state *rs)\n+{\n+\twake_up_all(&rs->wqh);\n+}\n+\n+static struct sdxi_desc *\n+sdxi_desc_ring_entry(const struct sdxi_ring_state *rs, u64 index)\n+{\n+\treturn &rs->entry[do_div(index, rs->entries)];\n+}\n+\n+struct sdxi_desc *sdxi_ring_resv_next(struct sdxi_ring_resv *resv)\n+{\n+\tif (resv->range.start <= resv->iter && resv->iter <= resv->range.end)\n+\t\treturn sdxi_desc_ring_entry(resv->rs, resv->iter++);\n+\t/*\n+\t * Caller has iterated to the end of the reservation.\n+\t */\n+\tif (resv->iter == resv->range.end + 1)\n+\t\treturn NULL;\n+\t/*\n+\t * Should happen only if caller messed with internal\n+\t * reservation state.\n+\t */\n+\tWARN_ONCE(1, \"reservation[%llu,%llu] with iter %llu\",\n+\t\t resv->range.start, resv->range.end, resv->iter);\n+\treturn NULL;\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_ring_resv_next);\ndiff --git a/drivers/dma/sdxi/ring.h b/drivers/dma/sdxi/ring.h\nnew file mode 100644\nindex 000000000000..d5682687c05c\n--- /dev/null\n+++ b/drivers/dma/sdxi/ring.h\n@@ -0,0 +1,84 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+/* Copyright Advanced Micro Devices, Inc. */\n+#ifndef DMA_SDXI_RING_H\n+#define DMA_SDXI_RING_H\n+\n+#include <linux/io-64-nonatomic-lo-hi.h>\n+#include <linux/range.h>\n+#include <linux/spinlock.h>\n+#include <linux/types.h>\n+#include <linux/wait.h>\n+#include <asm/barrier.h>\n+#include <asm/byteorder.h>\n+#include <asm/div64.h>\n+#include <asm/rwonce.h>\n+\n+#include \"hw.h\"\n+\n+/*\n+ * struct sdxi_ring_state - Descriptor ring management.\n+ *\n+ * @lock: Guards *read_index_ptr (RO), *write_index_ptr (RW),\n+ * write_index (RW). *read_index is incremented by hw.\n+ * @write_index: Cached write index value, minimizes dereferences in\n+ * critical sections.\n+ * @write_index_ptr: Location of the architected write index shared with\n+ * the SDXI implementation.\n+ * @read_index_ptr: Location of the architected read index shared with\n+ * the SDXI implementation.\n+ * @entries: Number of entries in the ring.\n+ * @entry: The descriptor ring itself, shared with the SDXI implementation.\n+ * @wqh: Pending reservations.\n+ */\n+struct sdxi_ring_state {\n+\tspinlock_t lock;\n+\tu64 write_index; /* Cache current value of write index. */\n+\t__le64 *write_index_ptr;\n+\tconst __le64 *read_index_ptr;\n+\tu32 entries;\n+\tstruct sdxi_desc *entry;\n+\twait_queue_head_t wqh;\n+};\n+\n+/*\n+ * Ring reservation and iteration state.\n+ */\n+struct sdxi_ring_resv {\n+\tconst struct sdxi_ring_state *rs;\n+\tstruct range range;\n+\tu64 iter;\n+};\n+\n+void sdxi_ring_state_init(struct sdxi_ring_state *ring, const __le64 *read_index,\n+\t\t\t __le64 *write_index, u32 entries,\n+\t\t\t struct sdxi_desc descs[static SZ_1K]);\n+void sdxi_ring_wake_up(struct sdxi_ring_state *rs);\n+int sdxi_ring_reserve(struct sdxi_ring_state *ring, size_t nr,\n+\t\t struct sdxi_ring_resv *resv);\n+int sdxi_ring_try_reserve(struct sdxi_ring_state *ring, size_t nr,\n+\t\t\t struct sdxi_ring_resv *resv);\n+struct sdxi_desc *sdxi_ring_resv_next(struct sdxi_ring_resv *resv);\n+\n+/* Reset reservation's internal iterator. */\n+static inline void sdxi_ring_resv_reset(struct sdxi_ring_resv *resv)\n+{\n+\tresv->iter = resv->range.start;\n+}\n+\n+/*\n+ * Return the value that should be written to the doorbell after\n+ * serializing descriptors for this reservation, i.e. the value of the\n+ * write index after obtaining the reservation.\n+ */\n+static inline u64 sdxi_ring_resv_dbval(const struct sdxi_ring_resv *resv)\n+{\n+\treturn resv->range.end + 1;\n+}\n+\n+#define sdxi_ring_resv_foreach(resv_, desc_)\t\t\t\\\n+\tfor (sdxi_ring_resv_reset(resv_),\t\t\t\\\n+\t desc_ = sdxi_ring_resv_next(resv_);\t\t\\\n+\t desc_;\t\t\t\t\t\t\\\n+\t desc_ = sdxi_ring_resv_next(resv_))\n+\n+#endif /* DMA_SDXI_RING_H */\n", "prefixes": [ "12/23" ] }