Author: marek Date: 2010-08-08 15:00:50 +0200 (Sun, 08 Aug 2010) New Revision: 1759
Modified: trunk/batman-adv/aggregation.c trunk/batman-adv/send.c trunk/batman-adv/types.h Log: batman-adv: Aggregate batman packets directly in skb
All originator messages are send through aggregation buffers. Those buffers can directly be allocated as skb to reduce the cost of allocation an extra buffer and copying them to a new allocated skb directly before it gets send.
Now only the skb must be cloned in case of send_packet_to_if as it gets called by send_packet for each interface. Non-primary ogms must not cloned at all because they will only send once and the forward_packet structure is freed by send_outstanding_bat_packet afterwards.
Reported-by: David S. Miller davem@davemloft.net Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de
Modified: trunk/batman-adv/aggregation.c =================================================================== --- trunk/batman-adv/aggregation.c 2010-08-08 13:00:46 UTC (rev 1758) +++ trunk/batman-adv/aggregation.c 2010-08-08 13:00:50 UTC (rev 1759) @@ -39,7 +39,7 @@ struct forw_packet *forw_packet) { struct batman_packet *batman_packet = - (struct batman_packet *)forw_packet->packet_buff; + (struct batman_packet *)forw_packet->skb->data; int aggregated_bytes = forw_packet->packet_len + packet_len;
/** @@ -106,6 +106,7 @@ { struct forw_packet *forw_packet_aggr; unsigned long flags; + unsigned char *skb_buff; /* FIXME: each batman_if will be attached to a softif */ struct bat_priv *bat_priv = netdev_priv(soft_device);
@@ -125,23 +126,22 @@ return; }
- forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES, - GFP_ATOMIC); - if (!forw_packet_aggr->packet_buff) { + forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + + sizeof(struct ethhdr)); + if (!forw_packet_aggr->skb) { if (!own_packet) atomic_inc(&bat_priv->batman_queue_left); kfree(forw_packet_aggr); return; } + skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
INIT_HLIST_NODE(&forw_packet_aggr->list);
+ skb_buff = skb_put(forw_packet_aggr->skb, packet_len); forw_packet_aggr->packet_len = packet_len; - memcpy(forw_packet_aggr->packet_buff, - packet_buff, - forw_packet_aggr->packet_len); + memcpy(skb_buff, packet_buff, packet_len);
- forw_packet_aggr->skb = NULL; forw_packet_aggr->own = own_packet; forw_packet_aggr->if_incoming = if_incoming; forw_packet_aggr->num_packets = 0; @@ -171,8 +171,10 @@ int packet_len, bool direct_link) { - memcpy((forw_packet_aggr->packet_buff + forw_packet_aggr->packet_len), - packet_buff, packet_len); + unsigned char *skb_buff; + + skb_buff = skb_put(forw_packet_aggr->skb, packet_len); + memcpy(skb_buff, packet_buff, packet_len); forw_packet_aggr->packet_len += packet_len; forw_packet_aggr->num_packets++;
Modified: trunk/batman-adv/send.c =================================================================== --- trunk/batman-adv/send.c 2010-08-08 13:00:46 UTC (rev 1758) +++ trunk/batman-adv/send.c 2010-08-08 13:00:50 UTC (rev 1759) @@ -132,14 +132,14 @@ uint8_t packet_num; int16_t buff_pos; struct batman_packet *batman_packet; + struct sk_buff *skb;
if (batman_if->if_status != IF_ACTIVE) return;
packet_num = 0; buff_pos = 0; - batman_packet = (struct batman_packet *) - (forw_packet->packet_buff); + batman_packet = (struct batman_packet *)forw_packet->skb->data;
/* adjust all flags and log packets */ while (aggregated_packet(buff_pos, @@ -171,12 +171,13 @@ (batman_packet->num_hna * ETH_ALEN); packet_num++; batman_packet = (struct batman_packet *) - (forw_packet->packet_buff + buff_pos); + (forw_packet->skb->data + buff_pos); }
- send_raw_packet(forw_packet->packet_buff, - forw_packet->packet_len, - batman_if, broadcast_addr); + /* create clone because function is called more than once */ + skb = skb_clone(forw_packet->skb, GFP_ATOMIC); + if (skb) + send_skb_packet(skb, batman_if, broadcast_addr); }
/* send a batman packet */ @@ -186,7 +187,7 @@ struct bat_priv *bat_priv = netdev_priv(soft_device); struct batman_if *batman_if; struct batman_packet *batman_packet = - (struct batman_packet *)(forw_packet->packet_buff); + (struct batman_packet *)(forw_packet->skb->data); unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) { @@ -212,10 +213,11 @@ batman_packet->ttl, forw_packet->if_incoming->dev, forw_packet->if_incoming->addr_str);
- send_raw_packet(forw_packet->packet_buff, - forw_packet->packet_len, - forw_packet->if_incoming, + /* skb is only used once and than forw_packet is free'd */ + send_skb_packet(forw_packet->skb, forw_packet->if_incoming, broadcast_addr); + forw_packet->skb = NULL; + return; }
@@ -379,7 +381,6 @@ { if (forw_packet->skb) kfree_skb(forw_packet->skb); - kfree(forw_packet->packet_buff); kfree(forw_packet); }
@@ -438,7 +439,6 @@ skb_reset_mac_header(skb);
forw_packet->skb = skb; - forw_packet->packet_buff = NULL;
/* how often did we send the bcast packet ? */ forw_packet->num_packets = 0;
Modified: trunk/batman-adv/types.h =================================================================== --- trunk/batman-adv/types.h 2010-08-08 13:00:46 UTC (rev 1758) +++ trunk/batman-adv/types.h 2010-08-08 13:00:50 UTC (rev 1759) @@ -172,7 +172,6 @@ unsigned long send_time; uint8_t own; struct sk_buff *skb; - unsigned char *packet_buff; uint16_t packet_len; uint32_t direct_link_flags; uint8_t num_packets;