@@ -1119,10 +1119,14 @@ static void veth_disable_xdp_range(struct net_device *dev, int start, int end,
11191119
11201120static int veth_enable_xdp (struct net_device * dev )
11211121{
1122- bool napi_already_on = veth_gro_requested (dev ) && (dev -> flags & IFF_UP );
11231122 struct veth_priv * priv = netdev_priv (dev );
1123+ bool napi_already_on ;
1124+ struct veth_rq * rq ;
11241125 int err , i ;
11251126
1127+ rq = & priv -> rq [0 ];
1128+ napi_already_on = (dev -> flags & IFF_UP ) && rcu_access_pointer (rq -> napi );
1129+
11261130 if (!xdp_rxq_info_is_reg (& priv -> rq [0 ].xdp_rxq )) {
11271131 err = veth_enable_xdp_range (dev , 0 , dev -> real_num_rx_queues , napi_already_on );
11281132 if (err )
@@ -1323,18 +1327,28 @@ static int veth_set_channels(struct net_device *dev,
13231327
13241328static int veth_open (struct net_device * dev )
13251329{
1326- struct veth_priv * priv = netdev_priv (dev );
1330+ struct veth_priv * peer_priv , * priv = netdev_priv (dev );
13271331 struct net_device * peer = rtnl_dereference (priv -> peer );
1332+ struct veth_rq * peer_rq ;
13281333 int err ;
13291334
13301335 if (!peer )
13311336 return - ENOTCONN ;
13321337
1338+ peer_priv = netdev_priv (peer );
1339+ peer_rq = & peer_priv -> rq [0 ];
1340+
13331341 if (priv -> _xdp_prog ) {
13341342 err = veth_enable_xdp (dev );
13351343 if (err )
13361344 return err ;
1337- } else if (veth_gro_requested (dev )) {
1345+ /* refer to the logic in veth_xdp_set() */
1346+ if (!rtnl_dereference (peer_rq -> napi )) {
1347+ err = veth_napi_enable (peer );
1348+ if (err )
1349+ return err ;
1350+ }
1351+ } else if (veth_gro_requested (dev ) || peer_priv -> _xdp_prog ) {
13381352 err = veth_napi_enable (dev );
13391353 if (err )
13401354 return err ;
@@ -1350,17 +1364,29 @@ static int veth_open(struct net_device *dev)
13501364
13511365static int veth_close (struct net_device * dev )
13521366{
1353- struct veth_priv * priv = netdev_priv (dev );
1367+ struct veth_priv * peer_priv , * priv = netdev_priv (dev );
13541368 struct net_device * peer = rtnl_dereference (priv -> peer );
1369+ struct veth_rq * peer_rq ;
13551370
13561371 netif_carrier_off (dev );
1357- if (peer )
1358- netif_carrier_off (peer );
1372+ if (peer ) {
1373+ peer_priv = netdev_priv (peer );
1374+ peer_rq = & peer_priv -> rq [0 ];
1375+ }
13591376
1360- if (priv -> _xdp_prog )
1377+ if (priv -> _xdp_prog ) {
13611378 veth_disable_xdp (dev );
1362- else if (veth_gro_requested (dev ))
1379+ /* refer to the logic in veth_xdp_set */
1380+ if (peer && rtnl_dereference (peer_rq -> napi )) {
1381+ if (!veth_gro_requested (peer ) && !peer_priv -> _xdp_prog )
1382+ veth_napi_del (peer );
1383+ }
1384+ } else if (veth_gro_requested (dev ) || (peer && peer_priv -> _xdp_prog )) {
13631385 veth_napi_del (dev );
1386+ }
1387+
1388+ if (peer )
1389+ netif_carrier_off (peer );
13641390
13651391 return 0 ;
13661392}
@@ -1470,17 +1496,21 @@ static int veth_set_features(struct net_device *dev,
14701496{
14711497 netdev_features_t changed = features ^ dev -> features ;
14721498 struct veth_priv * priv = netdev_priv (dev );
1499+ struct veth_rq * rq = & priv -> rq [0 ];
14731500 int err ;
14741501
14751502 if (!(changed & NETIF_F_GRO ) || !(dev -> flags & IFF_UP ) || priv -> _xdp_prog )
14761503 return 0 ;
14771504
14781505 if (features & NETIF_F_GRO ) {
1479- err = veth_napi_enable (dev );
1480- if (err )
1481- return err ;
1506+ if (!rtnl_dereference (rq -> napi )) {
1507+ err = veth_napi_enable (dev );
1508+ if (err )
1509+ return err ;
1510+ }
14821511 } else {
1483- veth_napi_del (dev );
1512+ if (rtnl_dereference (rq -> napi ))
1513+ veth_napi_del (dev );
14841514 }
14851515 return 0 ;
14861516}
@@ -1512,14 +1542,19 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15121542 struct netlink_ext_ack * extack )
15131543{
15141544 struct veth_priv * priv = netdev_priv (dev );
1545+ struct veth_priv * peer_priv ;
15151546 struct bpf_prog * old_prog ;
1547+ struct veth_rq * peer_rq ;
15161548 struct net_device * peer ;
1549+ bool napi_already_off ;
15171550 unsigned int max_mtu ;
1551+ bool noreq_napi ;
15181552 int err ;
15191553
15201554 old_prog = priv -> _xdp_prog ;
15211555 priv -> _xdp_prog = prog ;
15221556 peer = rtnl_dereference (priv -> peer );
1557+ peer_priv = netdev_priv (peer );
15231558
15241559 if (prog ) {
15251560 if (!peer ) {
@@ -1556,6 +1591,24 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15561591 }
15571592 }
15581593
1594+ if (peer && (peer -> flags & IFF_UP )) {
1595+ peer_rq = & peer_priv -> rq [0 ];
1596+
1597+ /* If the peer hasn't enabled GRO and loaded xdp,
1598+ * then we enable napi automatically if its napi
1599+ * is not ready.
1600+ */
1601+ napi_already_off = !rtnl_dereference (peer_rq -> napi );
1602+ if (napi_already_off ) {
1603+ err = veth_napi_enable (peer );
1604+ if (err ) {
1605+ NL_SET_ERR_MSG_MOD (extack ,
1606+ "Failed to automatically enable napi of peer" );
1607+ goto err ;
1608+ }
1609+ }
1610+ }
1611+
15591612 if (!old_prog ) {
15601613 peer -> hw_features &= ~NETIF_F_GSO_SOFTWARE ;
15611614 peer -> max_mtu = max_mtu ;
@@ -1570,6 +1623,17 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
15701623 if (peer ) {
15711624 peer -> hw_features |= NETIF_F_GSO_SOFTWARE ;
15721625 peer -> max_mtu = ETH_MAX_MTU ;
1626+ peer_rq = & peer_priv -> rq [0 ];
1627+
1628+ /* If the peer doesn't has its xdp and enabled
1629+ * GRO, then we disable napi if its napi is ready;
1630+ */
1631+ if (rtnl_dereference (peer_rq -> napi )) {
1632+ noreq_napi = !veth_gro_requested (peer ) &&
1633+ !peer_priv -> _xdp_prog ;
1634+ if (noreq_napi && (peer -> flags & IFF_UP ))
1635+ veth_napi_del (peer );
1636+ }
15731637 }
15741638 }
15751639 bpf_prog_put (old_prog );
0 commit comments