Re: PPP is not SMP safe in 2.2.X, Oops

From: Mitchell Blank Jr (mitch@sfgoth.com)
Date: Mon Feb 07 2000 - 04:48:30 EST


Oleg Drokin wrote:
> > another ppp_tty_push - uh, I really hope ppp->tty_pushing isn't the only
> > thing serializing access here.. that doesn't look healthy to me.
> I think that exactly this happens, we have 2 ppp_tty_push running, one after
> one.

Yeah, I wouldn't doubt it. Probably the solution will be to convert tty_pushing
to an atomic_t.

Time for the famous linux-kernel mantra: please try this untested patch

This isn't a fix for the problem, but is just a quick hack to keep track of
where the last place ppp->tpkt to NULL, and then report this when we try
to free it. As a bonus, it will probably prevent most of your ugly crashes...
the race is definately still there but at least its shorter.

Anyway, if the patch works you should get some lines logged in the format:

  ppp device ppp0: tpkt set to NULL at point N

where N is a number between 1 and 5. When you see that message, report back
with what N was so we know for sure what we're racing against.

-Mitch

--- ppp.c-before_debug Tue Feb 8 09:48:00 2000
+++ ppp.c Tue Feb 8 09:57:44 2000
@@ -131,6 +131,14 @@
 #define OPTIMIZE_FLAG_TIME 0
 #endif
 
+/* Gross debugging aids - to track down where we're racing on, we remember
+ * where the last place we set it to NULL is. Rather than adding a new
+ * item to struct ppp, let's just grab the last byte of the 8-byte ->name
+ * field...
+ */
+#define TPKT_CLEARED(ppp, where) ppp->name[7] = where
+#define TPKT_ERR(ppp) printk(KERN_CRIT "ppp device %s: tpkt set to NULL at point %d\n", ppp->name, ppp->name[7])
+
 /*
  * Parameters which may be changed via insmod.
  */
@@ -330,6 +338,7 @@
         ppp->xmit_async_map[3] = 0x60000000;
         ppp->recv_async_map = 0xffffffff;
 
+TPKT_CLEARED(ppp, 1);
         ppp->tpkt = NULL;
         ppp->tfcs = PPP_INITFCS;
         ppp->optr = ppp->obuf;
@@ -358,6 +367,7 @@
         ppp->rpkt = NULL;
         if ((skb = ppp->tpkt) != NULL)
                 kfree_skb(skb);
+TPKT_CLEARED(ppp, 2);
         ppp->tpkt = NULL;
 }
 
@@ -1026,6 +1036,7 @@
         ppp->stats.ppp_oerrors++;
         if (ppp->tpkt != 0) {
                 kfree_skb(ppp->tpkt);
+TPKT_CLEARED(ppp, 3);
                 ppp->tpkt = 0;
                 done = 1;
         }
@@ -1130,7 +1141,9 @@
                 *buf++ = PPP_FLAG;
                 ppp->olim = buf;
 
+if(ppp->tpkt == NULL) { TPKT_ERR(ppp); return 1; }
                 kfree_skb(ppp->tpkt);
+TPKT_CLEARED(ppp, 4);
                 ppp->tpkt = 0;
                 return 1;
         }
@@ -1161,6 +1174,7 @@
         ppp->optr = ppp->olim;
         if (ppp->tpkt != NULL) {
                 kfree_skb(ppp->tpkt);
+TPKT_CLEARED(ppp, 5);
                 ppp->tpkt = 0;
                 done = 1;
         }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Feb 07 2000 - 21:00:14 EST