diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 32a63f4c3a92..3470e7fff1f4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2175,6 +2175,20 @@ static bool remove_xps_queue_cpu(struct net_device *dev, | |||
2175 | return active; | 2175 | return active; |
2176 | } | 2176 | } |
2177 | 2177 | ||
2178 | static void reset_xps_maps(struct net_device *dev, | ||
2179 | struct xps_dev_maps *dev_maps, | ||
2180 | bool is_rxqs_map) | ||
2181 | { | ||
2182 | if (is_rxqs_map) { | ||
2183 | static_key_slow_dec_cpuslocked(&xps_rxqs_needed); | ||
2184 | RCU_INIT_POINTER(dev->xps_rxqs_map, NULL); | ||
2185 | } else { | ||
2186 | RCU_INIT_POINTER(dev->xps_cpus_map, NULL); | ||
2187 | } | ||
2188 | static_key_slow_dec_cpuslocked(&xps_needed); | ||
2189 | kfree_rcu(dev_maps, rcu); | ||
2190 | } | ||
2191 | |||
2178 | static void clean_xps_maps(struct net_device *dev, const unsigned long *mask, | 2192 | static void clean_xps_maps(struct net_device *dev, const unsigned long *mask, |
2179 | struct xps_dev_maps *dev_maps, unsigned int nr_ids, | 2193 | struct xps_dev_maps *dev_maps, unsigned int nr_ids, |
2180 | u16 offset, u16 count, bool is_rxqs_map) | 2194 | u16 offset, u16 count, bool is_rxqs_map) |
@@ -2186,13 +2200,8 @@ static void clean_xps_maps(struct net_device *dev, const unsigned long *mask, | |||
2186 | j < nr_ids;) | 2200 | j < nr_ids;) |
2187 | active |= remove_xps_queue_cpu(dev, dev_maps, j, offset, | 2201 | active |= remove_xps_queue_cpu(dev, dev_maps, j, offset, |
2188 | count); | 2202 | count); |
2189 | if (!active) { | 2203 | if (!active) |
2190 | if (is_rxqs_map) | 2204 | reset_xps_maps(dev, dev_maps, is_rxqs_map); |
2191 | RCU_INIT_POINTER(dev->xps_rxqs_map, NULL); | ||
2192 | else | ||
2193 | RCU_INIT_POINTER(dev->xps_cpus_map, NULL); | ||
2194 | kfree_rcu(dev_maps, rcu); | ||
2195 | } | ||
2196 | 2205 | ||
2197 | if (!is_rxqs_map) { | 2206 | if (!is_rxqs_map) { |
2198 | for (i = offset + (count - 1); count--; i--) { | 2207 | for (i = offset + (count - 1); count--; i--) { |
@@ -2236,10 +2245,6 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset, | |||
2236 | false); | 2245 | false); |
2237 | 2246 | ||
2238 | out_no_maps: | 2247 | out_no_maps: |
2239 | if (static_key_enabled(&xps_rxqs_needed)) | ||
2240 | static_key_slow_dec_cpuslocked(&xps_rxqs_needed); | ||
2241 | |||
2242 | static_key_slow_dec_cpuslocked(&xps_needed); | ||
2243 | mutex_unlock(&xps_map_mutex); | 2248 | mutex_unlock(&xps_map_mutex); |
2244 | cpus_read_unlock(); | 2249 | cpus_read_unlock(); |
2245 | } | 2250 | } |
@@ -2357,9 +2362,12 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask, | |||
2357 | if (!new_dev_maps) | 2362 | if (!new_dev_maps) |
2358 | goto out_no_new_maps; | 2363 | goto out_no_new_maps; |
2359 | 2364 | ||
2360 | static_key_slow_inc_cpuslocked(&xps_needed); | 2365 | if (!dev_maps) { |
2361 | if (is_rxqs_map) | 2366 | /* Increment static keys at most once per type */ |
2362 | static_key_slow_inc_cpuslocked(&xps_rxqs_needed); | 2367 | static_key_slow_inc_cpuslocked(&xps_needed); |
2368 | if (is_rxqs_map) | ||
2369 | static_key_slow_inc_cpuslocked(&xps_rxqs_needed); | ||
2370 | } | ||
2363 | 2371 | ||
2364 | for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids), | 2372 | for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids), |
2365 | j < nr_ids;) { | 2373 | j < nr_ids;) { |
@@ -2457,13 +2465,8 @@ out_no_new_maps: | |||
2457 | } | 2465 | } |
2458 | 2466 | ||
2459 | /* free map if not active */ | 2467 | /* free map if not active */ |
2460 | if (!active) { | 2468 | if (!active) |
2461 | if (is_rxqs_map) | 2469 | reset_xps_maps(dev, dev_maps, is_rxqs_map); |
2462 | RCU_INIT_POINTER(dev->xps_rxqs_map, NULL); | ||
2463 | else | ||
2464 | RCU_INIT_POINTER(dev->xps_cpus_map, NULL); | ||
2465 | kfree_rcu(dev_maps, rcu); | ||
2466 | } | ||
2467 | 2470 | ||
2468 | out_no_maps: | 2471 | out_no_maps: |
2469 | mutex_unlock(&xps_map_mutex); | 2472 | mutex_unlock(&xps_map_mutex); |