* [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case
2026-01-08 22:52 [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Jakub Kicinski
@ 2026-01-08 22:52 ` Jakub Kicinski
2026-01-09 8:23 ` Petr Machata
2026-01-09 8:38 ` [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Petr Machata
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2026-01-08 22:52 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, petrm, leitao,
jdamato, Jakub Kicinski
I wasted a couple of hours recently after accidentally adding
a defer() from within a function which itself was called as
part of defer(). This leads to an infinite loop of defer().
Make sure this cannot happen and raise a helpful exception.
I understand that the pair of _ksft_defer_arm() calls may
not be the most Pythonic way to implement this, but it's
easy enough to understand.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
tools/testing/selftests/net/lib/py/ksft.py | 7 +++++++
tools/testing/selftests/net/lib/py/utils.py | 3 +++
2 files changed, 10 insertions(+)
diff --git a/tools/testing/selftests/net/lib/py/ksft.py b/tools/testing/selftests/net/lib/py/ksft.py
index 248cd1a723a3..0a96f88bb60a 100644
--- a/tools/testing/selftests/net/lib/py/ksft.py
+++ b/tools/testing/selftests/net/lib/py/ksft.py
@@ -153,6 +153,11 @@ KSFT_DISRUPTIVE = True
print(res, flush=True)
+def _ksft_defer_arm(state):
+ """ Allow or disallow the use of defer() """
+ utils.GLOBAL_DEFER_ARMED = state
+
+
def ksft_flush_defer():
global KSFT_RESULT
@@ -315,6 +320,7 @@ KsftCaseFunction = namedtuple("KsftCaseFunction",
comment = ""
cnt_key = ""
+ _ksft_defer_arm(True)
try:
func(*args)
except KsftSkipEx as e:
@@ -332,6 +338,7 @@ KsftCaseFunction = namedtuple("KsftCaseFunction",
ksft_pr(f"Stopping tests due to {type(e).__name__}.")
KSFT_RESULT = False
cnt_key = 'fail'
+ _ksft_defer_arm(False)
try:
ksft_flush_defer()
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 2dde34560d65..824f039d384c 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -142,6 +142,7 @@ import time
GLOBAL_DEFER_QUEUE = []
+GLOBAL_DEFER_ARMED = False
class defer:
@@ -153,6 +154,8 @@ GLOBAL_DEFER_QUEUE = []
self.args = args
self.kwargs = kwargs
+ if not GLOBAL_DEFER_ARMED:
+ raise Exception("defer queue not armed, did you use defer() outside of a test case?")
self._queue = GLOBAL_DEFER_QUEUE
self._queue.append(self)
--
2.52.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case
2026-01-08 22:52 ` [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case Jakub Kicinski
@ 2026-01-09 8:23 ` Petr Machata
2026-01-09 14:39 ` Jakub Kicinski
0 siblings, 1 reply; 8+ messages in thread
From: Petr Machata @ 2026-01-09 8:23 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, petrm,
leitao, jdamato
Jakub Kicinski <kuba@kernel.org> writes:
> I wasted a couple of hours recently after accidentally adding
> a defer() from within a function which itself was called as
> part of defer(). This leads to an infinite loop of defer().
> Make sure this cannot happen and raise a helpful exception.
>
> I understand that the pair of _ksft_defer_arm() calls may
> not be the most Pythonic way to implement this, but it's
> easy enough to understand.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
I think we achieve the same without the extra globals though? Just drain
the queue and walk through a copy of it?
defer_queue = utils.GLOBAL_DEFER_QUEUE
utils.GLOBAL_DEFER_QUEUE = []
for i, entry in enumerate(defer_queue):
...
if utils.GLOBAL_DEFER_QUEUE:
warning / exception
> ---
> tools/testing/selftests/net/lib/py/ksft.py | 7 +++++++
> tools/testing/selftests/net/lib/py/utils.py | 3 +++
> 2 files changed, 10 insertions(+)
>
> diff --git a/tools/testing/selftests/net/lib/py/ksft.py b/tools/testing/selftests/net/lib/py/ksft.py
> index 248cd1a723a3..0a96f88bb60a 100644
> --- a/tools/testing/selftests/net/lib/py/ksft.py
> +++ b/tools/testing/selftests/net/lib/py/ksft.py
> @@ -153,6 +153,11 @@ KSFT_DISRUPTIVE = True
> print(res, flush=True)
>
>
> +def _ksft_defer_arm(state):
> + """ Allow or disallow the use of defer() """
> + utils.GLOBAL_DEFER_ARMED = state
> +
> +
> def ksft_flush_defer():
> global KSFT_RESULT
>
> @@ -315,6 +320,7 @@ KsftCaseFunction = namedtuple("KsftCaseFunction",
> comment = ""
> cnt_key = ""
>
> + _ksft_defer_arm(True)
> try:
> func(*args)
> except KsftSkipEx as e:
> @@ -332,6 +338,7 @@ KsftCaseFunction = namedtuple("KsftCaseFunction",
> ksft_pr(f"Stopping tests due to {type(e).__name__}.")
> KSFT_RESULT = False
> cnt_key = 'fail'
> + _ksft_defer_arm(False)
>
> try:
> ksft_flush_defer()
> diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
> index 2dde34560d65..824f039d384c 100644
> --- a/tools/testing/selftests/net/lib/py/utils.py
> +++ b/tools/testing/selftests/net/lib/py/utils.py
> @@ -142,6 +142,7 @@ import time
>
>
> GLOBAL_DEFER_QUEUE = []
> +GLOBAL_DEFER_ARMED = False
>
>
> class defer:
> @@ -153,6 +154,8 @@ GLOBAL_DEFER_QUEUE = []
> self.args = args
> self.kwargs = kwargs
>
> + if not GLOBAL_DEFER_ARMED:
> + raise Exception("defer queue not armed, did you use defer() outside of a test case?")
> self._queue = GLOBAL_DEFER_QUEUE
> self._queue.append(self)
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case
2026-01-09 8:23 ` Petr Machata
@ 2026-01-09 14:39 ` Jakub Kicinski
2026-01-09 15:43 ` Petr Machata
0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2026-01-09 14:39 UTC (permalink / raw)
To: Petr Machata
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, leitao,
jdamato
On Fri, 9 Jan 2026 09:23:54 +0100 Petr Machata wrote:
> > I wasted a couple of hours recently after accidentally adding
> > a defer() from within a function which itself was called as
> > part of defer(). This leads to an infinite loop of defer().
> > Make sure this cannot happen and raise a helpful exception.
> >
> > I understand that the pair of _ksft_defer_arm() calls may
> > not be the most Pythonic way to implement this, but it's
> > easy enough to understand.
> >
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
>
> I think we achieve the same without the extra globals though? Just drain
> the queue and walk through a copy of it?
>
> defer_queue = utils.GLOBAL_DEFER_QUEUE
> utils.GLOBAL_DEFER_QUEUE = []
> for i, entry in enumerate(defer_queue):
> ...
> if utils.GLOBAL_DEFER_QUEUE:
> warning / exception
That's what I had initially (IIUC), I was assigning None to the queue,
and then [] only while inside a test case. It gets slightly hairy
because either we need to pass in the queue into the flush function;
or we have to restore the queue if something raises and exception during
flush (in which case ksft_run() prints a warning and calls
ksft_flush_defer() one more time).
That approach definitely worked, but unless I'm missing a trick it was
higher complexity and LoC.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case
2026-01-09 14:39 ` Jakub Kicinski
@ 2026-01-09 15:43 ` Petr Machata
0 siblings, 0 replies; 8+ messages in thread
From: Petr Machata @ 2026-01-09 15:43 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Petr Machata, davem, netdev, edumazet, pabeni, andrew+netdev,
horms, leitao, jdamato
Jakub Kicinski <kuba@kernel.org> writes:
> On Fri, 9 Jan 2026 09:23:54 +0100 Petr Machata wrote:
>> > I wasted a couple of hours recently after accidentally adding
>> > a defer() from within a function which itself was called as
>> > part of defer(). This leads to an infinite loop of defer().
>> > Make sure this cannot happen and raise a helpful exception.
>> >
>> > I understand that the pair of _ksft_defer_arm() calls may
>> > not be the most Pythonic way to implement this, but it's
>> > easy enough to understand.
>> >
>> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
>>
>> I think we achieve the same without the extra globals though? Just drain
>> the queue and walk through a copy of it?
>>
>> defer_queue = utils.GLOBAL_DEFER_QUEUE
>> utils.GLOBAL_DEFER_QUEUE = []
>> for i, entry in enumerate(defer_queue):
>> ...
>> if utils.GLOBAL_DEFER_QUEUE:
>> warning / exception
>
> That's what I had initially (IIUC), I was assigning None to the queue,
> and then [] only while inside a test case. It gets slightly hairy
> because either we need to pass in the queue into the flush function;
> or we have to restore the queue if something raises and exception during
> flush (in which case ksft_run() prints a warning and calls
> ksft_flush_defer() one more time).
Hmm, yeah, the exception robustness will complicate it. OK, let's have
it your way then :)
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import
2026-01-08 22:52 [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Jakub Kicinski
2026-01-08 22:52 ` [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case Jakub Kicinski
@ 2026-01-09 8:38 ` Petr Machata
2026-01-09 9:57 ` Breno Leitao
2026-01-12 20:57 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: Petr Machata @ 2026-01-09 8:38 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, petrm,
leitao, jdamato
Jakub Kicinski <kuba@kernel.org> writes:
> Import utils and refer to the global defer queue that way instead
> of importing the queue. This will make it possible to assign value
> to the global variable. While at it capitalize the name, to comply
> with the Python coding style.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Petr Machata <petrm@nvidia.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import
2026-01-08 22:52 [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Jakub Kicinski
2026-01-08 22:52 ` [PATCH net-next 2/2] selftests: net: py: ensure defer() is only used within a test case Jakub Kicinski
2026-01-09 8:38 ` [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Petr Machata
@ 2026-01-09 9:57 ` Breno Leitao
2026-01-12 20:57 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: Breno Leitao @ 2026-01-09 9:57 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, petrm,
jdamato
On Thu, Jan 08, 2026 at 02:52:56PM -0800, Jakub Kicinski wrote:
> Import utils and refer to the global defer queue that way instead
> of importing the queue. This will make it possible to assign value
> to the global variable. While at it capitalize the name, to comply
> with the Python coding style.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviwed-by: Breno Leitao <leitao@debian.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import
2026-01-08 22:52 [PATCH net-next 1/2] selftests: net: py: capitalize defer queue and improve import Jakub Kicinski
` (2 preceding siblings ...)
2026-01-09 9:57 ` Breno Leitao
@ 2026-01-12 20:57 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-01-12 20:57 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, petrm,
leitao, jdamato
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 8 Jan 2026 14:52:56 -0800 you wrote:
> Import utils and refer to the global defer queue that way instead
> of importing the queue. This will make it possible to assign value
> to the global variable. While at it capitalize the name, to comply
> with the Python coding style.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
>
> [...]
Here is the summary with links:
- [net-next,1/2] selftests: net: py: capitalize defer queue and improve import
https://git.kernel.org/netdev/net-next/c/799a4912eea7
- [net-next,2/2] selftests: net: py: ensure defer() is only used within a test case
https://git.kernel.org/netdev/net-next/c/7a1ff3545ade
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread