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