aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorPankaj Gupta <pagupta@redhat.com>2015-01-12 01:11:28 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-12 17:05:05 -0500
commit1059590254fa9dce9cafc4f07d1103dbec415e76 (patch)
tree3763c2aa7f8dbe895102a627cffe1c063926b2c0 /net/core
parente350a96ec9e6c74f06235ded93ef3155f71c6c6b (diff)
net: allow large number of rx queues
netif_alloc_rx_queues() uses kcalloc() to allocate memory for "struct netdev_queue *_rx" array. If we are doing large rx queue allocation kcalloc() might fail, so this patch does a fallback to vzalloc(). Similar implementation is done for tx queue allocation in netif_alloc_netdev_queues(). We avoid failure of high order memory allocation with the help of vzalloc(), this allows us to do large rx and tx queue allocation which in turn helps us to increase the number of queues in tun. As vmalloc() adds overhead on a critical network path, __GFP_REPEAT flag is used with kzalloc() to do this fallback only when really needed. Signed-off-by: Pankaj Gupta <pagupta@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: David Gibson <dgibson@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 683d493aa1bf..805456147c30 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6172,13 +6172,16 @@ static int netif_alloc_rx_queues(struct net_device *dev)
6172{ 6172{
6173 unsigned int i, count = dev->num_rx_queues; 6173 unsigned int i, count = dev->num_rx_queues;
6174 struct netdev_rx_queue *rx; 6174 struct netdev_rx_queue *rx;
6175 size_t sz = count * sizeof(*rx);
6175 6176
6176 BUG_ON(count < 1); 6177 BUG_ON(count < 1);
6177 6178
6178 rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL); 6179 rx = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
6179 if (!rx) 6180 if (!rx) {
6180 return -ENOMEM; 6181 rx = vzalloc(sz);
6181 6182 if (!rx)
6183 return -ENOMEM;
6184 }
6182 dev->_rx = rx; 6185 dev->_rx = rx;
6183 6186
6184 for (i = 0; i < count; i++) 6187 for (i = 0; i < count; i++)
@@ -6808,7 +6811,7 @@ void free_netdev(struct net_device *dev)
6808 6811
6809 netif_free_tx_queues(dev); 6812 netif_free_tx_queues(dev);
6810#ifdef CONFIG_SYSFS 6813#ifdef CONFIG_SYSFS
6811 kfree(dev->_rx); 6814 kvfree(dev->_rx);
6812#endif 6815#endif
6813 6816
6814 kfree(rcu_dereference_protected(dev->ingress_queue, 1)); 6817 kfree(rcu_dereference_protected(dev->ingress_queue, 1));