kernel - Fix localhost packet misordering
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 4 Nov 2011 05:25:31 +0000 (22:25 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 4 Nov 2011 05:46:03 +0000 (22:46 -0700)
* netisr thread ports are based on IPIs, but when we enable asynch socket
  writes a user thread which gets moved between cpus sending async netmsgs
  while doing so can result in the netisr receiving those messages out
  of order, corrupting the data stream.

* Add TDF_FORCE_SPINPORT to allow the netisr threads to implement their
  message ports as spinports instead of threadports, which guarantees
  message ordering.

sys/kern/lwkt_thread.c
sys/net/if.c
sys/net/netisr.c
sys/sys/thread.h

index c55ebdd..d911876 100644 (file)
@@ -474,7 +474,7 @@ lwkt_init_thread(thread_t td, void *stack, int stksize, int flags,
     td->td_pri = TDPRI_KERN_DAEMON;
     td->td_critcount = 1;
     td->td_toks_stop = &td->td_toks_base;
-    if (lwkt_use_spin_port)
+    if (lwkt_use_spin_port || (flags & TDF_FORCE_SPINPORT))
        lwkt_initport_spin(&td->td_msgport);
     else
        lwkt_initport_thread(&td->td_msgport, td);
index 7ad51ab..9619eb5 100644 (file)
@@ -2753,7 +2753,8 @@ ifnetinit(void *dummy __unused)
                struct thread *thr = &ifnet_threads[i];
 
                lwkt_create(ifnet_service_loop, NULL, NULL,
-                           thr, TDF_STOPREQ, i, "ifnet %d", i);
+                           thr, TDF_STOPREQ|TDF_FORCE_SPINPORT,
+                           i, "ifnet %d", i);
                netmsg_service_port_init(&thr->td_msgport);
                lwkt_schedule(thr);
        }
index a62c555..945ebef 100644 (file)
@@ -181,8 +181,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_STOPREQ|TDF_FORCE_SPINPORT,
+                           i, "netisr_cpu %d", i);
                netmsg_service_port_init(&netisr_cpu[i].td_msgport);
                lwkt_schedule(&netisr_cpu[i]);
        }
index 0f22595..7d22ac4 100644 (file)
@@ -344,7 +344,7 @@ struct thread {
 #define TDF_BLOCKED            0x00040000      /* Thread is blocked */
 #define TDF_PANICWARN          0x00080000      /* panic warning in switch */
 #define TDF_BLOCKQ             0x00100000      /* on block queue */
-#define TDF_UNUSED00200000     0x00200000
+#define TDF_FORCE_SPINPORT     0x00200000
 #define TDF_EXITING            0x00400000      /* thread exiting */
 #define TDF_USINGFP            0x00800000      /* thread using fp coproc */
 #define TDF_KERNELFP           0x01000000      /* kernel using fp coproc */