bonding: fix potential deadlock in bond_uninit()
[safe/jmp/linux-2.6] / drivers / net / ppp_async.c
index 1fd319b..6a375ea 100644 (file)
@@ -36,7 +36,7 @@
 
 #define PPP_VERSION    "2.4.2"
 
-#define OBUFSIZE       256
+#define OBUFSIZE       4096
 
 /* Structure for storing local state. */
 struct asyncppp {
@@ -132,15 +132,13 @@ static DEFINE_RWLOCK(disc_data_lock);
 
 static struct asyncppp *ap_get(struct tty_struct *tty)
 {
-       unsigned long flags;
        struct asyncppp *ap;
 
-       read_lock_irqsave(&disc_data_lock, flags);
+       read_lock(&disc_data_lock);
        ap = tty->disc_data;
        if (ap != NULL)
                atomic_inc(&ap->refcnt);
-       read_unlock_irqrestore(&disc_data_lock, flags);
-
+       read_unlock(&disc_data_lock);
        return ap;
 }
 
@@ -217,13 +215,12 @@ ppp_asynctty_open(struct tty_struct *tty)
 static void
 ppp_asynctty_close(struct tty_struct *tty)
 {
-       unsigned long flags;
        struct asyncppp *ap;
 
-       write_lock_irqsave(&disc_data_lock, flags);
+       write_lock_irq(&disc_data_lock);
        ap = tty->disc_data;
        tty->disc_data = NULL;
-       write_unlock_irqrestore(&disc_data_lock, flags);
+       write_unlock_irq(&disc_data_lock);
        if (!ap)
                return;
 
@@ -340,10 +337,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
        return 0;
 }
 
-/*
- * This can now be called from hard interrupt level as well
- * as soft interrupt level or mainline.
- */
+/* May sleep, don't call from interrupt level or with interrupts disabled */
 static void
 ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
                  char *cflags, int count)
@@ -359,6 +353,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
        if (!skb_queue_empty(&ap->rqueue))
                tasklet_schedule(&ap->tsk);
        ap_put(ap);
+       tty_unthrottle(tty);
 }
 
 static void
@@ -563,8 +558,8 @@ ppp_async_encode(struct asyncppp *ap)
                 * Start of a new packet - insert the leading FLAG
                 * character if necessary.
                 */
-               if (islcp || flag_time == 0
-                   || time_after_eq(jiffies, ap->last_xmit + flag_time))
+               if (islcp || flag_time == 0 ||
+                   time_after_eq(jiffies, ap->last_xmit + flag_time))
                        *buf++ = PPP_FLAG;
                ap->last_xmit = jiffies;
                fcs = PPP_INITFCS;
@@ -701,8 +696,8 @@ ppp_async_push(struct asyncppp *ap)
                 */
                clear_bit(XMIT_BUSY, &ap->xmit_flags);
                /* any more work to do? if not, exit the loop */
-               if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
-                     || (!tty_stuffed && ap->tpkt)))
+               if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) ||
+                     (!tty_stuffed && ap->tpkt)))
                        break;
                /* more work to do, see if we can do it now */
                if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
@@ -759,8 +754,8 @@ scan_ordinary(struct asyncppp *ap, const unsigned char *buf, int count)
 
        for (i = 0; i < count; ++i) {
                c = buf[i];
-               if (c == PPP_ESCAPE || c == PPP_FLAG
-                   || (c < 0x20 && (ap->raccm & (1 << c)) != 0))
+               if (c == PPP_ESCAPE || c == PPP_FLAG ||
+                   (c < 0x20 && (ap->raccm & (1 << c)) != 0))
                        break;
        }
        return i;