@@ -1970,32 +1970,50 @@ static DEFINE_MUTEX(xps_map_mutex);
1970
1970
#define xmap_dereference (P ) \
1971
1971
rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex))
1972
1972
1973
- static struct xps_map * remove_xps_queue (struct xps_dev_maps * dev_maps ,
1974
- int cpu , u16 index )
1973
+ static bool remove_xps_queue (struct xps_dev_maps * dev_maps ,
1974
+ int tci , u16 index )
1975
1975
{
1976
1976
struct xps_map * map = NULL ;
1977
1977
int pos ;
1978
1978
1979
1979
if (dev_maps )
1980
- map = xmap_dereference (dev_maps -> cpu_map [cpu ]);
1980
+ map = xmap_dereference (dev_maps -> cpu_map [tci ]);
1981
+ if (!map )
1982
+ return false;
1981
1983
1982
- for (pos = 0 ; map && pos < map -> len ; pos ++ ) {
1983
- if (map -> queues [pos ] == index ) {
1984
- if (map -> len > 1 ) {
1985
- map -> queues [pos ] = map -> queues [-- map -> len ];
1986
- } else {
1987
- RCU_INIT_POINTER (dev_maps -> cpu_map [cpu ], NULL );
1988
- kfree_rcu (map , rcu );
1989
- map = NULL ;
1990
- }
1984
+ for (pos = map -> len ; pos -- ;) {
1985
+ if (map -> queues [pos ] != index )
1986
+ continue ;
1987
+
1988
+ if (map -> len > 1 ) {
1989
+ map -> queues [pos ] = map -> queues [-- map -> len ];
1991
1990
break ;
1992
1991
}
1992
+
1993
+ RCU_INIT_POINTER (dev_maps -> cpu_map [tci ], NULL );
1994
+ kfree_rcu (map , rcu );
1995
+ return false;
1993
1996
}
1994
1997
1995
- return map ;
1998
+ return true ;
1996
1999
}
1997
2000
1998
- static void netif_reset_xps_queues_gt (struct net_device * dev , u16 index )
2001
+ static bool remove_xps_queue_cpu (struct net_device * dev ,
2002
+ struct xps_dev_maps * dev_maps ,
2003
+ int cpu , u16 offset , u16 count )
2004
+ {
2005
+ int i , j ;
2006
+
2007
+ for (i = count , j = offset ; i -- ; j ++ ) {
2008
+ if (!remove_xps_queue (dev_maps , cpu , j ))
2009
+ break ;
2010
+ }
2011
+
2012
+ return i < 0 ;
2013
+ }
2014
+
2015
+ static void netif_reset_xps_queues (struct net_device * dev , u16 offset ,
2016
+ u16 count )
1999
2017
{
2000
2018
struct xps_dev_maps * dev_maps ;
2001
2019
int cpu , i ;
@@ -2007,28 +2025,28 @@ static void netif_reset_xps_queues_gt(struct net_device *dev, u16 index)
2007
2025
if (!dev_maps )
2008
2026
goto out_no_maps ;
2009
2027
2010
- for_each_possible_cpu (cpu ) {
2011
- for (i = index ; i < dev -> num_tx_queues ; i ++ ) {
2012
- if (!remove_xps_queue (dev_maps , cpu , i ))
2013
- break ;
2014
- }
2015
- if (i == dev -> num_tx_queues )
2016
- active = true;
2017
- }
2028
+ for_each_possible_cpu (cpu )
2029
+ active |= remove_xps_queue_cpu (dev , dev_maps , cpu ,
2030
+ offset , count );
2018
2031
2019
2032
if (!active ) {
2020
2033
RCU_INIT_POINTER (dev -> xps_maps , NULL );
2021
2034
kfree_rcu (dev_maps , rcu );
2022
2035
}
2023
2036
2024
- for (i = index ; i < dev -> num_tx_queues ; i ++ )
2037
+ for (i = offset + ( count - 1 ); count -- ; i -- )
2025
2038
netdev_queue_numa_node_write (netdev_get_tx_queue (dev , i ),
2026
2039
NUMA_NO_NODE );
2027
2040
2028
2041
out_no_maps :
2029
2042
mutex_unlock (& xps_map_mutex );
2030
2043
}
2031
2044
2045
+ static void netif_reset_xps_queues_gt (struct net_device * dev , u16 index )
2046
+ {
2047
+ netif_reset_xps_queues (dev , index , dev -> num_tx_queues - index );
2048
+ }
2049
+
2032
2050
static struct xps_map * expand_xps_map (struct xps_map * map ,
2033
2051
int cpu , u16 index )
2034
2052
{
@@ -2192,6 +2210,9 @@ EXPORT_SYMBOL(netif_set_xps_queue);
2192
2210
#endif
2193
2211
void netdev_reset_tc (struct net_device * dev )
2194
2212
{
2213
+ #ifdef CONFIG_XPS
2214
+ netif_reset_xps_queues_gt (dev , 0 );
2215
+ #endif
2195
2216
dev -> num_tc = 0 ;
2196
2217
memset (dev -> tc_to_txq , 0 , sizeof (dev -> tc_to_txq ));
2197
2218
memset (dev -> prio_tc_map , 0 , sizeof (dev -> prio_tc_map ));
@@ -2203,6 +2224,9 @@ int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
2203
2224
if (tc >= dev -> num_tc )
2204
2225
return - EINVAL ;
2205
2226
2227
+ #ifdef CONFIG_XPS
2228
+ netif_reset_xps_queues (dev , offset , count );
2229
+ #endif
2206
2230
dev -> tc_to_txq [tc ].count = count ;
2207
2231
dev -> tc_to_txq [tc ].offset = offset ;
2208
2232
return 0 ;
@@ -2214,6 +2238,9 @@ int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
2214
2238
if (num_tc > TC_MAX_QUEUE )
2215
2239
return - EINVAL ;
2216
2240
2241
+ #ifdef CONFIG_XPS
2242
+ netif_reset_xps_queues_gt (dev , 0 );
2243
+ #endif
2217
2244
dev -> num_tc = num_tc ;
2218
2245
return 0 ;
2219
2246
}
0 commit comments