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