ethernet: Add ether_demux(), which will send the packet to the correct netisr
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Jul 2011 07:24:34 +0000 (15:24 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Jul 2011 07:24:34 +0000 (15:24 +0800)
It is intended to be used by the function which does not know whether
the current thread is the correct netisr for the ethernet packet or not.

Currently only ng_ether uses this function, which incorrectly called
ether_demux_oncpu().  The other two callers of ether_demux_oncpu() are
already on the correct netisr.

This paves the way to avoid requeuing the packet to the current netisr
in the ether_demux_oncpu().

sys/net/if_ethersubr.c
sys/net/if_var.h
sys/netgraph/ether/ng_ether.c

index c666ab4..e6300c7 100644 (file)
@@ -1709,4 +1709,38 @@ ether_characterize(struct mbuf **m0)
        return isr;
 }
 
+static void
+ether_demux_handler(netmsg_t nmsg)
+{
+       struct netmsg_packet *nmp = &nmsg->packet;      /* actual size */
+       struct ifnet *ifp;
+       struct mbuf *m;
+
+       m = nmp->nm_packet;
+       M_ASSERTPKTHDR(m);
+       ifp = m->m_pkthdr.rcvif;
+
+       ether_demux_oncpu(ifp, m);
+}
+
+void
+ether_demux(struct mbuf *m)
+{
+       struct netmsg_packet *pmsg;
+       int isr;
+
+       isr = ether_characterize(&m);
+       if (m == NULL)
+               return;
+
+       KKASSERT(m->m_flags & M_HASH);
+       pmsg = &m->m_hdr.mh_netmsg;
+       netmsg_init(&pmsg->base, NULL, &netisr_apanic_rport,
+           0, ether_demux_handler);
+       pmsg->nm_packet = m;
+       pmsg->base.lmsg.u.ms_result = isr;
+
+       lwkt_sendmsg(cpu_portfn(m->m_pkthdr.hash), &pmsg->base.lmsg);
+}
+
 MODULE_VERSION(ether, 1);
index 114eb5f..e5a6efb 100644 (file)
@@ -740,6 +740,7 @@ void        ether_ifattach(struct ifnet *, uint8_t *, struct lwkt_serialize *);
 void   ether_ifattach_bpf(struct ifnet *, uint8_t *, u_int, u_int,
                        struct lwkt_serialize *);
 void   ether_ifdetach(struct ifnet *);
+void   ether_demux(struct mbuf *);
 void   ether_demux_oncpu(struct ifnet *, struct mbuf *);
 void   ether_reinput_oncpu(struct ifnet *, struct mbuf *, int);
 void   ether_input_chain(struct ifnet *, struct mbuf *,
index 682c63b..e00a5b8 100644 (file)
@@ -630,13 +630,8 @@ ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta)
 
        m->m_pkthdr.rcvif = priv->ifp;
 
-       /*
-        * XXX
-        * Since frame processing is run in netisr0,
-        * 'm' may _not_ even on its target CPU.
-        */
        /* Route packet back in */
-       ether_demux_oncpu(priv->ifp, m);
+       ether_demux(m);
        return (0);
 }