[PATCH] net/ipv4: check RTNH_F_LINKDOWN before ip_ignore_linkdown()

From
Vincent Bernat <hidden>
Date
2026-11-02 23:15:12
In commit c0c5a60f0f13 ("net: evaluate
net.ipvX.conf.all.ignore_routes_with_linkdown"), I introduced a small
performance regression of about 5 cycles per lookup by adding several
dependent memory loads through `IN_DEV_ORCONF`.

This patch cancels this regression in the most common case where an
interface is not down.

Here is the distribution before this fix for lookups in a table with
500k /32 routes:

    min=128 max=4657 count=994104 batch=24 average=134 95th=134 90th=133 50th=132 mad=0
        value │                         ┊                            count
          128 │                                                        120
          129 │                                                       2232
          130 │▒                                                     25224
          131 │▒▒▒▒▒▒▒▒▒▒▒▒▒░                                       264264
          132 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░             516480
          133 │▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░      126864
          134 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░      21624

The lighter shade of gray is the CDF. Here is the distribution after the
fix:

    min=124 max=208839 count=994104 batch=24 average=133 95th=128 90th=127 50th=126 mad=0
        value │                         ┊                            count
          124 │                                                        576
          125 │▒▒                                                    49440
          126 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░                      584904
          127 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░       284592
          128 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░      45288

The median lookup time goes from 132 to 126 cycls. Benchmark were run in
a VM pinned to an isolated CPU and running on an AMD EPYC 8024P (Zen
4c).

Signed-off-by: Vincent Bernat <redacted>
---
 net/ipv4/fib_trie.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index be1e40780ad7..39c8f441601c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1403,9 +1403,9 @@ bool fib_lookup_good_nhc(const struct fib_nh_common *nhc, int fib_flags,
 	if (nhc->nhc_flags & RTNH_F_DEAD)
 		return false;
 
-	if (ip_ignore_linkdown(nhc->nhc_dev) &&
-	    nhc->nhc_flags & RTNH_F_LINKDOWN &&
-	    !(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
+	if (nhc->nhc_flags & RTNH_F_LINKDOWN &&
+	    !(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE) &&
+	    ip_ignore_linkdown(nhc->nhc_dev))
 		return false;
 
 	if (flp->flowi4_oif && flp->flowi4_oif != nhc->nhc_oif)
-- 
2.55.0
Thread (2 messages) 2 messages, 2 authors, last reply 1d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help