1--- a/drivers/net/ppp_generic.c	2008-07-14 01:51:29.000000000 +0400
2+++ b/drivers/net/ppp_generic.c	2009-03-01 00:17:03.000000000 +0300
3@@ -44,6 +44,7 @@
4 #include <linux/stddef.h>
5 #include <linux/device.h>
6 #include <linux/mutex.h>
7+#include <linux/workqueue.h>
8 #include <net/slhc_vj.h>
9 #include <asm/atomic.h>
10 
11@@ -114,7 +115,8 @@
12 	void		*rc_state;	/* its internal state 98 */
13 	unsigned long	last_xmit;	/* jiffies when last pkt sent 9c */
14 	unsigned long	last_recv;	/* jiffies when last pkt rcvd a0 */
15-	struct net_device *dev;		/* network interface device a4 */
16+	struct net_device *dev;		/* network interface device a4 */	
17+	struct work_struct xmit_work;	
18 #ifdef CONFIG_PPP_MULTILINK
19 	int		nxchan;		/* next channel to send something on */
20 	u32		nxseq;		/* next sequence number to send */
21@@ -154,6 +156,10 @@
22 	struct ppp	*ppp;		/* ppp unit we're connected to */
23 	struct list_head clist;		/* link in list of channels per unit */
24 	rwlock_t	upl;		/* protects `ppp' */
25+
26+	struct work_struct recv_work;
27+	struct sk_buff_head rq;		/* receive queue for pppd */
28+
29 #ifdef CONFIG_PPP_MULTILINK
30 	u8		avail;		/* flag used in multilink stuff */
31 	u8		had_frag;	/* >= 1 fragments have been sent */
32@@ -270,6 +276,7 @@
33 static void ppp_destroy_channel(struct channel *pch);
34 
35 static struct class *ppp_class;
36+static struct workqueue_struct *kpppd_workqueue;
37 
38 /* Translates a PPP protocol number to a NP index (NP == network protocol) */
39 static inline int proto_to_npindex(int proto)
40@@ -849,6 +856,13 @@
41 	int err;
42 
43 	printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
44+	
45+	kpppd_workqueue = create_workqueue("kpppd");
46+	if (!kpppd_workqueue){
47+	    printk(KERN_ERR "failed to create workqueue\n");
48+	    return -1;
49+	}
50+	    
51 	err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
52 	if (!err) {
53 		ppp_class = class_create(THIS_MODULE, "ppp");
54@@ -858,10 +872,12 @@
55 		}
56 		device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), "ppp");
57 	}
58-
59+	
60 out:
61-	if (err)
62+	if (err) {
63+		destroy_workqueue(kpppd_workqueue);
64 		printk(KERN_ERR "failed to register PPP device (%d)\n", err);
65+	}
66 	return err;
67 
68 out_chrdev:
69@@ -869,6 +885,12 @@
70 	goto out;
71 }
72 
73+static void ppp_xmit_work(struct work_struct *work)
74+{
75+    struct ppp *ppp=container_of(work,typeof(*ppp),xmit_work);
76+    ppp_xmit_process(ppp);
77+}
78+
79 /*
80  * Network interface unit routines.
81  */
82@@ -908,7 +930,7 @@
83 
84 	netif_stop_queue(dev);
85 	skb_queue_tail(&ppp->file.xq, skb);
86-	ppp_xmit_process(ppp);
87+	queue_work(kpppd_workqueue,&ppp->xmit_work);
88 	return 0;
89 
90  outf:
91@@ -1453,13 +1475,29 @@
92 {
93 	ppp_recv_lock(ppp);
94 	/* ppp->dev == 0 means interface is closing down */
95-	if (ppp->dev)
96-		ppp_receive_frame(ppp, skb, pch);
97-	else
98+	if (ppp->dev) {
99+		skb_queue_tail(&pch->rq, skb);
100+		queue_work(kpppd_workqueue,&pch->recv_work);
101+	} else
102 		kfree_skb(skb);
103 	ppp_recv_unlock(ppp);
104 }
105 
106+static void ppp_recv_work(struct work_struct *work)
107+{
108+    struct channel *pch=container_of(work,typeof(*pch),recv_work);
109+    struct sk_buff *skb;
110+    
111+    ppp_recv_lock(pch->ppp);
112+    
113+    while((skb=skb_dequeue(&pch->rq))){
114+	if (pch->ppp->dev)
115+	    ppp_receive_frame(pch->ppp, skb, pch);
116+    }
117+    
118+    ppp_recv_unlock(pch->ppp);
119+}
120+
121 void
122 ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
123 {
124@@ -2000,6 +2038,8 @@
125 	chan->ppp = pch;
126 	init_ppp_file(&pch->file, CHANNEL);
127 	pch->file.hdrlen = chan->hdrlen;
128+	INIT_WORK(&pch->recv_work,ppp_recv_work);
129+	skb_queue_head_init(&pch->rq);
130 #ifdef CONFIG_PPP_MULTILINK
131 	pch->lastseq = -1;
132 #endif /* CONFIG_PPP_MULTILINK */
133@@ -2419,6 +2459,7 @@
134 	INIT_LIST_HEAD(&ppp->channels);
135 	spin_lock_init(&ppp->rlock);
136 	spin_lock_init(&ppp->wlock);
137+	INIT_WORK(&ppp->xmit_work,ppp_xmit_work);
138 #ifdef CONFIG_PPP_MULTILINK
139 	ppp->minseq = -1;
140 	skb_queue_head_init(&ppp->mrq);
141@@ -2529,6 +2570,7 @@
142 		slhc_free(ppp->vj);
143 		ppp->vj = NULL;
144 	}
145+	cancel_work_sync(&ppp->xmit_work);
146 	skb_queue_purge(&ppp->file.xq);
147 	skb_queue_purge(&ppp->file.rq);
148 #ifdef CONFIG_PPP_MULTILINK
149@@ -2664,6 +2706,8 @@
150 	}
151 	skb_queue_purge(&pch->file.xq);
152 	skb_queue_purge(&pch->file.rq);
153+	cancel_work_sync(&pch->recv_work);
154+	skb_queue_purge(&pch->rq);
155 	kfree(pch);
156 }
157 
158@@ -2676,6 +2720,7 @@
159 	unregister_chrdev(PPP_MAJOR, "ppp");
160 	device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
161 	class_destroy(ppp_class);
162+	destroy_workqueue(kpppd_workqueue);
163 }
164 
165 /*
166