move PPP_VERSION to ppp.c; don't use dev->tbusy as a lock
authorPaul Mackerras <paulus@samba.org>
Tue, 19 Jan 1999 23:57:44 +0000 (23:57 +0000)
committerPaul Mackerras <paulus@samba.org>
Tue, 19 Jan 1999 23:57:44 +0000 (23:57 +0000)
include/linux/if_ppp.h
include/linux/if_pppvar.h
linux/if_ppp.h
linux/if_pppvar.h
linux/ppp.c

index bb7a98db3f0e8542981817ce3f3fc36a1fb0053a..8456c7e8c8b88a0ec5b586ccd1afc4890d8e93a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: if_ppp.h,v 1.14 1998/07/07 04:27:33 paulus Exp $   */
+/*     $Id: if_ppp.h,v 1.15 1999/01/19 23:57:43 paulus Exp $   */
 
 /*
  * if_ppp.h - Point-to-Point Protocol definitions.
@@ -47,7 +47,6 @@
 
 #define        PPP_MTU         1500    /* Default MTU (size of Info field) */
 #define PPP_MAXMRU     65000   /* Largest MRU we allow */
-#define PPP_VERSION    "2.3.3"
 #define PPP_MAGIC      0x5002  /* Magic value for the ppp structure */
 #define PROTO_IPX      0x002b  /* protocol numbers */
 #define PROTO_DNA_RT    0x0027  /* DNA Routing */
index cf70fe655ea1dba5f311876f59600255575b3ade..a85b33cd1589a7bc40408ec2d0ad31d1df53d25d 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 /*
- *  ==FILEVERSION 980704==
+ *  ==FILEVERSION 981004==
  *
  *  NOTE TO MAINTAINERS:
  *   If you modify this file at all, please set the above date.
@@ -80,6 +80,7 @@ struct ppp {
        struct slcompress *slcomp;      /* for TCP header compression   */
        struct sk_buff_head xmt_q;      /* frames to send from pppd     */
        struct sk_buff_head rcv_q;      /* frames for pppd to read      */
+       unsigned long   xmit_busy;      /* bit 0 set when xmitter busy  */
 
        /* Information specific to using ppp on async serial lines. */
        struct tty_struct *tty;         /* ptr to TTY structure */
index bb7a98db3f0e8542981817ce3f3fc36a1fb0053a..8456c7e8c8b88a0ec5b586ccd1afc4890d8e93a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: if_ppp.h,v 1.14 1998/07/07 04:27:33 paulus Exp $   */
+/*     $Id: if_ppp.h,v 1.15 1999/01/19 23:57:43 paulus Exp $   */
 
 /*
  * if_ppp.h - Point-to-Point Protocol definitions.
@@ -47,7 +47,6 @@
 
 #define        PPP_MTU         1500    /* Default MTU (size of Info field) */
 #define PPP_MAXMRU     65000   /* Largest MRU we allow */
-#define PPP_VERSION    "2.3.3"
 #define PPP_MAGIC      0x5002  /* Magic value for the ppp structure */
 #define PROTO_IPX      0x002b  /* protocol numbers */
 #define PROTO_DNA_RT    0x0027  /* DNA Routing */
index cf70fe655ea1dba5f311876f59600255575b3ade..a85b33cd1589a7bc40408ec2d0ad31d1df53d25d 100644 (file)
@@ -42,7 +42,7 @@
  */
 
 /*
- *  ==FILEVERSION 980704==
+ *  ==FILEVERSION 981004==
  *
  *  NOTE TO MAINTAINERS:
  *   If you modify this file at all, please set the above date.
@@ -80,6 +80,7 @@ struct ppp {
        struct slcompress *slcomp;      /* for TCP header compression   */
        struct sk_buff_head xmt_q;      /* frames to send from pppd     */
        struct sk_buff_head rcv_q;      /* frames for pppd to read      */
+       unsigned long   xmit_busy;      /* bit 0 set when xmitter busy  */
 
        /* Information specific to using ppp on async serial lines. */
        struct tty_struct *tty;         /* ptr to TTY structure */
index 66c5e185f1306e46c3d3f492dadb538bffb4e674..f465e066029d62962e78fd6b36eaf877a5bc4df7 100644 (file)
@@ -4,7 +4,7 @@
  *  Al Longyear <longyear@netcom.com>
  *  Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au>
  *
- *  ==FILEVERSION 980704==
+ *  ==FILEVERSION 981004==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the number above to the
@@ -45,7 +45,7 @@
 
 #define PPP_MAX_RCV_QLEN       32      /* max # frames we queue up for pppd */
 
-/* $Id: ppp.c,v 1.19 1998/07/07 04:27:37 paulus Exp $ */
+/* $Id: ppp.c,v 1.20 1999/01/19 23:57:44 paulus Exp $ */
 
 #include <linux/version.h>
 #include <linux/config.h>
 #include <linux/kerneld.h>
 #endif
 
+#define PPP_VERSION    "2.3.5"
+
 #if LINUX_VERSION_CODE >= VERSION(2,1,4)
 
 #if LINUX_VERSION_CODE >= VERSION(2,1,5)
@@ -177,6 +179,7 @@ static void ppp_receive_error(struct ppp *ppp);
 static void ppp_output_wakeup(struct ppp *ppp);
 static void ppp_send_ctrl(struct ppp *ppp, struct sk_buff *skb);
 static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
+static void ppp_send_frames(struct ppp *ppp);
 static struct sk_buff *ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb);
 
 static struct ppp *ppp_find (int pid_value);
@@ -526,6 +529,8 @@ ppp_tty_close (struct tty_struct *tty)
                return;
        if (ppp->backup_tty) {
                ppp->tty = ppp->backup_tty;
+               if (ppp_tty_push(ppp))
+                       ppp_output_wakeup(ppp);
        } else {
                ppp->tty = 0;
                ppp->sc_xfer = 0;
@@ -535,7 +540,6 @@ ppp_tty_close (struct tty_struct *tty)
 
                ppp_async_release(ppp);
                ppp_release(ppp);
-               ppp->inuse = 0;
                MOD_DEC_USE_COUNT;
        }
 }
@@ -620,9 +624,9 @@ ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf,
        /*
         * Copy the received data from the buffer to the caller's area.
         */
-       err = COPY_TO_USER(buf, skb->data, len);
-       if (err == 0)
-               err = len;
+       err = len;
+       if (COPY_TO_USER(buf, skb->data, len))
+               err = -EFAULT;
 
 out:
        kfree_skb(skb);
@@ -1504,7 +1508,9 @@ ppp_dev_ioctl (struct device *dev, struct ifreq *ifr, int cmd)
                return -EINVAL;
        }
 
-       return COPY_TO_USER((void *) ifr->ifr_ifru.ifru_data, &u, nb);
+       if (COPY_TO_USER((void *) ifr->ifr_ifru.ifru_data, &u, nb))
+               return -EFAULT;
+       return 0;
 }
 
 /*
@@ -1537,6 +1543,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3)
                        break;
                if (temp_i < PPP_MRU)
                        temp_i = PPP_MRU;
+               ppp->mru = temp_i;
                if (ppp->flags & SC_DEBUG)
                        printk(KERN_INFO
                               "ppp_ioctl: set mru to %x\n", temp_i);
@@ -1736,8 +1743,9 @@ ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp)
        /*
         * Fetch the compression parameters
         */
+       error = -EFAULT;
        if (COPY_FROM_USER(&data, odp, sizeof (data)))
-               return -EFAULT;
+               goto out;
 
        nb  = data.length;
        ptr = data.ptr;
@@ -1745,10 +1753,11 @@ ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp)
                nb = CCP_MAX_OPTION_LENGTH;
 
        if (COPY_FROM_USER(ccp_option, ptr, nb))
-               return -EFAULT;
+               goto out;
 
+       error = -EINVAL;
        if (ccp_option[1] < 2)  /* preliminary check on the length byte */
-               return -EINVAL;
+               goto out;
 
        save_flags(flags);
        cli();
@@ -1771,7 +1780,7 @@ ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp)
                               "%s: no compressor for [%x %x %x], %x\n",
                               ppp->name, ccp_option[0], ccp_option[1],
                               ccp_option[2], nb);
-               return -EINVAL;         /* compressor not loaded */
+               goto out;               /* compressor not loaded */
        }
 
        /*
@@ -1786,7 +1795,6 @@ ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp)
 
                ppp->sc_xcomp    = cp;
                ppp->sc_xc_state = cp->comp_alloc(ccp_option, nb);
-
                if (ppp->sc_xc_state == NULL) {
                        if (ppp->flags & SC_DEBUG)
                                printk(KERN_DEBUG "%s: comp_alloc failed\n",
@@ -1807,7 +1815,7 @@ ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp)
                        error = -ENOBUFS;
                }
        }
-
+out:
        return error;
 }
 
@@ -2127,8 +2135,8 @@ ppp_rcv_rx(struct ppp *ppp, __u16 proto, struct sk_buff *skb)
         */
        skb->dev      = ppp2dev(ppp);   /* We are the device */
        skb->protocol = htons(proto);
-       skb->mac.raw  = skb->data;
        skb_pull(skb, PPP_HDRLEN);      /* pull off ppp header */
+       skb->mac.raw   = skb->data;
        ppp->last_recv = jiffies;
 #if LINUX_VERSION_CODE < VERSION(2,1,15)
        skb->free = 1;
@@ -2265,8 +2273,8 @@ extern inline __u8 * store_long (register __u8 *p, register int value) {
 
 /*
  * Compress and send an frame to the peer.
- * Should be called with dev->tbusy == 1, having been set by the caller.
- * That is, we use dev->tbusy as a lock to prevent reentry of this
+ * Should be called with xmit_busy == 1, having been set by the caller.
+ * That is, we use xmit_busy as a lock to prevent reentry of this
  * procedure.
  */
 static void
@@ -2338,7 +2346,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
                if (new_skb == NULL) {
                        printk(KERN_ERR "ppp_send_frame: no memory\n");
                        kfree_skb(skb);
-                       ppp->dev.tbusy = 0;
+                       ppp->xmit_busy = 0;
                        return;
                }
 
@@ -2367,9 +2375,9 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
        ret = ppp_async_send(ppp, skb);
        if (ret > 0) {
                /* we can release the lock */
-               ppp->dev.tbusy = 0;
+               ppp->xmit_busy = 0;
        } else if (ret < 0) {
-               /* this can't happen, since the caller got the tbusy lock */
+               /* can't happen, since the caller got the xmit_busy lock */
                printk(KERN_ERR "ppp: ppp_async_send didn't accept pkt\n");
        }
 }
@@ -2428,15 +2436,18 @@ ppp_send_frames(struct ppp *ppp)
 {
        struct sk_buff *skb;
 
-       while (!test_and_set_bit(0, &ppp->dev.tbusy)) {
+       while (!test_and_set_bit(0, &ppp->xmit_busy)) {
                skb = skb_dequeue(&ppp->xmt_q);
                if (skb == NULL) {
-                       ppp->dev.tbusy = 0;
-                       mark_bh(NET_BH);
+                       ppp->xmit_busy = 0;
                        break;
                }
                ppp_send_frame(ppp, skb);
        }
+       if (!ppp->xmit_busy && ppp->dev.tbusy) {
+               ppp->dev.tbusy = 0;
+               mark_bh(NET_BH);
+       }
 }
 
 /*
@@ -2448,11 +2459,11 @@ ppp_output_wakeup(struct ppp *ppp)
 {
        CHECK_PPP_VOID();
 
-       if (!ppp->dev.tbusy) {
-               printk(KERN_ERR "ppp_output_wakeup called but tbusy==0\n");
+       if (!ppp->xmit_busy) {
+               printk(KERN_ERR "ppp_output_wakeup called but xmit_busy==0\n");
                return;
        }
-       ppp->dev.tbusy = 0;
+       ppp->xmit_busy = 0;
        ppp_send_frames(ppp);
 }
 
@@ -2577,9 +2588,15 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
         * The dev->tbusy field acts as a lock to allow only
         * one packet to be processed at a time.  If we can't
         * get the lock, try again later.
+        * We deliberately queue as little as possible inside
+        * the ppp driver in order to minimize the latency
+        * for high-priority packets.
         */
-       if (test_and_set_bit(0, &dev->tbusy))
+       if (test_and_set_bit(0, &ppp->xmit_busy)) {
+               dev->tbusy = 1; /* can't take it now */
                return 1;
+       }
+       dev->tbusy = 0;
 
        /*
         * Put the 4-byte PPP header on the packet.
@@ -2593,7 +2610,8 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
                        printk(KERN_ERR "%s: skb hdr alloc failed\n",
                               ppp->name);
                        dev_kfree_skb(skb);
-                       dev->tbusy = 0;
+                       ppp->xmit_busy = 0;
+                       ppp_send_frames(ppp);
                        return 0;
                }
                skb_reserve(new_skb, PPP_HDRLEN);
@@ -2609,6 +2627,8 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
        hdr[3] = proto;
 
        ppp_send_frame(ppp, skb);
+       if (!ppp->xmit_busy)
+               ppp_send_frames(ppp);
        return 0;
 }
 
@@ -2772,6 +2792,7 @@ ppp_generic_init(struct ppp *ppp)
 
        ppp->last_xmit  = jiffies;
        ppp->last_recv  = jiffies;
+       ppp->xmit_busy  = 0;
 
        /* clear statistics */
        memset(&ppp->stats, 0, sizeof (struct pppstat));
@@ -2812,6 +2833,12 @@ ppp_release(struct ppp *ppp)
                kfree_skb(skb);
        while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL)
                kfree_skb(skb);
+
+       ppp->inuse = 0;
+       if (ppp->dev.tbusy) {
+               ppp->dev.tbusy = 0;
+               mark_bh(NET_BH);
+       }
 }
 
 /*