Changeset View
Changeset View
Standalone View
Standalone View
sys/tests/fib_lookup/fib_lookup.c
Show First 20 Lines • Show All 499 Lines • ▼ Show 20 Lines | printf("%zu packets in %zu nanoseconds, %zu pps\n", | ||||
total_packets, total_diff, total_packets * 1000000000 / total_diff); | total_packets, total_diff, total_packets * 1000000000 / total_diff); | ||||
return (0); | return (0); | ||||
} | } | ||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_inet_scan, | SYSCTL_PROC(_net_route_test, OID_AUTO, run_inet_scan, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | ||||
0, 0, run_test_inet_scan, "I", "Execute fib4_lookup scan tests"); | 0, 0, run_test_inet_scan, "I", "Execute fib4_lookup scan tests"); | ||||
#define LPS_SEQ 0x1 | |||||
#define LPS_ANN 0x2 | |||||
#define LPS_REP 0x4 | |||||
struct lps_walk_state { | |||||
uint32_t *keys; | |||||
int pos; | |||||
int lim; | |||||
}; | |||||
static int | static int | ||||
reduce_keys(struct rtentry *rt, void *_data) | |||||
{ | |||||
struct lps_walk_state *wa = (struct lps_walk_state *) _data; | |||||
struct in_addr addr; | |||||
uint32_t scopeid; | |||||
int plen; | |||||
rt_get_inet_prefix_plen(rt, &addr, &plen, &scopeid); | |||||
wa->keys[wa->pos] = ntohl(addr.s_addr) | | |||||
(wa->keys[wa->pos] & ~(0xffffffffU << (32 - plen))); | |||||
wa->pos++; | |||||
return (wa->pos == wa->lim); | |||||
} | |||||
static int | |||||
rnd_lps(SYSCTL_HANDLER_ARGS) | rnd_lps(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct epoch_tracker et; | struct epoch_tracker et; | ||||
struct in_addr key; | struct in_addr key; | ||||
struct lps_walk_state wa; | |||||
struct timespec ts_pre, ts_post; | struct timespec ts_pre, ts_post; | ||||
struct nhop_object *nh_fib; | |||||
uint64_t total_diff, lps; | uint64_t total_diff, lps; | ||||
uint32_t *keys; | uint32_t *keys; | ||||
uint32_t t, p; | |||||
uintptr_t acc = 0; | uintptr_t acc = 0; | ||||
int count = 0; | int i, pos, count = 0; | ||||
int seq = 0, rep = 0; | |||||
int error; | int error; | ||||
error = sysctl_handle_int(oidp, &count, 0, req); | error = sysctl_handle_int(oidp, &count, 0, req); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (count <= 0) | if (count <= 0) | ||||
return (0); | return (0); | ||||
keys = malloc(sizeof(*keys) * count, M_TEMP, M_NOWAIT); | keys = malloc(sizeof(*keys) * count, M_TEMP, M_NOWAIT); | ||||
if (keys == NULL) | if (keys == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
printf("Preparing %d random keys...\n", count); | printf("Preparing %d random keys...\n", count); | ||||
arc4random_buf(keys, sizeof(*keys) * count); | arc4random_buf(keys, sizeof(*keys) * count); | ||||
printf("Starting LPS test...\n"); | if (arg2 & LPS_ANN) { | ||||
wa.keys = keys; | |||||
wa.pos = 0; | |||||
wa.lim = count; | |||||
printf("Reducing keys to announced address space...\n"); | |||||
do { | |||||
rib_walk(RT_DEFAULT_FIB, AF_INET, false, reduce_keys, | |||||
&wa); | |||||
} while (wa.pos < wa.lim); | |||||
printf("Reshuffling keys...\n"); | |||||
for (int i = 0; i < count; i++) { | |||||
p = random() % count; | |||||
t = keys[p]; | |||||
keys[p] = keys[i]; | |||||
keys[i] = t; | |||||
} | |||||
} | |||||
if (arg2 & LPS_REP) { | |||||
rep = 1; | |||||
printf("REP "); | |||||
} | |||||
if (arg2 & LPS_SEQ) { | |||||
seq = 1; | |||||
printf("SEQ"); | |||||
} else if (arg2 & LPS_ANN) | |||||
printf("ANN"); | |||||
else | |||||
printf("RND"); | |||||
printf(" LPS test starting...\n"); | |||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
nanouptime(&ts_pre); | nanouptime(&ts_pre); | ||||
switch (arg2) { | for (i = 0, pos = 0; i < count; i++) { | ||||
case 0: | key.s_addr = keys[pos++] ^ ((acc >> 10) & 0xff); | ||||
for (int i = 0; i < count; i++) { | nh_fib = fib4_lookup(RT_DEFAULT_FIB, key, 0, NHR_NONE, 0); | ||||
key.s_addr = keys[i] + acc; | if (seq) { | ||||
acc += (uintptr_t) fib4_lookup(RT_DEFAULT_FIB, key, 0, | if (nh_fib != NULL) { | ||||
NHR_NONE, 0); | acc += (uintptr_t) nh_fib + 123; | ||||
if (acc & 0x1000) | |||||
acc += (uintptr_t) nh_fib->nh_ifp; | |||||
else | |||||
acc -= (uintptr_t) nh_fib->nh_ifp; | |||||
} else | |||||
acc ^= (acc >> 3) + (acc << 2) + i; | |||||
if (acc & 0x800) | |||||
pos++; | |||||
if (pos >= count) | |||||
pos = 0; | |||||
} | } | ||||
case 1: | if (rep && ((i & 0xf) == 0xf)) { | ||||
for (int i = 0; i < count; i++) { | pos -= 0xf; | ||||
key.s_addr = keys[i]; | if (pos < 0) | ||||
acc += (uintptr_t) fib4_lookup(RT_DEFAULT_FIB, key, 0, | pos += 0xf; | ||||
NHR_NONE, 0); | |||||
} | } | ||||
} | } | ||||
nanouptime(&ts_post); | nanouptime(&ts_post); | ||||
NET_EPOCH_EXIT(et); | NET_EPOCH_EXIT(et); | ||||
free(keys, M_TEMP); | free(keys, M_TEMP); | ||||
total_diff = (ts_post.tv_sec - ts_pre.tv_sec) * 1000000000 + | total_diff = (ts_post.tv_sec - ts_pre.tv_sec) * 1000000000 + | ||||
(ts_post.tv_nsec - ts_pre.tv_nsec) + (acc & 1); | (ts_post.tv_nsec - ts_pre.tv_nsec); | ||||
lps = 1000000000ULL * count / total_diff; | lps = 1000000000ULL * count / total_diff; | ||||
printf("%d lookups in %zu nanoseconds, %lu.%06lu MLPS\n", | printf("%d lookups in %zu.%06zu milliseconds, %lu.%06lu MLPS\n", | ||||
count, total_diff, lps / 1000000, lps % 1000000); | count, total_diff / 1000000, total_diff % 1000000, | ||||
lps / 1000000, lps % 1000000); | |||||
return (0); | return (0); | ||||
} | } | ||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_seq, | SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_rnd, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | ||||
0, 0, rnd_lps, "I", | 0, 0, rnd_lps, "I", | ||||
"Measure lookups per second, uniformly random keys, independent lookups"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_rnd_ann, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_ANN, rnd_lps, "I", | |||||
"Measure lookups per second, random keys from announced address space, " | |||||
"independent lookups"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_seq, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_SEQ, rnd_lps, "I", | |||||
"Measure lookups per second, uniformly random keys, " | "Measure lookups per second, uniformly random keys, " | ||||
"artificial dependencies between lookups"); | "artificial dependencies between lookups"); | ||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_rnd, | SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_seq_ann, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | ||||
0, 1, rnd_lps, "I", | 0, LPS_SEQ | LPS_ANN, rnd_lps, "I", | ||||
"Measure lookups per second, uniformly random keys, independent lookups"); | "Measure lookups per second, random keys from announced address space, " | ||||
"artificial dependencies between lookups"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_rnd_rep, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_REP, rnd_lps, "I", | |||||
"Measure lookups per second, uniformly random keys, independent lookups, " | |||||
"repeated keys"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_rnd_ann_rep, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_ANN | LPS_REP, rnd_lps, "I", | |||||
"Measure lookups per second, random keys from announced address space, " | |||||
"independent lookups, repeated keys"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_seq_rep, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_SEQ | LPS_REP, rnd_lps, "I", | |||||
"Measure lookups per second, uniformly random keys, " | |||||
"artificial dependencies between lookups, repeated keys"); | |||||
SYSCTL_PROC(_net_route_test, OID_AUTO, run_lps_seq_ann_rep, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, | |||||
0, LPS_SEQ | LPS_ANN | LPS_REP, rnd_lps, "I", | |||||
"Measure lookups per second, random keys from announced address space, " | |||||
"artificial dependencies between lookups, repeated keys"); | |||||
static int | static int | ||||
test_fib_lookup_modevent(module_t mod, int type, void *unused) | test_fib_lookup_modevent(module_t mod, int type, void *unused) | ||||
{ | { | ||||
int error = 0; | int error = 0; | ||||
switch (type) { | switch (type) { | ||||
case MOD_LOAD: | case MOD_LOAD: | ||||
Show All 22 Lines |