ethernet: Allow netisr handler to run directly
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Jul 2011 11:50:08 +0000 (19:50 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 24 Jul 2011 11:50:08 +0000 (19:50 +0800)
If the packet has already reach the correct netisr, we could simply call
the netisr handler instead of requeue the packet.

sys/net/if_ethersubr.c
sys/net/netisr.c
sys/net/netisr.h

index e6300c7..aa47d88 100644 (file)
@@ -154,6 +154,7 @@ static boolean_t ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst,
 static int ether_ipfw;
 static u_long ether_restore_hdr;
 static u_long ether_prepend_hdr;
+static u_long ether_input_wronghash;
 static int ether_debug;
 
 #ifdef RSS_DEBUG
@@ -161,6 +162,7 @@ static u_long ether_pktinfo_try;
 static u_long ether_pktinfo_hit;
 static u_long ether_rss_nopi;
 static u_long ether_rss_nohash;
+static u_long ether_input_requeue;
 #endif
 
 SYSCTL_DECL(_net_link);
@@ -174,6 +176,8 @@ SYSCTL_ULONG(_net_link_ether, OID_AUTO, restore_hdr, CTLFLAG_RW,
 SYSCTL_ULONG(_net_link_ether, OID_AUTO, prepend_hdr, CTLFLAG_RW,
     &ether_prepend_hdr, 0,
     "# of ether header restoration which prepends mbuf");
+SYSCTL_ULONG(_net_link_ether, OID_AUTO, input_wronghash, CTLFLAG_RW,
+    &ether_input_wronghash, 0, "# of input packets with wrong hash");
 #ifdef RSS_DEBUG
 SYSCTL_ULONG(_net_link_ether, OID_AUTO, rss_nopi, CTLFLAG_RW,
     &ether_rss_nopi, 0, "# of packets do not have pktinfo");
@@ -185,6 +189,8 @@ SYSCTL_ULONG(_net_link_ether, OID_AUTO, pktinfo_try, CTLFLAG_RW,
 SYSCTL_ULONG(_net_link_ether, OID_AUTO, pktinfo_hit, CTLFLAG_RW,
     &ether_pktinfo_hit, 0,
     "# of packets whose msgport are found using pktinfo");
+SYSCTL_ULONG(_net_link_ether, OID_AUTO, input_requeue, CTLFLAG_RW,
+    &ether_input_requeue, 0, "# of input packets gets requeued");
 #endif
 
 #define ETHER_KTR_STR          "ifp=%p"
@@ -1249,8 +1255,9 @@ post_stats:
        default:
                /*
                 * The accurate msgport is not determined before
-                * we reach here, so redo the dispatching
+                * we reach here, so recharacterize packet.
                 */
+               m->m_flags &= ~M_HASH;
 #ifdef IPX
                if (ef_inputp) {
                        /*
@@ -1304,6 +1311,22 @@ dropanyway:
                return;
        }
 
+       if (m->m_flags & M_HASH) {
+               if (&curthread->td_msgport == cpu_portfn(m->m_pkthdr.hash)) {
+                       netisr_handle(isr, m);
+                       return;
+               } else {
+                       /*
+                        * XXX Something is wrong,
+                        * we probably should panic here!
+                        */
+                       m->m_flags &= ~M_HASH;
+                       ether_input_wronghash++;
+               }
+       }
+#ifdef RSS_DEBUG
+       ether_input_requeue++;
+#endif
        netisr_queue(isr, m);
 }
 
index 5253bf4..a62c555 100644 (file)
@@ -380,6 +380,46 @@ netisr_queue(int num, struct mbuf *m)
 }
 
 /*
+ * Run a netisr service function on the packet.
+ *
+ * The packet must have been correctly characterized!
+ */
+int
+netisr_handle(int num, struct mbuf *m)
+{
+       struct netisr *ni;
+       struct netmsg_packet *pmsg;
+       lwkt_port_t port;
+
+       /*
+        * Get the protocol port based on the packet hash
+        */
+       KASSERT((m->m_flags & M_HASH), ("packet not characterized\n"));
+       port = cpu_portfn(m->m_pkthdr.hash);
+       KASSERT(&curthread->td_msgport == port, ("wrong msgport\n"));
+
+       KASSERT((num > 0 && num <= NELEM(netisrs)), ("bad isr %d", num));
+       ni = &netisrs[num];
+       if (ni->ni_handler == NULL) {
+               kprintf("unregistered isr %d\n", num);
+               m_freem(m);
+               return EIO;
+       }
+
+       /*
+        * Initialize the netmsg, and run the handler directly.
+        */
+       pmsg = &m->m_hdr.mh_netmsg;
+       netmsg_init(&pmsg->base, NULL, &netisr_apanic_rport,
+                   0, ni->ni_handler);
+       pmsg->nm_packet = m;
+       pmsg->base.lmsg.u.ms_result = num;
+       ni->ni_handler((netmsg_t)&pmsg->base);
+
+       return 0;
+}
+
+/*
  * Pre-characterization of a deeper portion of the packet for the
  * requested isr.
  *
index 8126176..9a2957c 100644 (file)
@@ -180,6 +180,7 @@ void                netisr_characterize(int num, struct mbuf **mp, int hoff);
 void           netisr_hashcheck(int num, struct mbuf *m,
                    const struct pktinfo *pi);
 int            netisr_queue(int, struct mbuf *);
+int            netisr_handle(int, struct mbuf *);
 
 struct netisr_barrier *netisr_barrier_create(void);
 void           netisr_barrier_set(struct netisr_barrier *);