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?

thanks and
regards
sasha

--------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);
 }
 
 /*

Reply via email to