diff options
-rw-r--r-- | include/linux/netdevice.h | 20 | ||||
-rw-r--r-- | net/core/dev.c | 5 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 12 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 4 |
4 files changed, 36 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4b0c7f3aa32b..a9ac5dc26e3c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -508,7 +508,9 @@ struct netdev_queue { | |||
508 | #ifdef CONFIG_RPS | 508 | #ifdef CONFIG_RPS |
509 | struct kobject kobj; | 509 | struct kobject kobj; |
510 | #endif | 510 | #endif |
511 | 511 | #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) | |
512 | int numa_node; | ||
513 | #endif | ||
512 | /* | 514 | /* |
513 | * write mostly part | 515 | * write mostly part |
514 | */ | 516 | */ |
@@ -523,6 +525,22 @@ struct netdev_queue { | |||
523 | u64 tx_dropped; | 525 | u64 tx_dropped; |
524 | } ____cacheline_aligned_in_smp; | 526 | } ____cacheline_aligned_in_smp; |
525 | 527 | ||
528 | static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) | ||
529 | { | ||
530 | #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) | ||
531 | return q->numa_node; | ||
532 | #else | ||
533 | return -1; | ||
534 | #endif | ||
535 | } | ||
536 | |||
537 | static inline void netdev_queue_numa_node_write(struct netdev_queue *q, int node) | ||
538 | { | ||
539 | #if defined(CONFIG_XPS) && defined(CONFIG_NUMA) | ||
540 | q->numa_node = node; | ||
541 | #endif | ||
542 | } | ||
543 | |||
526 | #ifdef CONFIG_RPS | 544 | #ifdef CONFIG_RPS |
527 | /* | 545 | /* |
528 | * This structure holds an RPS map which can be of variable length. The | 546 | * This structure holds an RPS map which can be of variable length. The |
diff --git a/net/core/dev.c b/net/core/dev.c index 3259d2c323a6..cd2437495428 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5125,9 +5125,10 @@ static int netif_alloc_netdev_queues(struct net_device *dev) | |||
5125 | } | 5125 | } |
5126 | dev->_tx = tx; | 5126 | dev->_tx = tx; |
5127 | 5127 | ||
5128 | for (i = 0; i < count; i++) | 5128 | for (i = 0; i < count; i++) { |
5129 | netdev_queue_numa_node_write(&tx[i], -1); | ||
5129 | tx[i].dev = dev; | 5130 | tx[i].dev = dev; |
5130 | 5131 | } | |
5131 | return 0; | 5132 | return 0; |
5132 | } | 5133 | } |
5133 | 5134 | ||
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index f85cee3d869e..85e8b5326dd6 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -913,6 +913,7 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
913 | struct xps_map *map, *new_map; | 913 | struct xps_map *map, *new_map; |
914 | struct xps_dev_maps *dev_maps, *new_dev_maps; | 914 | struct xps_dev_maps *dev_maps, *new_dev_maps; |
915 | int nonempty = 0; | 915 | int nonempty = 0; |
916 | int numa_node = -2; | ||
916 | 917 | ||
917 | if (!capable(CAP_NET_ADMIN)) | 918 | if (!capable(CAP_NET_ADMIN)) |
918 | return -EPERM; | 919 | return -EPERM; |
@@ -953,7 +954,14 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
953 | pos = map_len = alloc_len = 0; | 954 | pos = map_len = alloc_len = 0; |
954 | 955 | ||
955 | need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); | 956 | need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); |
956 | 957 | #ifdef CONFIG_NUMA | |
958 | if (need_set) { | ||
959 | if (numa_node == -2) | ||
960 | numa_node = cpu_to_node(cpu); | ||
961 | else if (numa_node != cpu_to_node(cpu)) | ||
962 | numa_node = -1; | ||
963 | } | ||
964 | #endif | ||
957 | if (need_set && pos >= map_len) { | 965 | if (need_set && pos >= map_len) { |
958 | /* Need to add queue to this CPU's map */ | 966 | /* Need to add queue to this CPU's map */ |
959 | if (map_len >= alloc_len) { | 967 | if (map_len >= alloc_len) { |
@@ -1001,6 +1009,8 @@ static ssize_t store_xps_map(struct netdev_queue *queue, | |||
1001 | if (dev_maps) | 1009 | if (dev_maps) |
1002 | call_rcu(&dev_maps->rcu, xps_dev_maps_release); | 1010 | call_rcu(&dev_maps->rcu, xps_dev_maps_release); |
1003 | 1011 | ||
1012 | netdev_queue_numa_node_write(queue, (numa_node >= 0) ? numa_node : -1); | ||
1013 | |||
1004 | mutex_unlock(&xps_map_mutex); | 1014 | mutex_unlock(&xps_map_mutex); |
1005 | 1015 | ||
1006 | free_cpumask_var(mask); | 1016 | free_cpumask_var(mask); |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7f0bd8952646..0918834ee4a1 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -553,7 +553,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
553 | size = QDISC_ALIGN(sizeof(*sch)); | 553 | size = QDISC_ALIGN(sizeof(*sch)); |
554 | size += ops->priv_size + (QDISC_ALIGNTO - 1); | 554 | size += ops->priv_size + (QDISC_ALIGNTO - 1); |
555 | 555 | ||
556 | p = kzalloc(size, GFP_KERNEL); | 556 | p = kzalloc_node(size, GFP_KERNEL, |
557 | netdev_queue_numa_node_read(dev_queue)); | ||
558 | |||
557 | if (!p) | 559 | if (!p) |
558 | goto errout; | 560 | goto errout; |
559 | sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); | 561 | sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); |