* [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie
@ 2023-11-05 8:58 Florian Lehner
2023-11-05 19:08 ` David Rheinsberg
2023-11-06 20:00 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 5+ messages in thread
From: Florian Lehner @ 2023-11-05 8:58 UTC (permalink / raw)
To: bpf
Cc: ast, daniel, andrii, martin.lau, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, david, davem, daniel,
Florian Lehner
When looking up an element in LPM trie, the condition 'matchlen ==
trie->max_prefixlen' will never return true, if key->prefixlen is larger
than trie->max_prefixlen. Consequently all elements in the LPM trie will
be visited and no element is returned in the end.
To resolve this, check key->prefixlen first before walking the LPM trie.
Fixes: b95a5c4db09b ("bpf: add a longest prefix match trie map implementation")
Signed-off-by: Florian Lehner <dev@der-flo.net>
---
kernel/bpf/lpm_trie.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
index 17c7e7782a1f..b32be680da6c 100644
--- a/kernel/bpf/lpm_trie.c
+++ b/kernel/bpf/lpm_trie.c
@@ -231,6 +231,9 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key)
struct lpm_trie_node *node, *found = NULL;
struct bpf_lpm_trie_key *key = _key;
+ if (key->prefixlen > trie->max_prefixlen)
+ return NULL;
+
/* Start walking the trie from the root node ... */
for (node = rcu_dereference_check(trie->root, rcu_read_lock_bh_held());
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie
2023-11-05 8:58 [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie Florian Lehner
@ 2023-11-05 19:08 ` David Rheinsberg
2023-11-05 20:33 ` Florian Lehner
2023-11-06 20:00 ` patchwork-bot+netdevbpf
1 sibling, 1 reply; 5+ messages in thread
From: David Rheinsberg @ 2023-11-05 19:08 UTC (permalink / raw)
To: Florian Lehner, bpf
Cc: ast, daniel, andrii, martin.lau, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, daniel
Hi
On Sun, Nov 5, 2023, at 9:58 AM, Florian Lehner wrote:
> When looking up an element in LPM trie, the condition 'matchlen ==
> trie->max_prefixlen' will never return true, if key->prefixlen is larger
> than trie->max_prefixlen. Consequently all elements in the LPM trie will
> be visited and no element is returned in the end.
>
> To resolve this, check key->prefixlen first before walking the LPM trie.
Am I understanding you right that this is an optimization to avoid walking the entire trie? Because the way I read your commit-message I assume the output has always been NULL? Or am I missing something.
Do you have a specific use-case where such lookups are common? Can you explain why it is important to optimize this case? Because you now add a condition for every lookup just to optimize for the lookup-miss of a special case. I don't think I understand your reasoning here, but I might be missing some context.
Thanks!
David
> Fixes: b95a5c4db09b ("bpf: add a longest prefix match trie map implementation")
> Signed-off-by: Florian Lehner <dev@der-flo.net>
> ---
> kernel/bpf/lpm_trie.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
> index 17c7e7782a1f..b32be680da6c 100644
> --- a/kernel/bpf/lpm_trie.c
> +++ b/kernel/bpf/lpm_trie.c
> @@ -231,6 +231,9 @@ static void *trie_lookup_elem(struct bpf_map *map,
> void *_key)
> struct lpm_trie_node *node, *found = NULL;
> struct bpf_lpm_trie_key *key = _key;
>
> + if (key->prefixlen > trie->max_prefixlen)
> + return NULL;
> +
> /* Start walking the trie from the root node ... */
>
> for (node = rcu_dereference_check(trie->root, rcu_read_lock_bh_held());
> --
> 2.39.2
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie
2023-11-05 19:08 ` David Rheinsberg
@ 2023-11-05 20:33 ` Florian Lehner
2023-11-06 8:00 ` David Rheinsberg
0 siblings, 1 reply; 5+ messages in thread
From: Florian Lehner @ 2023-11-05 20:33 UTC (permalink / raw)
To: David Rheinsberg
Cc: bpf, ast, daniel, andrii, martin.lau, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, daniel
On Sun, Nov 05, 2023 at 08:08:43PM +0100, David Rheinsberg wrote:
> Hi
>
> On Sun, Nov 5, 2023, at 9:58 AM, Florian Lehner wrote:
> > When looking up an element in LPM trie, the condition 'matchlen ==
> > trie->max_prefixlen' will never return true, if key->prefixlen is larger
> > than trie->max_prefixlen. Consequently all elements in the LPM trie will
> > be visited and no element is returned in the end.
> >
>
> Am I understanding you right that this is an optimization to avoid walking the entire trie? Because the way I read your commit-message I assume the output has always been NULL? Or am I missing something.
>
> Do you have a specific use-case where such lookups are common? Can you explain why it is important to optimize this case? Because you now add a condition for every lookup just to optimize for the lookup-miss of a special case. I don't think I understand your reasoning here, but I might be missing some context.
>
> Thanks!
> David
Hi David,
Your understanding is correct. The return value currently and with this patch is
in both cases the same for the case where key->prefixlen > trie->max_prefixlen.
The optimization is to avoid the locking mechanism, walking the trie and
checking its elements. It might not be the most common use case, so I see your
point.
>
> > Fixes: b95a5c4db09b ("bpf: add a longest prefix match trie map implementation")
> > Signed-off-by: Florian Lehner <dev@der-flo.net>
> > ---
> > kernel/bpf/lpm_trie.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
> > index 17c7e7782a1f..b32be680da6c 100644
> > --- a/kernel/bpf/lpm_trie.c
> > +++ b/kernel/bpf/lpm_trie.c
> > @@ -231,6 +231,9 @@ static void *trie_lookup_elem(struct bpf_map *map,
> > void *_key)
> > struct lpm_trie_node *node, *found = NULL;
> > struct bpf_lpm_trie_key *key = _key;
> >
> > + if (key->prefixlen > trie->max_prefixlen)
> > + return NULL;
> > +
> > /* Start walking the trie from the root node ... */
> >
> > for (node = rcu_dereference_check(trie->root, rcu_read_lock_bh_held());
> > --
> > 2.39.2
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie
2023-11-05 20:33 ` Florian Lehner
@ 2023-11-06 8:00 ` David Rheinsberg
0 siblings, 0 replies; 5+ messages in thread
From: David Rheinsberg @ 2023-11-06 8:00 UTC (permalink / raw)
To: Florian Lehner
Cc: bpf, ast, daniel, andrii, martin.lau, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, davem, daniel
Hi
On Sun, Nov 5, 2023, at 9:33 PM, Florian Lehner wrote:
> On Sun, Nov 05, 2023 at 08:08:43PM +0100, David Rheinsberg wrote:
>> On Sun, Nov 5, 2023, at 9:58 AM, Florian Lehner wrote:
>> > When looking up an element in LPM trie, the condition 'matchlen ==
>> > trie->max_prefixlen' will never return true, if key->prefixlen is larger
>> > than trie->max_prefixlen. Consequently all elements in the LPM trie will
>> > be visited and no element is returned in the end.
>>
>> Am I understanding you right that this is an optimization to avoid walking the entire trie? Because the way I read your commit-message I assume the output has always been NULL? Or am I missing something.
>>
>> Do you have a specific use-case where such lookups are common? Can you explain why it is important to optimize this case? Because you now add a condition for every lookup just to optimize for the lookup-miss of a special case. I don't think I understand your reasoning here, but I might be missing some context.
>
> Your understanding is correct. The return value currently and with this patch is
> in both cases the same for the case where key->prefixlen > trie->max_prefixlen.
Thanks for clarifying! I think using "fix" to describe the patch is misleading and confused me. Similarly, your "Fixes:" tag implies you repaired something that was broken.
> The optimization is to avoid the locking mechanism, walking the trie and
> checking its elements. It might not be the most common use case, so I see your
> point.
Can you elaborate on how you encountered this? Do you have an actual use-case where such lookups better be fast? Is it worth it slowing down every other lookup just to make this one faster?
The patch looks good, but I also don't see the benefit. I am not against it, though, if you insist you need it.
Thanks
David
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie
2023-11-05 8:58 [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie Florian Lehner
2023-11-05 19:08 ` David Rheinsberg
@ 2023-11-06 20:00 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-11-06 20:00 UTC (permalink / raw)
To: Florian Lehner
Cc: bpf, ast, daniel, andrii, martin.lau, song, yonghong.song,
john.fastabend, kpsingh, sdf, haoluo, jolsa, david, davem, daniel
Hello:
This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:
On Sun, 5 Nov 2023 09:58:01 +0100 you wrote:
> When looking up an element in LPM trie, the condition 'matchlen ==
> trie->max_prefixlen' will never return true, if key->prefixlen is larger
> than trie->max_prefixlen. Consequently all elements in the LPM trie will
> be visited and no element is returned in the end.
>
> To resolve this, check key->prefixlen first before walking the LPM trie.
>
> [...]
Here is the summary with links:
- [bpf-next] bpf, lpm: fix check prefixlen before walking trie
https://git.kernel.org/bpf/bpf-next/c/856624f12b04
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] 5+ messages in thread
end of thread, other threads:[~2023-11-06 20:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-05 8:58 [PATCH bpf-next] bpf, lpm: fix check prefixlen before walking trie Florian Lehner
2023-11-05 19:08 ` David Rheinsberg
2023-11-05 20:33 ` Florian Lehner
2023-11-06 8:00 ` David Rheinsberg
2023-11-06 20:00 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox