Module Name: src Committed By: rmind Date: Tue Sep 24 02:04:22 UTC 2013
Modified Files: src/usr.sbin/npf/npftest: npfstream.c npftest.c npftest.h src/usr.sbin/npf/npftest/libnpftest: Makefile npf_nat_test.c npf_rule_test.c npf_test.h npf_test_subr.c Added Files: src/usr.sbin/npf/npftest/libnpftest: npf_perf_test.c Log Message: npftest: add some concurrency testing code. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/npf/npftest/npfstream.c cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/npf/npftest/npftest.c cvs rdiff -u -r1.7 -r1.8 src/usr.sbin/npf/npftest/npftest.h cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/npf/npftest/libnpftest/Makefile cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c cvs rdiff -u -r0 -r1.1 src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c cvs rdiff -u -r1.8 -r1.9 src/usr.sbin/npf/npftest/libnpftest/npf_test.h cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/npf/npftest/npfstream.c diff -u src/usr.sbin/npf/npftest/npfstream.c:1.4 src/usr.sbin/npf/npftest/npfstream.c:1.5 --- src/usr.sbin/npf/npftest/npfstream.c:1.4 Wed Sep 12 16:26:02 2012 +++ src/usr.sbin/npf/npftest/npfstream.c Tue Sep 24 02:04:21 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npfstream.c,v 1.4 2012/09/12 16:26:02 martin Exp $ */ +/* $NetBSD: npfstream.c,v 1.5 2013/09/24 02:04:21 rmind Exp $ */ /* * NPF stream processor. @@ -71,7 +71,7 @@ process_tcpip(const void *data, size_t l memset(result, 0, sizeof(result)); len = ntohs(ip->ip_len); - error = rumpns_npf_test_handlepkt(ip, len, idx, forw, result); + error = rumpns_npf_test_statetrack(ip, len, idx, forw, result); fprintf(fp, "%s%2x %5d %3d %11u %11u %11u %11u %12" PRIxPTR, forw ? ">" : "<", (th->th_flags & (TH_SYN | TH_ACK | TH_FIN)), Index: src/usr.sbin/npf/npftest/npftest.c diff -u src/usr.sbin/npf/npftest/npftest.c:1.10 src/usr.sbin/npf/npftest/npftest.c:1.11 --- src/usr.sbin/npf/npftest/npftest.c:1.10 Thu Sep 19 01:49:07 2013 +++ src/usr.sbin/npf/npftest/npftest.c Tue Sep 24 02:04:21 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npftest.c,v 1.10 2013/09/19 01:49:07 rmind Exp $ */ +/* $NetBSD: npftest.c,v 1.11 2013/09/24 02:04:21 rmind Exp $ */ /* * NPF testing framework. @@ -139,6 +139,7 @@ main(int argc, char **argv) { bool benchmark, test, ok, fail, tname_matched; char *config, *interface, *stream, *testname; + unsigned nthreads = 0; int idx = -1, ch; benchmark = false; @@ -153,7 +154,7 @@ main(int argc, char **argv) verbose = false; quiet = false; - while ((ch = getopt(argc, argv, "bqvc:i:s:tT:L")) != -1) { + while ((ch = getopt(argc, argv, "bqvc:i:s:tT:Lp:")) != -1) { switch (ch) { case 'b': benchmark = true; @@ -182,18 +183,34 @@ main(int argc, char **argv) break; case 'L': describe_tests(); + break; + case 'p': + /* Note: RUMP_NCPU must be high enough. */ + if ((nthreads = atoi(optarg)) > 0 && + getenv("RUMP_NCPU") == NULL) { + char *val; + asprintf(&val, "%u", nthreads + 1); + setenv("RUMP_NCPU", val, 1); + free(val); + } + break; default: usage(); } } /* - * Either benchmark or test. If stream analysis, then the interface - * is needed as well. + * Either benchmark or test. If stream analysis, then the + * interface should be specified. If benchmark, then the + * config should be loaded. */ if (benchmark == test && (stream && !interface)) { usage(); } + if (benchmark && (!config || !nthreads)) { + errx(EXIT_FAILURE, "missing config for the benchmark or " + "invalid thread count"); + } /* XXX rn_init */ extern int rumpns_max_keylen; @@ -258,6 +275,10 @@ main(int argc, char **argv) process_stream(stream, NULL, idx); } + if (benchmark) { + rumpns_npf_test_conc(nthreads); + } + rump_unschedule(); if (testname && !tname_matched) Index: src/usr.sbin/npf/npftest/npftest.h diff -u src/usr.sbin/npf/npftest/npftest.h:1.7 src/usr.sbin/npf/npftest/npftest.h:1.8 --- src/usr.sbin/npf/npftest/npftest.h:1.7 Thu Sep 19 01:49:07 2013 +++ src/usr.sbin/npf/npftest/npftest.h Tue Sep 24 02:04:21 2013 @@ -7,15 +7,17 @@ #ifndef _NPF_TEST_H_ #define _NPF_TEST_H_ -#include <stdint.h> +#include <inttypes.h> #include <stdbool.h> void rumpns_npf_test_init(void); int rumpns_npf_test_load(const void *); unsigned rumpns_npf_test_addif(const char *, unsigned, bool); unsigned rumpns_npf_test_getif(const char *); -int rumpns_npf_test_handlepkt(const void *, size_t, + +int rumpns_npf_test_statetrack(const void *, size_t, unsigned, bool, int64_t *); +void rumpns_npf_test_conc(unsigned); bool rumpns_npf_nbuf_test(bool); bool rumpns_npf_bpf_test(bool); Index: src/usr.sbin/npf/npftest/libnpftest/Makefile diff -u src/usr.sbin/npf/npftest/libnpftest/Makefile:1.6 src/usr.sbin/npf/npftest/libnpftest/Makefile:1.7 --- src/usr.sbin/npf/npftest/libnpftest/Makefile:1.6 Thu Sep 19 01:49:07 2013 +++ src/usr.sbin/npf/npftest/libnpftest/Makefile Tue Sep 24 02:04:21 2013 @@ -18,6 +18,8 @@ SRCS+= npf_state_test.c SRCS+= npf_rule_test.c SRCS+= npf_nat_test.c +SRCS+= npf_perf_test.c + CPPFLAGS+= -D_NPF_TESTING CPPFLAGS+= -I${.CURDIR}/../../../../sys/net/npf CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern Index: src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c diff -u src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.3 src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.4 --- src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c:1.3 Thu Sep 19 01:04:46 2013 +++ src/usr.sbin/npf/npftest/libnpftest/npf_nat_test.c Tue Sep 24 02:04:21 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_nat_test.c,v 1.3 2013/09/19 01:04:46 rmind Exp $ */ +/* $NetBSD: npf_nat_test.c,v 1.4 2013/09/24 02:04:21 rmind Exp $ */ /* * NPF NAT test. @@ -11,18 +11,6 @@ #include "npf_impl.h" #include "npf_test.h" -#define IFNAME_EXT "npftest0" -#define IFNAME_INT "npftest1" - -#define LOCAL_IP1 "10.1.1.1" -#define LOCAL_IP2 "10.1.1.2" - -/* Note: RFC 5737 compliant addresses. */ -#define PUB_IP1 "192.0.2.1" -#define PUB_IP2 "192.0.2.2" -#define REMOTE_IP1 "192.0.2.3" -#define REMOTE_IP2 "192.0.2.4" - #define RESULT_PASS 0 #define RESULT_BLOCK ENETUNREACH Index: src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c diff -u src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.9 src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.10 --- src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c:1.9 Thu Sep 19 01:49:07 2013 +++ src/usr.sbin/npf/npftest/libnpftest/npf_rule_test.c Tue Sep 24 02:04:21 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_rule_test.c,v 1.9 2013/09/19 01:49:07 rmind Exp $ */ +/* $NetBSD: npf_rule_test.c,v 1.10 2013/09/24 02:04:21 rmind Exp $ */ /* * NPF ruleset test. @@ -11,9 +11,6 @@ #include "npf_impl.h" #include "npf_test.h" -#define IFNAME_EXT "npftest0" -#define IFNAME_INT "npftest1" - #define RESULT_PASS 0 #define RESULT_BLOCK ENETUNREACH Index: src/usr.sbin/npf/npftest/libnpftest/npf_test.h diff -u src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.8 src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.9 --- src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.8 Thu Sep 19 01:49:07 2013 +++ src/usr.sbin/npf/npftest/libnpftest/npf_test.h Tue Sep 24 02:04:21 2013 @@ -24,12 +24,28 @@ #include <net/if_ether.h> #include <net/ethertypes.h> +/* Test interfaces and IP addresses. */ +#define IFNAME_EXT "npftest0" +#define IFNAME_INT "npftest1" + +#define LOCAL_IP1 "10.1.1.1" +#define LOCAL_IP2 "10.1.1.2" +#define LOCAL_IP3 "10.1.1.3" + +/* Note: RFC 5737 compliant addresses. */ +#define PUB_IP1 "192.0.2.1" +#define PUB_IP2 "192.0.2.2" +#define REMOTE_IP1 "192.0.2.3" +#define REMOTE_IP2 "192.0.2.4" + void npf_test_init(void); int npf_test_load(const void *); unsigned npf_test_addif(const char *, unsigned, bool); unsigned npf_test_getif(const char *); -int npf_test_handlepkt(const void *, size_t, unsigned, + +int npf_test_statetrack(const void *, size_t, unsigned, bool, int64_t *); +void npf_test_conc(unsigned); struct mbuf * mbuf_getwithdata(const void *, size_t); struct mbuf * mbuf_construct_ether(int); Index: src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c diff -u src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.4 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.5 --- src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.4 Wed Aug 15 19:47:38 2012 +++ src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c Tue Sep 24 02:04:21 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_test_subr.c,v 1.4 2012/08/15 19:47:38 rmind Exp $ */ +/* $NetBSD: npf_test_subr.c,v 1.5 2013/09/24 02:04:21 rmind Exp $ */ /* * NPF initialisation and handler routines. @@ -72,7 +72,7 @@ npf_state_sample(npf_state_t *nst, bool } int -npf_test_handlepkt(const void *data, size_t len, unsigned idx, +npf_test_statetrack(const void *data, size_t len, unsigned idx, bool forw, int64_t *result) { ifnet_t ifp = { .if_index = idx }; Added files: Index: src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c diff -u /dev/null src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c:1.1 --- /dev/null Tue Sep 24 02:04:22 2013 +++ src/usr.sbin/npf/npftest/libnpftest/npf_perf_test.c Tue Sep 24 02:04:21 2013 @@ -0,0 +1,95 @@ +/* $NetBSD: npf_perf_test.c,v 1.1 2013/09/24 02:04:21 rmind Exp $ */ + +/* + * NPF benchmarking. + * + * Public Domain. + */ + +#include <sys/types.h> +#include <sys/param.h> + +#include <sys/kernel.h> +#include <sys/kmem.h> +#include <sys/kthread.h> + +#include "npf_impl.h" +#include "npf_test.h" + +#define NSECS 1 /* seconds */ + +static volatile int run; +static volatile int done; + +static struct mbuf * +fill_packet(void) +{ + struct mbuf *m; + struct ip *ip; + struct tcphdr *th; + + m = mbuf_construct(IPPROTO_TCP); + th = mbuf_return_hdrs(m, false, &ip); + ip->ip_src.s_addr = inet_addr(PUB_IP1); + ip->ip_dst.s_addr = inet_addr(LOCAL_IP3); + th->th_sport = htons(80); + th->th_dport = htons(15000); + return m; +} + +static void +worker(void *arg) +{ + ifnet_t *ifp = ifunit(IFNAME_INT); + uint64_t n = 0, *npackets = arg; + struct mbuf *m = fill_packet(); + + while (!run) + /* spin-wait */; + while (!done) { + int error; + + error = npf_packet_handler(NULL, &m, ifp, PFIL_OUT); + KASSERT(error == 0); + n++; + } + *npackets = n; + kthread_exit(0); +} + +void +npf_test_conc(unsigned nthreads) +{ + uint64_t total = 0, *npackets; + int error; + lwp_t **l; + + npackets = kmem_zalloc(sizeof(uint64_t) * nthreads, KM_SLEEP); + l = kmem_zalloc(sizeof(lwp_t *) * nthreads, KM_SLEEP); + + printf("THREADS\tPKTS\n"); + done = false; + run = false; + + for (unsigned i = 0; i < nthreads; i++) { + const int flags = KTHREAD_MUSTJOIN | KTHREAD_MPSAFE; + error = kthread_create(PRI_NONE, flags, NULL, + worker, &npackets[i], &l[i], "npfperf"); + KASSERT(error == 0); + } + + /* Let them spin! */ + run = true; + kpause("perf", false, NSECS * hz, NULL); + done = true; + + /* Wait until all threads exit and sum the counts. */ + for (unsigned i = 0; i < nthreads; i++) { + kthread_join(l[i]); + total += npackets[i]; + } + kmem_free(npackets, sizeof(uint64_t) * nthreads); + kmem_free(l, sizeof(lwp_t *) * nthreads); + + printf("%u\t%" PRIu64 "\n", nthreads, total); +}