diff options
-rw-r--r-- | drivers/staging/batman-adv/aggregation.c | 16 | ||||
-rw-r--r-- | drivers/staging/batman-adv/main.c | 5 | ||||
-rw-r--r-- | drivers/staging/batman-adv/main.h | 4 | ||||
-rw-r--r-- | drivers/staging/batman-adv/send.c | 33 | ||||
-rw-r--r-- | drivers/staging/batman-adv/send.h | 2 | ||||
-rw-r--r-- | drivers/staging/batman-adv/soft-interface.c | 6 |
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 */ |
99 | static void new_aggregated_packet(unsigned char *packet_buff, | 100 | static 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); | |||
42 | DEFINE_SPINLOCK(forw_bcast_list_lock); | 42 | DEFINE_SPINLOCK(forw_bcast_list_lock); |
43 | 43 | ||
44 | atomic_t vis_interval; | 44 | atomic_t vis_interval; |
45 | atomic_t bcast_queue_left; | ||
46 | atomic_t batman_queue_left; | ||
47 | |||
45 | int16_t num_hna; | 48 | int16_t num_hna; |
46 | 49 | ||
47 | struct net_device *soft_device; | 50 | struct 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; | |||
132 | extern spinlock_t forw_bcast_list_lock; | 134 | extern spinlock_t forw_bcast_list_lock; |
133 | 135 | ||
134 | extern atomic_t vis_interval; | 136 | extern atomic_t vis_interval; |
137 | extern atomic_t bcast_queue_left; | ||
138 | extern atomic_t batman_queue_left; | ||
135 | extern int16_t num_hna; | 139 | extern int16_t num_hna; |
136 | 140 | ||
137 | extern struct net_device *soft_device; | 141 | extern 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 | ||
378 | void 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. */ | ||
387 | int 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 | ||
401 | packet_free: | 416 | packet_free: |
402 | kfree(forw_packet); | 417 | kfree(forw_packet); |
418 | out_and_inc: | ||
419 | atomic_inc(&bcast_queue_left); | ||
403 | out: | 420 | out: |
404 | return; | 421 | return NETDEV_TX_BUSY; |
405 | } | 422 | } |
406 | 423 | ||
407 | void send_outstanding_bcast_packet(struct work_struct *work) | 424 | void 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 | ||
443 | void send_outstanding_bat_packet(struct work_struct *work) | 462 | void 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); |
36 | void add_bcast_packet_to_list(struct sk_buff *skb); | 36 | int add_bcast_packet_to_list(struct sk_buff *skb); |
37 | void send_outstanding_bcast_packet(struct work_struct *work); | 37 | void send_outstanding_bcast_packet(struct work_struct *work); |
38 | void send_outstanding_bat_packet(struct work_struct *work); | 38 | void send_outstanding_bat_packet(struct work_struct *work); |
39 | void purge_outstanding_packets(struct batman_if *batman_if); | 39 | void 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); |