Commit df334545 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

rps: add CONFIG_RPS

RPS currently depends on SMP and SYSFS

Adding a CONFIG_RPS makes sense in case this requirement changes in the
future. This patch saves about 1500 bytes of kernel text in case SMP is
on but SYSFS is off.
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2381a55c
...@@ -531,6 +531,7 @@ struct netdev_queue { ...@@ -531,6 +531,7 @@ struct netdev_queue {
unsigned long tx_dropped; unsigned long tx_dropped;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
#ifdef CONFIG_RPS
/* /*
* This structure holds an RPS map which can be of variable length. The * This structure holds an RPS map which can be of variable length. The
* map is an array of CPUs. * map is an array of CPUs.
...@@ -549,6 +550,7 @@ struct netdev_rx_queue { ...@@ -549,6 +550,7 @@ struct netdev_rx_queue {
struct netdev_rx_queue *first; struct netdev_rx_queue *first;
atomic_t count; atomic_t count;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
#endif
/* /*
* This structure defines the management hooks for network devices. * This structure defines the management hooks for network devices.
...@@ -897,12 +899,14 @@ struct net_device { ...@@ -897,12 +899,14 @@ struct net_device {
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
#ifdef CONFIG_RPS
struct kset *queues_kset; struct kset *queues_kset;
struct netdev_rx_queue *_rx; struct netdev_rx_queue *_rx;
/* Number of RX queues allocated at alloc_netdev_mq() time */ /* Number of RX queues allocated at alloc_netdev_mq() time */
unsigned int num_rx_queues; unsigned int num_rx_queues;
#endif
struct netdev_queue rx_queue; struct netdev_queue rx_queue;
......
...@@ -203,6 +203,11 @@ source "net/ieee802154/Kconfig" ...@@ -203,6 +203,11 @@ source "net/ieee802154/Kconfig"
source "net/sched/Kconfig" source "net/sched/Kconfig"
source "net/dcb/Kconfig" source "net/dcb/Kconfig"
config RPS
boolean
depends on SMP && SYSFS
default y
menu "Network testing" menu "Network testing"
config NET_PKTGEN config NET_PKTGEN
......
...@@ -2177,7 +2177,7 @@ int weight_p __read_mostly = 64; /* old backlog weight */ ...@@ -2177,7 +2177,7 @@ int weight_p __read_mostly = 64; /* old backlog weight */
DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
/* /*
* get_rps_cpu is called from netif_receive_skb and returns the target * get_rps_cpu is called from netif_receive_skb and returns the target
* CPU from the RPS map of the receiving queue for a given skb. * CPU from the RPS map of the receiving queue for a given skb.
...@@ -2325,7 +2325,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu) ...@@ -2325,7 +2325,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu)
/* Schedule NAPI for backlog device */ /* Schedule NAPI for backlog device */
if (napi_schedule_prep(&queue->backlog)) { if (napi_schedule_prep(&queue->backlog)) {
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
if (cpu != smp_processor_id()) { if (cpu != smp_processor_id()) {
struct rps_remote_softirq_cpus *rcpus = struct rps_remote_softirq_cpus *rcpus =
&__get_cpu_var(rps_remote_softirq_cpus); &__get_cpu_var(rps_remote_softirq_cpus);
...@@ -2376,7 +2376,7 @@ int netif_rx(struct sk_buff *skb) ...@@ -2376,7 +2376,7 @@ int netif_rx(struct sk_buff *skb)
if (!skb->tstamp.tv64) if (!skb->tstamp.tv64)
net_timestamp(skb); net_timestamp(skb);
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
cpu = get_rps_cpu(skb->dev, skb); cpu = get_rps_cpu(skb->dev, skb);
if (cpu < 0) if (cpu < 0)
cpu = smp_processor_id(); cpu = smp_processor_id();
...@@ -2750,7 +2750,7 @@ int __netif_receive_skb(struct sk_buff *skb) ...@@ -2750,7 +2750,7 @@ int __netif_receive_skb(struct sk_buff *skb)
*/ */
int netif_receive_skb(struct sk_buff *skb) int netif_receive_skb(struct sk_buff *skb)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
int cpu; int cpu;
cpu = get_rps_cpu(skb->dev, skb); cpu = get_rps_cpu(skb->dev, skb);
...@@ -3189,7 +3189,7 @@ void netif_napi_del(struct napi_struct *napi) ...@@ -3189,7 +3189,7 @@ void netif_napi_del(struct napi_struct *napi)
} }
EXPORT_SYMBOL(netif_napi_del); EXPORT_SYMBOL(netif_napi_del);
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
/* /*
* net_rps_action sends any pending IPI's for rps. This is only called from * net_rps_action sends any pending IPI's for rps. This is only called from
* softirq and interrupts must be enabled. * softirq and interrupts must be enabled.
...@@ -3214,7 +3214,7 @@ static void net_rx_action(struct softirq_action *h) ...@@ -3214,7 +3214,7 @@ static void net_rx_action(struct softirq_action *h)
unsigned long time_limit = jiffies + 2; unsigned long time_limit = jiffies + 2;
int budget = netdev_budget; int budget = netdev_budget;
void *have; void *have;
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
int select; int select;
struct rps_remote_softirq_cpus *rcpus; struct rps_remote_softirq_cpus *rcpus;
#endif #endif
...@@ -3280,7 +3280,7 @@ static void net_rx_action(struct softirq_action *h) ...@@ -3280,7 +3280,7 @@ static void net_rx_action(struct softirq_action *h)
netpoll_poll_unlock(have); netpoll_poll_unlock(have);
} }
out: out:
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
rcpus = &__get_cpu_var(rps_remote_softirq_cpus); rcpus = &__get_cpu_var(rps_remote_softirq_cpus);
select = rcpus->select; select = rcpus->select;
rcpus->select ^= 1; rcpus->select ^= 1;
...@@ -5277,6 +5277,7 @@ int register_netdevice(struct net_device *dev) ...@@ -5277,6 +5277,7 @@ int register_netdevice(struct net_device *dev)
dev->iflink = -1; dev->iflink = -1;
#ifdef CONFIG_RPS
if (!dev->num_rx_queues) { if (!dev->num_rx_queues) {
/* /*
* Allocate a single RX queue if driver never called * Allocate a single RX queue if driver never called
...@@ -5293,7 +5294,7 @@ int register_netdevice(struct net_device *dev) ...@@ -5293,7 +5294,7 @@ int register_netdevice(struct net_device *dev)
atomic_set(&dev->_rx->count, 1); atomic_set(&dev->_rx->count, 1);
dev->num_rx_queues = 1; dev->num_rx_queues = 1;
} }
#endif
/* Init, if this function is available */ /* Init, if this function is available */
if (dev->netdev_ops->ndo_init) { if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev); ret = dev->netdev_ops->ndo_init(dev);
...@@ -5653,11 +5654,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, ...@@ -5653,11 +5654,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
void (*setup)(struct net_device *), unsigned int queue_count) void (*setup)(struct net_device *), unsigned int queue_count)
{ {
struct netdev_queue *tx; struct netdev_queue *tx;
struct netdev_rx_queue *rx;
struct net_device *dev; struct net_device *dev;
size_t alloc_size; size_t alloc_size;
struct net_device *p; struct net_device *p;
#ifdef CONFIG_RPS
struct netdev_rx_queue *rx;
int i; int i;
#endif
BUG_ON(strlen(name) >= sizeof(dev->name)); BUG_ON(strlen(name) >= sizeof(dev->name));
...@@ -5683,6 +5686,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, ...@@ -5683,6 +5686,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
goto free_p; goto free_p;
} }
#ifdef CONFIG_RPS
rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL); rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
if (!rx) { if (!rx) {
printk(KERN_ERR "alloc_netdev: Unable to allocate " printk(KERN_ERR "alloc_netdev: Unable to allocate "
...@@ -5698,6 +5702,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, ...@@ -5698,6 +5702,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
*/ */
for (i = 0; i < queue_count; i++) for (i = 0; i < queue_count; i++)
rx[i].first = rx; rx[i].first = rx;
#endif
dev = PTR_ALIGN(p, NETDEV_ALIGN); dev = PTR_ALIGN(p, NETDEV_ALIGN);
dev->padded = (char *)dev - (char *)p; dev->padded = (char *)dev - (char *)p;
...@@ -5713,8 +5718,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, ...@@ -5713,8 +5718,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
dev->num_tx_queues = queue_count; dev->num_tx_queues = queue_count;
dev->real_num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count;
#ifdef CONFIG_RPS
dev->_rx = rx; dev->_rx = rx;
dev->num_rx_queues = queue_count; dev->num_rx_queues = queue_count;
#endif
dev->gso_max_size = GSO_MAX_SIZE; dev->gso_max_size = GSO_MAX_SIZE;
...@@ -5731,8 +5738,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, ...@@ -5731,8 +5738,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
return dev; return dev;
free_rx: free_rx:
#ifdef CONFIG_RPS
kfree(rx); kfree(rx);
free_tx: free_tx:
#endif
kfree(tx); kfree(tx);
free_p: free_p:
kfree(p); kfree(p);
...@@ -6236,7 +6245,7 @@ static int __init net_dev_init(void) ...@@ -6236,7 +6245,7 @@ static int __init net_dev_init(void)
queue->completion_queue = NULL; queue->completion_queue = NULL;
INIT_LIST_HEAD(&queue->poll_list); INIT_LIST_HEAD(&queue->poll_list);
#ifdef CONFIG_SMP #ifdef CONFIG_RPS
queue->csd.func = trigger_softirq; queue->csd.func = trigger_softirq;
queue->csd.info = queue; queue->csd.info = queue;
queue->csd.flags = 0; queue->csd.flags = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment