]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/staging/batman-adv/aggregation.c
Staging: batman-adv: Limit queue lengths for batman and broadcast packets
[net-next-2.6.git] / drivers / staging / batman-adv / aggregation.c
index a5818ff6139e6b2949a63dbb63f0d0a125391edd..ce8b8a6e5ae6462d8336236a1a46ad0cef8d2126 100644 (file)
@@ -95,6 +95,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet,
        return false;
 }
 
+#define atomic_dec_not_zero(v)          atomic_add_unless((v), -1, 0)
 /* create a new aggregated packet and add this packet to it */
 static void new_aggregated_packet(unsigned char *packet_buff,
                           int packet_len,
@@ -106,13 +107,26 @@ static void new_aggregated_packet(unsigned char *packet_buff,
        struct forw_packet *forw_packet_aggr;
        unsigned long flags;
 
+       /* own packet should always be scheduled */
+       if (!own_packet) {
+               if (!atomic_dec_not_zero(&batman_queue_left)) {
+                       bat_dbg(DBG_BATMAN, "batman packet queue full\n");
+                       return;
+               }
+       }
+
        forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
-       if (!forw_packet_aggr)
+       if (!forw_packet_aggr) {
+               if (!own_packet)
+                       atomic_inc(&batman_queue_left);
                return;
+       }
 
        forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
                                                GFP_ATOMIC);
        if (!forw_packet_aggr->packet_buff) {
+               if (!own_packet)
+                       atomic_inc(&batman_queue_left);
                kfree(forw_packet_aggr);
                return;
        }