@@ -224,10 +224,13 @@ static void veth_get_channels(struct net_device *dev,
224224{
225225 channels -> tx_count = dev -> real_num_tx_queues ;
226226 channels -> rx_count = dev -> real_num_rx_queues ;
227- channels -> max_tx = dev -> real_num_tx_queues ;
228- channels -> max_rx = dev -> real_num_rx_queues ;
227+ channels -> max_tx = dev -> num_tx_queues ;
228+ channels -> max_rx = dev -> num_rx_queues ;
229229}
230230
231+ static int veth_set_channels (struct net_device * dev ,
232+ struct ethtool_channels * ch );
233+
231234static const struct ethtool_ops veth_ethtool_ops = {
232235 .get_drvinfo = veth_get_drvinfo ,
233236 .get_link = ethtool_op_get_link ,
@@ -237,6 +240,7 @@ static const struct ethtool_ops veth_ethtool_ops = {
237240 .get_link_ksettings = veth_get_link_ksettings ,
238241 .get_ts_info = ethtool_op_get_ts_info ,
239242 .get_channels = veth_get_channels ,
243+ .set_channels = veth_set_channels ,
240244};
241245
242246/* general routines */
@@ -1136,6 +1140,123 @@ static int veth_napi_enable(struct net_device *dev)
11361140 return veth_napi_enable_range (dev , 0 , dev -> real_num_rx_queues );
11371141}
11381142
1143+ static void veth_disable_range_safe (struct net_device * dev , int start , int end )
1144+ {
1145+ struct veth_priv * priv = netdev_priv (dev );
1146+
1147+ if (start >= end )
1148+ return ;
1149+
1150+ if (priv -> _xdp_prog ) {
1151+ veth_napi_del_range (dev , start , end );
1152+ veth_disable_xdp_range (dev , start , end , false);
1153+ } else if (veth_gro_requested (dev )) {
1154+ veth_napi_del_range (dev , start , end );
1155+ }
1156+ }
1157+
1158+ static int veth_enable_range_safe (struct net_device * dev , int start , int end )
1159+ {
1160+ struct veth_priv * priv = netdev_priv (dev );
1161+ int err ;
1162+
1163+ if (start >= end )
1164+ return 0 ;
1165+
1166+ if (priv -> _xdp_prog ) {
1167+ /* these channels are freshly initialized, napi is not on there even
1168+ * when GRO is requeste
1169+ */
1170+ err = veth_enable_xdp_range (dev , start , end , false);
1171+ if (err )
1172+ return err ;
1173+
1174+ err = __veth_napi_enable_range (dev , start , end );
1175+ if (err ) {
1176+ /* on error always delete the newly added napis */
1177+ veth_disable_xdp_range (dev , start , end , true);
1178+ return err ;
1179+ }
1180+ } else if (veth_gro_requested (dev )) {
1181+ return veth_napi_enable_range (dev , start , end );
1182+ }
1183+ return 0 ;
1184+ }
1185+
1186+ static int veth_set_channels (struct net_device * dev ,
1187+ struct ethtool_channels * ch )
1188+ {
1189+ struct veth_priv * priv = netdev_priv (dev );
1190+ unsigned int old_rx_count , new_rx_count ;
1191+ struct veth_priv * peer_priv ;
1192+ struct net_device * peer ;
1193+ int err ;
1194+
1195+ /* sanity check. Upper bounds are already enforced by the caller */
1196+ if (!ch -> rx_count || !ch -> tx_count )
1197+ return - EINVAL ;
1198+
1199+ /* avoid braking XDP, if that is enabled */
1200+ peer = rtnl_dereference (priv -> peer );
1201+ peer_priv = peer ? netdev_priv (peer ) : NULL ;
1202+ if (priv -> _xdp_prog && peer && ch -> rx_count < peer -> real_num_tx_queues )
1203+ return - EINVAL ;
1204+
1205+ if (peer && peer_priv && peer_priv -> _xdp_prog && ch -> tx_count > peer -> real_num_rx_queues )
1206+ return - EINVAL ;
1207+
1208+ old_rx_count = dev -> real_num_rx_queues ;
1209+ new_rx_count = ch -> rx_count ;
1210+ if (netif_running (dev )) {
1211+ /* turn device off */
1212+ netif_carrier_off (dev );
1213+ if (peer )
1214+ netif_carrier_off (peer );
1215+
1216+ /* try to allocate new resurces, as needed*/
1217+ err = veth_enable_range_safe (dev , old_rx_count , new_rx_count );
1218+ if (err )
1219+ goto out ;
1220+ }
1221+
1222+ err = netif_set_real_num_rx_queues (dev , ch -> rx_count );
1223+ if (err )
1224+ goto revert ;
1225+
1226+ err = netif_set_real_num_tx_queues (dev , ch -> tx_count );
1227+ if (err ) {
1228+ int err2 = netif_set_real_num_rx_queues (dev , old_rx_count );
1229+
1230+ /* this error condition could happen only if rx and tx change
1231+ * in opposite directions (e.g. tx nr raises, rx nr decreases)
1232+ * and we can't do anything to fully restore the original
1233+ * status
1234+ */
1235+ if (err2 )
1236+ pr_warn ("Can't restore rx queues config %d -> %d %d" ,
1237+ new_rx_count , old_rx_count , err2 );
1238+ else
1239+ goto revert ;
1240+ }
1241+
1242+ out :
1243+ if (netif_running (dev )) {
1244+ /* note that we need to swap the arguments WRT the enable part
1245+ * to identify the range we have to disable
1246+ */
1247+ veth_disable_range_safe (dev , new_rx_count , old_rx_count );
1248+ netif_carrier_on (dev );
1249+ if (peer )
1250+ netif_carrier_on (peer );
1251+ }
1252+ return err ;
1253+
1254+ revert :
1255+ new_rx_count = old_rx_count ;
1256+ old_rx_count = ch -> rx_count ;
1257+ goto out ;
1258+ }
1259+
11391260static int veth_open (struct net_device * dev )
11401261{
11411262 struct veth_priv * priv = netdev_priv (dev );
0 commit comments