aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/batman-adv/aggregation.c16
-rw-r--r--drivers/staging/batman-adv/main.c5
-rw-r--r--drivers/staging/batman-adv/main.h4
-rw-r--r--drivers/staging/batman-adv/send.c33
-rw-r--r--drivers/staging/batman-adv/send.h2
-rw-r--r--drivers/staging/batman-adv/soft-interface.c6
6 files changed, 56 insertions, 10 deletions
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c
index a5818ff6139..ce8b8a6e5ae 100644
--- a/drivers/staging/batman-adv/aggregation.c
+++ b/drivers/staging/batman-adv/aggregation.c
@@ -95,6 +95,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
95 return false; 95 return false;
96} 96}
97 97
98#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
98/* create a new aggregated packet and add this packet to it */ 99/* create a new aggregated packet and add this packet to it */
99static void new_aggregated_packet(unsigned char *packet_buff, 100static void new_aggregated_packet(unsigned char *packet_buff,
100 int packet_len, 101 int packet_len,
@@ -106,13 +107,26 @@ static void new_aggregated_packet(unsigned char *packet_buff,
106 struct forw_packet *forw_packet_aggr; 107 struct forw_packet *forw_packet_aggr;
107 unsigned long flags; 108 unsigned long flags;
108 109
110 /* own packet should always be scheduled */
111 if (!own_packet) {
112 if (!atomic_dec_not_zero(&batman_queue_left)) {
113 bat_dbg(DBG_BATMAN, "batman packet queue full\n");
114 return;
115 }
116 }
117
109 forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 118 forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
110 if (!forw_packet_aggr) 119 if (!forw_packet_aggr) {
120 if (!own_packet)
121 atomic_inc(&batman_queue_left);
111 return; 122 return;
123 }
112 124
113 forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES, 125 forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
114 GFP_ATOMIC); 126 GFP_ATOMIC);
115 if (!forw_packet_aggr->packet_buff) { 127 if (!forw_packet_aggr->packet_buff) {
128 if (!own_packet)
129 atomic_inc(&batman_queue_left);
116 kfree(forw_packet_aggr); 130 kfree(forw_packet_aggr);
117 return; 131 return;
118 } 132 }
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index c1e57aaf2e5..aa072d15134 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -42,6 +42,9 @@ DEFINE_SPINLOCK(forw_bat_list_lock);
42DEFINE_SPINLOCK(forw_bcast_list_lock); 42DEFINE_SPINLOCK(forw_bcast_list_lock);
43 43
44atomic_t vis_interval; 44atomic_t vis_interval;
45atomic_t bcast_queue_left;
46atomic_t batman_queue_left;
47
45int16_t num_hna; 48int16_t num_hna;
46 49
47struct net_device *soft_device; 50struct net_device *soft_device;
@@ -79,6 +82,8 @@ int init_module(void)
79 82
80 atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only 83 atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
81 * for debugging now. */ 84 * for debugging now. */
85 atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
86 atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
82 87
83 /* the name should not be longer than 10 chars - see 88 /* the name should not be longer than 10 chars - see
84 * http://lwn.net/Articles/23634/ */ 89 * http://lwn.net/Articles/23634/ */
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h
index 58c1ec16741..6749ce036b9 100644
--- a/drivers/staging/batman-adv/main.h
+++ b/drivers/staging/batman-adv/main.h
@@ -69,6 +69,8 @@
69#define MODULE_ACTIVE 1 69#define MODULE_ACTIVE 1
70#define MODULE_DEACTIVATING 2 70#define MODULE_DEACTIVATING 2
71 71
72#define BCAST_QUEUE_LEN 256
73#define BATMAN_QUEUE_LE 256
72 74
73/* 75/*
74 * Debug Messages 76 * Debug Messages
@@ -132,6 +134,8 @@ extern spinlock_t forw_bat_list_lock;
132extern spinlock_t forw_bcast_list_lock; 134extern spinlock_t forw_bcast_list_lock;
133 135
134extern atomic_t vis_interval; 136extern atomic_t vis_interval;
137extern atomic_t bcast_queue_left;
138extern atomic_t batman_queue_left;
135extern int16_t num_hna; 139extern int16_t num_hna;
136 140
137extern struct net_device *soft_device; 141extern struct net_device *soft_device;
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index 31d86ae9b14..f58a9edfc2c 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -375,13 +375,28 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
375 send_time); 375 send_time);
376} 376}
377 377
378void add_bcast_packet_to_list(struct sk_buff *skb) 378#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
379/* add a broadcast packet to the queue and setup timers. broadcast packets
380 * are sent multiple times to increase probability for beeing received.
381 *
382 * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on
383 * errors.
384 *
385 * The skb is not consumed, so the caller should make sure that the
386 * skb is freed. */
387int add_bcast_packet_to_list(struct sk_buff *skb)
379{ 388{
380 struct forw_packet *forw_packet; 389 struct forw_packet *forw_packet;
381 390
391 if (!atomic_dec_not_zero(&bcast_queue_left)) {
392 bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
393 goto out;
394 }
395
382 forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 396 forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
397
383 if (!forw_packet) 398 if (!forw_packet)
384 goto out; 399 goto out_and_inc;
385 400
386 skb = skb_copy(skb, GFP_ATOMIC); 401 skb = skb_copy(skb, GFP_ATOMIC);
387 if (!skb) 402 if (!skb)
@@ -396,12 +411,14 @@ void add_bcast_packet_to_list(struct sk_buff *skb)
396 forw_packet->num_packets = 0; 411 forw_packet->num_packets = 0;
397 412
398 _add_bcast_packet_to_list(forw_packet, 1); 413 _add_bcast_packet_to_list(forw_packet, 1);
399 return; 414 return NETDEV_TX_OK;
400 415
401packet_free: 416packet_free:
402 kfree(forw_packet); 417 kfree(forw_packet);
418out_and_inc:
419 atomic_inc(&bcast_queue_left);
403out: 420out:
404 return; 421 return NETDEV_TX_BUSY;
405} 422}
406 423
407void send_outstanding_bcast_packet(struct work_struct *work) 424void send_outstanding_bcast_packet(struct work_struct *work)
@@ -436,8 +453,10 @@ void send_outstanding_bcast_packet(struct work_struct *work)
436 if ((forw_packet->num_packets < 3) && 453 if ((forw_packet->num_packets < 3) &&
437 (atomic_read(&module_state) != MODULE_DEACTIVATING)) 454 (atomic_read(&module_state) != MODULE_DEACTIVATING))
438 _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000)); 455 _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
439 else 456 else {
440 forw_packet_free(forw_packet); 457 forw_packet_free(forw_packet);
458 atomic_inc(&bcast_queue_left);
459 }
441} 460}
442 461
443void send_outstanding_bat_packet(struct work_struct *work) 462void send_outstanding_bat_packet(struct work_struct *work)
@@ -463,6 +482,10 @@ void send_outstanding_bat_packet(struct work_struct *work)
463 (atomic_read(&module_state) != MODULE_DEACTIVATING)) 482 (atomic_read(&module_state) != MODULE_DEACTIVATING))
464 schedule_own_packet(forw_packet->if_incoming); 483 schedule_own_packet(forw_packet->if_incoming);
465 484
485 /* don't count own packet */
486 if (!forw_packet->own)
487 atomic_inc(&batman_queue_left);
488
466 forw_packet_free(forw_packet); 489 forw_packet_free(forw_packet);
467} 490}
468 491
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h
index b84a470e510..feaa2fc7f9a 100644
--- a/drivers/staging/batman-adv/send.h
+++ b/drivers/staging/batman-adv/send.h
@@ -33,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
33 struct batman_packet *batman_packet, 33 struct batman_packet *batman_packet,
34 uint8_t directlink, int hna_buff_len, 34 uint8_t directlink, int hna_buff_len,
35 struct batman_if *if_outgoing); 35 struct batman_if *if_outgoing);
36void add_bcast_packet_to_list(struct sk_buff *skb); 36int add_bcast_packet_to_list(struct sk_buff *skb);
37void send_outstanding_bcast_packet(struct work_struct *work); 37void send_outstanding_bcast_packet(struct work_struct *work);
38void send_outstanding_bat_packet(struct work_struct *work); 38void send_outstanding_bat_packet(struct work_struct *work);
39void purge_outstanding_packets(struct batman_if *batman_if); 39void purge_outstanding_packets(struct batman_if *batman_if);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index 681a0ad7cb8..14b5ccaeaca 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -216,10 +216,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
216 /* set broadcast sequence number */ 216 /* set broadcast sequence number */
217 bcast_packet->seqno = htons(bcast_seqno); 217 bcast_packet->seqno = htons(bcast_seqno);
218 218
219 bcast_seqno++; 219 /* broadcast packet. on success, increase seqno. */
220 if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
221 bcast_seqno++;
220 222
221 /* broadcast packet */
222 add_bcast_packet_to_list(skb);
223 /* a copy is stored in the bcast list, therefore removing 223 /* a copy is stored in the bcast list, therefore removing
224 * the original skb. */ 224 * the original skb. */
225 kfree_skb(skb); 225 kfree_skb(skb);