* [PATCH v4 2/8] dt-bindings: net: wireless: qcom,ath10k: Document NVMEM cells
From: Loic Poulain @ 2026-06-09 7:52 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Jens Axboe, Johannes Berg,
Jeff Johnson, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Srinivas Kandagatla, Andrew Lunn, Heiner Kallweit,
Russell King, Saravana Kannan
Cc: linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
linux-wireless, ath10k, linux-bluetooth, netdev, daniel,
Loic Poulain, Bartosz Golaszewski
In-Reply-To: <20260609-block-as-nvmem-v4-0-45712e6b22c6@oss.qualcomm.com>
Document the NVMEM cells supported by the ath10k driver, the
mac-address, pre-calibration data, and calibration data.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
.../devicetree/bindings/net/wireless/qcom,ath10k.yaml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
index c21d66c7cd558ab792524be9afec8b79272d1c87..7391df5e7071e626af4c64b9919d48c41ac09f1e 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.yaml
@@ -92,6 +92,22 @@ properties:
ieee80211-freq-limit: true
+ nvmem-cells:
+ minItems: 1
+ maxItems: 3
+ description: |
+ References to nvmem cells for MAC address and/or calibration data.
+ Supported cell names are mac-address, calibration, and pre-calibration.
+
+ nvmem-cell-names:
+ minItems: 1
+ maxItems: 3
+ items:
+ enum:
+ - mac-address
+ - calibration
+ - pre-calibration
+
qcom,calibration-data:
$ref: /schemas/types.yaml#/definitions/uint8-array
description:
--
2.34.1
^ permalink raw reply related
* [PATCH v4 1/8] dt-bindings: mmc: Document support for nvmem-layout
From: Loic Poulain @ 2026-06-09 7:52 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Jens Axboe, Johannes Berg,
Jeff Johnson, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Srinivas Kandagatla, Andrew Lunn, Heiner Kallweit,
Russell King, Saravana Kannan
Cc: linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
linux-wireless, ath10k, linux-bluetooth, netdev, daniel,
Loic Poulain, Bartosz Golaszewski
In-Reply-To: <20260609-block-as-nvmem-v4-0-45712e6b22c6@oss.qualcomm.com>
Add support for an nvmem-layout subnode under an eMMC hardware
partition. This allows the partition to be exposed as an NVMEM
provider and its internal layout to be described. For example,
an eMMC boot partition can be used to store device-specific
information such as a WiFi MAC address.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
.../devicetree/bindings/mmc/mmc-card.yaml | 29 ++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.yaml b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
index a61d6c96df759102f9c1fbfd548b026a77921cae..ca907ad73095925b234b119948f94ae81e698c86 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-card.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
@@ -40,6 +40,9 @@ patternProperties:
contains:
const: fixed-partitions
+ nvmem-layout:
+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml
+
required:
- compatible
- reg
@@ -86,6 +89,32 @@ examples:
read-only;
};
};
+
+ partitions-boot2 {
+ compatible = "fixed-partitions";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mac-addr@4400 {
+ compatible = "mac-base";
+ reg = <0x4400 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ bd-addr@5400 {
+ compatible = "mac-base";
+ reg = <0x5400 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
};
};
--
2.34.1
^ permalink raw reply related
* [PATCH v4 0/8] Support for block device NVMEM providers
From: Loic Poulain @ 2026-06-09 7:52 UTC (permalink / raw)
To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Jens Axboe, Johannes Berg,
Jeff Johnson, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Srinivas Kandagatla, Andrew Lunn, Heiner Kallweit,
Russell King, Saravana Kannan
Cc: linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
linux-wireless, ath10k, linux-bluetooth, netdev, daniel,
Loic Poulain, Bartosz Golaszewski, Konrad Dybcio
On embedded devices, it is common for factory provisioning to store
device-specific information, such as Ethernet or WiFi MAC addresses,
in a dedicated area of an eMMC partition. This avoids the need for
and additional EEPROM/OTP and leverages the persistence of eMMC.
One example is the Arduino UNO-Q, where the WiFi MAC address and the
Bluetooth Device address are stored in the eMMC Boot1 partition.
Until now, accessing this information required a custom bootloader
to read the data and inject it into the Device Tree before handing
control over to the kernel. This approach is fragile and leads to
device-specific workarounds.
Rather than adding a new NVMEM provider specifically to the eMMC
subsystem, the new support operates at the block layer, allowing any
block device to behave like other non-volatile memories such as EEPROM
or OTP.
This series builds on earlier work by Daniel Golle that enables block
devices to act as NVMEM providers:
https://lore.kernel.org/all/6061aa4201030b9bb2f8d03ef32a564fdb786ed1.1709667858.git.daniel@makrotopia.org/
It also introduces an NVMEM layout description for the Arduino UNO-Q,
allowing device-specific data stored in the eMMC Boot1 partition to
be accessed in a standard way.
WiFi and Ethernet already support retrieving MAC addresses from NVMEM.
Bluetooth requires similar support, which is also addressed.
Note that this is currently limited to MMC-backed block devices, as
only the MMC core associates a firmware node with the block device
(add_disk_fwnode). This can be easily extended in the future to
support additional block drivers.
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
Changes in v4:
- Fix squash issue (dts commit incorrectly squashed) (Konrad)
- Use devres for nvmem resources (Bartosz)
- use __free() destructor helper when possible (Bartosz)
- Fix value return checking for bdev_file_open_by_dev
- Link to v3: https://lore.kernel.org/r/20260608-block-as-nvmem-v3-0-82681f50aa35@oss.qualcomm.com
Changes in v3:
- Fixed missing 'fixed-partitions' compatible in partition (Rob)
- Fixed clashing nvmem cells, document calibration along mac (Sashiko)
- Remove workaround to handle dangling nvmem references after
unregistering, this is a generic nvmem framework issue handled
in Bartosz's series:
https://lore.kernel.org/all/20260429-nvmem-unbind-v3-0-2a694f95395b@oss.qualcomm.com/
- Validate mac (is_valid_ether_addr) before copying to output buffer
- Link to v2: https://lore.kernel.org/r/20260507-block-as-nvmem-v2-0-bf17edd5134e@oss.qualcomm.com
Changes in v2:
- Fix example nvmem-layout cells to use compatible = "mac-base"
- Squash WiFi MAC and Bluetooth BD address consumer patches into the nvmem layout patch
- Fix possible use-after-free in blk-nvmem: bnv (nvmem priv) linked to nvmem lifetime
- Simplify nvmem-cell-names from items: - const: to plain const:
- Factor out common NVMEM EUI-48 retrieval logic
- Reorder changes
- Link to v1: https://lore.kernel.org/r/20260428-block-as-nvmem-v1-0-6ad23e75190a@oss.qualcomm.com
---
Daniel Golle (1):
block: implement NVMEM provider
Loic Poulain (7):
dt-bindings: mmc: Document support for nvmem-layout
dt-bindings: net: wireless: qcom,ath10k: Document NVMEM cells
dt-bindings: bluetooth: qcom: Add NVMEM BD address cell
net: of_net: Add of_get_nvmem_eui48() helper for EUI-48 lookup
Bluetooth: hci_sync: Add NVMEM-backed BD address retrieval
Bluetooth: qca: Set NVMEM BD address quirks when address is invalid
arm64: dts: qcom: arduino-imola: Describe NVMEM layout for WiFi/BT addresses
.../devicetree/bindings/mmc/mmc-card.yaml | 29 ++++++
.../net/bluetooth/qcom,bluetooth-common.yaml | 9 ++
.../bindings/net/wireless/qcom,ath10k.yaml | 16 +++
arch/arm64/boot/dts/qcom/qrb2210-arduino-imola.dts | 39 +++++++
block/Kconfig | 9 ++
block/Makefile | 1 +
block/blk-nvmem.c | 114 +++++++++++++++++++++
drivers/bluetooth/btqca.c | 5 +-
include/linux/of_net.h | 7 ++
include/net/bluetooth/hci.h | 18 ++++
net/bluetooth/hci_sync.c | 39 ++++++-
net/core/of_net.c | 49 ++++++---
12 files changed, 321 insertions(+), 14 deletions(-)
---
base-commit: 47c4835fc0fed583d01d90387b67633950eba2b2
change-id: 20260428-block-as-nvmem-4b308e8bda9a
Best regards,
--
Loic Poulain <loic.poulain@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH 4/4] block: add configurable error injection
From: Christoph Hellwig @ 2026-06-09 7:47 UTC (permalink / raw)
To: Bart Van Assche
Cc: Christoph Hellwig, Jens Axboe, Jonathan Corbet, Damien Le Moal,
Hannes Reinecke, Keith Busch, linux-block, linux-doc,
Hannes Reinecke
In-Reply-To: <3b276ff3-2065-4cd5-adcf-6664606d1eea@acm.org>
On Mon, Jun 08, 2026 at 03:08:47PM -0700, Bart Van Assche wrote:
> On 6/7/26 10:14 PM, Christoph Hellwig wrote:
>> +Configurable error injection allows injecting specific block layer status codes
>> +for ranges of a block device. Errors can be injected unconditionally, or with a
>
> ranges -> sector ranges?
>
>> +static void error_inject_removall(struct gendisk *disk)
> > +{
>
> Is a letter "e" perhaps missing from the above function name? (remov ->
> remove)
Sure, fixed.
^ permalink raw reply
* Re: [PATCH 3/4] block: add a str_to_blk_op helper
From: Christoph Hellwig @ 2026-06-09 7:45 UTC (permalink / raw)
To: Bart Van Assche
Cc: Christoph Hellwig, Jens Axboe, Jonathan Corbet, Damien Le Moal,
Hannes Reinecke, Keith Busch, linux-block, linux-doc,
Hannes Reinecke
In-Reply-To: <5e738f79-e1d9-4224-ae85-322967682a1a@acm.org>
On Mon, Jun 08, 2026 at 02:57:40PM -0700, Bart Van Assche wrote:
> On 6/7/26 10:14 PM, Christoph Hellwig wrote:
>> +enum req_op str_to_blk_op(const char *op)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < ARRAY_SIZE(blk_op_name); i++)
>> + if (blk_op_name[i] && !strcmp(blk_op_name[i], op))
>> + return (enum req_op)i;
>> + return REQ_OP_LAST;
>> +}
> The above function is similar but not identical to
> __sysfs_match_string(). Is __sysfs_match_string() good enough in this
> context?
__sysfs_match_string exists as soon as an array entry is NULL, but
blk_status values are not fully contiguous, so no.
^ permalink raw reply
* Re: [PATCH 2/4] block: add a "tag" for block status codes
From: Christoph Hellwig @ 2026-06-09 7:43 UTC (permalink / raw)
To: Bart Van Assche
Cc: Christoph Hellwig, Jens Axboe, Jonathan Corbet, Damien Le Moal,
Hannes Reinecke, Keith Busch, linux-block, linux-doc,
Hannes Reinecke
In-Reply-To: <f4c0895b-4758-4eb1-9c3a-38cda0db50d2@acm.org>
On Mon, Jun 08, 2026 at 02:55:20PM -0700, Bart Van Assche wrote:
> On 6/7/26 10:14 PM, Christoph Hellwig wrote:
>> +const char *blk_status_to_tag(blk_status_t status)
>> +{
>> + int idx = (__force int)status;
>> +
>> + if (WARN_ON_ONCE(idx >= ARRAY_SIZE(blk_errors)))
>> + return "<null>";
>> + return blk_errors[idx].tag;
>> +}
>
> Since designated initializers are used to initialize blk_errors[], it's
> probably a good idea to check the value of blk_errors[idx].tag, e.g. as
> follows:
>
> return blk_errors[idx].tag ?: "<null>";
I'd go for the good old and readable if statement, but yes, I can add
extra error checking here.
^ permalink raw reply
* Re: [PATCH 4/4] block: add configurable error injection
From: Christoph Hellwig @ 2026-06-09 7:41 UTC (permalink / raw)
To: Jens Axboe
Cc: Christoph Hellwig, Jonathan Corbet, Damien Le Moal,
Hannes Reinecke, Keith Busch, linux-block, linux-doc,
Hannes Reinecke
In-Reply-To: <bac50400-dd86-4c7f-bab3-481c1306877b@kernel.dk>
On Mon, Jun 08, 2026 at 08:53:22AM -0600, Jens Axboe wrote:
> > + if (!test_bit(GD_ERROR_INJECT, &bio->bi_bdev->bd_disk->state))
> > + return false;
> > + return __blk_error_inject(bio);
> > +}
>
> I really hate this part, that's a pretty deep set of pointer chasings to
> figure out if injection is enabled or not,
It's to the bdev we use everywhere, and then to the disk which we use
in a lot of places in the submission path.
The only easy way to reduce it would be to move the state to the
block_device. We currently don't do partitions in debugfs, but maybe
we should?
> when in practice error
> injection is only ever enabled for specific test cases and distros
> invariably will set CONFIG_BLK_ERROR_INJECTION because they turn on
> every damn thing under the sun.
>
> IOW, that won't fly for the hot path. Maybe a static key would be useful
> here?
a static_key makes sense here, probably including the legacy error
injection.
^ permalink raw reply
* Re: [PATCH] block: optimize I/O merge hot path with unlikely() hints
From: Christoph Hellwig @ 2026-06-09 7:38 UTC (permalink / raw)
To: Steven Feng; +Cc: Jens Axboe, linux-block, linux-kernel
In-Reply-To: <tencent_79B652BD0CC23E093F27914380F161E7E505@qq.com>
On Sat, Jun 06, 2026 at 10:42:18AM +0800, Steven Feng wrote:
> Remove redundant '== false' comparisons and add unlikely() branch
> prediction hints in block I/O merge path functions.
>
> These functions (ll_new_hw_segment, ll_merge_requests_fn, and
> blk_rq_merge_ok) are executed on every I/O request merge attempt,
> making them critical hot paths. Data integrity check failures are
> rare events, so marking these conditions as unlikely() helps the
> CPU optimize the common case by improving branch prediction.
Umm, these are not failures. Just conditions to not merge because
of this, and not merging, both because of these conditions and others,
it the most common case for most workloads.
With your patch the object file size of blk-merge.o increases slightly
for me on x86_64:
text data bss dec hex filename
12299 577 0 12876 324c block/blk-merge.o.old
12331 577 0 12908 326c block/blk-merge.o
and looking at the assembly this is due to worse code generation
because it now splits different error returns.
What kind of optimization are you attempting and how did you measure
the results of this "optimizatіon"?
^ permalink raw reply
* Re: [LSF/MM/BPF TOPIC] Memory fragmentation with large block sizes
From: Christoph Hellwig @ 2026-06-09 7:28 UTC (permalink / raw)
To: Hannes Reinecke
Cc: lsf-pc, linux-nvme@lists.infradead.org,
linux-block@vger.kernel.org, linux-mm
In-Reply-To: <f22caf98-1375-493a-a275-0500ffac3e81@suse.de>
Hannes,
can you share your results on the mailing list?
On Thu, Feb 19, 2026 at 10:54:48AM +0100, Hannes Reinecke wrote:
> Hi all,
>
> I (together with the Czech Technical University) did some experiments trying
> to measure memory fragmentation with large block sizes.
> Testbed used was an nvme setup talking to a nvmet storage over
> the network.
>
> Doing so raised some challenges:
>
> - How do you _generate_ memory fragmentation? The MM subsystem is
> precisely geared up to avoid it, so you would need to come up
> with some idea how to defeat it. With the help from Willy I managed
> to come up with something, but I really would like to discuss
> what would be the best option here.
> - What is acceptable memory fragmentation? Are we good enough if the
> measured fragmentation does not grow during the test runs?
> - Do we have better visibility into memory fragmentation other than
> just reading /proc/buddyinfo?
>
> And, of course, I would like to present (and discuss) the results
> of the testruns done on 4k, 8k, and 16k blocksizes.
>
> Not sure if this should be a storage or MM topic; I'll let the
> lsf-pc decide.
>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke Kernel Storage Architect
> hare@suse.de +49 911 74053 688
> SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
> HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
>
>
---end quoted text---
^ permalink raw reply
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
From: Andy Shevchenko @ 2026-06-09 7:05 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng
In-Reply-To: <aie299WveL1utNya@ashevche-desk.local>
On Tue, Jun 09, 2026 at 09:47:34AM +0300, Andy Shevchenko wrote:
> On Tue, Jun 09, 2026 at 02:13:33PM +0800, Kaitao Cheng wrote:
> >
> > This series prepares for, and then updates, the list_for_each_entry()
> > family so the common entry iterators cache their next or previous cursor
> > before the loop body runs.
While code looks okay, this doesn't explain "why?" aspects.
> > The first 13 patches open-code loops that intentionally depend on the
> > old "derive the next entry from the current cursor at the end of the
> > iteration" behaviour. These loops append work to the list being walked,
> > restart traversal after dropping a lock, skip an entry consumed by the
> > current iteration, or otherwise adjust the cursor in the loop body.
> >
> > The final patch changes include/linux/list.h to keep a private cursor in
> > the common entry iterators while preserving the public macro interface.
> > The safe variants remain available when callers need the temporary
> > cursor explicitly or have stronger mutation requirements.
>
> Something is really wrong with the patch series email chaining.
> Patches 3, 10, and 13 start the subthreads. Please, check your
> tools and fix them accordingly.
>
> Note, `git format-patch ...` should not have this "side-effect"
> when used correctly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 07/14] spi: fsi: Open-code message transfer walk
From: Andy Shevchenko @ 2026-06-09 7:02 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaitao Cheng
In-Reply-To: <20260609062526.94907-5-kaitao.cheng@linux.dev>
On Tue, Jun 09, 2026 at 02:25:19PM +0800, Kaitao Cheng wrote:
>
> A later change will make list_for_each_entry() cache the next element
> before entering the loop body. fsi_spi_transfer_one_message() can combine
> the current transfer with the following transfer and then advance the
> cursor to that consumed entry.
>
> Keep the transfer walk open-coded so the loop step observes that cursor
> update and skips the consumed transfer. This preserves the existing
> message sequencing semantics and prepares the code for the list iterator
> update.
...
> - list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
> + for (transfer = list_first_entry(&mesg->transfers,
> + typeof(*transfer), transfer_list);
You can keep this on a single line for more logical split.
for (transfer = list_first_entry(&mesg->transfers, typeof(*transfer), transfer_list);
it's under relaxed limits for the line length.
> + !list_entry_is_head(transfer, &mesg->transfers, transfer_list);
> + transfer = list_next_entry(transfer, transfer_list)) {
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk
From: Andy Shevchenko @ 2026-06-09 7:00 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaitao Cheng
In-Reply-To: <20260609062526.94907-2-kaitao.cheng@linux.dev>
On Tue, Jun 09, 2026 at 02:25:16PM +0800, Kaitao Cheng wrote:
>
> A later change will make list_for_each_entry() cache the next element
> before entering the loop body. __intel_gt_unset_wedged() drops
> timelines->lock while waiting on a fence and then restarts the walk from
> the list head after the lock is reacquired.
>
> Keep the loop open-coded so the next timeline is selected after that
> restart logic has run. This preserves the existing lock-drop traversal
> semantics and prepares the code for the list iterator update.
...
> spin_lock(&timelines->lock);
> - list_for_each_entry(tl, &timelines->active_list, link) {
> + for (tl = list_first_entry(&timelines->active_list, typeof(*tl), link);
> + !list_entry_is_head(tl, &timelines->active_list, link);
> + tl = list_next_entry(tl, link)) {
Yeah, these cases should rather be converted to do {} while or while-loop.
This will make the intention clearer and reduces the possibility that someone
mistakenly changes these back to use list_for_each_entry().
See, for example, deferred_probe_work_func() implementation.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state
From: Andy Shevchenko @ 2026-06-09 6:47 UTC (permalink / raw)
To: Kaitao Cheng
Cc: Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Matthew Auld, Matthew Brost, Waiman Long,
drbd-dev, linux-block, linux1394-devel, dri-devel, intel-gfx,
linux-spi, linux-stm32, linux-arm-kernel, linux-tegra,
linux-sound, linux-kernel, Andrew Morton, Randy Dunlap,
Christian Brauner, David Howells, Luca Ceresoli, Kaito Cheng
In-Reply-To: <20260609061347.93688-1-kaitao.cheng@linux.dev>
On Tue, Jun 09, 2026 at 02:13:33PM +0800, Kaitao Cheng wrote:
>
> This series prepares for, and then updates, the list_for_each_entry()
> family so the common entry iterators cache their next or previous cursor
> before the loop body runs.
>
> The first 13 patches open-code loops that intentionally depend on the
> old "derive the next entry from the current cursor at the end of the
> iteration" behaviour. These loops append work to the list being walked,
> restart traversal after dropping a lock, skip an entry consumed by the
> current iteration, or otherwise adjust the cursor in the loop body.
>
> The final patch changes include/linux/list.h to keep a private cursor in
> the common entry iterators while preserving the public macro interface.
> The safe variants remain available when callers need the temporary
> cursor explicitly or have stronger mutation requirements.
Something is really wrong with the patch series email chaining.
Patches 3, 10, and 13 start the subthreads. Please, check your
tools and fix them accordingly.
Note, `git format-patch ...` should not have this "side-effect"
when used correctly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH v2 14/14] list: Cache cursors in entry iterators
From: Kaitao Cheng @ 2026-06-09 6:41 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609064122.95825-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
The non-safe list_for_each_entry() family advances by deriving the next
element from the current cursor in the loop step. If the loop body
unlinks the current entry, the step can no longer rely on the current
entry's list pointers.
Callers can use the _safe variants today, but those interfaces require a
temporary cursor to be declared outside the macro. That is necessary when
the caller actually needs the temporary cursor, but it looks redundant
and awkward when the cursor is only there to satisfy the macro and is
never otherwise used.
Add private next and previous cursors for the common entry iterators and
use unique internal names so callers keep the same interface. This lets
the loop step use a cursor captured before the body runs, while callers
that need to alter traversal state can still open-code the walk.
The safe variants remain useful when the caller needs access to the
temporary cursor or has stronger mutation requirements. Update their
comments to steer users toward the simpler iterators when that temporary
cursor is not needed.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
include/linux/list.h | 46 +++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/include/linux/list.h b/include/linux/list.h
index 09d979976b3b..9df84a56a789 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -809,6 +809,29 @@ static inline size_t list_count_nodes(struct list_head *head)
#define list_entry_is_head(pos, head, member) \
list_is_head(&pos->member, (head))
+#define __list_for_each_entry(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos = \
+ list_first_entry(head, typeof(*pos), member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
+#define __list_for_each_entry_reverse(pos, prev, head, member) \
+ for (typeof(pos) prev = list_prev_entry(pos = \
+ list_last_entry(head, typeof(*pos), member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = prev, prev = list_prev_entry(prev, member))
+
+#define __list_for_each_entry_continue(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos = \
+ list_next_entry(pos, member), member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
+#define __list_for_each_entry_from(pos, next, head, member) \
+ for (typeof(pos) next = list_next_entry(pos, member); \
+ !list_entry_is_head(pos, head, member); \
+ pos = next, next = list_next_entry(next, member))
+
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
@@ -816,9 +839,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
- for (pos = list_first_entry(head, typeof(*pos), member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
@@ -827,9 +848,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_last_entry(head, typeof(*pos), member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_prev_entry(pos, member))
+ __list_for_each_entry_reverse(pos, __UNIQUE_ID(prev), head, member)
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
@@ -852,9 +871,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_next_entry(pos, member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry_continue(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
@@ -879,8 +896,7 @@ static inline size_t list_count_nodes(struct list_head *head)
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
- for (; !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+ __list_for_each_entry_from(pos, __UNIQUE_ID(next), head, member)
/**
* list_for_each_entry_from_reverse - iterate backwards over list of given type
@@ -901,6 +917,8 @@ static inline size_t list_count_nodes(struct list_head *head)
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
+ *
+ * Prefer list_for_each_entry() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
@@ -917,6 +935,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
+ *
+ * Prefer list_for_each_entry_continue() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_next_entry(pos, member), \
@@ -933,6 +953,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
+ *
+ * Prefer list_for_each_entry_from() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_next_entry(pos, member); \
@@ -948,6 +970,8 @@ static inline size_t list_count_nodes(struct list_head *head)
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
+ *
+ * Prefer list_for_each_entry_reverse() unless the temporary cursor is needed.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, typeof(*pos), member), \
--
2.43.0
^ permalink raw reply related
* [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk
From: Kaitao Cheng @ 2026-06-09 6:41 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609061347.93688-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. dapm_widget_invalidate_paths() appends
newly reached widgets to the temporary work list while walking it.
Keep the work-list walk open-coded so the next widget is looked up after
new widgets have been appended. This preserves the existing invalidation
traversal semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
sound/soc/soc-dapm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d6192204e613..5bd921fca132 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -255,7 +255,9 @@ static __always_inline void dapm_widget_invalidate_paths(
list_add_tail(&w->work_list, &list);
w->endpoints[dir] = -1;
- list_for_each_entry(w, &list, work_list) {
+ for (w = list_first_entry(&list, typeof(*w), work_list);
+ !list_entry_is_head(w, &list, work_list);
+ w = list_next_entry(w, work_list)) {
snd_soc_dapm_widget_for_each_path(w, dir, p) {
if (p->is_supply || !p->connect)
continue;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder list walk
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609063855.95710-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stress_reorder_work() can move list
entries while handling wound/wait locking conflicts and then continue
from the adjusted cursor.
Keep the list walk open-coded so the loop step observes the cursor
selected by the body. This preserves the existing stress-test traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
kernel/locking/test-ww_mutex.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c
index 838d631544ed..08a6ab5ac041 100644
--- a/kernel/locking/test-ww_mutex.c
+++ b/kernel/locking/test-ww_mutex.c
@@ -519,7 +519,9 @@ static void stress_reorder_work(struct work_struct *work)
do {
ww_acquire_init(&ctx, stress->class);
- list_for_each_entry(ll, &locks, link) {
+ for (ll = list_first_entry(&locks, typeof(*ll), link);
+ !list_entry_is_head(ll, &locks, link);
+ ll = list_next_entry(ll, link)) {
err = ww_mutex_lock(ll->lock, &ctx);
if (!err)
continue;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609063855.95710-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. The ww-mutex torture path can move list
entries while it resolves a wound/wait conflict and then continue from
the adjusted cursor.
Keep the list walk open-coded so the loop step observes the cursor
selected by the body. This preserves the existing stress-test traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
kernel/locking/locktorture.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index e618bcf75e2d..0eb75e9bccaa 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -644,7 +644,9 @@ __acquires(torture_ww_mutex_2)
ww_acquire_init(ctx, &torture_ww_class);
- list_for_each_entry(ll, &list, link) {
+ for (ll = list_first_entry(&list, typeof(*ll), link);
+ !list_entry_is_head(ll, &list, link);
+ ll = list_next_entry(ll, link)) {
int err;
err = ww_mutex_lock(ll->lock, ctx);
--
2.43.0
^ permalink raw reply related
* [PATCH v2 10/14] spi: tegra210-quad: Open-code message transfer walk
From: Kaitao Cheng @ 2026-06-09 6:38 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609061347.93688-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. tegra_qspi_non_combined_seq_xfer() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-tegra210-quad.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index db28dd556484..42dd5cf53c67 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -1302,7 +1302,9 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
if (tqspi->soc_data->supports_tpm)
val &= ~QSPI_TPM_WAIT_POLL_EN;
tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers, typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
struct spi_transfer *xfer = transfer;
u8 dummy_bytes = 0;
u32 cmd1;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 09/14] spi: stm32-qspi: Open-code message transfer walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stm32_qspi_transfer_one_message() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-stm32-qspi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index df1bbacec90a..27d82a578c9f 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -577,7 +577,10 @@ static int stm32_qspi_transfer_one_message(struct spi_controller *ctrl,
gpiod_set_value_cansleep(spi_get_csgpiod(spi, 0), true);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers,
+ typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
u8 dummy_bytes = 0;
memset(&op, 0, sizeof(op));
--
2.43.0
^ permalink raw reply related
* [PATCH v2 08/14] spi: stm32-ospi: Open-code message transfer walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. stm32_ospi_transfer_one_message() can
consume the following transfer as part of the current operation and then
advance the loop cursor to that entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-stm32-ospi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
index 4461c6e24b9e..4dc2b56b4c20 100644
--- a/drivers/spi/spi-stm32-ospi.c
+++ b/drivers/spi/spi-stm32-ospi.c
@@ -675,7 +675,9 @@ static int stm32_ospi_transfer_one_message(struct spi_controller *ctrl,
gpiod_set_value_cansleep(cs_gpiod, true);
- list_for_each_entry(transfer, &msg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&msg->transfers, typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &msg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
u8 dummy_bytes = 0;
memset(&op, 0, sizeof(op));
--
2.43.0
^ permalink raw reply related
* [PATCH v2 07/14] spi: fsi: Open-code message transfer walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. fsi_spi_transfer_one_message() can combine
the current transfer with the following transfer and then advance the
cursor to that consumed entry.
Keep the transfer walk open-coded so the loop step observes that cursor
update and skips the consumed transfer. This preserves the existing
message sequencing semantics and prepares the code for the list iterator
update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/spi/spi-fsi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c
index f6a75f0184c4..44999f00f5f6 100644
--- a/drivers/spi/spi-fsi.c
+++ b/drivers/spi/spi-fsi.c
@@ -434,7 +434,10 @@ static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,
if (rc)
goto error;
- list_for_each_entry(transfer, &mesg->transfers, transfer_list) {
+ for (transfer = list_first_entry(&mesg->transfers,
+ typeof(*transfer), transfer_list);
+ !list_entry_is_head(transfer, &mesg->transfers, transfer_list);
+ transfer = list_next_entry(transfer, transfer_list)) {
struct fsi_spi_sequence seq;
struct spi_transfer *next = NULL;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 06/14] drm/ttm: Open-code reservation list walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. ttm_eu_reserve_buffers() may move the
current validation buffer to the duplicates list and then rewinds the
cursor before continuing.
Keep the reservation walk open-coded so the loop step uses the cursor
selected by that duplicate handling. This preserves the existing
traversal semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/ttm/ttm_execbuf_util.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
index bc7a83a9fe44..8072f07d5557 100644
--- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
+++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
@@ -86,7 +86,9 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
if (ticket)
ww_acquire_init(ticket, &reservation_ww_class);
- list_for_each_entry(entry, list, head) {
+ for (entry = list_first_entry(list, typeof(*entry), head);
+ !list_entry_is_head(entry, list, head);
+ entry = list_next_entry(entry, head)) {
struct ttm_buffer_object *bo = entry->bo;
unsigned int num_fences;
--
2.43.0
^ permalink raw reply related
* [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. __i915_schedule() builds its DFS work list
while walking it by moving newly discovered dependencies to the tail.
Keep the DFS walk open-coded so the next dependency is resolved after any
tail moves performed by the body. This preserves the existing traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/i915/i915_scheduler.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index aec1342402ca..da1f60282df8 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -190,7 +190,9 @@ static void __i915_schedule(struct i915_sched_node *node,
* end result is a topological list of requests in reverse order, the
* last element in the list is the request we must execute first.
*/
- list_for_each_entry(dep, &dfs, dfs_link) {
+ for (dep = list_first_entry(&dfs, typeof(*dep), dfs_link);
+ !list_entry_is_head(dep, &dfs, dfs_link);
+ dep = list_next_entry(dep, dfs_link)) {
struct i915_sched_node *node = dep->signaler;
/* If we are already flying, we know we have no signalers */
--
2.43.0
^ permalink raw reply related
* [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609062526.94907-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry() cache the next element
before entering the loop body. __intel_gt_unset_wedged() drops
timelines->lock while waiting on a fence and then restarts the walk from
the list head after the lock is reacquired.
Keep the loop open-coded so the next timeline is selected after that
restart logic has run. This preserves the existing lock-drop traversal
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/i915/gt/intel_reset.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index adff482a6c9c..fe0d87e248a7 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1077,7 +1077,9 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
* No more can be submitted until we reset the wedged bit.
*/
spin_lock(&timelines->lock);
- list_for_each_entry(tl, &timelines->active_list, link) {
+ for (tl = list_first_entry(&timelines->active_list, typeof(*tl), link);
+ !list_entry_is_head(tl, &timelines->active_list, link);
+ tl = list_next_entry(tl, link)) {
struct dma_fence *fence;
fence = i915_active_fence_get(&tl->last_request);
--
2.43.0
^ permalink raw reply related
* [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks
From: Kaitao Cheng @ 2026-06-09 6:25 UTC (permalink / raw)
To: Andy Shevchenko, Muchun Song, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Takashi Sakamoto,
Andrzej Hajda, Neil Armstrong, Robert Foss, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
Christian Koenig, Huang Rui, Eddie James, Mark Brown,
Maxime Coquelin, Alexandre Torgue, Laxman Dewangan,
Thierry Reding, Jonathan Hunter, Sowjanya Komatineni,
Davidlohr Bueso, Paul E . McKenney, Josh Triplett, Peter Zijlstra,
Ingo Molnar, Will Deacon, Boqun Feng, Liam Girdwood,
Jaroslav Kysela, Takashi Iwai
Cc: Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Matthew Auld,
Matthew Brost, Waiman Long, drbd-dev, linux-block,
linux1394-devel, dri-devel, intel-gfx, linux-spi, linux-stm32,
linux-arm-kernel, linux-tegra, linux-sound, linux-kernel,
Andrew Morton, Randy Dunlap, Christian Brauner, David Howells,
Luca Ceresoli, Kaitao Cheng, Kaitao Cheng
In-Reply-To: <20260609061347.93688-1-kaitao.cheng@linux.dev>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
A later change will make list_for_each_entry_from() and
list_for_each_entry_reverse() cache the next or previous element before
entering the loop body. The bridge enable and disable ordering code
adjusts its cursor to skip ranges that have already been handled.
Keep those walks open-coded so the loop step observes the cursor
selected by the body. This preserves the existing bridge ordering
semantics and prepares the code for the list iterator update.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
drivers/gpu/drm/drm_bridge.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index d6f512b73389..a538aabc4e0b 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -868,7 +868,8 @@ void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
encoder = bridge->encoder;
- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ for (; !list_entry_is_head(bridge, &encoder->bridge_chain, chain_node);
+ bridge = list_next_entry(bridge, chain_node)) {
limit = NULL;
if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) {
@@ -962,7 +963,9 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
encoder = bridge->encoder;
- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
+ for (iter = list_last_entry(&encoder->bridge_chain, typeof(*iter), chain_node);
+ !list_entry_is_head(iter, &encoder->bridge_chain, chain_node);
+ iter = list_prev_entry(iter, chain_node)) {
if (iter->pre_enable_prev_first) {
next = iter;
limit = bridge;
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox