Network threading stage 1/3: netisrs are already software interrupts,
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 8 Nov 2003 07:57:52 +0000 (07:57 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 8 Nov 2003 07:57:52 +0000 (07:57 +0000)
which means they alraedy run in their own thread.  This commit creates
multiple supporting threads for netisrs rather then just one and code
has been added to begin routing packets to particular threads based on
their content.  Eventually this will lead to us being able to isolate and
serialize PCBs in particular threads.  The tail end of the ip_input path's
protocol dispatch, the UIPC (user entry) code, and listen socket have not
been covered yet and still need to be serialized.

A new debugging sysctl, net.inet.ip.mthread_enable, has been added.  It
defaults to 1.  If you set this sysctl 0 netisr processing will revert to
the prior single-threaded behavior.

Submitted-by: Jeffrey Hsu <hsu@FreeBSD.org>
Additional-work-by: dillon
22 files changed:
sys/bus/usb/usb_ethersubr.c
sys/conf/files
sys/kern/kern_poll.c
sys/net/netisr.c
sys/net/netisr.h
sys/net/ppp/if_ppp.c
sys/netgraph/netgraph/ng_base.c
sys/netinet/if_ether.c
sys/netinet/ip_demux.c [new file with mode: 0644]
sys/netinet/ip_input.c
sys/netinet/ip_var.h
sys/netinet/tcp_subr.c
sys/netinet/tcp_var.h
sys/netinet/udp_usrreq.c
sys/netinet/udp_var.h
sys/netinet6/ip6_input.c
sys/netproto/atalk/ddp_usrreq.c
sys/netproto/atm/atm_subr.c
sys/netproto/ipx/ipx_input.c
sys/netproto/natm/natm.c
sys/netproto/ns/ns_input.c
sys/sys/msgport.h

index a27ed7d..e3a4042 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/usb/usb_ethersubr.c,v 1.4.2.4 2002/11/06 14:23:20 joe Exp $
- * $DragonFly: src/sys/bus/usb/usb_ethersubr.c,v 1.4 2003/09/15 23:38:12 hsu Exp $
+ * $DragonFly: src/sys/bus/usb/usb_ethersubr.c,v 1.5 2003/11/08 07:57:45 dillon Exp $
  *
  * $FreeBSD: src/sys/dev/usb/usb_ethersubr.c,v 1.4.2.4 2002/11/06 14:23:20 joe Exp $
  */
@@ -120,7 +120,7 @@ Static void usbintr(struct mbuf *m)
 
 void usb_register_netisr()
 {
-       netisr_register(NETISR_USB, usbintr, NULL);
+       netisr_register(NETISR_USB, cpu0_portfn, usbintr);
        return;
 }
 
@@ -131,21 +131,11 @@ void usb_register_netisr()
 void usb_ether_input(m)
        struct mbuf             *m;
 {
-       int                     s;
-       s = splimp();
-       IF_ENQUEUE(&usbq_rx, m);
-       schednetisr(NETISR_USB);
-       splx(s);
-       return;
+       netisr_queue(NETISR_USB, m);
 }
 
 void usb_tx_done(m)
        struct mbuf             *m;
 {
-       int                     s;
-       s = splimp();
-       IF_ENQUEUE(&usbq_tx, m);
-       schednetisr(NETISR_USB);
-       splx(s);
-       return;
+       netisr_queue(NETISR_USB, m);
 }
index e5d8223..5792da5 100644 (file)
@@ -1,5 +1,5 @@
 # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $
-# $DragonFly: src/sys/conf/files,v 1.25 2003/11/05 23:26:15 dillon Exp $
+# $DragonFly: src/sys/conf/files,v 1.26 2003/11/08 07:57:40 dillon Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -1069,6 +1069,7 @@ net/ipfw/ip_fw.c          optional ipfirewall
 net/ipfw/ip_fw2.c              optional ipfw2
 netinet/ip_icmp.c              optional inet
 netinet/ip_input.c             optional inet
+netinet/ip_demux.c             optional inet
 net/ip_mroute/ip_mroute.c      optional mrouting
 netinet/ip_output.c            optional inet
 netinet/raw_ip.c               optional inet
index 1284723..e2b26fd 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_poll.c,v 1.2.2.4 2002/06/27 23:26:33 luigi Exp $
- * $DragonFly: src/sys/kern/kern_poll.c,v 1.5 2003/09/15 23:38:13 hsu Exp $
+ * $DragonFly: src/sys/kern/kern_poll.c,v 1.6 2003/11/08 07:57:41 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -45,8 +45,8 @@
 #endif
 #endif
 
-static void netisr_poll(void);         /* the two netisr handlers      */
-static void netisr_pollmore(void);
+static void netisr_poll(struct mbuf *);        /* the two netisr handlers      */
+static void netisr_pollmore(struct mbuf *);
 
 void init_device_poll(void);           /* init routine                 */
 void hardclock_device_poll(void);      /* hook from hardclock          */
@@ -185,8 +185,8 @@ static struct pollrec pr[POLL_LIST_LEN];
 void
 init_device_poll(void)
 {
-       netisr_register(NETISR_POLL, (netisr_fn_t)netisr_poll, NULL);
-       netisr_register(NETISR_POLLMORE, (netisr_fn_t)netisr_pollmore, NULL);
+       netisr_register(NETISR_POLL, cpu0_portfn, netisr_poll);
+       netisr_register(NETISR_POLLMORE, cpu0_portfn, netisr_pollmore);
 }
 
 /*
@@ -293,11 +293,11 @@ idle_poll(void)
  * handling and forwarding.
  */
 
-
 static struct timeval poll_start_t;
 
+/* ARGSUSED */
 static void
-netisr_pollmore()
+netisr_pollmore(struct mbuf *dummy __unused)
 {
        struct timeval t;
        int kern_load;
@@ -346,8 +346,9 @@ netisr_pollmore()
  * per tick. It is called at splnet() so first thing to do is to upgrade to
  * splimp(), and call all registered handlers.
  */
+/* ARGSUSED */
 static void
-netisr_poll(void)
+netisr_poll(struct mbuf *dummy __unused)
 {
        static int reg_frac_count;
        int i, cycles;
index ad3282e..678b7f7 100644 (file)
@@ -3,11 +3,14 @@
  * Copyright (c) 2003 Jonathan Lemon
  * Copyright (c) 2003 Matthew Dillon
  *
- * $DragonFly: src/sys/net/netisr.c,v 1.2 2003/09/15 23:38:13 hsu Exp $
+ * $DragonFly: src/sys/net/netisr.c,v 1.3 2003/11/08 07:57:42 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/msgport.h>
+#include <sys/msgport2.h>
 #include <sys/proc.h>
 #include <sys/interrupt.h>
 #include <sys/socket.h>
 #include <machine/cpufunc.h>
 #include <machine/ipl.h>
 
-int isrmask;
-static int isrsoftint_installed;
-static struct netisr netisrs[NETISR_MAX];
+struct netmsg {
+    struct lwkt_msg    nm_lmsg;
+    struct mbuf                *nm_packet;
+    netisr_fn_t                nm_handler;
+};
 
-/* SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr counters"); */
+#define CMD_NETMSG_NEWPKT      (MSG_CMD_NETMSG | 0x0001)
+#define CMD_NETMSG_POLL                (MSG_CMD_NETMSG | 0x0002)
 
-static int netisr_directdispatch = 0;
-/*
-SYSCTL_INT(_net_isr, OID_AUTO, directdispatch, CTLFLAG_RW,
-    &netisr_directdispatch, 0, "enable direct dispatch");
-*/
+static struct netisr netisrs[NETISR_MAX];
+
+/* Per-CPU thread to handle any protocol.  */
+struct thread netisr_cpu[MAXCPU];
 
 static void
-swi_net(void *arg)
+netisr_init(void)
 {
-    int mask;
-    int bit;
-       
-    while ((mask = isrmask) != 0) {
-       bit = bsfl(mask);
-       if (btrl(&isrmask, bit)) {
-           struct netisr *ni = &netisrs[bit];
-           netisr_fn_t func = ni->ni_handler;
-
-           if (ni->ni_queue) {
-               while (1) {
-                   struct mbuf *m;
-                   int s;
-
-                   s = splimp();
-                   IF_DEQUEUE(ni->ni_queue, m);
-                   splx(s);
-                   if (!m)
-                       break;
-                   func(m);
-               }
-           } else
-               func(NULL);
-       }
-    }
+    int i;
+
+    /* Create default per-cpu threads for generic protocol handling. */
+    for (i = 0; i < ncpus; ++i)
+       lwkt_create(netmsg_service_loop, NULL, NULL, &netisr_cpu[i], 0, i,
+           "netisr_cpu %d", i);
 }
 
-/*
- * Call the netisr directly instead of queueing the packet, if possible.
- */
+SYSINIT(netisr, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, netisr_init, NULL);
+
 void
-netisr_dispatch(int num, struct mbuf *m)
+netmsg_service_loop(void *arg)
 {
-    struct netisr *ni;
-
-    KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
-       ("bad isr %d", num));
+    struct netmsg *msg;
 
-    ni = &netisrs[num];
+    while ((msg = lwkt_waitport(&curthread->td_msgport))) {
+       struct mbuf *m = msg->nm_packet;
+       netisr_fn_t handler = msg->nm_handler;
 
-    if (!ni->ni_queue) {
-       m_freem(m);
-       return;
+       if (handler)
+               handler(m);
+       else if (m)
+               m_freem(m);
+       free(msg, M_TEMP);
     }
+}
 
-    if (netisr_directdispatch) {
-      /*
-       * missing check for concurrent execution from swi_net() XXX JH
-       * Address this after conversion to message ports.
-       */
-       ni->ni_handler(m);
-    } else {
-       if (IF_HANDOFF(ni->ni_queue, m, NULL))
-           schednetisr(num);
-    }
+/*
+ * Call the netisr directly.
+ * Queueing may be done in the msg port layer at its discretion.
+ */
+void
+netisr_dispatch(int num, struct mbuf *m)
+{
+    /* just queue it for now XXX JH */
+    netisr_queue(num, m);
 }
 
 /*
@@ -98,38 +84,35 @@ netisr_dispatch(int num, struct mbuf *m)
 int
 netisr_queue(int num, struct mbuf *m)
 {
-    struct netisr *ni;
+    struct netisr *ni = &netisrs[num];
+    struct netmsg *pmsg;
+    lwkt_port_t port;
 
     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
        ("bad isr %d", num));
 
-    ni = &netisrs[num];
-
-    if (!ni->ni_queue) {
-       m_freem(m);
+    /* use better message allocation system with limits later XXX JH */
+    if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
        return (ENOBUFS);
-    }
 
-    if (!IF_HANDOFF(ni->ni_queue, m, NULL))
-       return (ENOBUFS);
+    if (!(port = ni->ni_mport(m)))
+       return EIO;
 
-    schednetisr(num);
+    lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_NEWPKT);
+    pmsg->nm_packet = m;
+    pmsg->nm_handler = ni->ni_handler;
+    lwkt_sendmsg(port, &pmsg->nm_lmsg);
     return (0);
 }
 
-int
-netisr_register(int num, netisr_fn_t handler, struct ifqueue *ifq)
+void
+netisr_register(int num, lwkt_portfn_t mportfn, netisr_fn_t handler)
 {
     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
        ("bad isr %d", num));
 
-    if (isrsoftint_installed == 0) {
-       isrsoftint_installed = 1;
-       register_swi(SWI_NET, swi_net, NULL, "swi_net");
-    }
+    netisrs[num].ni_mport = mportfn;
     netisrs[num].ni_handler = handler;
-    netisrs[num].ni_queue = ifq;
-    return (0);
 }
 
 int
@@ -138,13 +121,38 @@ netisr_unregister(int num)
     KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
        ("unregister_netisr: bad isr number: %d\n", num));
 
-    if (netisrs[num].ni_queue != NULL) {
-       int s;
-
-       s = splimp();
-       IF_DRAIN(netisrs[num].ni_queue);
-       splx(s);
-    }
-    netisrs[num].ni_handler = NULL;
+    /* XXX JH */
     return (0);
 }
+
+/*
+ * Return message port for default handler thread on CPU 0.
+ */
+lwkt_port_t
+cpu0_portfn(struct mbuf *m)
+{
+    return (&netisr_cpu[0].td_msgport);
+}
+
+/*
+ * This function is used to call the netisr handler from the appropriate
+ * netisr thread for polling and other purposes.  pmsg->nm_packet will be
+ * undefined.  At the moment operation is restricted to non-packet ISRs only.
+ */
+void
+schednetisr(int num)
+{
+    struct netisr *ni = &netisrs[num];
+    struct netmsg *pmsg;
+    lwkt_port_t port = &netisr_cpu[0].td_msgport;
+
+    KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
+       ("bad isr %d", num));
+
+    if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
+       return;
+
+    lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_POLL);
+    pmsg->nm_handler = ni->ni_handler;
+    lwkt_sendmsg(port, &pmsg->nm_lmsg);
+}
index 9d9b04d..2c1f1ff 100644 (file)
  *
  *     @(#)netisr.h    8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/net/netisr.h,v 1.21.2.5 2002/02/09 23:02:39 luigi Exp $
- * $DragonFly: src/sys/net/netisr.h,v 1.5 2003/09/15 23:38:13 hsu Exp $
+ * $DragonFly: src/sys/net/netisr.h,v 1.6 2003/11/08 07:57:42 dillon Exp $
  */
 
 #ifndef _NET_NETISR_H_
 #define _NET_NETISR_H_
 
+#include <sys/msgport.h>
+
 /*
  * The networking code runs off software interrupts.
  *
 
 #define        NETISR_MAX      32
 
-
-#ifndef LOCORE
 #ifdef _KERNEL
-extern int isrmask;
-
-static __inline void
-schednetisr(int isrnum) 
-{
-    atomic_set_int(&isrmask, 1 << isrnum);
-    setsoftnet();
-}
 
 struct mbuf;
-struct ifqueue;
 
 typedef void (*netisr_fn_t)(struct mbuf *);
+typedef lwkt_port_t (*lwkt_portfn_t)(struct mbuf *);
 
-/*
- * This structure will change to use message ports instead of struct ifqueue.
- * XXX JH
- */
 struct netisr {
+       lwkt_port       ni_port;                /* must be first */
+       lwkt_portfn_t   ni_mport;
        netisr_fn_t     ni_handler;
-       struct ifqueue  *ni_queue;
 };
 
-void   netisr_dispatch(int, struct mbuf *);
-int    netisr_queue(int, struct mbuf *);
-int    netisr_register(int, netisr_fn_t, struct ifqueue *);
-int    netisr_unregister(int);
+lwkt_port_t    cpu0_portfn(struct mbuf *m);
+void           netisr_dispatch(int, struct mbuf *);
+int            netisr_queue(int, struct mbuf *);
+void           netisr_register(int, lwkt_portfn_t, netisr_fn_t);
+int            netisr_unregister(int);
+void           netmsg_service_loop(void *arg);
+void           schednetisr(int);
 
-#endif
 #endif
 
-#endif
+#endif /* _NET_NETISR_H_ */
index 1a80da1..1c3b2e1 100644 (file)
@@ -70,7 +70,7 @@
  */
 
 /* $FreeBSD: src/sys/net/if_ppp.c,v 1.67.2.4 2002/04/14 21:41:48 luigi Exp $ */
-/* $DragonFly: src/sys/net/ppp/if_ppp.c,v 1.9 2003/09/15 23:38:13 hsu Exp $ */
+/* $DragonFly: src/sys/net/ppp/if_ppp.c,v 1.10 2003/11/08 07:57:46 dillon Exp $ */
 /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
 /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
 
@@ -215,7 +215,7 @@ pppattach(dummy)
        if_attach(&sc->sc_if);
        bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN);
     }
-    netisr_register(NETISR_PPP, pppintr, NULL);
+    netisr_register(NETISR_PPP, cpu0_portfn, pppintr);
     /*
      * XXX layering violation - if_ppp can work over any lower level
      * transport that cares to attach to it.
index 77a6b3c..b2a5599 100644 (file)
@@ -38,7 +38,7 @@
  *          Archie Cobbs <archie@freebsd.org>
  *
  * $FreeBSD: src/sys/netgraph/ng_base.c,v 1.11.2.17 2002/07/02 23:44:02 archie Exp $
- * $DragonFly: src/sys/netgraph/netgraph/ng_base.c,v 1.8 2003/09/16 05:03:13 hsu Exp $
+ * $DragonFly: src/sys/netgraph/netgraph/ng_base.c,v 1.9 2003/11/08 07:57:50 dillon Exp $
  * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
  */
 
@@ -1783,7 +1783,8 @@ ngb_mod_event(module_t mod, int event, void *data)
        case MOD_LOAD:
                /* Register line discipline */
                s = splimp();
-               error = netisr_register(NETISR_NETGRAPH, ngintr, NULL);
+               netisr_register(NETISR_NETGRAPH, cpu0_portfn, ngintr);
+               error = 0;
                splx(s);
                break;
        case MOD_UNLOAD:
index 86df5f5..1bb91b9 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)if_ether.c  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netinet/if_ether.c,v 1.64.2.23 2003/04/11 07:23:15 fjoe Exp $
- * $DragonFly: src/sys/netinet/if_ether.c,v 1.7 2003/09/25 02:22:23 dillon Exp $
+ * $DragonFly: src/sys/netinet/if_ether.c,v 1.8 2003/11/08 07:57:51 dillon Exp $
  */
 
 /*
@@ -103,7 +103,6 @@ struct llinfo_arp {
 
 static LIST_HEAD(, llinfo_arp) llinfo_arp;
 
-static struct  ifqueue arpintrq = {0, 0, 0, 50};
 static int     arp_inuse, arp_allocated, arpinit_done;
 
 static int     arp_maxtries = 5;
@@ -917,7 +916,7 @@ static void
 arp_init(void)
 {
        LIST_INIT(&llinfo_arp);
-       netisr_register(NETISR_ARP, arpintr, &arpintrq);
+       netisr_register(NETISR_ARP, cpu0_portfn, arpintr);
 }
 
 SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
diff --git a/sys/netinet/ip_demux.c b/sys/netinet/ip_demux.c
new file mode 100644 (file)
index 0000000..824539c
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2003 Jeffrey Hsu
+ * All rights reserved.
+ *
+ * $DragonFly: src/sys/netinet/ip_demux.c,v 1.1 2003/11/08 07:57:51 dillon Exp $
+ */
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/thread.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/netisr.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+extern struct thread netisr_cpu[];
+
+static struct thread tcp_thread[MAXCPU];
+static struct thread udp_thread[MAXCPU];
+
+/*
+ * XXX when we remove the MP lock changes to this must be master-synchronized
+ */
+static int      ip_mthread_enable = 1;
+SYSCTL_INT(_net_inet_ip, OID_AUTO, mthread_enable, CTLFLAG_RW,
+    &ip_mthread_enable, 0, "");
+
+static int
+INP_MPORT_HASH(in_addr_t src, in_addr_t dst, int sport, int dport)
+{
+       int hv;
+
+       hv = (int)ntohl(src) ^ (int)ntohl(dst) ^ 
+               (int)ntohs(sport) ^ (int)ntohs(dport);
+       return(hv % ncpus);
+}
+
+lwkt_port_t
+ip_mport(struct mbuf *m)
+{
+       struct ip *ip = mtod(m, struct ip *);
+       int hlen;
+       struct tcphdr *th;
+       struct udphdr *uh;
+       lwkt_port_t port;
+
+       if (ip_mthread_enable == 0)
+               return (&netisr_cpu[0].td_msgport);
+
+       if (m->m_len < sizeof(struct ip) &&
+           (m = m_pullup(m, sizeof(struct ip))) == NULL) {
+               ipstat.ips_toosmall++;
+               return (NULL);
+       }
+
+       /*
+        * XXX generic packet handling defrag on CPU 0 for now.
+        */
+       if (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK))
+               return (&netisr_cpu[0].td_msgport);
+
+       hlen = ip->ip_hl << 2;
+
+       switch (ip->ip_p) {
+       case IPPROTO_TCP:
+               if (m->m_len < sizeof(struct tcpiphdr) &&
+                   (m = m_pullup(m, sizeof(struct tcpiphdr))) == NULL) {
+                       tcpstat.tcps_rcvshort++;
+                       return (NULL);
+               }
+
+               th = (struct tcphdr *)((caddr_t)ip + hlen);
+               port = &tcp_thread[INP_MPORT_HASH(ip->ip_src.s_addr,
+                   ip->ip_dst.s_addr, th->th_sport, th->th_dport)].td_msgport;
+               break;
+       case IPPROTO_UDP:
+               if (m->m_len < hlen + sizeof(struct udphdr) &&
+                   (m = m_pullup(m, hlen + sizeof(struct udphdr))) == NULL) {
+                       udpstat.udps_hdrops++;
+                       return (NULL);
+               }
+
+               uh = (struct udphdr *)((caddr_t)ip + hlen);
+               port = &udp_thread[INP_MPORT_HASH(ip->ip_src.s_addr,
+                   ip->ip_dst.s_addr, uh->uh_sport, uh->uh_dport)].td_msgport;
+               break;
+       default:
+               port = &netisr_cpu[0].td_msgport;
+               break;
+       }
+
+       return (port);
+}
+
+lwkt_port_t
+tcp_soport(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       return (&tcp_thread[INP_MPORT_HASH(inp->inp_laddr.s_addr,
+           inp->inp_faddr.s_addr, inp->inp_lport, inp->inp_fport)].td_msgport);
+}
+
+lwkt_port_t
+udp_soport(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       return (&udp_thread[INP_MPORT_HASH(inp->inp_laddr.s_addr,
+           inp->inp_faddr.s_addr, inp->inp_lport, inp->inp_fport)].td_msgport);
+}
+
+void
+tcp_thread_init(void)
+{
+       int cpu;
+
+       for (cpu = 0; cpu < ncpus; cpu++) {
+               lwkt_create(netmsg_service_loop, NULL, NULL, 
+                       &tcp_thread[cpu], 0, cpu, "tcp_thread %d", cpu);
+       }
+}
+
+void
+udp_thread_init(void)
+{
+       int cpu;
+
+       for (cpu = 0; cpu < ncpus; cpu++) {
+               lwkt_create(netmsg_service_loop, NULL, NULL,
+                       &udp_thread[cpu], 0, cpu, "udp_thread %d", cpu);
+       }
+}
index ab8f806..b987366 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ip_input.c  8.2 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/netinet/ip_input.c,v 1.130.2.52 2003/03/07 07:01:28 silby Exp $
- * $DragonFly: src/sys/netinet/ip_input.c,v 1.7 2003/09/15 23:38:14 hsu Exp $
+ * $DragonFly: src/sys/netinet/ip_input.c,v 1.8 2003/11/08 07:57:51 dillon Exp $
  */
 
 #define        _IP_VHL
@@ -273,7 +273,7 @@ ip_init()
 #endif
        ipintrq.ifq_maxlen = ipqmaxlen;
 
-       netisr_register(NETISR_IP, ip_input, &ipintrq);
+       netisr_register(NETISR_IP, ip_mport, ip_input);
 }
 
 /*
@@ -816,8 +816,9 @@ found:
                        ip->ip_len -= hlen;
                }
 #endif
-       } else
+       } else {
                ip->ip_len -= hlen;
+       }
 
 #ifdef IPDIVERT
        /*
@@ -911,6 +912,8 @@ DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
 
        /*
         * Switch out to protocol's input routine.
+        *
+        * XXX queue packet to protocol's message port.
         */
        ipstat.ips_delivered++;
        if (args.next_hop && ip->ip_p == IPPROTO_TCP) {
@@ -924,8 +927,9 @@ DPRINTF(("ip_input: no SP, packet discarded\n"));/*XXX*/
 
                (*inetsw[ip_protox[ip->ip_p]].pr_input)(
                        (struct mbuf *)&tag, hlen, ip->ip_p);
-       } else
+       } else {
                (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, ip->ip_p);
+       }
        return;
 bad:
        m_freem(m);
index 677e703..d7d6b69 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ip_var.h    8.2 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/netinet/ip_var.h,v 1.50.2.13 2003/08/24 08:24:38 hsu Exp $
- * $DragonFly: src/sys/netinet/ip_var.h,v 1.3 2003/08/24 23:07:08 hsu Exp $
+ * $DragonFly: src/sys/netinet/ip_var.h,v 1.4 2003/11/08 07:57:51 dillon Exp $
  */
 
 #ifndef _NETINET_IP_VAR_H_
@@ -142,6 +142,7 @@ struct ip;
 struct inpcb;
 struct route;
 struct sockopt;
+struct lwkt_port;
 
 extern struct  ipstat  ipstat;
 #ifndef RANDOM_IP_ID
@@ -166,6 +167,8 @@ void         ip_freemoptions(struct ip_moptions *);
 void    ip_init(void);
 extern int      (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
                          struct ip_moptions *);
+struct lwkt_port *
+        ip_mport(struct mbuf *);
 int     ip_output(struct mbuf *,
            struct mbuf *, struct route *, int, struct ip_moptions *,
            struct inpcb *);
index 566a7bf..560933b 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)tcp_subr.c  8.2 (Berkeley) 5/24/95
  * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.73.2.31 2003/01/24 05:11:34 sam Exp $
- * $DragonFly: src/sys/netinet/tcp_subr.c,v 1.8 2003/08/23 11:18:00 rob Exp $
+ * $DragonFly: src/sys/netinet/tcp_subr.c,v 1.9 2003/11/08 07:57:51 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -220,7 +220,7 @@ void
 tcp_init()
 {
        int hashsize = TCBHASHSIZE;
-       
+
        tcp_ccgen = 1;
        tcp_cleartaocache();
 
@@ -258,6 +258,7 @@ tcp_init()
 #undef TCP_MINPROTOHDR
 
        syncache_init();
+       tcp_thread_init();
 }
 
 /*
@@ -1623,4 +1624,3 @@ tcp_xmit_bandwidth_limit(struct tcpcb *tp, tcp_seq ack_seq)
                bwnd = tp->t_maxseg * 2;
        tp->snd_bwnd = bwnd;
 }
-
index 538714f..53238f3 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)tcp_var.h   8.4 (Berkeley) 5/24/95
  * $FreeBSD: src/sys/netinet/tcp_var.h,v 1.56.2.13 2003/02/03 02:34:07 hsu Exp $
- * $DragonFly: src/sys/netinet/tcp_var.h,v 1.8 2003/08/23 11:18:00 rob Exp $
+ * $DragonFly: src/sys/netinet/tcp_var.h,v 1.9 2003/11/08 07:57:51 dillon Exp $
  */
 
 #ifndef _NETINET_TCP_VAR_H_
@@ -441,7 +441,6 @@ struct      xtcpcb {
        { "v6mssdflt", CTLTYPE_INT }, \
 }
 
-
 #ifdef _KERNEL
 #ifdef SYSCTL_DECL
 SYSCTL_DECL(_net_inet_tcp);
@@ -469,6 +468,7 @@ void         tcp_fasttimo (void);
 struct rmxp_tao *
         tcp_gettaocache (struct in_conninfo *);
 void    tcp_init (void);
+void    tcp_thread_init (void);
 void    tcp_input (struct mbuf *, int, int);
 void    tcp_mss (struct tcpcb *, int);
 int     tcp_mssopt (struct tcpcb *);
@@ -489,6 +489,8 @@ void         tcp_slowtimo (void);
 struct tcptemp *
         tcp_maketemplate (struct tcpcb *);
 void    tcp_fillheaders (struct tcpcb *, void *, void *);
+struct lwkt_port *
+        tcp_soport(struct socket *);
 struct tcpcb *
         tcp_timers (struct tcpcb *, int);
 void    tcp_trace (int, int, struct tcpcb *, void *, struct tcphdr *,
index b81ac2d..1e95e73 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95
  * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.64.2.18 2003/01/24 05:11:34 sam Exp $
- * $DragonFly: src/sys/netinet/udp_usrreq.c,v 1.7 2003/10/28 03:51:51 dillon Exp $
+ * $DragonFly: src/sys/netinet/udp_usrreq.c,v 1.8 2003/11/08 07:57:51 dillon Exp $
  */
 
 #include "opt_ipsec.h"
@@ -154,6 +154,7 @@ udp_init()
                                        &udbinfo.porthashmask);
        udbinfo.ipi_zone = zinit("udpcb", sizeof(struct inpcb), maxsockets,
                                 ZONE_INTERRUPT, 0);
+       udp_thread_init();
 }
 
 /*
index fa3a3d0..74c7855 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)udp_var.h   8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netinet/udp_var.h,v 1.22.2.1 2001/02/18 07:12:25 luigi Exp $
- * $DragonFly: src/sys/netinet/udp_var.h,v 1.3 2003/08/23 11:18:00 rob Exp $
+ * $DragonFly: src/sys/netinet/udp_var.h,v 1.4 2003/11/08 07:57:51 dillon Exp $
  */
 
 #ifndef _NETINET_UDP_VAR_H_
@@ -94,7 +94,9 @@ struct        udpstat {
 }
 
 #ifdef _KERNEL
+#ifdef SYSCTL_DECL
 SYSCTL_DECL(_net_inet_udp);
+#endif
 
 extern struct  pr_usrreqs udp_usrreqs;
 extern struct  inpcbhead udb;
@@ -106,10 +108,14 @@ extern int        log_in_vain;
 
 void   udp_ctlinput (int, struct sockaddr *, void *);
 void   udp_init (void);
+void   udp_thread_init (void);
 void   udp_input (struct mbuf *, int, int);
 
 void   udp_notify (struct inpcb *inp, int errno);
 int    udp_shutdown (struct socket *so);
+
+struct lwkt_port *
+       udp_soport(struct socket *);
 #endif
 
 #endif
index a075583..359daf0 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/netinet6/ip6_input.c,v 1.11.2.15 2003/01/24 05:11:35 sam Exp $        */
-/*     $DragonFly: src/sys/netinet6/ip6_input.c,v 1.9 2003/09/16 01:58:00 hsu Exp $    */
+/*     $DragonFly: src/sys/netinet6/ip6_input.c,v 1.10 2003/11/08 07:57:51 dillon Exp $        */
 /*     $KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $     */
 
 /*
@@ -90,7 +90,6 @@
 #include <net/if_dl.h>
 #include <net/route.h>
 #include <net/netisr.h>
-#include <net/intrq.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -135,8 +134,6 @@ extern struct domain inet6domain;
 extern struct ip6protosw inet6sw[];
 
 u_char ip6_protox[IPPROTO_MAX];
-static struct ifqueue ip6intrq;
-static int ip6qmaxlen = IFQ_MAXLEN;
 struct in6_ifaddr *in6_ifaddr;
 
 extern struct callout in6_tmpaddrtimer_ch;
@@ -144,7 +141,6 @@ extern struct callout in6_tmpaddrtimer_ch;
 int ip6_forward_srcrt;                 /* XXX */
 int ip6_sourcecheck;                   /* XXX */
 int ip6_sourcecheck_interval;          /* XXX */
-const int int6intrq_present = 1;
 
 int ip6_ours_check_algorithm;
 
@@ -187,8 +183,7 @@ ip6_init()
                if (pr->pr_domain->dom_family == PF_INET6 &&
                    pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
                        ip6_protox[pr->pr_protocol] = pr - inet6sw;
-       ip6intrq.ifq_maxlen = ip6qmaxlen;
-       netisr_register(NETISR_IPV6, ip6_input, &ip6intrq);
+       netisr_register(NETISR_IPV6, cpu0_portfn, ip6_input);
        nd6_init();
        frag6_init();
        /*
index 355644e..dec4afe 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  *
- * $DragonFly: src/sys/netproto/atalk/ddp_usrreq.c,v 1.5 2003/09/16 05:03:13 hsu Exp $
+ * $DragonFly: src/sys/netproto/atalk/ddp_usrreq.c,v 1.6 2003/11/08 07:57:51 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -36,8 +36,6 @@ struct ddpcb  *ddpcb = NULL;
 static u_long  ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
 static u_long  ddp_recvspace = 10 * ( 587 + sizeof( struct sockaddr_at ));
 
-static struct ifqueue atintrq1, atintrq2, aarpintrq;
-
 static int
 ddp_attach(struct socket *so, int proto, struct thread *td)
 {
@@ -549,12 +547,9 @@ at_setsockaddr(struct socket *so, struct sockaddr **nam)
 void 
 ddp_init(void )
 {
-       atintrq1.ifq_maxlen = IFQ_MAXLEN;
-       atintrq2.ifq_maxlen = IFQ_MAXLEN;
-       aarpintrq.ifq_maxlen = IFQ_MAXLEN;
-       netisr_register(NETISR_ATALK1, at1intr, &atintrq1);
-       netisr_register(NETISR_ATALK2, at2intr, &atintrq2);
-       netisr_register(NETISR_AARP, aarpintr, &aarpintrq);
+       netisr_register(NETISR_ATALK1, cpu0_portfn, at1intr);
+       netisr_register(NETISR_ATALK2, cpu0_portfn, at2intr);
+       netisr_register(NETISR_AARP, cpu0_portfn, aarpintr);
 }
 
 #if 0
index 6d2e8a8..c98aaf5 100644 (file)
@@ -24,7 +24,7 @@
  * notice must be reproduced on all copies.
  *
  *     @(#) $FreeBSD: src/sys/netatm/atm_subr.c,v 1.7 2000/02/13 03:31:59 peter Exp $
- *     @(#) $DragonFly: src/sys/netproto/atm/atm_subr.c,v 1.7 2003/09/16 06:25:35 hsu Exp $
+ *     @(#) $DragonFly: src/sys/netproto/atm/atm_subr.c,v 1.8 2003/11/08 07:57:52 dillon Exp $
  */
 
 /*
@@ -122,7 +122,7 @@ atm_initialize()
        atm_intr_index = register_isr(atm_intr);
 #endif
 #ifdef __FreeBSD__
-       netisr_register(NETISR_ATM, atm_intr, &atm_intrq);
+       netisr_register(NETISR_ATM, cpu0_portfn, atm_intr);
 #endif
 
        /*
index f0e3ea7..d950d26 100644 (file)
@@ -34,7 +34,7 @@
  *     @(#)ipx_input.c
  *
  * $FreeBSD: src/sys/netipx/ipx_input.c,v 1.22.2.2 2001/02/22 09:44:18 bp Exp $
- * $DragonFly: src/sys/netproto/ipx/ipx_input.c,v 1.5 2003/09/15 23:38:15 hsu Exp $
+ * $DragonFly: src/sys/netproto/ipx/ipx_input.c,v 1.6 2003/11/08 07:57:52 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -88,10 +88,8 @@ struct       ipxpcb ipxpcb;
 struct ipxpcb ipxrawpcb;
 
 static int ipxqmaxlen = IFQ_MAXLEN;
-static struct ifqueue ipxintrq;
 
 long   ipx_pexseq;
-const int ipxintrq_present = 1;
 
 static void ipxintr(struct mbuf *);
 static int ipx_do_route(struct ipx_addr *src, struct route *ro);
@@ -109,7 +107,6 @@ ipx_init()
        ipx_broadhost = *(union ipx_host *)allones;
 
        read_random(&ipx_pexseq, sizeof ipx_pexseq);
-       ipxintrq.ifq_maxlen = ipxqmaxlen;
        ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb;
        ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb;
 
@@ -120,7 +117,7 @@ ipx_init()
        ipx_hostmask.sipx_addr.x_net = ipx_broadnet;
        ipx_hostmask.sipx_addr.x_host = ipx_broadhost;
 
-       netisr_register(NETISR_IPX, ipxintr, &ipxintrq);
+       netisr_register(NETISR_IPX, cpu0_portfn, ipxintr);
 }
 
 /*
index 97c8f43..fbbe38b 100644 (file)
@@ -1,6 +1,6 @@
 /*     $NetBSD: natm.c,v 1.5 1996/11/09 03:26:26 chuck Exp $   */
 /* $FreeBSD: src/sys/netnatm/natm.c,v 1.12 2000/02/13 03:32:03 peter Exp $ */
-/* $DragonFly: src/sys/netproto/natm/natm.c,v 1.6 2003/09/15 23:38:15 hsu Exp $ */
+/* $DragonFly: src/sys/netproto/natm/natm.c,v 1.7 2003/11/08 07:57:52 dillon Exp $ */
 
 /*
  *
@@ -717,18 +717,14 @@ int natm5_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
   return (ENOPROTOOPT);
 }
 
-static int natmqmaxlen = IFQ_MAXLEN;   /* max # of packets on queue */
 static void natmintr(struct mbuf *);
-static struct ifqueue natmintrq;
-
-const int natmintrq_present = 1;
 
 #if defined(__FreeBSD__)
 static void
 netisr_natm_setup(void *dummy __unused)
 {
 
-       netisr_register(NETISR_NATM, natmintr,  &natmintrq);
+       netisr_register(NETISR_NATM, cpu0_portfn, natmintr);
 }
 SYSINIT(natm_setup, SI_SUB_CPU, SI_ORDER_ANY, netisr_natm_setup, NULL);
 #endif
@@ -737,10 +733,8 @@ void
 natm_init()
 {
   LIST_INIT(&natm_pcbs);
-  bzero(&natmintrq, sizeof(natmintrq));
-  natmintrq.ifq_maxlen = natmqmaxlen;
 
-  netisr_register(NETISR_NATM, natmintr, &natmintrq);
+  netisr_register(NETISR_NATM, cpu0_portfn, natmintr);
 }
 
 /*
index 1a363eb..88fe058 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ns_input.c  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/netns/ns_input.c,v 1.13 2000/02/13 03:32:04 peter Exp $
- * $DragonFly: src/sys/netproto/ns/ns_input.c,v 1.7 2003/09/16 05:03:13 hsu Exp $
+ * $DragonFly: src/sys/netproto/ns/ns_input.c,v 1.8 2003/11/08 07:57:52 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -73,16 +73,11 @@ struct sockaddr_ns ns_netmask, ns_hostmask;
 
 static u_short allones[] = {-1, -1, -1};
 
-static struct ifqueue nsintrq;
 struct nspcb nsrawpcb;
 
-int    nsqmaxlen = IFQ_MAXLEN;
-
 int    idpcksum = 1;
 long   ns_pexseq;
 
-const int      nsintrq_present = 1;
-
 static void nsintr(struct mbuf *m);
 
 void
@@ -98,8 +93,7 @@ ns_init()
        ns_hostmask.sns_len = 12;
        ns_hostmask.sns_addr.x_net = ns_broadnet;
        ns_hostmask.sns_addr.x_host = ns_broadhost;
-       nsintrq.ifq_maxlen = nsqmaxlen;
-       netisr_register(NETISR_NS, nsintr, &nsintrq);
+       netisr_register(NETISR_NS, cpu0_portfn, nsintr);
 }
 
 /*
index dbc53c8..a83ec73 100644 (file)
@@ -3,7 +3,7 @@
  *
  *     Implements LWKT messages and ports.
  * 
- * $DragonFly: src/sys/sys/msgport.h,v 1.7 2003/08/12 02:36:15 dillon Exp $
+ * $DragonFly: src/sys/sys/msgport.h,v 1.8 2003/11/08 07:57:43 dillon Exp $
  */
 
 #ifndef _SYS_MSGPORT_H_
@@ -72,6 +72,7 @@ typedef struct lwkt_msg {
 #define MSG_CMD_CDEV   0x00010000
 #define MSG_CMD_VFS    0x00020000
 #define MSG_CMD_SYSCALL        0x00030000
+#define MSG_CMD_NETMSG 0x00040000
 #define MSG_SUBCMD_MASK        0x0000FFFF
 
 typedef struct lwkt_port {