* [LTP] [PATCH] uevent02: Make wait_for_uevents() order-independent
@ 2026-08-25 17:14 Avinesh Kumar via ltp
2026-08-25 17:36 ` [LTP] " linuxtestproject.agent
0 siblings, 1 reply; 14+ messages in thread
From: Avinesh Kumar via ltp @ 2026-08-25 17:14 UTC (permalink / raw)
To: ltp
From: Avinesh Kumar <avinesh.kumar@suse.com>
Commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD uevent until the
device is published")[0] in kernel v7.2 changed register_netdevice()
to emit a network interface's own "add" uevent only after the
interface is fully registered, instead of before its queue kobjects
are created. This flips the uevent order for tun device creation from:
add(net), add(rx queue), add(tx queue)
to:
add(rx queue), add(tx queue), add(net)
wait_for_uevents() matched events strictly in the order given in the
uevents array, so on kernels with the reordered uevents the "add(net)"
event only matches once the rx/tx queue events have already been
consumed from the socket, leaving wait_for_uevents() stuck waiting for
events that already went by, until uevent02 times out and fails.
Since the relative order of unrelated uevents is a kernel
implementation detail the test should not depend on, make
wait_for_uevents() track the still-unmatched events in a pending set
and match incoming uevents against any of them, regardless of
position.
[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e63c9e6179a
Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
testcases/kernel/uevents/uevent.h | 37 ++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/testcases/kernel/uevents/uevent.h b/testcases/kernel/uevents/uevent.h
index 1ad092d5ea39..b4e4fce2b2f5 100644
--- a/testcases/kernel/uevents/uevent.h
+++ b/testcases/kernel/uevents/uevent.h
@@ -117,15 +117,30 @@ static inline int open_uevent_netlink(void)
return fd;
}
+#define UEVENT_MAX_PENDING 16
+
/*
* Reads events from uevent netlink socket until all expected events passed in
- * the uevent array are matched.
+ * the uevent array are matched. Events do not have to arrive in the order
+ * they are listed in the uevents array, since the kernel is free to reorder
+ * unrelated uevents, e.g. commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD
+ * uevent until the device is published") changed the order in which a
+ * network interface and its queues announce themselves.
*/
static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[])
{
- int i = 0;
+ const struct uevent_desc *pending[UEVENT_MAX_PENDING];
+ int i, cnt = 0, remaining;
+
+ while (uevents[cnt]) {
+ if (cnt >= UEVENT_MAX_PENDING)
+ tst_brk(TBROK, "Too many expected uevents, increase UEVENT_MAX_PENDING");
+ pending[cnt] = uevents[cnt];
+ cnt++;
+ }
+ remaining = cnt;
- while (1) {
+ while (remaining) {
int len;
char buf[4096];
@@ -136,14 +151,20 @@ static inline void wait_for_uevents(int fd, const struct uevent_desc *const ueve
print_uevent(buf, len);
- if (uevent_match(buf, len, uevents[i])) {
- tst_res(TPASS, "Got expected UEVENT");
- if (!uevents[++i]) {
- close(fd);
- return;
+ for (i = 0; i < cnt; i++) {
+ if (!pending[i])
+ continue;
+
+ if (uevent_match(buf, len, pending[i])) {
+ tst_res(TPASS, "Got expected UEVENT");
+ pending[i] = NULL;
+ remaining--;
+ break;
}
}
}
+
+ close(fd);
}
/*
--
2.55.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [LTP] uevent02: Make wait_for_uevents() order-independent 2026-08-25 17:14 [LTP] [PATCH] uevent02: Make wait_for_uevents() order-independent Avinesh Kumar via ltp @ 2026-08-25 17:36 ` linuxtestproject.agent 2026-08-28 15:26 ` [LTP] [PATCH v2] " Avinesh Kumar via ltp 0 siblings, 1 reply; 14+ messages in thread From: linuxtestproject.agent @ 2026-08-25 17:36 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi Avinesh, On Tue, 25 Aug 2026, Avinesh Kumar wrote: > uevent02: Make wait_for_uevents() order-independent > + for (i = 0; i < cnt; i++) { > + if (!pending[i]) > + continue; > + > + if (uevent_match(buf, len, pending[i])) { > + tst_res(TPASS, "Got expected UEVENT"); > + pending[i] = NULL; > + remaining--; > + break; > } > } Could this preserve ordering between dependent lifecycle phases? The callers put add and remove events for the same objects in one array. Matching every pending entry means that a remove received before its add is accepted, causing the test to pass despite an invalid lifecycle order. The kernel change only requires the interface and queue add events to be order-independent. Could each independent group be matched without order while retaining the ordering between the add and remove phases? Verdict - Needs revision --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v2] uevent02: Make wait_for_uevents() order-independent 2026-08-25 17:36 ` [LTP] " linuxtestproject.agent @ 2026-08-28 15:26 ` Avinesh Kumar via ltp 2026-08-28 21:09 ` [LTP] " linuxtestproject.agent ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Avinesh Kumar via ltp @ 2026-08-28 15:26 UTC (permalink / raw) To: ltp From: Avinesh Kumar <avinesh.kumar@suse.com> Commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD uevent until the device is published")[0] moved a network interface's "add" uevent to after its queue kobjects are created, flipping the uevent order for tun device creation from: add(net), add(rx queue), add(tx queue) to: add(rx queue), add(tx queue), add(net) wait_for_uevents() matches events strictly in array order, so on kernels with the new order "add(net)" is still awaited after its queue events have already been consumed off the socket, and uevent02 hangs until it times out and fails. The relative order of these uevents is a kernel implementation detail the test shouldn't depend on. Track still-unmatched events in a pending set and match incoming uevents against any of them regardless of position. wait_for_uevents() leaves fd open so it can be called more than once on the same socket, keeping independent lifecycle phases ordered: uevent02 matches all add events before looking for the remove events. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e63c9e6179a Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com> --- testcases/kernel/uevents/uevent.h | 39 +++++++++++++++++++++++------ testcases/kernel/uevents/uevent02.c | 28 +++++++++++++-------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/testcases/kernel/uevents/uevent.h b/testcases/kernel/uevents/uevent.h index 1ad092d5ea39..f7e7c671e499 100644 --- a/testcases/kernel/uevents/uevent.h +++ b/testcases/kernel/uevents/uevent.h @@ -117,15 +117,34 @@ static inline int open_uevent_netlink(void) return fd; } +#define UEVENT_MAX_PENDING 16 + /* * Reads events from uevent netlink socket until all expected events passed in - * the uevent array are matched. + * the uevent array are matched. Events do not have to arrive in the order + * they are listed in the uevents array, since the kernel is free to reorder + * unrelated uevents, e.g. commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD + * uevent until the device is published") changed the order in which a + * network interface and its queues announce themselves. + * + * Does not close fd; the caller owns the socket and can call this more + * than once on it to keep independent lifecycle phases ordered, e.g. + * matching all "add" events before looking for "remove" events. */ static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[]) { - int i = 0; + const struct uevent_desc *pending[UEVENT_MAX_PENDING]; + int i, cnt = 0, remaining; + + while (uevents[cnt]) { + if (cnt >= UEVENT_MAX_PENDING) + tst_brk(TBROK, "Too many expected uevents, increase UEVENT_MAX_PENDING"); + pending[cnt] = uevents[cnt]; + cnt++; + } + remaining = cnt; - while (1) { + while (remaining) { int len; char buf[4096]; @@ -136,11 +155,15 @@ static inline void wait_for_uevents(int fd, const struct uevent_desc *const ueve print_uevent(buf, len); - if (uevent_match(buf, len, uevents[i])) { - tst_res(TPASS, "Got expected UEVENT"); - if (!uevents[++i]) { - close(fd); - return; + for (i = 0; i < cnt; i++) { + if (!pending[i]) + continue; + + if (uevent_match(buf, len, pending[i])) { + tst_res(TPASS, "Got expected UEVENT"); + pending[i] = NULL; + remaining--; + break; } } } diff --git a/testcases/kernel/uevents/uevent02.c b/testcases/kernel/uevents/uevent02.c index 1135f55a87db..26c0dbd10547 100644 --- a/testcases/kernel/uevents/uevent02.c +++ b/testcases/kernel/uevents/uevent02.c @@ -25,7 +25,8 @@ #include "uevent.h" #define TUN_PATH "/dev/net/tun" -#define MAX_UEVENTS 7 +#define MAX_ADD_UEVENTS 4 +#define MAX_REM_UEVENTS 4 static struct uevent_desc add = { .msg = "add@/devices/virtual/net/ltp-tun0", @@ -88,7 +89,8 @@ static struct uevent_desc rem = { "INTERFACE=ltp-tun0", } }; -static const struct uevent_desc *uevents[MAX_UEVENTS]; +static const struct uevent_desc *add_uevents[MAX_ADD_UEVENTS]; +static const struct uevent_desc *rem_uevents[MAX_REM_UEVENTS]; static void generate_tun_uevents(void) { @@ -114,7 +116,9 @@ static void verify_uevent(void) if (!pid) { fd = open_uevent_netlink(); TST_CHECKPOINT_WAKE(0); - wait_for_uevents(fd, uevents); + wait_for_uevents(fd, add_uevents); + wait_for_uevents(fd, rem_uevents); + close(fd); exit(0); } @@ -128,19 +132,21 @@ static void verify_uevent(void) static void setup(void) { struct tst_kconfig_var kconfig = TST_KCONFIG_INIT("CONFIG_RPS"); - int i = 0; + int i = 0, j = 0; tst_kconfig_read(&kconfig, 1); - uevents[i++] = &add; + add_uevents[i++] = &add; if (kconfig.choice == 'y') - uevents[i++] = &add_rx; - uevents[i++] = &add_tx; + add_uevents[i++] = &add_rx; + add_uevents[i++] = &add_tx; + add_uevents[i++] = NULL; + if (kconfig.choice == 'y') - uevents[i++] = &rem_rx; - uevents[i++] = &rem_tx; - uevents[i++] = &rem; - uevents[i++] = NULL; + rem_uevents[j++] = &rem_rx; + rem_uevents[j++] = &rem_tx; + rem_uevents[j++] = &rem; + rem_uevents[j++] = NULL; } static struct tst_test test = { -- 2.55.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] uevent02: Make wait_for_uevents() order-independent 2026-08-28 15:26 ` [LTP] [PATCH v2] " Avinesh Kumar via ltp @ 2026-08-28 21:09 ` linuxtestproject.agent 2026-09-03 13:25 ` [LTP] [PATCH v2] " Andrea Cervesato via ltp 2026-09-03 14:42 ` Cyril Hrubis 2 siblings, 0 replies; 14+ messages in thread From: linuxtestproject.agent @ 2026-08-28 21:09 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi Avinesh, On Fri, 28 Aug 2026, Avinesh Kumar wrote: > uevent02: Make wait_for_uevents() order-independent Verdict - Reviewed --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v2] uevent02: Make wait_for_uevents() order-independent 2026-08-28 15:26 ` [LTP] [PATCH v2] " Avinesh Kumar via ltp 2026-08-28 21:09 ` [LTP] " linuxtestproject.agent @ 2026-09-03 13:25 ` Andrea Cervesato via ltp 2026-09-03 14:42 ` Cyril Hrubis 2 siblings, 0 replies; 14+ messages in thread From: Andrea Cervesato via ltp @ 2026-09-03 13:25 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Acked-by: Andrea Cervesato <andrea.cervesato@suse.com> -- Andrea Cervesato SUSE QE Automation Engineer Linux andrea.cervesato@suse.com -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v2] uevent02: Make wait_for_uevents() order-independent 2026-08-28 15:26 ` [LTP] [PATCH v2] " Avinesh Kumar via ltp 2026-08-28 21:09 ` [LTP] " linuxtestproject.agent 2026-09-03 13:25 ` [LTP] [PATCH v2] " Andrea Cervesato via ltp @ 2026-09-03 14:42 ` Cyril Hrubis 2026-09-07 19:44 ` [LTP] [PATCH v3] " Avinesh Kumar via ltp 2 siblings, 1 reply; 14+ messages in thread From: Cyril Hrubis @ 2026-09-03 14:42 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi! > static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[]) > { > - int i = 0; > + const struct uevent_desc *pending[UEVENT_MAX_PENDING]; > + int i, cnt = 0, remaining; > + > + while (uevents[cnt]) { > + if (cnt >= UEVENT_MAX_PENDING) > + tst_brk(TBROK, "Too many expected uevents, increase UEVENT_MAX_PENDING"); > + pending[cnt] = uevents[cnt]; > + cnt++; > + } > + remaining = cnt; We can as well count the uevents[] first, then create the pending[] array with the cnt. Also I would have used array of bitflags. while (uevents[cnt]) cnt++; uint8_t not_pending[cnt] = {}; ... if (not_pending[i]) continue; if (uevent_match(buf, len, uevents[i])) { not_pendig[i] = 1; ... } With that we avoid copying the pointers and static limit. But that is largerly cosmetic changes. -- Cyril Hrubis chrubis@suse.cz -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v3] uevent02: Make wait_for_uevents() order-independent 2026-09-03 14:42 ` Cyril Hrubis @ 2026-09-07 19:44 ` Avinesh Kumar via ltp 2026-09-07 22:01 ` [LTP] " linuxtestproject.agent 2026-09-15 10:53 ` [LTP] [PATCH v3] " Cyril Hrubis 0 siblings, 2 replies; 14+ messages in thread From: Avinesh Kumar via ltp @ 2026-09-07 19:44 UTC (permalink / raw) To: ltp From: Avinesh Kumar <avinesh.kumar@suse.com> Commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD uevent until the device is published")[0] moved a network interface's "add" uevent to after its queue kobjects are created, flipping the uevent order for tun device creation from: add(net), add(rx queue), add(tx queue) to: add(rx queue), add(tx queue), add(net) wait_for_uevents() matches events strictly in array order, so on kernels with the new order "add(net)" is still awaited after its queue events have already been consumed off the socket, and uevent02 hangs until it times out and fails. The relative order of these uevents is a kernel implementation detail the test shouldn't depend on. Track still-unmatched events in a pending set and match incoming uevents against any of them regardless of position. wait_for_uevents() leaves fd open so it can be called more than once on the same socket, keeping independent lifecycle phases ordered: uevent02 matches all add events before looking for the remove events. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e63c9e6179a Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com> --- testcases/kernel/uevents/uevent.h | 39 +++++++++++++++++++++++------ testcases/kernel/uevents/uevent02.c | 29 +++++++++++++-------- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/testcases/kernel/uevents/uevent.h b/testcases/kernel/uevents/uevent.h index 1ad092d5ea39..495c1254ff10 100644 --- a/testcases/kernel/uevents/uevent.h +++ b/testcases/kernel/uevents/uevent.h @@ -6,6 +6,8 @@ #ifndef UEVENT_H__ #define UEVENT_H__ +#include <stdint.h> +#include <string.h> #include "tst_netlink.h" /* @@ -119,13 +121,30 @@ static inline int open_uevent_netlink(void) /* * Reads events from uevent netlink socket until all expected events passed in - * the uevent array are matched. + * the uevent array are matched. Events do not have to arrive in the order + * they are listed in the uevents array, since the kernel is free to reorder + * unrelated uevents, e.g. commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD + * uevent until the device is published") changed the order in which a + * network interface and its queues announce themselves. + * + * Does not close fd; the caller owns the socket and can call this more + * than once on it to keep independent lifecycle phases ordered, e.g. + * matching all "add" events before looking for "remove" events. */ static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[]) { - int i = 0; + int i, cnt = 0, remaining; + + while (uevents[cnt]) + cnt++; + + uint8_t matched[cnt]; + + memset(matched, 0, sizeof(matched)); - while (1) { + remaining = cnt; + + while (remaining) { int len; char buf[4096]; @@ -136,11 +155,15 @@ static inline void wait_for_uevents(int fd, const struct uevent_desc *const ueve print_uevent(buf, len); - if (uevent_match(buf, len, uevents[i])) { - tst_res(TPASS, "Got expected UEVENT"); - if (!uevents[++i]) { - close(fd); - return; + for (i = 0; i < cnt; i++) { + if (matched[i]) + continue; + + if (uevent_match(buf, len, uevents[i])) { + tst_res(TPASS, "Got expected UEVENT"); + matched[i] = 1; + remaining--; + break; } } } diff --git a/testcases/kernel/uevents/uevent02.c b/testcases/kernel/uevents/uevent02.c index 1135f55a87db..a48239d2a40e 100644 --- a/testcases/kernel/uevents/uevent02.c +++ b/testcases/kernel/uevents/uevent02.c @@ -25,7 +25,8 @@ #include "uevent.h" #define TUN_PATH "/dev/net/tun" -#define MAX_UEVENTS 7 +#define MAX_ADD_UEVENTS 4 +#define MAX_REM_UEVENTS 4 static struct uevent_desc add = { .msg = "add@/devices/virtual/net/ltp-tun0", @@ -88,7 +89,9 @@ static struct uevent_desc rem = { "INTERFACE=ltp-tun0", } }; -static const struct uevent_desc *uevents[MAX_UEVENTS]; + +static const struct uevent_desc *add_uevents[MAX_ADD_UEVENTS]; +static const struct uevent_desc *rem_uevents[MAX_REM_UEVENTS]; static void generate_tun_uevents(void) { @@ -114,7 +117,9 @@ static void verify_uevent(void) if (!pid) { fd = open_uevent_netlink(); TST_CHECKPOINT_WAKE(0); - wait_for_uevents(fd, uevents); + wait_for_uevents(fd, add_uevents); + wait_for_uevents(fd, rem_uevents); + close(fd); exit(0); } @@ -128,19 +133,21 @@ static void verify_uevent(void) static void setup(void) { struct tst_kconfig_var kconfig = TST_KCONFIG_INIT("CONFIG_RPS"); - int i = 0; + int i = 0, j = 0; tst_kconfig_read(&kconfig, 1); - uevents[i++] = &add; + add_uevents[i++] = &add; if (kconfig.choice == 'y') - uevents[i++] = &add_rx; - uevents[i++] = &add_tx; + add_uevents[i++] = &add_rx; + add_uevents[i++] = &add_tx; + add_uevents[i++] = NULL; + if (kconfig.choice == 'y') - uevents[i++] = &rem_rx; - uevents[i++] = &rem_tx; - uevents[i++] = &rem; - uevents[i++] = NULL; + rem_uevents[j++] = &rem_rx; + rem_uevents[j++] = &rem_tx; + rem_uevents[j++] = &rem; + rem_uevents[j++] = NULL; } static struct tst_test test = { -- 2.55.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] uevent02: Make wait_for_uevents() order-independent 2026-09-07 19:44 ` [LTP] [PATCH v3] " Avinesh Kumar via ltp @ 2026-09-07 22:01 ` linuxtestproject.agent 2026-09-15 10:53 ` [LTP] [PATCH v3] " Cyril Hrubis 1 sibling, 0 replies; 14+ messages in thread From: linuxtestproject.agent @ 2026-09-07 22:01 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi Avinesh, On September 7, 2026, Avinesh Kumar wrote: > uevent02: Make wait_for_uevents() order-independent Verdict - Reviewed --- Note: The agent can sometimes produce false positives although often its findings are genuine. If you find issues with the review, please comment this email or ignore the suggestions. Regards, LTP AI Reviewer -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v3] uevent02: Make wait_for_uevents() order-independent 2026-09-07 19:44 ` [LTP] [PATCH v3] " Avinesh Kumar via ltp 2026-09-07 22:01 ` [LTP] " linuxtestproject.agent @ 2026-09-15 10:53 ` Cyril Hrubis 2026-09-15 11:37 ` [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() Avinesh Kumar via ltp 1 sibling, 1 reply; 14+ messages in thread From: Cyril Hrubis @ 2026-09-15 10:53 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi! > static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[]) > { > - int i = 0; > + int i, cnt = 0, remaining; > + > + while (uevents[cnt]) > + cnt++; > + > + uint8_t matched[cnt]; > + > + memset(matched, 0, sizeof(matched)); > > - while (1) { > + remaining = cnt; > + > + while (remaining) { > int len; > char buf[4096]; > > @@ -136,11 +155,15 @@ static inline void wait_for_uevents(int fd, const struct uevent_desc *const ueve > > print_uevent(buf, len); > > - if (uevent_match(buf, len, uevents[i])) { > - tst_res(TPASS, "Got expected UEVENT"); > - if (!uevents[++i]) { > - close(fd); > - return; > + for (i = 0; i < cnt; i++) { > + if (matched[i]) > + continue; > + > + if (uevent_match(buf, len, uevents[i])) { > + tst_res(TPASS, "Got expected UEVENT"); > + matched[i] = 1; > + remaining--; > + break; > } > } > } Unfortunately this is not yet ready either. The problem is that this relaxes the conditions for uevent01.c and uevent03.c too, since these two tests does not inforce any order after this change. Well techically for uevent01.c the order does not matter, since the two events for attach/detach are the same, as the event only reports "change". But uevent03.c is exactly the same patter, sequence of add and remove events. Hence we have to enforce at least partial order. I would however enforce the full order unless we are told otherwise. So maybe we need two different wait_for_uevents() helpers one that would keep the order and one that would match events in any order. And we should use the order enforcing one in the uevent01 and uevent03. -- Cyril Hrubis chrubis@suse.cz -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() 2026-09-15 10:53 ` [LTP] [PATCH v3] " Cyril Hrubis @ 2026-09-15 11:37 ` Avinesh Kumar via ltp 2026-09-15 12:36 ` Petr Vorel 2026-09-15 12:41 ` Cyril Hrubis 0 siblings, 2 replies; 14+ messages in thread From: Avinesh Kumar via ltp @ 2026-09-15 11:37 UTC (permalink / raw) To: ltp From: Avinesh Kumar <avinesh.kumar@suse.com> Commit 8e63c9e6179a ("net: Defer netdev KOBJ_ADD uevent until the device is published")[0] moved a network interface's "add" uevent to after its queue kobjects are created, flipping the uevent order for tun device creation from: add(net), add(rx queue), add(tx queue) to: add(rx queue), add(tx queue), add(net) wait_for_uevents() matches events strictly in array order, so on kernels with the new order "add(net)" is still awaited after its queue events have already been consumed off the socket, and uevent02 hangs until it times out and fails. The relative order of these uevents is a kernel implementation detail the test shouldn't depend on, but other callers rely on wait_for_uevents() enforcing order between related events, so add a separate wait_for_uevents_unordered() instead of relaxing it there: it tracks still-unmatched events and matches incoming uevents against any of them regardless of position. wait_for_uevents_unordered() also leaves fd open so it can be called more than once on the same socket, keeping independent lifecycle phases ordered: uevent02 matches all add events before looking for the remove events. [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8e63c9e6179a Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com> --- testcases/kernel/uevents/uevent.h | 54 ++++++++++++++++++++++++++++- testcases/kernel/uevents/uevent02.c | 29 ++++++++++------ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/testcases/kernel/uevents/uevent.h b/testcases/kernel/uevents/uevent.h index 1ad092d5ea39..dee63d20f0af 100644 --- a/testcases/kernel/uevents/uevent.h +++ b/testcases/kernel/uevents/uevent.h @@ -6,6 +6,8 @@ #ifndef UEVENT_H__ #define UEVENT_H__ +#include <stdint.h> +#include <string.h> #include "tst_netlink.h" /* @@ -119,7 +121,7 @@ static inline int open_uevent_netlink(void) /* * Reads events from uevent netlink socket until all expected events passed in - * the uevent array are matched. + * the uevent array are matched, in the exact order they are listed. */ static inline void wait_for_uevents(int fd, const struct uevent_desc *const uevents[]) { @@ -146,6 +148,56 @@ static inline void wait_for_uevents(int fd, const struct uevent_desc *const ueve } } +/* + * Reads events from uevent netlink socket until all expected events passed in + * the uevent array are matched. Unlike wait_for_uevents(), events do not have + * to arrive in the order they are listed in the uevents array, since the kernel + * is free to reorder unrelated uevents, e.g. commit 8e63c9e6179a ("net: Defer + * netdev KOBJ_ADD uevent until the device is published") changed the order in + * which a network interface and its queues announce themselves. + * + * Does not close fd; the caller owns the socket and can call this more + * than once on it to keep independent lifecycle phases ordered, e.g. + * matching all "add" events before looking for "remove" events. + */ +static inline void wait_for_uevents_unordered(int fd, const struct uevent_desc *const uevents[]) +{ + int i, cnt = 0, remaining; + + while (uevents[cnt]) + cnt++; + + uint8_t matched[cnt]; + + memset(matched, 0, sizeof(matched)); + + remaining = cnt; + + while (remaining) { + int len; + char buf[4096]; + + len = recv(fd, &buf, sizeof(buf), 0); + + if (len == 0) + continue; + + print_uevent(buf, len); + + for (i = 0; i < cnt; i++) { + if (matched[i]) + continue; + + if (uevent_match(buf, len, uevents[i])) { + tst_res(TPASS, "Got expected UEVENT"); + matched[i] = 1; + remaining--; + break; + } + } + } +} + /* * Waits 5 seconds for a child to exit, kills the child after a timeout. */ diff --git a/testcases/kernel/uevents/uevent02.c b/testcases/kernel/uevents/uevent02.c index 1135f55a87db..f3d2ebc87a74 100644 --- a/testcases/kernel/uevents/uevent02.c +++ b/testcases/kernel/uevents/uevent02.c @@ -25,7 +25,8 @@ #include "uevent.h" #define TUN_PATH "/dev/net/tun" -#define MAX_UEVENTS 7 +#define MAX_ADD_UEVENTS 4 +#define MAX_REM_UEVENTS 4 static struct uevent_desc add = { .msg = "add@/devices/virtual/net/ltp-tun0", @@ -88,7 +89,9 @@ static struct uevent_desc rem = { "INTERFACE=ltp-tun0", } }; -static const struct uevent_desc *uevents[MAX_UEVENTS]; + +static const struct uevent_desc *add_uevents[MAX_ADD_UEVENTS]; +static const struct uevent_desc *rem_uevents[MAX_REM_UEVENTS]; static void generate_tun_uevents(void) { @@ -114,7 +117,9 @@ static void verify_uevent(void) if (!pid) { fd = open_uevent_netlink(); TST_CHECKPOINT_WAKE(0); - wait_for_uevents(fd, uevents); + wait_for_uevents_unordered(fd, add_uevents); + wait_for_uevents_unordered(fd, rem_uevents); + close(fd); exit(0); } @@ -128,19 +133,21 @@ static void verify_uevent(void) static void setup(void) { struct tst_kconfig_var kconfig = TST_KCONFIG_INIT("CONFIG_RPS"); - int i = 0; + int i = 0, j = 0; tst_kconfig_read(&kconfig, 1); - uevents[i++] = &add; + add_uevents[i++] = &add; if (kconfig.choice == 'y') - uevents[i++] = &add_rx; - uevents[i++] = &add_tx; + add_uevents[i++] = &add_rx; + add_uevents[i++] = &add_tx; + add_uevents[i++] = NULL; + if (kconfig.choice == 'y') - uevents[i++] = &rem_rx; - uevents[i++] = &rem_tx; - uevents[i++] = &rem; - uevents[i++] = NULL; + rem_uevents[j++] = &rem_rx; + rem_uevents[j++] = &rem_tx; + rem_uevents[j++] = &rem; + rem_uevents[j++] = NULL; } static struct tst_test test = { -- 2.55.0 -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() 2026-09-15 11:37 ` [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() Avinesh Kumar via ltp @ 2026-09-15 12:36 ` Petr Vorel 2026-09-15 12:43 ` Cyril Hrubis 2026-09-15 12:41 ` Cyril Hrubis 1 sibling, 1 reply; 14+ messages in thread From: Petr Vorel @ 2026-09-15 12:36 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi Avinesh, LGTM, thanks! Reviewed-by: Petr Vorel <pvorel@suse.cz> Kind regards, Petr -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() 2026-09-15 12:36 ` Petr Vorel @ 2026-09-15 12:43 ` Cyril Hrubis 2026-09-15 12:55 ` Petr Vorel 0 siblings, 1 reply; 14+ messages in thread From: Cyril Hrubis @ 2026-09-15 12:43 UTC (permalink / raw) To: Petr Vorel; +Cc: ltp Hi! > LGTM, thanks! > Reviewed-by: Petr Vorel <pvorel@suse.cz> Sorry, I've pushed the patch before this email arrived... -- Cyril Hrubis chrubis@suse.cz -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() 2026-09-15 12:43 ` Cyril Hrubis @ 2026-09-15 12:55 ` Petr Vorel 0 siblings, 0 replies; 14+ messages in thread From: Petr Vorel @ 2026-09-15 12:55 UTC (permalink / raw) To: Cyril Hrubis; +Cc: ltp > Hi! > > LGTM, thanks! > > Reviewed-by: Petr Vorel <pvorel@suse.cz> > Sorry, I've pushed the patch before this email arrived... No problem, thanks for pushing the fix. Kind regards, Petr -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() 2026-09-15 11:37 ` [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() Avinesh Kumar via ltp 2026-09-15 12:36 ` Petr Vorel @ 2026-09-15 12:41 ` Cyril Hrubis 1 sibling, 0 replies; 14+ messages in thread From: Cyril Hrubis @ 2026-09-15 12:41 UTC (permalink / raw) To: Avinesh Kumar; +Cc: ltp Hi! Pushed, thanks. -- Cyril Hrubis chrubis@suse.cz -- Mailing list info: https://lists.linux.it/listinfo/ltp ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-09-15 12:55 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-25 17:14 [LTP] [PATCH] uevent02: Make wait_for_uevents() order-independent Avinesh Kumar via ltp 2026-08-25 17:36 ` [LTP] " linuxtestproject.agent 2026-08-28 15:26 ` [LTP] [PATCH v2] " Avinesh Kumar via ltp 2026-08-28 21:09 ` [LTP] " linuxtestproject.agent 2026-09-03 13:25 ` [LTP] [PATCH v2] " Andrea Cervesato via ltp 2026-09-03 14:42 ` Cyril Hrubis 2026-09-07 19:44 ` [LTP] [PATCH v3] " Avinesh Kumar via ltp 2026-09-07 22:01 ` [LTP] " linuxtestproject.agent 2026-09-15 10:53 ` [LTP] [PATCH v3] " Cyril Hrubis 2026-09-15 11:37 ` [LTP] [PATCH v4] uevents: introduce wait_for_uevents_unordered() Avinesh Kumar via ltp 2026-09-15 12:36 ` Petr Vorel 2026-09-15 12:43 ` Cyril Hrubis 2026-09-15 12:55 ` Petr Vorel 2026-09-15 12:41 ` Cyril Hrubis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).