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);
+}

Reply via email to