aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/rose/rose_loopback.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index 7af4f99c4a93..094a6621f8e8 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18static struct sk_buff_head loopback_queue; 18static struct sk_buff_head loopback_queue;
19#define ROSE_LOOPBACK_LIMIT 1000
19static struct timer_list loopback_timer; 20static struct timer_list loopback_timer;
20 21
21static void rose_set_loopback_timer(void); 22static void rose_set_loopback_timer(void);
@@ -35,29 +36,27 @@ static int rose_loopback_running(void)
35 36
36int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh) 37int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh)
37{ 38{
38 struct sk_buff *skbn; 39 struct sk_buff *skbn = NULL;
39 40
40 skbn = skb_clone(skb, GFP_ATOMIC); 41 if (skb_queue_len(&loopback_queue) < ROSE_LOOPBACK_LIMIT)
42 skbn = skb_clone(skb, GFP_ATOMIC);
41 43
42 kfree_skb(skb); 44 if (skbn) {
43 45 consume_skb(skb);
44 if (skbn != NULL) {
45 skb_queue_tail(&loopback_queue, skbn); 46 skb_queue_tail(&loopback_queue, skbn);
46 47
47 if (!rose_loopback_running()) 48 if (!rose_loopback_running())
48 rose_set_loopback_timer(); 49 rose_set_loopback_timer();
50 } else {
51 kfree_skb(skb);
49 } 52 }
50 53
51 return 1; 54 return 1;
52} 55}
53 56
54
55static void rose_set_loopback_timer(void) 57static void rose_set_loopback_timer(void)
56{ 58{
57 del_timer(&loopback_timer); 59 mod_timer(&loopback_timer, jiffies + 10);
58
59 loopback_timer.expires = jiffies + 10;
60 add_timer(&loopback_timer);
61} 60}
62 61
63static void rose_loopback_timer(struct timer_list *unused) 62static void rose_loopback_timer(struct timer_list *unused)
@@ -68,8 +67,12 @@ static void rose_loopback_timer(struct timer_list *unused)
68 struct sock *sk; 67 struct sock *sk;
69 unsigned short frametype; 68 unsigned short frametype;
70 unsigned int lci_i, lci_o; 69 unsigned int lci_i, lci_o;
70 int count;
71 71
72 while ((skb = skb_dequeue(&loopback_queue)) != NULL) { 72 for (count = 0; count < ROSE_LOOPBACK_LIMIT; count++) {
73 skb = skb_dequeue(&loopback_queue);
74 if (!skb)
75 return;
73 if (skb->len < ROSE_MIN_LEN) { 76 if (skb->len < ROSE_MIN_LEN) {
74 kfree_skb(skb); 77 kfree_skb(skb);
75 continue; 78 continue;
@@ -106,6 +109,8 @@ static void rose_loopback_timer(struct timer_list *unused)
106 kfree_skb(skb); 109 kfree_skb(skb);
107 } 110 }
108 } 111 }
112 if (!skb_queue_empty(&loopback_queue))
113 mod_timer(&loopback_timer, jiffies + 1);
109} 114}
110 115
111void __exit rose_loopback_clear(void) 116void __exit rose_loopback_clear(void)