Skip to content

Commit

Permalink
net: allow large number of rx queues
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Pankaj Gupta authored and David S. Miller committed Jan 12, 2015
1 parent e350a96 commit 1059590
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6172,13 +6172,16 @@ static int netif_alloc_rx_queues(struct net_device *dev)
{
unsigned int i, count = dev->num_rx_queues;
struct netdev_rx_queue *rx;
size_t sz = count * sizeof(*rx);

BUG_ON(count < 1);

rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
if (!rx)
return -ENOMEM;

rx = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
if (!rx) {
rx = vzalloc(sz);
if (!rx)
return -ENOMEM;
}
dev->_rx = rx;

for (i = 0; i < count; i++)
Expand Down Expand Up @@ -6808,7 +6811,7 @@ void free_netdev(struct net_device *dev)

netif_free_tx_queues(dev);
#ifdef CONFIG_SYSFS
kfree(dev->_rx);
kvfree(dev->_rx);
#endif

kfree(rcu_dereference_protected(dev->ingress_queue, 1));
Expand Down

0 comments on commit 1059590

Please sign in to comment.