rib: size the routing table for the routes the peers are expected to send

The routing table's shards started empty and grew as routes came in,
each growth moving every row of the shard into a table twice the size.
In a profile of the daemon taking in a full table, the growth showed as
up to a seventh of the session's time, and the daemon's resident memory
had the old and the new table of each shard side by side for a moment.

This change adds `RibTable::expect_prefixes`, which reserves room for
that many prefixes spread over the shards, and has the server call it at
startup with the largest `expected_routes` among the configured peers:
the prefixes of several full tables are mostly the same ones. Without
`expected_routes` nothing changes. The `full_table` benchmark does the
same unless `BENCH_PRESIZE=0`.

Measured, the saving in time is within the run-to-run noise: in the
Linux VM one peer's table is in the routing table in 0.81 s instead of
0.89 s, and the kernel is in step at about the same time as before;
three pairs of runs of the benchmark on a Mac average 0.33 s against
0.35 s. The profile's attribution to the growth was mostly sampling skid.
The memory saving is real: 442 MiB resident with one peer's table in
instead of 483 MiB, and 626 MiB instead of 632 MiB with four.

Also: the profiling script printed nothing for the kernel's change
counts because it asked `/metrics` for them; the endpoint is `/metricz`.
With that fixed, a four-peer load shows 1.25 million installs for 1.23
million prefixes: the journal already gives the kernel task only the
latest change of a prefix when it lags, so no further coalescing of
installs is called for.

Documentation: `expected_routes` in the configuration reference, the
neighbor guide and the proto comment say that the table is sized by it;
the testing guide's VM results are brought up to date.

Testing: a table test checks that the room is there and is kept; the
workspace tests pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Rayhaan JaufeerallyandClaude Fable 5.1 committed 2026-10-09 00:13:02 +02:00
1 parent 9e9e4f90ef
commit 48da8cc7d2
9 files changed
+75 -14

No files matched your search

+4 -3
View File
@@ -87,8 +87,8 @@ listen_endpoints { address: "192.0.2.254" port: 1790 }
http_endpoint { address: "127.0.0.1" port: 8080 }
CONFIG
# The peers are configured as a router's would be, with how many routes
# to expect of each; the synthetic table has a few bogons, which the
# default import policy refuses.
# to expect of each. They have private AS numbers and the synthetic table
# has a few bogon prefixes, so bogons are taken.
for n in $(seq "$peers"); do
cat >> "$out/daemon.textpb" <<CONFIG
peers {
@@ -96,6 +96,7 @@ peers {
endpoint { address: "192.0.2.$n" port: 179 }
remote_asn: $(( 64512 + n ))
expected_routes: $prefixes
import { accept_bogons: true }
}
CONFIG
done
@@ -146,7 +147,7 @@ if [ "$kernel" = 1 ]; then
fi
rss=$(awk '/VmRSS/ { printf "%.0f", $2 / 1024 }' "/proc/$daemon_pid/status")
echo "daemon: $rss MiB resident with the table in"
run curl -sf http://127.0.0.1:8080/metrics | grep '^bgp_kernel_route_changes_total' | sed 's/^/kernel: /'
run curl -sf http://127.0.0.1:8080/metricz | grep '^bgp_kernel_route_changes_total' | sed 's/^/kernel: /'
sleep 1
sudo kill -INT "$perf_pid"
wait "$perf_pid" || true