On 30/10/17(Mon) 08:36, Alexandr Nedvedicky wrote: > Hello, > > patch below adds additional softnet taskq. This will allow certain degree of > parallelism for packet processing in pf_test(). The current plan is to let > packets received by even NICs (even ifindex) to be processed by task0, packets > received by odd NICs (odd ifindex) by task1. > > big thanks should go to mpi@, who 'programmed' me to program the patch below. > > OK?
ok with SOFTNET_TASKS defined to 1, then we can bump it when needed. > --------8<---------------8<---------------8<------------------8<-------- > diff --git a/sys/net/if.c b/sys/net/if.c > index e9e9f07add1..d688456b677 100644 > --- a/sys/net/if.c > +++ b/sys/net/if.c > @@ -224,7 +224,9 @@ int net_livelocked(void); > int ifq_congestion; > > int netisr; > -struct taskq *softnettq; > + > +#define SOFTNET_TASKS 2 > +struct taskq *softnettq[SOFTNET_TASKS]; > > struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL); > > @@ -240,6 +242,8 @@ struct rwlock netlock = RWLOCK_INITIALIZER("netlock"); > void > ifinit(void) > { > + unsigned int i; > + > /* > * most machines boot with 4 or 5 interfaces, so size the initial map > * to accomodate this > @@ -248,9 +252,11 @@ ifinit(void) > > timeout_set(&net_tick_to, net_tick, &net_tick_to); > > - softnettq = taskq_create("softnet", 1, IPL_NET, TASKQ_MPSAFE); > - if (softnettq == NULL) > - panic("unable to create softnet taskq"); > + for (i = 0; i < SOFTNET_TASKS; i++) { > + softnettq[i] = taskq_create("softnet", 1, IPL_NET, > TASKQ_MPSAFE); > + if (softnettq[i] == NULL) > + panic("unable to create softnet taskq"); > + } > > net_tick(&net_tick_to); > } > @@ -725,7 +731,7 @@ if_input(struct ifnet *ifp, struct mbuf_list *ml) > #endif > > if (mq_enlist(&ifp->if_inputqueue, ml) == 0) > - task_add(softnettq, ifp->if_inputtask); > + task_add(net_tq(ifp->if_index), ifp->if_inputtask); > } > > int > @@ -1025,15 +1031,15 @@ if_detach(struct ifnet *ifp) > ifp->if_watchdog = NULL; > > /* Remove the input task */ > - task_del(softnettq, ifp->if_inputtask); > + task_del(net_tq(ifp->if_index), ifp->if_inputtask); > mq_purge(&ifp->if_inputqueue); > > /* Remove the watchdog timeout & task */ > timeout_del(ifp->if_slowtimo); > - task_del(softnettq, ifp->if_watchdogtask); > + task_del(net_tq(ifp->if_index), ifp->if_watchdogtask); > > /* Remove the link state task */ > - task_del(softnettq, ifp->if_linkstatetask); > + task_del(net_tq(ifp->if_index), ifp->if_linkstatetask); > > #if NBPFILTER > 0 > bpfdetach(ifp); > @@ -1583,7 +1589,7 @@ if_linkstate(struct ifnet *ifp) > void > if_link_state_change(struct ifnet *ifp) > { > - task_add(softnettq, ifp->if_linkstatetask); > + task_add(net_tq(ifp->if_index), ifp->if_linkstatetask); > } > > /* > @@ -1599,7 +1605,7 @@ if_slowtimo(void *arg) > > if (ifp->if_watchdog) { > if (ifp->if_timer > 0 && --ifp->if_timer == 0) > - task_add(softnettq, ifp->if_watchdogtask); > + task_add(net_tq(ifp->if_index), ifp->if_watchdogtask); > timeout_add(ifp->if_slowtimo, hz / IFNET_SLOWHZ); > } > splx(s); > @@ -2881,3 +2887,13 @@ unhandled_af(int af) > { > panic("unhandled af %d", af); > } > + > +struct taskq * > +net_tq(unsigned int ifindex) > +{ > + struct taskq *t = NULL; > + > + t = softnettq[ifindex % SOFTNET_TASKS]; > + > + return (t); > +} > diff --git a/sys/net/if.h b/sys/net/if.h > index 89867eac340..6a0770a8ea0 100644 > --- a/sys/net/if.h > +++ b/sys/net/if.h > @@ -489,6 +489,7 @@ void if_congestion(void); > int if_congested(void); > __dead void unhandled_af(int); > int if_setlladdr(struct ifnet *, const uint8_t *); > +struct taskq * net_tq(unsigned int); > > #endif /* _KERNEL */ > > diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c > index 277e7f966a2..e9f58a4ee52 100644 > --- a/sys/net/if_loop.c > +++ b/sys/net/if_loop.c > @@ -244,7 +244,7 @@ looutput(struct ifnet *ifp, struct mbuf *m, struct > sockaddr *dst, > m->m_pkthdr.ph_family = dst->sa_family; > if (mq_enqueue(&ifp->if_inputqueue, m)) > return ENOBUFS; > - task_add(softnettq, ifp->if_inputtask); > + task_add(net_tq(ifp->if_index), ifp->if_inputtask); > > return (0); > } > diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c > index 38efb02be7e..91a61fe4c15 100644 > --- a/sys/net/if_pflow.c > +++ b/sys/net/if_pflow.c > @@ -286,7 +286,7 @@ pflow_clone_destroy(struct ifnet *ifp) > if (timeout_initialized(&sc->sc_tmo_tmpl)) > timeout_del(&sc->sc_tmo_tmpl); > pflow_flush(sc); > - task_del(softnettq, &sc->sc_outputtask); > + task_del(net_tq(ifp->if_index), &sc->sc_outputtask); > mq_purge(&sc->sc_outputqueue); > m_freem(sc->send_nam); > if (sc->so != NULL) { > @@ -1087,7 +1087,7 @@ pflow_sendout_v5(struct pflow_softc *sc) > h->time_sec = htonl(tv.tv_sec); /* XXX 2038 */ > h->time_nanosec = htonl(tv.tv_nsec); > if (mq_enqueue(&sc->sc_outputqueue, m) == 0) > - task_add(softnettq, &sc->sc_outputtask); > + task_add(net_tq(ifp->if_index), &sc->sc_outputtask); > return (0); > } > > @@ -1149,7 +1149,7 @@ pflow_sendout_ipfix(struct pflow_softc *sc, sa_family_t > af) > sc->sc_sequence += count; > h10->observation_dom = htonl(PFLOW_ENGINE_TYPE); > if (mq_enqueue(&sc->sc_outputqueue, m) == 0) > - task_add(softnettq, &sc->sc_outputtask); > + task_add(net_tq(ifp->if_index), &sc->sc_outputtask); > return (0); > } > > @@ -1191,7 +1191,7 @@ pflow_sendout_ipfix_tmpl(struct pflow_softc *sc) > > timeout_add_sec(&sc->sc_tmo_tmpl, PFLOW_TMPL_TIMEOUT); > if (mq_enqueue(&sc->sc_outputqueue, m) == 0) > - task_add(softnettq, &sc->sc_outputtask); > + task_add(net_tq(ifp->if_index), &sc->sc_outputtask); > return (0); > } > > diff --git a/sys/net/if_var.h b/sys/net/if_var.h > index 85c4836255f..7ca5e60f1c1 100644 > --- a/sys/net/if_var.h > +++ b/sys/net/if_var.h > @@ -298,7 +298,6 @@ int niq_enlist(struct niqueue *, struct > mbuf_list *); > sysctl_mq((_n), (_l), (_op), (_olp), (_np), (_nl), &(_niq)->ni_q) > > extern struct ifnet_head ifnet; > -extern struct taskq *softnettq; > > void if_start(struct ifnet *); > int if_enqueue_try(struct ifnet *, struct mbuf *); > diff --git a/sys/net/netisr.h b/sys/net/netisr.h > index 813ddd6d2bb..7df2c6faa47 100644 > --- a/sys/net/netisr.h > +++ b/sys/net/netisr.h > @@ -75,7 +75,7 @@ void pipexintr(void); > #define schednetisr(anisr) > \ > do { \ > atomic_setbits_int(&netisr, (1 << (anisr))); \ > - task_add(softnettq, &if_input_task_locked); \ > + task_add(net_tq(0), &if_input_task_locked); \ > } while (/* CONSTCOND */0) > > #endif /* _KERNEL */ > diff --git a/sys/net/pf.c b/sys/net/pf.c > index 0133aeeb63c..20f2c0a3f13 100644 > --- a/sys/net/pf.c > +++ b/sys/net/pf.c > @@ -1222,7 +1222,7 @@ pf_purge_expired_rules(void) > void > pf_purge_timeout(void *unused) > { > - task_add(softnettq, &pf_purge_task); > + task_add(net_tq(0), &pf_purge_task); > } > > void > diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c > index de40e934112..18eecaf9647 100644 > --- a/sys/net/pf_ioctl.c > +++ b/sys/net/pf_ioctl.c > @@ -2310,7 +2310,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, > struct proc *p) > pf_default_rule_new.timeout[i]; > if (pf_default_rule.timeout[i] == PFTM_INTERVAL && > pf_default_rule.timeout[i] < old) > - task_add(softnettq, &pf_purge_task); > + task_add(net_tq(0), &pf_purge_task); > } > pfi_xcommit(); > pf_trans_set_commit(); > diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c > index 95c9194efcb..33cc3161bcb 100644 > --- a/sys/netinet/ip_input.c > +++ b/sys/netinet/ip_input.c > @@ -1839,5 +1839,5 @@ void > ip_send(struct mbuf *m) > { > mq_enqueue(&ipsend_mq, m); > - task_add(softnettq, &ipsend_task); > + task_add(net_tq(0), &ipsend_task); > } > diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c > index d62aa8a429b..f46aa475be7 100644 > --- a/sys/netinet6/ip6_input.c > +++ b/sys/netinet6/ip6_input.c > @@ -1477,5 +1477,5 @@ void > ip6_send(struct mbuf *m) > { > mq_enqueue(&ip6send_mq, m); > - task_add(softnettq, &ip6send_task); > + task_add(net_tq(0), &ip6send_task); > } > diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c > index 9a94a753a6d..b27b5c1b708 100644 > --- a/sys/netinet6/nd6.c > +++ b/sys/netinet6/nd6.c > @@ -486,7 +486,7 @@ nd6_expire(void *unused) > void > nd6_expire_timer(void *unused) > { > - task_add(softnettq, &nd6_expire_task); > + task_add(net_tq(0), &nd6_expire_task); > } > > /* >