aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-09-23 13:26:35 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-26 22:04:07 -0400
commit1b4bf461f05d56ced6d6b8f3b4831adc7076f565 (patch)
tree632708e37f7f9ccdef2a774b38904c5dfd6a8ecc /net/core/dev.c
parent7a91b434e2bad554b709265db7603b1aa52dd92e (diff)
rps: allocate rx queues in register_netdevice only
Instead of having two places were we allocate dev->_rx, introduce netif_alloc_rx_queues() helper and call it only from register_netdevice(), not from alloc_netdev_mq() Goal is to let drivers change dev->num_rx_queues after allocating netdev and before registering it. This also removes a lot of ifdefs in net/core/dev.c Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index e0c0b86f57a1..72e99835e5b8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4964,6 +4964,34 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
4964} 4964}
4965EXPORT_SYMBOL(netif_stacked_transfer_operstate); 4965EXPORT_SYMBOL(netif_stacked_transfer_operstate);
4966 4966
4967static int netif_alloc_rx_queues(struct net_device *dev)
4968{
4969#ifdef CONFIG_RPS
4970 unsigned int i, count = dev->num_rx_queues;
4971
4972 if (count) {
4973 struct netdev_rx_queue *rx;
4974
4975 rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
4976 if (!rx) {
4977 pr_err("netdev: Unable to allocate %u rx queues.\n",
4978 count);
4979 return -ENOMEM;
4980 }
4981 dev->_rx = rx;
4982 atomic_set(&rx->count, count);
4983
4984 /*
4985 * Set a pointer to first element in the array which holds the
4986 * reference count.
4987 */
4988 for (i = 0; i < count; i++)
4989 rx[i].first = rx;
4990 }
4991#endif
4992 return 0;
4993}
4994
4967/** 4995/**
4968 * register_netdevice - register a network device 4996 * register_netdevice - register a network device
4969 * @dev: device to register 4997 * @dev: device to register
@@ -5001,24 +5029,10 @@ int register_netdevice(struct net_device *dev)
5001 5029
5002 dev->iflink = -1; 5030 dev->iflink = -1;
5003 5031
5004#ifdef CONFIG_RPS 5032 ret = netif_alloc_rx_queues(dev);
5005 if (!dev->num_rx_queues) { 5033 if (ret)
5006 /* 5034 goto out;
5007 * Allocate a single RX queue if driver never called
5008 * alloc_netdev_mq
5009 */
5010
5011 dev->_rx = kzalloc(sizeof(struct netdev_rx_queue), GFP_KERNEL);
5012 if (!dev->_rx) {
5013 ret = -ENOMEM;
5014 goto out;
5015 }
5016 5035
5017 dev->_rx->first = dev->_rx;
5018 atomic_set(&dev->_rx->count, 1);
5019 dev->num_rx_queues = 1;
5020 }
5021#endif
5022 /* Init, if this function is available */ 5036 /* Init, if this function is available */
5023 if (dev->netdev_ops->ndo_init) { 5037 if (dev->netdev_ops->ndo_init) {
5024 ret = dev->netdev_ops->ndo_init(dev); 5038 ret = dev->netdev_ops->ndo_init(dev);
@@ -5415,10 +5429,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
5415 struct net_device *dev; 5429 struct net_device *dev;
5416 size_t alloc_size; 5430 size_t alloc_size;
5417 struct net_device *p; 5431 struct net_device *p;
5418#ifdef CONFIG_RPS
5419 struct netdev_rx_queue *rx;
5420 int i;
5421#endif
5422 5432
5423 BUG_ON(strlen(name) >= sizeof(dev->name)); 5433 BUG_ON(strlen(name) >= sizeof(dev->name));
5424 5434
@@ -5444,29 +5454,12 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
5444 goto free_p; 5454 goto free_p;
5445 } 5455 }
5446 5456
5447#ifdef CONFIG_RPS
5448 rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
5449 if (!rx) {
5450 printk(KERN_ERR "alloc_netdev: Unable to allocate "
5451 "rx queues.\n");
5452 goto free_tx;
5453 }
5454
5455 atomic_set(&rx->count, queue_count);
5456
5457 /*
5458 * Set a pointer to first element in the array which holds the
5459 * reference count.
5460 */
5461 for (i = 0; i < queue_count; i++)
5462 rx[i].first = rx;
5463#endif
5464 5457
5465 dev = PTR_ALIGN(p, NETDEV_ALIGN); 5458 dev = PTR_ALIGN(p, NETDEV_ALIGN);
5466 dev->padded = (char *)dev - (char *)p; 5459 dev->padded = (char *)dev - (char *)p;
5467 5460
5468 if (dev_addr_init(dev)) 5461 if (dev_addr_init(dev))
5469 goto free_rx; 5462 goto free_tx;
5470 5463
5471 dev_mc_init(dev); 5464 dev_mc_init(dev);
5472 dev_uc_init(dev); 5465 dev_uc_init(dev);
@@ -5478,7 +5471,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
5478 dev->real_num_tx_queues = queue_count; 5471 dev->real_num_tx_queues = queue_count;
5479 5472
5480#ifdef CONFIG_RPS 5473#ifdef CONFIG_RPS
5481 dev->_rx = rx;
5482 dev->num_rx_queues = queue_count; 5474 dev->num_rx_queues = queue_count;
5483#endif 5475#endif
5484 5476
@@ -5496,11 +5488,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
5496 strcpy(dev->name, name); 5488 strcpy(dev->name, name);
5497 return dev; 5489 return dev;
5498 5490
5499free_rx:
5500#ifdef CONFIG_RPS
5501 kfree(rx);
5502free_tx: 5491free_tx:
5503#endif
5504 kfree(tx); 5492 kfree(tx);
5505free_p: 5493free_p:
5506 kfree(p); 5494 kfree(p);