1 /* $NetBSD: npf_perf_test.c,v 1.4 2014/06/25 00:21:42 rmind Exp $ */ 2 3 /* 4 * NPF benchmarking. 5 * 6 * Public Domain. 7 */ 8 9 #include <sys/types.h> 10 #include <sys/param.h> 11 12 #include <sys/kernel.h> 13 #include <sys/kmem.h> 14 #include <sys/kthread.h> 15 16 #include "npf_impl.h" 17 #include "npf_test.h" 18 19 #define NSECS 10 /* seconds */ 20 21 static volatile int run; 22 static volatile int done; 23 24 static uint64_t * npackets; 25 static bool stateful; 26 27 static struct mbuf * 28 fill_packet(unsigned i) 29 { 30 struct mbuf *m; 31 struct ip *ip; 32 struct udphdr *uh; 33 char buf[32]; 34 35 m = mbuf_construct(IPPROTO_UDP); 36 uh = mbuf_return_hdrs(m, false, &ip); 37 38 snprintf(buf, sizeof(buf), "192.0.2.%u", i + i); 39 ip->ip_src.s_addr = inet_addr(PUB_IP1); 40 ip->ip_dst.s_addr = inet_addr(stateful ? LOCAL_IP2 : LOCAL_IP3); 41 uh->uh_sport = htons(80); 42 uh->uh_dport = htons(15000 + i); 43 return m; 44 } 45 46 __dead static void 47 worker(void *arg) 48 { 49 ifnet_t *ifp = ifunit(IFNAME_INT); 50 unsigned int i = (uintptr_t)arg; 51 struct mbuf *m = fill_packet(i); 52 uint64_t n = 0; 53 54 while (!run) 55 /* spin-wait */; 56 while (!done) { 57 int error; 58 59 error = npf_packet_handler(NULL, &m, ifp, PFIL_OUT); 60 KASSERT(error == 0); 61 n++; 62 } 63 npackets[i] = n; 64 kthread_exit(0); 65 } 66 67 void 68 npf_test_conc(bool st, unsigned nthreads) 69 { 70 uint64_t total = 0; 71 int error; 72 lwp_t **l; 73 74 printf("THREADS\tPKTS\n"); 75 stateful = st; 76 done = false; 77 run = false; 78 79 npackets = kmem_zalloc(sizeof(uint64_t) * nthreads, KM_SLEEP); 80 l = kmem_zalloc(sizeof(lwp_t *) * nthreads, KM_SLEEP); 81 82 for (unsigned i = 0; i < nthreads; i++) { 83 const int flags = KTHREAD_MUSTJOIN | KTHREAD_MPSAFE; 84 error = kthread_create(PRI_NONE, flags, NULL, 85 worker, (void *)(uintptr_t)i, &l[i], "npfperf"); 86 KASSERT(error == 0); 87 } 88 89 /* Let them spin! */ 90 run = true; 91 kpause("perf", false, NSECS * hz, NULL); 92 done = true; 93 94 /* Wait until all threads exit and sum the counts. */ 95 for (unsigned i = 0; i < nthreads; i++) { 96 kthread_join(l[i]); 97 total += npackets[i]; 98 } 99 kmem_free(npackets, sizeof(uint64_t) * nthreads); 100 kmem_free(l, sizeof(lwp_t *) * nthreads); 101 102 printf("%u\t%" PRIu64 "\n", nthreads, total / NSECS); 103 } 104