From edf7358a16283b8be33654a18754d9ef5d5fa69e Mon Sep 17 00:00:00 2001 From: Kaitao Cheng Date: Mon, 22 Jun 2026 12:05:31 +0800 Subject: [PATCH 1/3] list: Add mutable iterator variants The list_for_each*_safe() helpers are used when the loop body may remove the current entry. Their API exposes the temporary cursor at every call site, even though most users only need it for the iterator implementation and never reference it in the loop body. Add *_mutable() variants for list and hlist iteration. The new helpers support both forms: callers may keep passing an explicit temporary cursor when they need to inspect or reset it, or omit it and let the helper use a unique internal cursor. This makes call sites that only mutate the list through the current entry less noisy, while keeping the existing *_safe() helpers available for compatibility. Signed-off-by: Kaitao Cheng --- include/linux/list.h | 269 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 231 insertions(+), 38 deletions(-) diff --git a/include/linux/list.h b/include/linux/list.h index 09d979976b3b8..1081def7cea92 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -763,28 +764,72 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. +/* + * list_for_each_safe is an old interface, use list_for_each_mutable instead. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; \ !list_is_head(pos, (head)); \ pos = n, n = pos->next) +#define __list_for_each_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->next)->next; \ + !list_is_head(pos, (head)); \ + pos = tmp, tmp = pos->next) + +#define __list_for_each_mutable1(pos, head) \ + __list_for_each_mutable_internal(pos, __UNIQUE_ID(next), head) + +#define __list_for_each_mutable2(pos, next, head) \ + list_for_each_safe(pos, next, head) + /** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * list_for_each_mutable - iterate over a list safe against entry removal * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. + * @...: either (head) or (next, head) + * + * next: another &struct list_head to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your list. + */ +#define list_for_each_mutable(pos, ...) \ + CONCATENATE(__list_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + +/* + * list_for_each_prev_safe is an old interface, use list_for_each_prev_mutable instead. */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ !list_is_head(pos, (head)); \ pos = n, n = pos->prev) +#define __list_for_each_prev_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->prev)->prev; \ + !list_is_head(pos, (head)); \ + pos = tmp, tmp = pos->prev) + +#define __list_for_each_prev_mutable1(pos, head) \ + __list_for_each_prev_mutable_internal(pos, __UNIQUE_ID(prev), head) + +#define __list_for_each_prev_mutable2(pos, prev, head) \ + list_for_each_prev_safe(pos, prev, head) + +/** + * list_for_each_prev_mutable - iterate over a list backwards safe against entry removal + * @pos: the &struct list_head to use as a loop cursor. + * @...: either (head) or (prev, head) + * + * prev: another &struct list_head to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your list. + */ +#define list_for_each_prev_mutable(pos, ...) \ + CONCATENATE(__list_for_each_prev_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + /** * list_count_nodes - count nodes in the list * @head: the head for your list. @@ -895,12 +940,8 @@ static inline size_t list_count_nodes(struct list_head *head) for (; !list_entry_is_head(pos, head, member); \ pos = list_prev_entry(pos, member)) -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. +/* + * list_for_each_entry_safe is an old interface, use list_for_each_entry_mutable instead. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member), \ @@ -908,15 +949,36 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos = \ + list_first_entry(head, typeof(*pos), member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable2(pos, head, member) \ + __list_for_each_entry_mutable_internal(pos, __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable3(pos, next, head, member) \ + list_for_each_entry_safe(pos, next, head, member) + /** - * list_for_each_entry_safe_continue - continue list iteration safe against removal + * list_for_each_entry_mutable - iterate over a list safe against entry removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + */ +#define list_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_continue is an old interface, + * use list_for_each_entry_mutable_continue instead. */ #define list_for_each_entry_safe_continue(pos, n, head, member) \ for (pos = list_next_entry(pos, member), \ @@ -924,30 +986,79 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_continue_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos = \ + list_next_entry(pos, member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable_continue2(pos, head, member) \ + __list_for_each_entry_mutable_continue_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable_continue3(pos, next, head, member) \ + list_for_each_entry_safe_continue(pos, next, head, member) + /** - * list_for_each_entry_safe_from - iterate over list from current point safe against removal + * list_for_each_entry_mutable_continue - continue list iteration safe against removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate over list of given type from current point, safe against - * removal of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define list_for_each_entry_mutable_continue(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_continue, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_from is an old interface, + * use list_for_each_entry_mutable_from instead. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) +#define __list_for_each_entry_mutable_from_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_next_entry(tmp, member)) + +#define __list_for_each_entry_mutable_from2(pos, head, member) \ + __list_for_each_entry_mutable_from_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __list_for_each_entry_mutable_from3(pos, next, head, member) \ + list_for_each_entry_safe_from(pos, next, head, member) + /** - * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal + * list_for_each_entry_mutable_from - iterate over list from current point safe against removal * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_head within the struct. + * @...: either (head, member) or (next, head, member) * - * Iterate backwards over list of given type, safe against removal - * of list entry. + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define list_for_each_entry_mutable_from(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_from, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + +/* + * list_for_each_entry_safe_reverse is an old interface, + * use list_for_each_entry_mutable_reverse instead. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_last_entry(head, typeof(*pos), member), \ @@ -955,6 +1066,37 @@ static inline size_t list_count_nodes(struct list_head *head) !list_entry_is_head(pos, head, member); \ pos = n, n = list_prev_entry(n, member)) +#define __list_for_each_entry_mutable_reverse_internal(pos, tmp, head, member) \ + for (typeof(pos) tmp = list_prev_entry(pos = \ + list_last_entry(head, typeof(*pos), member), member); \ + !list_entry_is_head(pos, head, member); \ + pos = tmp, tmp = list_prev_entry(tmp, member)) + +#define __list_for_each_entry_mutable_reverse2(pos, head, member) \ + __list_for_each_entry_mutable_reverse_internal(pos, \ + __UNIQUE_ID(prev), head, member) + +#define __list_for_each_entry_mutable_reverse3(pos, prev, head, member) \ + list_for_each_entry_safe_reverse(pos, prev, head, member) + +/** + * list_for_each_entry_mutable_reverse - iterate backwards over list safe against removal + * @pos: the type * to use as a loop cursor. + * @...: either (head, member) or (prev, head, member) + * + * prev: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your list. + * member: the name of the list_head within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define list_for_each_entry_mutable_reverse(pos, ...) \ + CONCATENATE(__list_for_each_entry_mutable_reverse, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + /** * list_safe_reset_next - reset a stale list_for_each_entry_safe loop * @pos: the loop cursor used in the list_for_each_entry_safe loop @@ -1189,6 +1331,31 @@ static inline void hlist_splice_init(struct hlist_head *from, for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ pos = n) +#define __hlist_for_each_mutable_internal(pos, tmp, head) \ + for (typeof(pos) tmp = (pos = (head)->first) ? pos->next : NULL; \ + pos; \ + pos = tmp, tmp = pos ? pos->next : NULL) + +#define __hlist_for_each_mutable1(pos, head) \ + __hlist_for_each_mutable_internal(pos, __UNIQUE_ID(next), head) + +#define __hlist_for_each_mutable2(pos, next, head) \ + hlist_for_each_safe(pos, next, head) + +/** + * hlist_for_each_mutable - iterate over a hlist safe against entry removal + * @pos: the &struct hlist_node to use as a loop cursor. + * @...: either (head) or (next, head) + * + * next: another &struct hlist_node to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * head: the head for your hlist. + */ +#define hlist_for_each_mutable(pos, ...) \ + CONCATENATE(__hlist_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) + #define hlist_entry_safe(ptr, type, member) \ ({ typeof(ptr) ____ptr = (ptr); \ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ @@ -1224,18 +1391,44 @@ static inline void hlist_splice_init(struct hlist_head *from, for (; pos; \ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: a &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. +/* + * hlist_for_each_entry_safe is an old interface, use hlist_for_each_entry_mutable instead. */ #define hlist_for_each_entry_safe(pos, n, head, member) \ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ pos && ({ n = pos->member.next; 1; }); \ pos = hlist_entry_safe(n, typeof(*pos), member)) +#define __hlist_for_each_entry_mutable_internal(pos, tmp, head, member) \ + for (struct hlist_node *tmp = (pos = \ + hlist_entry_safe((head)->first, typeof(*pos), member)) ? \ + pos->member.next : NULL; \ + pos; \ + pos = hlist_entry_safe((tmp), typeof(*pos), member), \ + tmp = pos ? pos->member.next : NULL) + +#define __hlist_for_each_entry_mutable2(pos, head, member) \ + __hlist_for_each_entry_mutable_internal(pos, \ + __UNIQUE_ID(next), head, member) + +#define __hlist_for_each_entry_mutable3(pos, next, head, member) \ + hlist_for_each_entry_safe(pos, next, head, member) + +/** + * hlist_for_each_entry_mutable - iterate over hlist safe against entry removal + * @pos: the type * to use as a loop cursor. + * @...: either (head, member) or (next, head, member) + * + * next: a &struct hlist_node to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * head: the head for your hlist. + * member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__hlist_for_each_entry_mutable, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) + /** * hlist_count_nodes - count nodes in the hlist * @head: the head for your hlist. From 4a04a7f0d200d9070f47d5a9a68a0d5af11de867 Mon Sep 17 00:00:00 2001 From: Kaitao Cheng Date: Mon, 22 Jun 2026 12:05:32 +0800 Subject: [PATCH 2/3] llist: Add mutable iterator variants llist_for_each_safe() and llist_for_each_entry_safe() require callers to provide a temporary cursor even when the cursor is only needed by the iterator itself. This makes call sites noisier than necessary for the common case where the loop body may remove the current entry but does not otherwise inspect the saved next pointer. Add llist_for_each_mutable() and llist_for_each_entry_mutable() variants that support both forms. Callers may omit the temporary cursor and let the helper create an internal unique cursor, or keep passing an explicit cursor when the loop needs to inspect or reset it. Keep the existing safe helpers as compatibility wrappers so current users continue to build unchanged while new code can use the shorter mutable form. Signed-off-by: Kaitao Cheng --- include/linux/llist.h | 81 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/include/linux/llist.h b/include/linux/llist.h index 8846b7709669f..1c6f12411d5eb 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -49,6 +49,7 @@ */ #include +#include #include #include #include @@ -143,12 +144,33 @@ static inline bool llist_on_list(const struct llist_node *node) #define llist_for_each(pos, node) \ for ((pos) = (node); pos; (pos) = (pos)->next) +/* + * llist_for_each_safe is an old interface, use llist_for_each_mutable instead. + */ +#define llist_for_each_safe(pos, n, node) \ + for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) + +#define __llist_for_each_mutable_internal(pos, tmp, node) \ + for (typeof(pos) tmp = ((pos) = (node)) ? (pos)->next : NULL; \ + (pos); \ + (pos) = tmp, tmp = (pos) ? (pos)->next : NULL) + +#define __llist_for_each_mutable1(pos, node) \ + __llist_for_each_mutable_internal(pos, __UNIQUE_ID(next), node) + +#define __llist_for_each_mutable2(pos, next, node) \ + llist_for_each_safe(pos, next, node) + /** - * llist_for_each_safe - iterate over some deleted entries of a lock-less list - * safe against removal of list entry + * llist_for_each_mutable - iterate over some deleted entries of a lock-less list + * safe against removal of list entry * @pos: the &struct llist_node to use as a loop cursor - * @n: another &struct llist_node to use as temporary storage - * @node: the first entry of deleted list entries + * @...: either (node) or (next, node) + * + * next: another &struct llist_node to use as optional temporary storage. + * The temporary cursor is internal unless explicitly supplied by + * the caller. + * node: the first entry of deleted list entries * * In general, some entries of the lock-less list can be traversed * safely only after being deleted from list, so start with an entry @@ -159,8 +181,9 @@ static inline bool llist_on_list(const struct llist_node *node) * you want to traverse from the oldest to the newest, you must * reverse the order by yourself before traversing. */ -#define llist_for_each_safe(pos, n, node) \ - for ((pos) = (node); (pos) && ((n) = (pos)->next, true); (pos) = (n)) +#define llist_for_each_mutable(pos, ...) \ + CONCATENATE(__llist_for_each_mutable, COUNT_ARGS(__VA_ARGS__)) \ + (pos, __VA_ARGS__) /** * llist_for_each_entry - iterate over some deleted entries of lock-less list of given type @@ -182,13 +205,41 @@ static inline bool llist_on_list(const struct llist_node *node) member_address_is_nonnull(pos, member); \ (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) +/* + * llist_for_each_entry_safe is an old interface, use llist_for_each_entry_mutable instead. + */ +#define llist_for_each_entry_safe(pos, n, node, member) \ + for (pos = llist_entry((node), typeof(*pos), member); \ + member_address_is_nonnull(pos, member) && \ + (n = llist_entry(pos->member.next, typeof(*n), member), true); \ + pos = n) + +#define __llist_for_each_entry_mutable_internal(pos, tmp, node, member) \ + for (typeof(pos) tmp = ((pos) = llist_entry((node), typeof(*pos), member), \ + member_address_is_nonnull(pos, member) ? \ + llist_entry((pos)->member.next, typeof(*pos), member) : NULL); \ + member_address_is_nonnull(pos, member); \ + (pos) = tmp, tmp = member_address_is_nonnull(pos, member) ? \ + llist_entry((pos)->member.next, typeof(*pos), member) : NULL) + +#define __llist_for_each_entry_mutable2(pos, node, member) \ + __llist_for_each_entry_mutable_internal(pos, __UNIQUE_ID(next), node, member) + +#define __llist_for_each_entry_mutable3(pos, next, node, member) \ + llist_for_each_entry_safe(pos, next, node, member) + /** - * llist_for_each_entry_safe - iterate over some deleted entries of lock-less list of given type - * safe against removal of list entry + * llist_for_each_entry_mutable - iterate over some deleted entries of + * lock-less list of given type safe against + * removal of list entry * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @node: the first entry of deleted list entries. - * @member: the name of the llist_node with the struct. + * @...: either (node, member) or (next, node, member) + * + * next: another type * to use as optional temporary storage. The + * temporary cursor is internal unless explicitly supplied by the + * caller. + * node: the first entry of deleted list entries. + * member: the name of the llist_node with the struct. * * In general, some entries of the lock-less list can be traversed * safely only after being removed from list, so start with an entry @@ -199,11 +250,9 @@ static inline bool llist_on_list(const struct llist_node *node) * you want to traverse from the oldest to the newest, you must * reverse the order by yourself before traversing. */ -#define llist_for_each_entry_safe(pos, n, node, member) \ - for (pos = llist_entry((node), typeof(*pos), member); \ - member_address_is_nonnull(pos, member) && \ - (n = llist_entry(pos->member.next, typeof(*n), member), true); \ - pos = n) +#define llist_for_each_entry_mutable(pos, ...) \ + CONCATENATE(__llist_for_each_entry_mutable, \ + COUNT_ARGS(__VA_ARGS__))(pos, __VA_ARGS__) /** * llist_empty - tests whether a lock-less list is empty From fcf138b6960c32c34661d08e1f8e663818924812 Mon Sep 17 00:00:00 2001 From: Kaitao Cheng Date: Mon, 22 Jun 2026 12:19:59 +0800 Subject: [PATCH 3/3] block: Use mutable list iterators The safe list iterators require callers to provide a temporary cursor even when the cursor is only used by the iterator itself. The mutable iterator variants keep the same removal-safe traversal semantics while allowing those internal cursors to be hidden from the call sites. Convert block users of list, hlist and llist safe iterators to the new mutable helpers. Drop the now-unused temporary cursor variables where the loop body does not inspect or reset them. This is a mechanical cleanup with no intended change in traversal order or list mutation behavior. Signed-off-by: Kaitao Cheng --- block/bfq-iosched.c | 17 +++++++---------- block/blk-cgroup.c | 12 ++++++------ block/blk-flush.c | 4 ++-- block/blk-iocost.c | 18 +++++++++--------- block/blk-mq.c | 8 ++++---- block/blk-throttle.c | 4 ++-- block/kyber-iosched.c | 4 ++-- block/partitions/ldm.c | 8 ++++---- block/sed-opal.c | 4 ++-- 9 files changed, 38 insertions(+), 41 deletions(-) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 141c602d5e858..78e32ba0553d0 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -1209,9 +1209,8 @@ static int bfqq_process_refs(struct bfq_queue *bfqq) static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq) { struct bfq_queue *item; - struct hlist_node *n; - hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) + hlist_for_each_entry_mutable(item, &bfqd->burst_list, burst_list_node) hlist_del_init(&item->burst_list_node); /* @@ -1236,7 +1235,6 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { struct bfq_queue *pos, *bfqq_item; - struct hlist_node *n; /* * Enough queues have been activated shortly after each @@ -1260,8 +1258,8 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) * belonging to a large burst. So the burst list is not * needed any more. Remove it. */ - hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, - burst_list_node) + hlist_for_each_entry_mutable(pos, &bfqd->burst_list, + burst_list_node) hlist_del_init(&pos->burst_list_node); } else /* * Burst not yet large: add bfqq to the burst list. Do @@ -5330,7 +5328,6 @@ static struct request *bfq_dispatch_request(struct blk_mq_hw_ctx *hctx) void bfq_put_queue(struct bfq_queue *bfqq) { struct bfq_queue *item; - struct hlist_node *n; struct bfq_group *bfqg = bfqq_group(bfqq); bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref); @@ -5391,8 +5388,8 @@ void bfq_put_queue(struct bfq_queue *bfqq) hlist_del_init(&bfqq->woken_list_node); /* reset waker for all queues in woken list */ - hlist_for_each_entry_safe(item, n, &bfqq->woken_list, - woken_list_node) { + hlist_for_each_entry_mutable(item, &bfqq->woken_list, + woken_list_node) { item->waker_bfqq = NULL; hlist_del_init(&item->woken_list_node); } @@ -7141,13 +7138,13 @@ static void bfq_depth_updated(struct request_queue *q) static void bfq_exit_queue(struct elevator_queue *e) { struct bfq_data *bfqd = e->elevator_data; - struct bfq_queue *bfqq, *n; + struct bfq_queue *bfqq; unsigned int actuator; hrtimer_cancel(&bfqd->idle_slice_timer); spin_lock_irq(&bfqd->lock); - list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) + list_for_each_entry_mutable(bfqq, &bfqd->idle_list, bfqq_list) bfq_deactivate_bfqq(bfqd, bfqq, false, false); spin_unlock_irq(&bfqd->lock); diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 3093c1c039022..ced900019f2ea 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -997,7 +997,7 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu) { struct llist_head *lhead = per_cpu_ptr(blkcg->lhead, cpu); struct llist_node *lnode; - struct blkg_iostat_set *bisc, *next_bisc; + struct blkg_iostat_set *bisc; unsigned long flags; rcu_read_lock(); @@ -1017,17 +1017,17 @@ static void __blkcg_rstat_flush(struct blkcg *blkcg, int cpu) /* * Iterate only the iostat_cpu's queued in the lockless list. */ - llist_for_each_entry_safe(bisc, next_bisc, lnode, lnode) { + llist_for_each_entry_mutable(bisc, lnode, lnode) { struct blkcg_gq *blkg = bisc->blkg; struct blkcg_gq *parent = blkg->parent; struct blkg_iostat cur; unsigned int seq; /* - * Order assignment of `next_bisc` from `bisc->lnode.next` in - * llist_for_each_entry_safe and clearing `bisc->lqueued` for - * avoiding to assign `next_bisc` with new next pointer added - * in blk_cgroup_bio_start() in case of re-ordering. + * Order the iterator's internal `bisc->lnode.next` load before + * clearing `bisc->lqueued`, so the iterator can't pick up a new + * next pointer added in blk_cgroup_bio_start() in case of + * re-ordering. * * The pair barrier is implied in llist_add() in blk_cgroup_bio_start(). */ diff --git a/block/blk-flush.c b/block/blk-flush.c index 403a46c864117..20654c2103f2c 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -204,7 +204,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq, { struct request_queue *q = flush_rq->q; struct list_head *running; - struct request *rq, *n; + struct request *rq; unsigned long flags = 0; struct blk_flush_queue *fq = blk_get_flush_queue(flush_rq->mq_ctx); @@ -243,7 +243,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq, fq->flush_running_idx ^= 1; /* and push the waiting requests to the next stage */ - list_for_each_entry_safe(rq, n, running, queuelist) { + list_for_each_entry_mutable(rq, running, queuelist) { unsigned int seq = blk_flush_cur_seq(rq); BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH); diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 563cc7dcf3480..2ca18e52bc132 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -1718,7 +1718,7 @@ static void iocg_flush_stat_leaf(struct ioc_gq *iocg, struct ioc_now *now) static void iocg_flush_stat(struct list_head *target_iocgs, struct ioc_now *now) { LIST_HEAD(inner_walk); - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; /* flush leaves and build inner node walk list */ list_for_each_entry(iocg, target_iocgs, active_list) { @@ -1727,7 +1727,7 @@ static void iocg_flush_stat(struct list_head *target_iocgs, struct ioc_now *now) } /* keep flushing upwards by walking the inner list backwards */ - list_for_each_entry_safe_reverse(iocg, tiocg, &inner_walk, walk_list) { + list_for_each_entry_mutable_reverse(iocg, &inner_walk, walk_list) { iocg_flush_stat_upward(iocg); list_del_init(&iocg->walk_list); } @@ -1848,7 +1848,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) { LIST_HEAD(over_hwa); LIST_HEAD(inner_walk); - struct ioc_gq *iocg, *tiocg, *root_iocg; + struct ioc_gq *iocg, *root_iocg; u32 after_sum, over_sum, over_target, gamma; /* @@ -1884,7 +1884,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) over_target = 0; } - list_for_each_entry_safe(iocg, tiocg, &over_hwa, walk_list) { + list_for_each_entry_mutable(iocg, &over_hwa, walk_list) { if (over_target) iocg->hweight_after_donation = div_u64((u64)iocg->hweight_after_donation * @@ -2055,7 +2055,7 @@ static void transfer_surpluses(struct list_head *surpluses, struct ioc_now *now) } /* walk list should be dissolved after use */ - list_for_each_entry_safe(iocg, tiocg, &inner_walk, walk_list) + list_for_each_entry_mutable(iocg, &inner_walk, walk_list) list_del_init(&iocg->walk_list); } @@ -2166,9 +2166,9 @@ static void ioc_forgive_debts(struct ioc *ioc, u64 usage_us_sum, int nr_debtors, static int ioc_check_iocgs(struct ioc *ioc, struct ioc_now *now) { int nr_debtors = 0; - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; - list_for_each_entry_safe(iocg, tiocg, &ioc->active_iocgs, active_list) { + list_for_each_entry_mutable(iocg, &ioc->active_iocgs, active_list) { if (!waitqueue_active(&iocg->waitq) && !iocg->abs_vdebt && !iocg->delay && !iocg_is_idle(iocg)) continue; @@ -2234,7 +2234,7 @@ static int ioc_check_iocgs(struct ioc *ioc, struct ioc_now *now) static void ioc_timer_fn(struct timer_list *timer) { struct ioc *ioc = container_of(timer, struct ioc, timer); - struct ioc_gq *iocg, *tiocg; + struct ioc_gq *iocg; struct ioc_now now; LIST_HEAD(surpluses); int nr_debtors, nr_shortages = 0, nr_lagging = 0; @@ -2378,7 +2378,7 @@ static void ioc_timer_fn(struct timer_list *timer) commit_weights(ioc); /* surplus list should be dissolved after use */ - list_for_each_entry_safe(iocg, tiocg, &surpluses, surplus_list) + list_for_each_entry_mutable(iocg, &surpluses, surplus_list) list_del_init(&iocg->surplus_list); /* diff --git a/block/blk-mq.c b/block/blk-mq.c index 88cb5acc4f39e..2daed45ad4e7d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1216,9 +1216,9 @@ EXPORT_SYMBOL_GPL(blk_mq_end_request_batch); static void blk_complete_reqs(struct llist_head *list) { struct llist_node *entry = llist_reverse_order(llist_del_all(list)); - struct request *rq, *next; + struct request *rq; - llist_for_each_entry_safe(rq, next, entry, ipi_list) + llist_for_each_entry_mutable(rq, entry, ipi_list) rq->q->mq_ops->complete(rq); } @@ -4383,14 +4383,14 @@ static int blk_mq_alloc_ctxs(struct request_queue *q) */ void blk_mq_release(struct request_queue *q) { - struct blk_mq_hw_ctx *hctx, *next; + struct blk_mq_hw_ctx *hctx; unsigned long i; queue_for_each_hw_ctx(q, hctx, i) WARN_ON_ONCE(hctx && list_empty(&hctx->hctx_list)); /* all hctx are in .unused_hctx_list now */ - list_for_each_entry_safe(hctx, next, &q->unused_hctx_list, hctx_list) { + list_for_each_entry_mutable(hctx, &q->unused_hctx_list, hctx_list) { list_del_init(&hctx->hctx_list); kobject_put(&hctx->kobj); } diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 47052ba21d1bc..1dd4901f00f35 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1686,10 +1686,10 @@ static void tg_cancel_writeback_bios(struct throtl_grp *tg, tg->flags |= THROTL_TG_CANCELING; for (rw = READ; rw <= WRITE; rw++) { - struct throtl_qnode *qn, *tmp; + struct throtl_qnode *qn; unsigned int nr_bios = 0; - list_for_each_entry_safe(qn, tmp, &sq->queued[rw], node) { + list_for_each_entry_mutable(qn, &sq->queued[rw], node) { struct bio *bio; while ((bio = bio_list_pop(&qn->bios_iops))) { diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index 971818bcdc9db..1a509666b861b 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c @@ -578,9 +578,9 @@ static void kyber_insert_requests(struct blk_mq_hw_ctx *hctx, blk_insert_t flags) { struct kyber_hctx_data *khd = hctx->sched_data; - struct request *rq, *next; + struct request *rq; - list_for_each_entry_safe(rq, next, rq_list, queuelist) { + list_for_each_entry_mutable(rq, rq_list, queuelist) { unsigned int sched_domain = kyber_sched_domain(rq->cmd_flags); struct kyber_ctx_queue *kcq = &khd->kcqs[rq->mq_ctx->index_hw[hctx->type]]; struct list_head *head = &kcq->rq_list[sched_domain]; diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c index c0bdcae58a3ee..459f72f2148af 100644 --- a/block/partitions/ldm.c +++ b/block/partitions/ldm.c @@ -1285,11 +1285,11 @@ static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) */ static void ldm_frag_free (struct list_head *list) { - struct list_head *item, *tmp; + struct list_head *item; BUG_ON (!list); - list_for_each_safe (item, tmp, list) + list_for_each_mutable(item, list) kfree (list_entry (item, struct frag, list)); } @@ -1400,11 +1400,11 @@ static bool ldm_get_vblks(struct parsed_partitions *state, unsigned long base, */ static void ldm_free_vblks (struct list_head *lh) { - struct list_head *item, *tmp; + struct list_head *item; BUG_ON (!lh); - list_for_each_safe (item, tmp, lh) + list_for_each_mutable(item, lh) kfree (list_entry (item, struct vblk, list)); } diff --git a/block/sed-opal.c b/block/sed-opal.c index 79b290d9458a9..5bf9ebce84527 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -2573,10 +2573,10 @@ static int check_opal_support(struct opal_dev *dev) static void clean_opal_dev(struct opal_dev *dev) { - struct opal_suspend_data *suspend, *next; + struct opal_suspend_data *suspend; mutex_lock(&dev->dev_lock); - list_for_each_entry_safe(suspend, next, &dev->unlk_lst, node) { + list_for_each_entry_mutable(suspend, &dev->unlk_lst, node) { list_del(&suspend->node); kfree(suspend); }