Commit bf26414510103448ad3dc069c7422462f03ea3d7
Committed by
David S. Miller
1 parent
8fa9208e30
Exists in
master
and in
4 other branches
xps: Add CONFIG_XPS
This patch adds XPS_CONFIG option to enable and disable XPS. This is done in the same manner as RPS_CONFIG. This is also fixes build failure in XPS code when SMP is not enabled. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 5 changed files with 73 additions and 43 deletions Side-by-side Diff
include/linux/netdevice.h
... | ... | @@ -536,30 +536,6 @@ |
536 | 536 | #define RPS_MAP_SIZE(_num) (sizeof(struct rps_map) + (_num * sizeof(u16))) |
537 | 537 | |
538 | 538 | /* |
539 | - * This structure holds an XPS map which can be of variable length. The | |
540 | - * map is an array of queues. | |
541 | - */ | |
542 | -struct xps_map { | |
543 | - unsigned int len; | |
544 | - unsigned int alloc_len; | |
545 | - struct rcu_head rcu; | |
546 | - u16 queues[0]; | |
547 | -}; | |
548 | -#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) | |
549 | -#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ | |
550 | - / sizeof(u16)) | |
551 | - | |
552 | -/* | |
553 | - * This structure holds all XPS maps for device. Maps are indexed by CPU. | |
554 | - */ | |
555 | -struct xps_dev_maps { | |
556 | - struct rcu_head rcu; | |
557 | - struct xps_map *cpu_map[0]; | |
558 | -}; | |
559 | -#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ | |
560 | - (nr_cpu_ids * sizeof(struct xps_map *))) | |
561 | - | |
562 | -/* | |
563 | 539 | * The rps_dev_flow structure contains the mapping of a flow to a CPU and the |
564 | 540 | * tail pointer for that CPU's input queue at the time of last enqueue. |
565 | 541 | */ |
566 | 542 | |
... | ... | @@ -626,7 +602,33 @@ |
626 | 602 | } ____cacheline_aligned_in_smp; |
627 | 603 | #endif /* CONFIG_RPS */ |
628 | 604 | |
605 | +#ifdef CONFIG_XPS | |
629 | 606 | /* |
607 | + * This structure holds an XPS map which can be of variable length. The | |
608 | + * map is an array of queues. | |
609 | + */ | |
610 | +struct xps_map { | |
611 | + unsigned int len; | |
612 | + unsigned int alloc_len; | |
613 | + struct rcu_head rcu; | |
614 | + u16 queues[0]; | |
615 | +}; | |
616 | +#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) | |
617 | +#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ | |
618 | + / sizeof(u16)) | |
619 | + | |
620 | +/* | |
621 | + * This structure holds all XPS maps for device. Maps are indexed by CPU. | |
622 | + */ | |
623 | +struct xps_dev_maps { | |
624 | + struct rcu_head rcu; | |
625 | + struct xps_map *cpu_map[0]; | |
626 | +}; | |
627 | +#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ | |
628 | + (nr_cpu_ids * sizeof(struct xps_map *))) | |
629 | +#endif /* CONFIG_XPS */ | |
630 | + | |
631 | +/* | |
630 | 632 | * This structure defines the management hooks for network devices. |
631 | 633 | * The following hooks can be defined; unless noted otherwise, they are |
632 | 634 | * optional and can be filled with a null pointer. |
633 | 635 | |
... | ... | @@ -1046,7 +1048,9 @@ |
1046 | 1048 | unsigned long tx_queue_len; /* Max frames per queue allowed */ |
1047 | 1049 | spinlock_t tx_global_lock; |
1048 | 1050 | |
1051 | +#ifdef CONFIG_XPS | |
1049 | 1052 | struct xps_dev_maps *xps_maps; |
1053 | +#endif | |
1050 | 1054 | |
1051 | 1055 | /* These may be needed for future network-power-down code. */ |
1052 | 1056 |
net/Kconfig
net/core/dev.c
... | ... | @@ -1567,6 +1567,9 @@ |
1567 | 1567 | |
1568 | 1568 | rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, |
1569 | 1569 | txq); |
1570 | + if (rc) | |
1571 | + return rc; | |
1572 | + | |
1570 | 1573 | if (txq < dev->real_num_tx_queues) |
1571 | 1574 | qdisc_reset_all_tx_gt(dev, txq); |
1572 | 1575 | } |
... | ... | @@ -2148,7 +2151,7 @@ |
2148 | 2151 | |
2149 | 2152 | static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) |
2150 | 2153 | { |
2151 | -#ifdef CONFIG_RPS | |
2154 | +#ifdef CONFIG_XPS | |
2152 | 2155 | struct xps_dev_maps *dev_maps; |
2153 | 2156 | struct xps_map *map; |
2154 | 2157 | int queue_index = -1; |
2155 | 2158 | |
... | ... | @@ -5085,9 +5088,9 @@ |
5085 | 5088 | } |
5086 | 5089 | EXPORT_SYMBOL(netif_stacked_transfer_operstate); |
5087 | 5090 | |
5091 | +#ifdef CONFIG_RPS | |
5088 | 5092 | static int netif_alloc_rx_queues(struct net_device *dev) |
5089 | 5093 | { |
5090 | -#ifdef CONFIG_RPS | |
5091 | 5094 | unsigned int i, count = dev->num_rx_queues; |
5092 | 5095 | struct netdev_rx_queue *rx; |
5093 | 5096 | |
5094 | 5097 | |
... | ... | @@ -5102,9 +5105,9 @@ |
5102 | 5105 | |
5103 | 5106 | for (i = 0; i < count; i++) |
5104 | 5107 | rx[i].dev = dev; |
5105 | -#endif | |
5106 | 5108 | return 0; |
5107 | 5109 | } |
5110 | +#endif | |
5108 | 5111 | |
5109 | 5112 | static int netif_alloc_netdev_queues(struct net_device *dev) |
5110 | 5113 | { |
net/core/net-sysfs.c
... | ... | @@ -751,10 +751,12 @@ |
751 | 751 | |
752 | 752 | return error; |
753 | 753 | } |
754 | +#endif /* CONFIG_RPS */ | |
754 | 755 | |
755 | 756 | int |
756 | 757 | net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) |
757 | 758 | { |
759 | +#ifdef CONFIG_RPS | |
758 | 760 | int i; |
759 | 761 | int error = 0; |
760 | 762 | |
761 | 763 | |
... | ... | @@ -770,8 +772,12 @@ |
770 | 772 | kobject_put(&net->_rx[i].kobj); |
771 | 773 | |
772 | 774 | return error; |
775 | +#else | |
776 | + return 0; | |
777 | +#endif | |
773 | 778 | } |
774 | 779 | |
780 | +#ifdef CONFIG_XPS | |
775 | 781 | /* |
776 | 782 | * netdev_queue sysfs structures and functions. |
777 | 783 | */ |
778 | 784 | |
... | ... | @@ -1090,10 +1096,12 @@ |
1090 | 1096 | |
1091 | 1097 | return error; |
1092 | 1098 | } |
1099 | +#endif /* CONFIG_XPS */ | |
1093 | 1100 | |
1094 | 1101 | int |
1095 | 1102 | netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) |
1096 | 1103 | { |
1104 | +#ifdef CONFIG_XPS | |
1097 | 1105 | int i; |
1098 | 1106 | int error = 0; |
1099 | 1107 | |
1100 | 1108 | |
1101 | 1109 | |
1102 | 1110 | |
1103 | 1111 | |
1104 | 1112 | |
1105 | 1113 | |
1106 | 1114 | |
... | ... | @@ -1109,27 +1117,36 @@ |
1109 | 1117 | kobject_put(&net->_tx[i].kobj); |
1110 | 1118 | |
1111 | 1119 | return error; |
1120 | +#else | |
1121 | + return 0; | |
1122 | +#endif | |
1112 | 1123 | } |
1113 | 1124 | |
1114 | 1125 | static int register_queue_kobjects(struct net_device *net) |
1115 | 1126 | { |
1116 | - int error = 0, txq = 0, rxq = 0; | |
1127 | + int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; | |
1117 | 1128 | |
1129 | +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) | |
1118 | 1130 | net->queues_kset = kset_create_and_add("queues", |
1119 | 1131 | NULL, &net->dev.kobj); |
1120 | 1132 | if (!net->queues_kset) |
1121 | 1133 | return -ENOMEM; |
1134 | +#endif | |
1122 | 1135 | |
1123 | - error = net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); | |
1136 | +#ifdef CONFIG_RPS | |
1137 | + real_rx = net->real_num_rx_queues; | |
1138 | +#endif | |
1139 | + real_tx = net->real_num_tx_queues; | |
1140 | + | |
1141 | + error = net_rx_queue_update_kobjects(net, 0, real_rx); | |
1124 | 1142 | if (error) |
1125 | 1143 | goto error; |
1126 | - rxq = net->real_num_rx_queues; | |
1144 | + rxq = real_rx; | |
1127 | 1145 | |
1128 | - error = netdev_queue_update_kobjects(net, 0, | |
1129 | - net->real_num_tx_queues); | |
1146 | + error = netdev_queue_update_kobjects(net, 0, real_tx); | |
1130 | 1147 | if (error) |
1131 | 1148 | goto error; |
1132 | - txq = net->real_num_tx_queues; | |
1149 | + txq = real_tx; | |
1133 | 1150 | |
1134 | 1151 | return 0; |
1135 | 1152 | |
1136 | 1153 | |
1137 | 1154 | |
... | ... | @@ -1141,11 +1158,19 @@ |
1141 | 1158 | |
1142 | 1159 | static void remove_queue_kobjects(struct net_device *net) |
1143 | 1160 | { |
1144 | - net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); | |
1145 | - netdev_queue_update_kobjects(net, net->real_num_tx_queues, 0); | |
1161 | + int real_rx = 0, real_tx = 0; | |
1162 | + | |
1163 | +#ifdef CONFIG_RPS | |
1164 | + real_rx = net->real_num_rx_queues; | |
1165 | +#endif | |
1166 | + real_tx = net->real_num_tx_queues; | |
1167 | + | |
1168 | + net_rx_queue_update_kobjects(net, real_rx, 0); | |
1169 | + netdev_queue_update_kobjects(net, real_tx, 0); | |
1170 | +#if defined(CONFIG_RPS) || defined(CONFIG_XPS) | |
1146 | 1171 | kset_unregister(net->queues_kset); |
1172 | +#endif | |
1147 | 1173 | } |
1148 | -#endif /* CONFIG_RPS */ | |
1149 | 1174 | |
1150 | 1175 | static const void *net_current_ns(void) |
1151 | 1176 | { |
1152 | 1177 | |
... | ... | @@ -1244,9 +1269,7 @@ |
1244 | 1269 | |
1245 | 1270 | kobject_get(&dev->kobj); |
1246 | 1271 | |
1247 | -#ifdef CONFIG_RPS | |
1248 | 1272 | remove_queue_kobjects(net); |
1249 | -#endif | |
1250 | 1273 | |
1251 | 1274 | device_del(dev); |
1252 | 1275 | } |
1253 | 1276 | |
... | ... | @@ -1285,13 +1308,11 @@ |
1285 | 1308 | if (error) |
1286 | 1309 | return error; |
1287 | 1310 | |
1288 | -#ifdef CONFIG_RPS | |
1289 | 1311 | error = register_queue_kobjects(net); |
1290 | 1312 | if (error) { |
1291 | 1313 | device_del(dev); |
1292 | 1314 | return error; |
1293 | 1315 | } |
1294 | -#endif | |
1295 | 1316 | |
1296 | 1317 | return error; |
1297 | 1318 | } |
net/core/net-sysfs.h
... | ... | @@ -4,12 +4,9 @@ |
4 | 4 | int netdev_kobject_init(void); |
5 | 5 | int netdev_register_kobject(struct net_device *); |
6 | 6 | void netdev_unregister_kobject(struct net_device *); |
7 | -#ifdef CONFIG_RPS | |
8 | 7 | int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); |
9 | 8 | int netdev_queue_update_kobjects(struct net_device *net, |
10 | 9 | int old_num, int new_num); |
11 | - | |
12 | -#endif | |
13 | 10 | |
14 | 11 | #endif |