diff options
author | Tom Herbert <therbert@google.com> | 2011-01-09 14:36:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-10 19:05:30 -0500 |
commit | 36909ea43814cba34f7c921e99cba33d770a54e1 (patch) | |
tree | 294b44411dc7939e152aa1002f9f5fe9868751f6 | |
parent | 91b5c98c2e062f982423686c77b8bf31f37fa196 (diff) |
net: Add alloc_netdev_mqs function
Added alloc_netdev_mqs function which allows the number of transmit and
receive queues to be specified independenty. alloc_netdev_mq was
changed to a macro to call the new function. Also added
alloc_etherdev_mqs with same purpose.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/etherdevice.h | 4 | ||||
-rw-r--r-- | include/linux/netdevice.h | 10 | ||||
-rw-r--r-- | net/core/dev.c | 32 | ||||
-rw-r--r-- | net/ethernet/eth.c | 12 |
4 files changed, 38 insertions, 20 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index f16a01081e15..bec8b82889bf 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -48,8 +48,10 @@ extern int eth_validate_addr(struct net_device *dev); | |||
48 | 48 | ||
49 | 49 | ||
50 | 50 | ||
51 | extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count); | 51 | extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, |
52 | unsigned int rxqs); | ||
52 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) | 53 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) |
54 | #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) | ||
53 | 55 | ||
54 | /** | 56 | /** |
55 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. | 57 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index de2bfe6da359..be4957cf6511 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -2191,11 +2191,15 @@ static inline void netif_addr_unlock_bh(struct net_device *dev) | |||
2191 | extern void ether_setup(struct net_device *dev); | 2191 | extern void ether_setup(struct net_device *dev); |
2192 | 2192 | ||
2193 | /* Support for loadable net-drivers */ | 2193 | /* Support for loadable net-drivers */ |
2194 | extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | 2194 | extern struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, |
2195 | void (*setup)(struct net_device *), | 2195 | void (*setup)(struct net_device *), |
2196 | unsigned int queue_count); | 2196 | unsigned int txqs, unsigned int rxqs); |
2197 | #define alloc_netdev(sizeof_priv, name, setup) \ | 2197 | #define alloc_netdev(sizeof_priv, name, setup) \ |
2198 | alloc_netdev_mq(sizeof_priv, name, setup, 1) | 2198 | alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1) |
2199 | |||
2200 | #define alloc_netdev_mq(sizeof_priv, name, setup, count) \ | ||
2201 | alloc_netdev_mqs(sizeof_priv, name, setup, count, count) | ||
2202 | |||
2199 | extern int register_netdev(struct net_device *dev); | 2203 | extern int register_netdev(struct net_device *dev); |
2200 | extern void unregister_netdev(struct net_device *dev); | 2204 | extern void unregister_netdev(struct net_device *dev); |
2201 | 2205 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 3fe443be4b15..3295b94884ab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5617,18 +5617,20 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) | |||
5617 | } | 5617 | } |
5618 | 5618 | ||
5619 | /** | 5619 | /** |
5620 | * alloc_netdev_mq - allocate network device | 5620 | * alloc_netdev_mqs - allocate network device |
5621 | * @sizeof_priv: size of private data to allocate space for | 5621 | * @sizeof_priv: size of private data to allocate space for |
5622 | * @name: device name format string | 5622 | * @name: device name format string |
5623 | * @setup: callback to initialize device | 5623 | * @setup: callback to initialize device |
5624 | * @queue_count: the number of subqueues to allocate | 5624 | * @txqs: the number of TX subqueues to allocate |
5625 | * @rxqs: the number of RX subqueues to allocate | ||
5625 | * | 5626 | * |
5626 | * Allocates a struct net_device with private data area for driver use | 5627 | * Allocates a struct net_device with private data area for driver use |
5627 | * and performs basic initialization. Also allocates subquue structs | 5628 | * and performs basic initialization. Also allocates subquue structs |
5628 | * for each queue on the device at the end of the netdevice. | 5629 | * for each queue on the device. |
5629 | */ | 5630 | */ |
5630 | struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | 5631 | struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, |
5631 | void (*setup)(struct net_device *), unsigned int queue_count) | 5632 | void (*setup)(struct net_device *), |
5633 | unsigned int txqs, unsigned int rxqs) | ||
5632 | { | 5634 | { |
5633 | struct net_device *dev; | 5635 | struct net_device *dev; |
5634 | size_t alloc_size; | 5636 | size_t alloc_size; |
@@ -5636,12 +5638,20 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5636 | 5638 | ||
5637 | BUG_ON(strlen(name) >= sizeof(dev->name)); | 5639 | BUG_ON(strlen(name) >= sizeof(dev->name)); |
5638 | 5640 | ||
5639 | if (queue_count < 1) { | 5641 | if (txqs < 1) { |
5640 | pr_err("alloc_netdev: Unable to allocate device " | 5642 | pr_err("alloc_netdev: Unable to allocate device " |
5641 | "with zero queues.\n"); | 5643 | "with zero queues.\n"); |
5642 | return NULL; | 5644 | return NULL; |
5643 | } | 5645 | } |
5644 | 5646 | ||
5647 | #ifdef CONFIG_RPS | ||
5648 | if (rxqs < 1) { | ||
5649 | pr_err("alloc_netdev: Unable to allocate device " | ||
5650 | "with zero RX queues.\n"); | ||
5651 | return NULL; | ||
5652 | } | ||
5653 | #endif | ||
5654 | |||
5645 | alloc_size = sizeof(struct net_device); | 5655 | alloc_size = sizeof(struct net_device); |
5646 | if (sizeof_priv) { | 5656 | if (sizeof_priv) { |
5647 | /* ensure 32-byte alignment of private area */ | 5657 | /* ensure 32-byte alignment of private area */ |
@@ -5672,14 +5682,14 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5672 | 5682 | ||
5673 | dev_net_set(dev, &init_net); | 5683 | dev_net_set(dev, &init_net); |
5674 | 5684 | ||
5675 | dev->num_tx_queues = queue_count; | 5685 | dev->num_tx_queues = txqs; |
5676 | dev->real_num_tx_queues = queue_count; | 5686 | dev->real_num_tx_queues = txqs; |
5677 | if (netif_alloc_netdev_queues(dev)) | 5687 | if (netif_alloc_netdev_queues(dev)) |
5678 | goto free_pcpu; | 5688 | goto free_pcpu; |
5679 | 5689 | ||
5680 | #ifdef CONFIG_RPS | 5690 | #ifdef CONFIG_RPS |
5681 | dev->num_rx_queues = queue_count; | 5691 | dev->num_rx_queues = rxqs; |
5682 | dev->real_num_rx_queues = queue_count; | 5692 | dev->real_num_rx_queues = rxqs; |
5683 | if (netif_alloc_rx_queues(dev)) | 5693 | if (netif_alloc_rx_queues(dev)) |
5684 | goto free_pcpu; | 5694 | goto free_pcpu; |
5685 | #endif | 5695 | #endif |
@@ -5707,7 +5717,7 @@ free_p: | |||
5707 | kfree(p); | 5717 | kfree(p); |
5708 | return NULL; | 5718 | return NULL; |
5709 | } | 5719 | } |
5710 | EXPORT_SYMBOL(alloc_netdev_mq); | 5720 | EXPORT_SYMBOL(alloc_netdev_mqs); |
5711 | 5721 | ||
5712 | /** | 5722 | /** |
5713 | * free_netdev - free network device | 5723 | * free_netdev - free network device |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index f00ef2f1d814..f9d7ac924f15 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -347,10 +347,11 @@ void ether_setup(struct net_device *dev) | |||
347 | EXPORT_SYMBOL(ether_setup); | 347 | EXPORT_SYMBOL(ether_setup); |
348 | 348 | ||
349 | /** | 349 | /** |
350 | * alloc_etherdev_mq - Allocates and sets up an Ethernet device | 350 | * alloc_etherdev_mqs - Allocates and sets up an Ethernet device |
351 | * @sizeof_priv: Size of additional driver-private structure to be allocated | 351 | * @sizeof_priv: Size of additional driver-private structure to be allocated |
352 | * for this Ethernet device | 352 | * for this Ethernet device |
353 | * @queue_count: The number of queues this device has. | 353 | * @txqs: The number of TX queues this device has. |
354 | * @txqs: The number of RX queues this device has. | ||
354 | * | 355 | * |
355 | * Fill in the fields of the device structure with Ethernet-generic | 356 | * Fill in the fields of the device structure with Ethernet-generic |
356 | * values. Basically does everything except registering the device. | 357 | * values. Basically does everything except registering the device. |
@@ -360,11 +361,12 @@ EXPORT_SYMBOL(ether_setup); | |||
360 | * this private data area. | 361 | * this private data area. |
361 | */ | 362 | */ |
362 | 363 | ||
363 | struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count) | 364 | struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, |
365 | unsigned int rxqs) | ||
364 | { | 366 | { |
365 | return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count); | 367 | return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs); |
366 | } | 368 | } |
367 | EXPORT_SYMBOL(alloc_etherdev_mq); | 369 | EXPORT_SYMBOL(alloc_etherdev_mqs); |
368 | 370 | ||
369 | static size_t _format_mac_addr(char *buf, int buflen, | 371 | static size_t _format_mac_addr(char *buf, int buflen, |
370 | const unsigned char *addr, int len) | 372 | const unsigned char *addr, int len) |