ether_input/rss: Pass packet info to ether_input_chain.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 21 Mar 2009 02:46:12 +0000 (10:46 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 21 Mar 2009 02:46:12 +0000 (10:46 +0800)
- Pass packet info to ether_input_chain(), if netisr_find_pktinfo_port()
  could locate the msgport, then short circuit the rest of the ether_input
  code and dispatch the ethernet packet directly.
- Revoke the pi_hash field in pktinfo and extend the pktinfo_portfn_t to
  accpet an mbuf parameter, so that pktinfo_portfn_t could change the mbuf
  hash value.  e.g. pktinfo_portfn_cpu0() will always set m_pkthdr.hash
  to 0.
- Adjust ether_input_chain() callers accordingly.

16 files changed:
sys/dev/netif/bce/if_bce.c
sys/dev/netif/bfe/if_bfe.c
sys/dev/netif/bge/if_bge.c
sys/dev/netif/em/if_em.c
sys/dev/netif/emx/if_emx.c
sys/dev/netif/et/if_et.c
sys/dev/netif/fxp/if_fxp.c
sys/dev/netif/jme/if_jme.c
sys/dev/netif/msk/if_msk.c
sys/dev/netif/nfe/if_nfe.c
sys/dev/netif/re/if_re.c
sys/dev/netif/xl/if_xl.c
sys/net/if_ethersubr.c
sys/net/if_var.h
sys/net/netisr.c
sys/net/netisr.h

index b51b7bb..b0e06ed 100644 (file)
@@ -3918,7 +3918,7 @@ bce_rx_int_next_rx:
                                m->m_pkthdr.ether_vlantag =
                                        l2fhdr->l2_fhdr_vlan_tag;
                        }
-                       ether_input_chain(ifp, m, chain);
+                       ether_input_chain(ifp, m, NULL, chain);
 
                        DBRUNIF(1, sc->rx_mbuf_alloc--);
                }
index f21f5cc..bf2d016 100644 (file)
@@ -1151,7 +1151,7 @@ bfe_rxeof(struct bfe_softc *sc)
                ifp->if_ipackets++;
                m->m_pkthdr.rcvif = ifp;
 
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
                BFE_INC(cons, BFE_RX_LIST_CNT);
        }
 
index 5d1e594..fcd0b89 100644 (file)
@@ -2453,7 +2453,7 @@ bge_rxeof(struct bge_softc *sc)
                        m->m_pkthdr.ether_vlantag = vlan_tag;
                        have_tag = vlan_tag = 0;
                }
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
        }
 
        ether_input_dispatch(chain);
index 63a4f46..fa8be1e 100644 (file)
@@ -3310,7 +3310,7 @@ discard:
                current_desc->status = 0;
 
                if (m != NULL)
-                       ether_input_chain(ifp, m, chain);
+                       ether_input_chain(ifp, m, NULL, chain);
 
                /* Advance our pointers to the next descriptor. */
                if (++i == adapter->num_rx_desc)
index 202dfdf..62ed00b 100644 (file)
@@ -2851,7 +2851,7 @@ discard:
                }
 
                if (m != NULL)
-                       ether_input_chain(ifp, m, chain);
+                       ether_input_chain(ifp, m, NULL, chain);
 
                /* Advance our pointers to the next descriptor. */
                if (++i == rdata->num_rx_desc)
index def0ce8..30f6900 100644 (file)
@@ -1907,7 +1907,7 @@ et_rxeof(struct et_softc *sc)
                                m_adj(m, -ETHER_CRC_LEN);
 
                                ifp->if_ipackets++;
-                               ether_input_chain(ifp, m, chain);
+                               ether_input_chain(ifp, m, NULL, chain);
                        }
                } else {
                        ifp->if_ierrors++;
index 9dcfcf7..a5f0ab3 100644 (file)
@@ -1401,7 +1401,7 @@ fxp_intr_body(struct fxp_softc *sc, u_int8_t statack, int count)
                                continue;
                        }
                        m->m_pkthdr.len = m->m_len = total_len;
-                       ether_input_chain(ifp, m, chain);
+                       ether_input_chain(ifp, m, NULL, chain);
                }
        }
 
index af9a9ee..0b50237 100644 (file)
@@ -2131,7 +2131,7 @@ jme_rxpkt(struct jme_softc *sc, int ring, struct mbuf_chain *chain)
 
                        ifp->if_ipackets++;
                        /* Pass it on. */
-                       ether_input_chain(ifp, m, chain);
+                       ether_input_chain(ifp, m, NULL, chain);
 
                        /* Reset mbuf chains. */
                        JME_RXCHAIN_RESET(sc, ring);
index 9a1fd13..26c04e1 100644 (file)
@@ -2729,7 +2729,7 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len,
                }
 #endif
 
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
        } while (0);
 
        MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
index f91a422..9c769b6 100644 (file)
@@ -1097,7 +1097,7 @@ nfe_rxeof(struct nfe_softc *sc)
                }
 
                ifp->if_ipackets++;
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
 skip:
                nfe_set_ready_rxdesc(sc, ring, ring->cur);
                sc->rxq.cur = (sc->rxq.cur + 1) % sc->sc_rx_ring_count;
index a4a1866..74ed2e5 100644 (file)
@@ -1986,7 +1986,7 @@ re_rxeof(struct re_softc *sc)
                        m->m_pkthdr.ether_vlantag =
                                be16toh((rxctrl & RE_RDESC_CTL_TAGDATA));
                }
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
        }
 
        ether_input_dispatch(chain);
index 6745185..2309ba1 100644 (file)
@@ -2063,7 +2063,7 @@ again:
                        }
                }
 
-               ether_input_chain(ifp, m, chain);
+               ether_input_chain(ifp, m, NULL, chain);
        }
 
        if (sc->xl_type != XL_TYPE_905B) {
index e373540..bf85c2a 100644 (file)
@@ -601,7 +601,7 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, struct ip_fw **rule,
 static void
 ether_input(struct ifnet *ifp, struct mbuf *m)
 {
-       ether_input_chain(ifp, m, NULL);
+       ether_input_chain(ifp, m, NULL, NULL);
 }
 
 /*
@@ -1528,6 +1528,10 @@ ether_mport(int num, struct mbuf **m)
        return netisr_find_port(num, m);
 }
 
+/*
+ * Send the packet to the target msgport or
+ * queue it into 'chain'.
+ */
 static void
 ether_dispatch(int isr, struct lwkt_port *port, struct mbuf *m,
               struct mbuf_chain *chain)
@@ -1576,7 +1580,8 @@ ether_dispatch(int isr, struct lwkt_port *port, struct mbuf *m,
  *   queued on 'chain' to their target msgport.
  */
 void
-ether_input_chain(struct ifnet *ifp, struct mbuf *m, struct mbuf_chain *chain)
+ether_input_chain(struct ifnet *ifp, struct mbuf *m, const struct pktinfo *pi,
+                 struct mbuf_chain *chain)
 {
        struct ether_header *eh, *save_eh, save_eh0;
        struct lwkt_port *port;
@@ -1620,6 +1625,29 @@ ether_input_chain(struct ifnet *ifp, struct mbuf *m, struct mbuf_chain *chain)
                return;
        }
 
+       if (pi != NULL && (m->m_flags & M_HASH)) {
+               /* Try finding the port using the packet info */
+               port = netisr_find_pktinfo_port(pi, m);
+               if (port != NULL) {
+                       ether_dispatch(pi->pi_netisr, port, m, chain);
+                       return;
+               }
+
+               /*
+                * The packet info does not contain enough
+                * information, we will have to check the
+                * packet content.
+                */
+       }
+
+       /*
+        * Packet hash will be recalculated by software,
+        * so clear the M_HASH flag set by the driver;
+        * the hash value calculated by the hardware may
+        * not be exactly what we want.
+        */
+       m->m_flags &= ~M_HASH;
+
        if (!ether_vlancheck(&m)) {
                logether(chain_end, ifp);
                KKASSERT(m == NULL);
@@ -1728,10 +1756,6 @@ ether_input_chain(struct ifnet *ifp, struct mbuf *m, struct mbuf_chain *chain)
                m->m_pkthdr.len += ETHER_HDR_LEN;
        }
 
-       /*
-        * Send the packet to the target msgport or
-        * queue it into 'chain'.
-        */
        ether_dispatch(isr, port, m, chain);
 
        logether(chain_end, ifp);
index ae2a7e8..9c0d933 100644 (file)
@@ -89,6 +89,7 @@ struct        ifaddr;
 struct lwkt_port;
 struct lwkt_msg;
 struct netmsg;
+struct pktinfo;
 
 #include <sys/queue.h>         /* get TAILQ macros */
 
@@ -567,7 +568,8 @@ void        ether_ifdetach(struct ifnet *);
 void   ether_demux_oncpu(struct ifnet *, struct mbuf *);
 void   ether_input_oncpu(struct ifnet *, struct mbuf *);
 void   ether_reinput_oncpu(struct ifnet *, struct mbuf *, int);
-void   ether_input_chain(struct ifnet *, struct mbuf *, struct mbuf_chain *);
+void   ether_input_chain(struct ifnet *, struct mbuf *,
+                         const struct pktinfo *, struct mbuf_chain *);
 void   ether_input_chain_init(struct mbuf_chain *);
 void   ether_input_dispatch(struct mbuf_chain *);
 int    ether_output_frame(struct ifnet *, struct mbuf *);
index c457492..2e65a87 100644 (file)
@@ -559,30 +559,34 @@ netisr_run(int num, struct mbuf *m)
 }
 
 lwkt_port_t
-pktinfo_portfn_cpu0(const struct pktinfo *dummy __unused)
+pktinfo_portfn_cpu0(const struct pktinfo *dummy __unused,
+                   struct mbuf *m)
 {
+    m->m_pkthdr.hash = 0;
     return &netisr_cpu[0].td_msgport;
 }
 
 lwkt_port_t
-pktinfo_portfn_notsupp(const struct pktinfo *dummy __unused)
+pktinfo_portfn_notsupp(const struct pktinfo *dummy __unused,
+                      struct mbuf *m __unused)
 {
     return NULL;
 }
 
 lwkt_port_t
-netisr_find_pktinfo_port(const struct pktinfo *pi)
+netisr_find_pktinfo_port(const struct pktinfo *pi, struct mbuf *m)
 {
     struct netisr *ni;
+    int num = pi->pi_netisr;
 
-    KASSERT((pi->pi_netisr > 0 &&
-            pi->pi_netisr <= (sizeof(netisrs)/sizeof(netisrs[0]))),
-           ("%s: bad isr %d", __func__, pi->pi_netisr));
+    KASSERT(m->m_flags & M_HASH, ("packet does not contain hash\n"));
+    KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
+           ("%s: bad isr %d", __func__, num));
 
-    ni = &netisrs[pi->pi_netisr];
+    ni = &netisrs[num];
     if (ni->ni_mport_pktinfo == NULL) {
-       kprintf("%s: unregistered isr %d\n", __func__, pi->pi_netisr);
+       kprintf("%s: unregistered isr %d\n", __func__, num);
        return NULL;
     }
-    return ni->ni_mport_pktinfo(pi);
+    return ni->ni_mport_pktinfo(pi, m);
 }
index 579a926..5642f2b 100644 (file)
@@ -201,13 +201,12 @@ struct pktinfo {
        int             pi_netisr;      /* netisr index, e.g. NETISR_IP */
        uint32_t        pi_flags;       /* PKTINFO_FLAG_ */
        int             pi_l3proto;     /* layer3 protocol number */
-       int             pi_hash;        /* packet hash value */
 };
 
 #define PKTINFO_FLAG_FRAG      0x1
 
 typedef lwkt_port_t (*pkt_portfn_t)(struct mbuf **);
-typedef lwkt_port_t (*pktinfo_portfn_t)(const struct pktinfo *);
+typedef lwkt_port_t (*pktinfo_portfn_t)(const struct pktinfo *, struct mbuf *);
 
 struct netisr {
        lwkt_port       ni_port;        /* must be first */
@@ -234,12 +233,12 @@ extern lwkt_port netisr_apanic_rport;
 
 lwkt_port_t    cpu0_portfn(struct mbuf **mptr);
 lwkt_port_t    cpu_portfn(int cpu);
-lwkt_port_t    pktinfo_portfn_cpu0(const struct pktinfo *);
-lwkt_port_t    pktinfo_portfn_notsupp(const struct pktinfo *);
+lwkt_port_t    pktinfo_portfn_cpu0(const struct pktinfo *, struct mbuf *);
+lwkt_port_t    pktinfo_portfn_notsupp(const struct pktinfo *, struct mbuf *);
 lwkt_port_t    cur_netport(void);
 
 lwkt_port_t    netisr_find_port(int, struct mbuf **);
-lwkt_port_t    netisr_find_pktinfo_port(const struct pktinfo *);
+lwkt_port_t    netisr_find_pktinfo_port(const struct pktinfo *, struct mbuf *);
 void           netisr_dispatch(int, struct mbuf *);
 void           netisr_run(int, struct mbuf *);
 int            netisr_queue(int, struct mbuf *);