From 693b12113d974fb0b92a5446732ff0836d97d318 Mon Sep 17 00:00:00 2001 From: Ella Stanforth Date: Thu, 28 Aug 2025 15:08:42 +0100 Subject: [PATCH] util/list: Fix next instruction removal usecase for non safe iterators Introducing this iterator debug information breaks the usecase of removing elements in the list other than the current element. Fixes: 372e83b95f9 Reviewed-by: Rob Clark Reviewed-by: Erik Faye-Lund Part-of: (cherry picked from commit 68632230336d79434a04a93e894a81dff105118b) --- .pick_status.json | 2 +- src/util/list.h | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index f2a5bd9c550..afc321830c1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -6504,7 +6504,7 @@ "description": "util/list: Fix next instruction removal usecase for non safe iterators", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "372e83b95f9277fe1d09b1c65c70a38918843b6f", "notes": null diff --git a/src/util/list.h b/src/util/list.h index 97419b85572..99670ba00e3 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -44,6 +44,9 @@ #define list_assert(cond, msg) assert(cond && msg) +#define list_validate_iter(item, msg) \ + list_assert(list_is_linked(item) && !list_is_empty(item), msg) + struct list_head { struct list_head *prev; @@ -234,12 +237,10 @@ static inline void list_move_to(struct list_head *item, struct list_head *loc) { pos = list_container_of(pos->member.prev, pos, member)) #define list_for_each_entry(type, pos, head, member) \ - for (type *pos = list_entry((head)->next, type, member), \ - *__next = list_entry(pos->member.next, type, member); \ + for (type *pos = list_entry((head)->next, type, member); \ &pos->member != (head); \ - pos = list_entry(pos->member.next, type, member), \ - list_assert(pos == __next, "use _safe iterator"), \ - __next = list_entry(__next->member.next, type, member)) + list_validate_iter(&pos->member, "use _safe iterator"), \ + pos = list_entry(pos->member.next, type, member)) #define list_for_each_entry_safe(type, pos, head, member) \ for (type *pos = list_entry((head)->next, type, member), \ @@ -249,12 +250,10 @@ static inline void list_move_to(struct list_head *item, struct list_head *loc) { __next = list_entry(__next->member.next, type, member)) #define list_for_each_entry_rev(type, pos, head, member) \ - for (type *pos = list_entry((head)->prev, type, member), \ - *__prev = list_entry(pos->member.prev, type, member); \ + for (type *pos = list_entry((head)->prev, type, member); \ &pos->member != (head); \ - pos = list_entry(pos->member.prev, type, member), \ - list_assert(pos == __prev, "use _safe iterator"), \ - __prev = list_entry(__prev->member.prev, type, member)) + list_validate_iter(&pos->member, "use _safe iterator"), \ + pos = list_entry(pos->member.prev, type, member)) #define list_for_each_entry_safe_rev(type, pos, head, member) \ for (type *pos = list_entry((head)->prev, type, member), \