diff mbox series

[net-next,v3] selftests/net: fix waiting time for ipv6_gc test in fib_tests.sh.

Message ID 20240305183949.258473-1-thinker.li@gmail.com (mailing list archive)
State Accepted
Commit 4af9a0bee116e927a88da903a9244bb7d03483e3
Delegated to: Netdev Maintainers
Headers show
Series [net-next,v3] selftests/net: fix waiting time for ipv6_gc test in fib_tests.sh. | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/build_tools success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 3 maintainers not CCed: shuah@kernel.org edumazet@google.com linux-kselftest@vger.kernel.org
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success net selftest script(s) already in Makefile
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 54 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-03-06--21-00 (tests: 892)

Commit Message

Kui-Feng Lee March 5, 2024, 6:39 p.m. UTC
ipv6_gc fails occasionally. According to the study, fib6_run_gc() using
jiffies_round() to round the GC interval could increase the waiting time up
to 750ms (3/4 seconds). The timer has a granularity of 512ms at the range
4s to 32s. That means a route with an expiration time E seconds can wait
for more than E * 2 + 1 seconds if the GC interval is also E seconds.

E * 2 + 2 seconds should be enough for waiting for removing routes.

Also remove a check immediately after replacing 5 routes since it is very
likely to remove some of routes before completing the last route with a
slow environment.

Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>

---

I made the follow change to simulate the case that a route misses the first
GC, and the waiting time of the next GC is rounded up by round_jiffies())
adding 750ms extra waiting time.

    diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
    index 6540d877d369..88479daa6ff7 100644
    --- a/net/ipv6/ip6_fib.c
    +++ b/net/ipv6/ip6_fib.c
    @@ -1487,8 +1487,10 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt,
     			list_add(&rt->nh_list, &rt->nh->f6i_list);
     		__fib6_update_sernum_upto_root(rt, fib6_new_sernum(info->nl_net));

    -		if (rt->fib6_flags & RTF_EXPIRES)
    +		if (rt->fib6_flags & RTF_EXPIRES) {
    +			printk(KERN_CRIT "fib6_add expires\n");
     			fib6_add_gc_list(rt);
    +		}

     		fib6_start_gc(info->nl_net, rt);
     	}
    @@ -2296,6 +2298,7 @@ static void fib6_flush_trees(struct net *net)
     static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args)
     {
     	unsigned long now = jiffies;
    +	static int expire_cnt = 0;

     	/*
     	 *	check addrconf expiration here.
    @@ -2303,8 +2306,9 @@ static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args)
     	 */

     	if (rt->fib6_flags & RTF_EXPIRES && rt->expires) {
    -		if (time_after(now, rt->expires)) {
    +		if (time_after(now, rt->expires) && expire_cnt++) {
     			pr_debug("expiring %p\n", rt);
    +			printk(KERN_CRIT "fib6_age expiring\n");
     			return -1;
     		}
     		gc_args->more++;
    @@ -2376,8 +2380,7 @@ void fib6_run_gc(unsigned long expires, struct net *net, bool force)

     	if (gc_args.more)
     		mod_timer(&net->ipv6.ip6_fib_timer,
    -			  round_jiffies(now
    -					+ net->ipv6.sysctl.ip6_rt_gc_interval));
    +			  now + net->ipv6.sysctl.ip6_rt_gc_interval + HZ * 3 / 4);
     	else
     		del_timer(&net->ipv6.ip6_fib_timer);
     	spin_unlock_bh(&net->ipv6.fib6_gc_lock);

The following is the test case.

    fib6_gc_test()
    {
    	setup

    	echo
    	echo "Fib6 garbage collection test"
    	set -e

    	EXPIRE=5

    	# Check expiration of routes every $EXPIRE seconds (GC)
    	$NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE

    	$IP link add dummy_10 type dummy
    	$IP link set dev dummy_10 up
    	$IP -6 address add 2001:10::1/64 dev dummy_10

    	$NS_EXEC sysctl -wq net.ipv6.route.flush=1

    	# Temporary routes
    	$IP -6 route add 2001:20::1 \
    		via 2001:10::2 dev dummy_10 expires $EXPIRE

    	sleep $(($EXPIRE * 4 + 1))
    	set +e

    	cleanup &> /dev/null
    }

According to what I found from the kernel messages, the route waited
11.258s before being removed. It is longer than $EXPIRE * 2 + 1 seconds
where EXPIRE=5.

    [    8.674004] fib6_add expires
    [   19.932557] fib6_age expiring

Waiting for EXPIRE * 2 + 2 seconds should be enough for non-debug build.

Changes from v2:

 - GC_WAIT_TIME to replace $(($EXPIRE * 2 + 2))

v2: https://lore.kernel.org/all/20240305013734.872968-1-thinker.li@gmail.com/
---
 tools/testing/selftests/net/fib_tests.sh | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

Comments

patchwork-bot+netdevbpf@kernel.org March 8, 2024, 5 a.m. UTC | #1
Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue,  5 Mar 2024 10:39:49 -0800 you wrote:
> ipv6_gc fails occasionally. According to the study, fib6_run_gc() using
> jiffies_round() to round the GC interval could increase the waiting time up
> to 750ms (3/4 seconds). The timer has a granularity of 512ms at the range
> 4s to 32s. That means a route with an expiration time E seconds can wait
> for more than E * 2 + 1 seconds if the GC interval is also E seconds.
> 
> E * 2 + 2 seconds should be enough for waiting for removing routes.
> 
> [...]

Here is the summary with links:
  - [net-next,v3] selftests/net: fix waiting time for ipv6_gc test in fib_tests.sh.
    https://git.kernel.org/netdev/net-next/c/4af9a0bee116

You are awesome, thank you!
diff mbox series

Patch

diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
index 3ec1050e47a2..73895711cdf4 100755
--- a/tools/testing/selftests/net/fib_tests.sh
+++ b/tools/testing/selftests/net/fib_tests.sh
@@ -789,6 +789,7 @@  fib6_gc_test()
 	set -e
 
 	EXPIRE=5
+	GC_WAIT_TIME=$((EXPIRE * 2 + 2))
 
 	# Check expiration of routes every $EXPIRE seconds (GC)
 	$NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE
@@ -805,7 +806,7 @@  fib6_gc_test()
 	    $IP -6 route add 2001:20::$i \
 		via 2001:10::2 dev dummy_10 expires $EXPIRE
 	done
-	sleep $(($EXPIRE * 2 + 1))
+	sleep $GC_WAIT_TIME
 	$NS_EXEC sysctl -wq net.ipv6.route.flush=1
 	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
 	log_test $ret 0 "ipv6 route garbage collection"
@@ -823,7 +824,8 @@  fib6_gc_test()
 	    $IP -6 route add 2001:20::$i \
 		via 2001:10::2 dev dummy_10 expires $EXPIRE
 	done
-	sleep $(($EXPIRE * 2 + 1))
+	# Wait for GC
+	sleep $GC_WAIT_TIME
 	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
 	log_test $ret 0 "ipv6 route garbage collection (with permanent routes)"
 
@@ -840,10 +842,8 @@  fib6_gc_test()
 	    $IP -6 route replace 2001:20::$i \
 		via 2001:10::2 dev dummy_10 expires $EXPIRE
 	done
-	check_rt_num_clean 5 $($IP -6 route list |grep expires|wc -l) || return
 	# Wait for GC
-	sleep $(($EXPIRE * 2 + 1))
-	$NS_EXEC sysctl -wq net.ipv6.route.flush=1
+	sleep $GC_WAIT_TIME
 	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
 	log_test $ret 0 "ipv6 route garbage collection (replace with expires)"
 
@@ -863,8 +863,7 @@  fib6_gc_test()
 	check_rt_num_clean 0 $($IP -6 route list |grep expires|wc -l) || return
 
 	# Wait for GC
-	sleep $(($EXPIRE * 2 + 1))
-
+	sleep $GC_WAIT_TIME
 	check_rt_num 5 $($IP -6 route list |grep -v expires|grep 2001:20::|wc -l)
 	log_test $ret 0 "ipv6 route garbage collection (replace with permanent)"
 
@@ -901,9 +900,7 @@  fib6_gc_test()
 	check_rt_num_clean 1 $($IP -6 route list|grep expires|wc -l) || return
 
 	# Wait for GC
-	sleep $(($EXPIRE * 2 + 1))
-
-	$NS_EXEC sysctl -wq net.ipv6.route.flush=1
+	sleep $GC_WAIT_TIME
 	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
 	log_test $ret 0 "ipv6 route garbage collection (RA message)"