igb: skb recycling
Subsystems (2)
RFC 2/2 igb: skb recycling
This driver is multiqueue, so implement a small skb recycling queue per cpu. It doesn't make sense to have a global queue since then a lock would be required. Not sure if this is going to work; compile tested only, needs more evaluation
drivers/net/igb/igb.h +1 -0
@@ -232,6 +232,7 @@ struct igb_adapter {/* TX */ struct igb_ring *tx_ring;/* One per active queue */ +struct sk_buff_head *rx_recycle;/* One per cpu */ unsigned int restart_queue;unsigned long tx_queue_len;u32 txd_cmd;
drivers/net/igb/igb_main.c +38 -11
93 lines not on this page · raw message
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
Quoted 4 lines · Stephen Hemminger
This driver is multiqueue, so implement a small skb recycling queue per cpu. It doesn't make sense to have a global queue since then a lock would be required. Not sure if this is going to work; compile tested only, needs more evaluation
I did a bit of quick testing and found an issue in the sections of code below. As is the current patch generates a null pointer exception on unload because the percpu_alloc and for_each_possible_cpu are working off of two different CPU masks.
The simple solution is to either replace percpu_alloc with alloc_percpu and use cpu_possible_map or replace for_each_possible_cpu with for_each_online_cpu and use the cpu_online_map.
Attached is the version I tested at my desk that used the cpu_possible_map solution. I went that route since alloc_percpu seemed like a fairly clean macro.
Thanks,
Alex
Quoted 16 lines
---
a/drivers/net/igb/igb_main.c2008-10-21 09:39:25.000000000
-0700 +++b/drivers/net/igb/igb_main.c2008-10-21
10:13:42.000000000 -0700 @@ -824,6 +824,11 @@ void igb_down(structigb_adapter *adapte igb_reset(adapter); igb_clean_all_tx_rings(adapter); igb_clean_all_rx_rings(adapter);(quoted diff) +3
-0+ + for_each_possible_cpu(i) { + struct sk_buff_head *rx_recycle =
per_cpu_ptr(adapter->rx_recycle,i); +__skb_queue_purge(rx_recycle); + }
}void
igb_reinit_locked(struct igb_adapter *adapter)(quoted diff) +0
-0@@ -1022,6 +1027,11 @@ static int __devinit igb_probe(struct pc adapter = netdev_priv(netdev);
Review static int __devinit igb_probe(struct pc
Quoted 10 lines
(quoted diff) +4
-0adapter->netdev = netdev; adapter->pdev = pdev; + + adapter->rx_recycle = percpu_alloc(sizeof(struct sk_buff_head), GFP_KERNEL); + if (!adapter->rx_recycle) + goto err_alloc_recycle; + hw = &adapter->hw; hw->back = adapter; adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
---
drivers/net/igb/igb.h | 1 + drivers/net/igb/igb_main.c | 48 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 10 deletions(-)
drivers/net/igb/igb.h +1 -0
@@ -232,6 +232,7 @@ struct igb_adapter {/* TX */ struct igb_ring *tx_ring;/* One per active queue */ +struct sk_buff_head *rx_recycle;/* One per cpu */ unsigned int restart_queue;unsigned long tx_queue_len;u32 txd_cmd;
drivers/net/igb/igb_main.c +38 -10
93 lines not on this page · raw message
Quoted 11 lines · Alexander H
Quoted 4 lines · Stephen Hemminger
This driver is multiqueue, so implement a small skb recycling queue per cpu. It doesn't make sense to have a global queue since then a lock would be required. Not sure if this is going to work; compile tested only, needs more evaluation
I did a bit of quick testing and found an issue in the sections of code below. As is the current patch generates a null pointer exception on unload because the
percpu_allocandfor_each_possible_cpuare working off of two different CPU masks.
Quoted 8 lines
The simple solution is to either replace
percpu_allocwithalloc_percpuand usecpu_possible_mapor replacefor_each_possible_cpuwithfor_each_online_cpuand use thecpu_online_map.Attached is the version I tested at my desk that used the
cpu_possible_mapsolution. I went that route sincealloc_percpuseemed like a fairly clean macro.
It turns out I missed one issue in my testing that was brought to my attention. It looks like the issue was just due to the fact that the per cpu queues weren't initialized to store packets. This updated patch adds a loop that goes through and calls __skb_queue_init_head on all the queues.
Thanks,
Alex
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
E1000-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/e1000-devel