nataraid(4): Add devstat support.
[dragonfly.git] / sys / net / netisr.c
index 8dbbcf1..03d53dc 100644 (file)
@@ -57,9 +57,9 @@
 #include <net/netmsg2.h>
 #include <sys/mplock2.h>
 
-static void netmsg_sync_func(netmsg_t msg);
 static void netmsg_service_loop(void *arg);
 static void cpu0_cpufn(struct mbuf **mp, int hoff);
+static void netisr_nohashck(struct mbuf *, const struct pktinfo *);
 
 struct netmsg_port_registration {
        TAILQ_ENTRY(netmsg_port_registration) npr_entry;
@@ -180,8 +180,8 @@ netisr_init(void)
         */
        for (i = 0; i < ncpus; ++i) {
                lwkt_create(netmsg_service_loop, NULL, NULL,
-                           &netisr_cpu[i], TDF_STOPREQ, i,
-                           "netisr_cpu %d", i);
+                           &netisr_cpu[i], TDF_NOSTART|TDF_FORCE_SPINPORT,
+                           i, "netisr_cpu %d", i);
                netmsg_service_port_init(&netisr_cpu[i].td_msgport);
                lwkt_schedule(&netisr_cpu[i]);
        }
@@ -251,7 +251,7 @@ netmsg_service_sync(void)
        struct netmsg_port_registration *reg;
        struct netmsg_base smsg;
 
-       netmsg_init(&smsg, NULL, &curthread->td_msgport, 0, netmsg_sync_func);
+       netmsg_init(&smsg, NULL, &curthread->td_msgport, 0, netmsg_sync_handler);
 
        TAILQ_FOREACH(reg, &netreglist, npr_entry) {
                lwkt_domsg(reg->npr_port, &smsg.lmsg, 0);
@@ -262,8 +262,8 @@ netmsg_service_sync(void)
  * The netmsg function simply replies the message.  API semantics require
  * EASYNC to be returned if the netmsg function disposes of the message.
  */
-static void
-netmsg_sync_func(netmsg_t msg)
+void
+netmsg_sync_handler(netmsg_t msg)
 {
        lwkt_replymsg(&msg->lmsg, 0);
 }
@@ -378,6 +378,46 @@ netisr_queue(int num, struct mbuf *m)
        return (0);
 }
 
+/*
+ * 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.
@@ -443,10 +483,23 @@ netisr_register(int num, netisr_fn_t handler, netisr_cpufn_t cpufn)
        ni = &netisrs[num];
 
        ni->ni_handler = handler;
+       ni->ni_hashck = netisr_nohashck;
        ni->ni_cpufn = cpufn;
        netmsg_init(&ni->ni_netmsg, NULL, &netisr_adone_rport, 0, NULL);
 }
 
+void
+netisr_register_hashcheck(int num, netisr_hashck_t hashck)
+{
+       struct netisr *ni;
+
+       KASSERT((num > 0 && num <= NELEM(netisrs)),
+               ("netisr_register: bad isr %d", num));
+
+       ni = &netisrs[num];
+       ni->ni_hashck = hashck;
+}
+
 void
 netisr_register_rollup(netisr_ru_t ru_func)
 {
@@ -663,3 +716,27 @@ netisr_barrier_rem(struct netisr_barrier *br)
 #endif
        br->br_isset = 0;
 }
+
+static void
+netisr_nohashck(struct mbuf *m, const struct pktinfo *pi __unused)
+{
+       m->m_flags &= ~M_HASH;
+}
+
+void
+netisr_hashcheck(int num, struct mbuf *m, const struct pktinfo *pi)
+{
+       struct netisr *ni;
+
+       if (num < 0 || num >= NETISR_MAX)
+               panic("Bad isr %d", num);
+
+       /*
+        * Valid netisr?
+        */
+       ni = &netisrs[num];
+       if (ni->ni_handler == NULL)
+               panic("Unregistered isr %d\n", num);
+
+       ni->ni_hashck(m, pi);
+}