Merge tag 'net-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Mar 2024 21:50:39 +0000 (14:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Mar 2024 21:50:39 +0000 (14:50 -0700)
Pull networking fixes from Jakub Kicinski:
 "Including fixes from CAN, netfilter, wireguard and IPsec.

  I'd like to highlight [ lowlight? - Linus ] Florian W stepping down as
  a netfilter maintainer due to constant stream of bug reports. Not sure
  what we can do but IIUC this is not the first such case.

  Current release - regressions:

   - rxrpc: fix use of page_frag_alloc_align(), it changed semantics and
     we added a new caller in a different subtree

   - xfrm: allow UDP encapsulation only in offload modes

  Current release - new code bugs:

   - tcp: fix refcnt handling in __inet_hash_connect()

   - Revert "net: Re-use and set mono_delivery_time bit for userspace
     tstamp packets", conflicted with some expectations in BPF uAPI

  Previous releases - regressions:

   - ipv4: raw: fix sending packets from raw sockets via IPsec tunnels

   - devlink: fix devlink's parallel command processing

   - veth: do not manipulate GRO when using XDP

   - esp: fix bad handling of pages from page_pool

  Previous releases - always broken:

   - report RCU QS for busy network kthreads (with Paul McK's blessing)

   - tcp/rds: fix use-after-free on netns with kernel TCP reqsk

   - virt: vmxnet3: fix missing reserved tailroom with XDP

  Misc:

   - couple of build fixes for Documentation"

* tag 'net-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (59 commits)
  selftests: forwarding: Fix ping failure due to short timeout
  MAINTAINERS: step down as netfilter maintainer
  netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
  net: dsa: mt7530: fix handling of all link-local frames
  net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports
  bpf: report RCU QS in cpumap kthread
  net: report RCU QS on threaded NAPI repolling
  rcu: add a helper to report consolidated flavor QS
  ionic: update documentation for XDP support
  lib/bitmap: Fix bitmap_scatter() and bitmap_gather() kernel doc
  netfilter: nf_tables: do not compare internal table flags on updates
  netfilter: nft_set_pipapo: release elements in clone only from destroy path
  octeontx2-af: Use separate handlers for interrupts
  octeontx2-pf: Send UP messages to VF only when VF is up.
  octeontx2-pf: Use default max_active works instead of one
  octeontx2-pf: Wait till detach_resources msg is complete
  octeontx2: Detect the mbox up or down message via register
  devlink: fix port new reply cmd type
  tcp: Clear req->syncookie in reqsk_alloc().
  net/bnx2x: Prevent access to a freed page in page_pool
  ...

71 files changed:
Documentation/networking/device_drivers/ethernet/pensando/ionic.rst
Documentation/networking/multi-pf-netdev.rst
Documentation/networking/net_cachelines/net_device.rst
MAINTAINERS
drivers/net/can/kvaser_pciefd.c
drivers/net/dsa/mt7530.c
drivers/net/dsa/mt7530.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/marvell/octeontx2/af/mbox.c
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mediatek/mtk_ppe.c
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
drivers/net/phy/phy_device.c
drivers/net/veth.c
drivers/net/vmxnet3/vmxnet3_xdp.c
drivers/net/wan/fsl_qmc_hdlc.c
drivers/net/wireguard/device.c
drivers/net/wireguard/netlink.c
drivers/net/wireguard/receive.c
drivers/soc/fsl/qbman/qman.c
include/linux/bitmap.h
include/linux/netdevice.h
include/linux/rcupdate.h
include/linux/skbuff.h
include/linux/socket.h
include/net/request_sock.h
kernel/bpf/cpumap.c
net/core/dev.c
net/devlink/netlink.c
net/devlink/port.c
net/hsr/hsr_framereg.c
net/hsr/hsr_main.c
net/ipv4/esp4.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_output.c
net/ipv4/raw.c
net/ipv4/syncookies.c
net/ipv4/tcp_minisocks.c
net/ipv6/esp6.c
net/ipv6/ip6_output.c
net/ipv6/raw.c
net/ipv6/syncookies.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_pipapo.c
net/packet/af_packet.c
net/rds/send.c
net/rxrpc/sendmsg.c
net/rxrpc/txbuf.c
net/sched/sch_fq_pie.c
net/sched/sch_taprio.c
net/socket.c
net/xfrm/xfrm_device.c
tools/net/ynl/Makefile.deps
tools/perf/trace/beauty/include/linux/socket.h
tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh
tools/testing/selftests/net/udpgro_fwd.sh
tools/testing/selftests/net/veth.sh
tools/testing/selftests/wireguard/qemu/arch/riscv32.config
tools/testing/selftests/wireguard/qemu/arch/riscv64.config

index 6ec7d686efab04546045a3ccfe0a2d096a2d89b5..05fe2b11bb18834cade782b1426f7c2991de42b8 100644 (file)
@@ -99,6 +99,12 @@ Minimal SR-IOV support is currently offered and can be enabled by setting
 the sysfs 'sriov_numvfs' value, if supported by your particular firmware
 configuration.
 
+XDP
+---
+
+Support for XDP includes the basics, plus Jumbo frames, Redirect and
+ndo_xmit.  There is no current support for zero-copy sockets or HW offload.
+
 Statistics
 ==========
 
@@ -138,6 +144,12 @@ Driver port specific::
      rx_csum_none: 0
      rx_csum_complete: 3
      rx_csum_error: 0
+     xdp_drop: 0
+     xdp_aborted: 0
+     xdp_pass: 0
+     xdp_tx: 0
+     xdp_redirect: 0
+     xdp_frames: 0
 
 Driver queue specific::
 
@@ -149,9 +161,12 @@ Driver queue specific::
      tx_0_frags: 0
      tx_0_tso: 0
      tx_0_tso_bytes: 0
+     tx_0_hwstamp_valid: 0
+     tx_0_hwstamp_invalid: 0
      tx_0_csum_none: 3
      tx_0_csum: 0
      tx_0_vlan_inserted: 0
+     tx_0_xdp_frames: 0
      rx_0_pkts: 2
      rx_0_bytes: 120
      rx_0_dma_map_err: 0
@@ -159,8 +174,15 @@ Driver queue specific::
      rx_0_csum_none: 0
      rx_0_csum_complete: 0
      rx_0_csum_error: 0
+     rx_0_hwstamp_valid: 0
+     rx_0_hwstamp_invalid: 0
      rx_0_dropped: 0
      rx_0_vlan_stripped: 0
+     rx_0_xdp_drop: 0
+     rx_0_xdp_aborted: 0
+     rx_0_xdp_pass: 0
+     rx_0_xdp_tx: 0
+     rx_0_xdp_redirect: 0
 
 Firmware port specific::
 
index be8e4bcadf119021496fc98db04c5c77cd24b39f..268819225866cb1a023470ad3017026394ac7f89 100644 (file)
@@ -87,35 +87,35 @@ all using the same instance under "priv->mdev".
 
 Observability
 =============
-The relation between PF, irq, napi, and queue can be observed via netlink spec:
-
-$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
-[{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'},
- {'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'},
- {'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'},
- {'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'rx'},
- {'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'rx'},
- {'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'tx'},
- {'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'tx'},
- {'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'tx'},
- {'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'},
- {'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}]
-
-$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
-[{'id': 543, 'ifindex': 13, 'irq': 42},
- {'id': 542, 'ifindex': 13, 'irq': 41},
- {'id': 541, 'ifindex': 13, 'irq': 40},
- {'id': 540, 'ifindex': 13, 'irq': 39},
- {'id': 539, 'ifindex': 13, 'irq': 36}]
-
-Here you can clearly observe our channels distribution policy:
-
-$ ls /proc/irq/{36,39,40,41,42}/mlx5* -d -1
-/proc/irq/36/mlx5_comp1@pci:0000:08:00.0
-/proc/irq/39/mlx5_comp1@pci:0000:09:00.0
-/proc/irq/40/mlx5_comp2@pci:0000:08:00.0
-/proc/irq/41/mlx5_comp2@pci:0000:09:00.0
-/proc/irq/42/mlx5_comp3@pci:0000:08:00.0
+The relation between PF, irq, napi, and queue can be observed via netlink spec::
+
+  $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}'
+  [{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'},
  {'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'},
  {'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'},
  {'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'rx'},
  {'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'rx'},
  {'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'tx'},
  {'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'tx'},
  {'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'tx'},
  {'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'},
  {'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}]
+
+  $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}'
+  [{'id': 543, 'ifindex': 13, 'irq': 42},
  {'id': 542, 'ifindex': 13, 'irq': 41},
  {'id': 541, 'ifindex': 13, 'irq': 40},
  {'id': 540, 'ifindex': 13, 'irq': 39},
  {'id': 539, 'ifindex': 13, 'irq': 36}]
+
+Here you can clearly observe our channels distribution policy::
+
+  $ ls /proc/irq/{36,39,40,41,42}/mlx5* -d -1
+  /proc/irq/36/mlx5_comp1@pci:0000:08:00.0
+  /proc/irq/39/mlx5_comp1@pci:0000:09:00.0
+  /proc/irq/40/mlx5_comp2@pci:0000:08:00.0
+  /proc/irq/41/mlx5_comp2@pci:0000:09:00.0
+  /proc/irq/42/mlx5_comp3@pci:0000:08:00.0
 
 Steering
 ========
index dceb49d56a91158232543e920c7ed23bed74106e..70c4fb9d4e5ce0feb0d82578b878da3dbd00a7fb 100644 (file)
@@ -13,7 +13,7 @@ struct_dev_ifalias*                 ifalias
 unsigned_long                       mem_end                                                         
 unsigned_long                       mem_start                                                       
 unsigned_long                       base_addr                                                       
-unsigned_long                       state                                                           
+unsigned_long                       state                   read_mostly         read_mostly         netif_running(dev)
 struct_list_head                    dev_list                                                        
 struct_list_head                    napi_list                                                       
 struct_list_head                    unreg_list                                                      
index 5b251bcc91f0138fc169c6063516f197e3f5d18f..f736af98d7b591fa0711c7b18ad3a882748b53e1 100644 (file)
@@ -15237,7 +15237,6 @@ F:      drivers/net/ethernet/neterion/
 NETFILTER
 M:     Pablo Neira Ayuso <pablo@netfilter.org>
 M:     Jozsef Kadlecsik <kadlec@netfilter.org>
-M:     Florian Westphal <fw@strlen.de>
 L:     netfilter-devel@vger.kernel.org
 L:     coreteam@netfilter.org
 S:     Maintained
index f81b598147b3062b453a246f27032c23f9e0d2cb..7b5028b67cd5cb56943c86c946f14d838b25b531 100644 (file)
@@ -370,8 +370,8 @@ static const struct kvaser_pciefd_irq_mask kvaser_pciefd_sf2_irq_mask = {
 
 static const struct kvaser_pciefd_irq_mask kvaser_pciefd_xilinx_irq_mask = {
        .kcan_rx0 = BIT(4),
-       .kcan_tx = { BIT(16), BIT(17), BIT(18), BIT(19) },
-       .all = GENMASK(19, 16) | BIT(4),
+       .kcan_tx = { BIT(16), BIT(17), BIT(18), BIT(19), BIT(20), BIT(21), BIT(22), BIT(23) },
+       .all = GENMASK(23, 16) | BIT(4),
 };
 
 static const struct kvaser_pciefd_dev_ops kvaser_pciefd_altera_dev_ops = {
index 678b51f9cea61512641b1b4c14891b57b5d6434a..767f66c37f6b5cf63db379232af407b9813428a1 100644 (file)
@@ -950,20 +950,56 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
        mutex_unlock(&priv->reg_mutex);
 }
 
+/* On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE Std
+ * 802.1Qâ„¢-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC DA
+ * must only be propagated to C-VLAN and MAC Bridge components. That means
+ * VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports,
+ * these frames are supposed to be processed by the CPU (software). So we make
+ * the switch only forward them to the CPU port. And if received from a CPU
+ * port, forward to a single port. The software is responsible of making the
+ * switch conform to the latter by setting a single port as destination port on
+ * the special tag.
+ *
+ * This switch intellectual property cannot conform to this part of the standard
+ * fully. Whilst the REV_UN frame tag covers the remaining :04-0D and :0F MAC
+ * DAs, it also includes :22-FF which the scope of propagation is not supposed
+ * to be restricted for these MAC DAs.
+ */
 static void
 mt753x_trap_frames(struct mt7530_priv *priv)
 {
-       /* Trap BPDUs to the CPU port(s) */
-       mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
+       /* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them
+        * VLAN-untagged.
+        */
+       mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_EG_TAG_MASK |
+                  MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
+                  MT753X_BPDU_PORT_FW_MASK,
+                  MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+                  MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
                   MT753X_BPDU_CPU_ONLY);
 
-       /* Trap 802.1X PAE frames to the CPU port(s) */
-       mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK,
-                  MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY));
+       /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       mt7530_rmw(priv, MT753X_RGAC1, MT753X_R02_EG_TAG_MASK |
+                  MT753X_R02_PORT_FW_MASK | MT753X_R01_EG_TAG_MASK |
+                  MT753X_R01_PORT_FW_MASK,
+                  MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+                  MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_BPDU_CPU_ONLY);
 
-       /* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
-       mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
-                  MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
+       /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_EG_TAG_MASK |
+                  MT753X_R0E_PORT_FW_MASK | MT753X_R03_EG_TAG_MASK |
+                  MT753X_R03_PORT_FW_MASK,
+                  MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+                  MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+                  MT753X_BPDU_CPU_ONLY);
 }
 
 static void
@@ -2192,22 +2228,16 @@ mt7530_setup(struct dsa_switch *ds)
                }
        }
 
-       /* Disable LEDs before reset to prevent the MT7530 sampling a
-        * potentially incorrect HT_XTAL_FSEL value.
-        */
-       mt7530_write(priv, MT7530_LED_EN, 0);
-       usleep_range(1000, 1100);
-
        /* Reset whole chip through gpio pin or memory-mapped registers for
         * different type of hardware
         */
        if (priv->mcm) {
                reset_control_assert(priv->rstc);
-               usleep_range(1000, 1100);
+               usleep_range(5000, 5100);
                reset_control_deassert(priv->rstc);
        } else {
                gpiod_set_value_cansleep(priv->reset, 0);
-               usleep_range(1000, 1100);
+               usleep_range(5000, 5100);
                gpiod_set_value_cansleep(priv->reset, 1);
        }
 
@@ -2420,11 +2450,11 @@ mt7531_setup(struct dsa_switch *ds)
         */
        if (priv->mcm) {
                reset_control_assert(priv->rstc);
-               usleep_range(1000, 1100);
+               usleep_range(5000, 5100);
                reset_control_deassert(priv->rstc);
        } else {
                gpiod_set_value_cansleep(priv->reset, 0);
-               usleep_range(1000, 1100);
+               usleep_range(5000, 5100);
                gpiod_set_value_cansleep(priv->reset, 1);
        }
 
index a71166e0a7fcf2411292bc713f0bcbd75c2db32c..d17b318e6ee4882ed8b6f6668eaa57a99a38d184 100644 (file)
@@ -65,14 +65,33 @@ enum mt753x_id {
 
 /* Registers for BPDU and PAE frame control*/
 #define MT753X_BPC                     0x24
-#define  MT753X_BPDU_PORT_FW_MASK      GENMASK(2, 0)
+#define  MT753X_PAE_EG_TAG_MASK                GENMASK(24, 22)
+#define  MT753X_PAE_EG_TAG(x)          FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
 #define  MT753X_PAE_PORT_FW_MASK       GENMASK(18, 16)
 #define  MT753X_PAE_PORT_FW(x)         FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
+#define  MT753X_BPDU_EG_TAG_MASK       GENMASK(8, 6)
+#define  MT753X_BPDU_EG_TAG(x)         FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
+#define  MT753X_BPDU_PORT_FW_MASK      GENMASK(2, 0)
+
+/* Register for :01 and :02 MAC DA frame control */
+#define MT753X_RGAC1                   0x28
+#define  MT753X_R02_EG_TAG_MASK                GENMASK(24, 22)
+#define  MT753X_R02_EG_TAG(x)          FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
+#define  MT753X_R02_PORT_FW_MASK       GENMASK(18, 16)
+#define  MT753X_R02_PORT_FW(x)         FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
+#define  MT753X_R01_EG_TAG_MASK                GENMASK(8, 6)
+#define  MT753X_R01_EG_TAG(x)          FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
+#define  MT753X_R01_PORT_FW_MASK       GENMASK(2, 0)
 
 /* Register for :03 and :0E MAC DA frame control */
 #define MT753X_RGAC2                   0x2c
+#define  MT753X_R0E_EG_TAG_MASK                GENMASK(24, 22)
+#define  MT753X_R0E_EG_TAG(x)          FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
 #define  MT753X_R0E_PORT_FW_MASK       GENMASK(18, 16)
 #define  MT753X_R0E_PORT_FW(x)         FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
+#define  MT753X_R03_EG_TAG_MASK                GENMASK(8, 6)
+#define  MT753X_R03_EG_TAG(x)          FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
+#define  MT753X_R03_PORT_FW_MASK       GENMASK(2, 0)
 
 enum mt753x_bpdu_port_fw {
        MT753X_BPDU_FOLLOW_MFC,
@@ -253,6 +272,7 @@ enum mt7530_port_mode {
 enum mt7530_vlan_port_eg_tag {
        MT7530_VLAN_EG_DISABLED = 0,
        MT7530_VLAN_EG_CONSISTENT = 1,
+       MT7530_VLAN_EG_UNTAGGED = 4,
 };
 
 enum mt7530_vlan_port_attr {
index d8b1824c334d3b0d7b515b8f5dd11aa34190a909..0bc1367fd64924b2338cf6c1483f8b80119ee421 100644 (file)
@@ -1002,9 +1002,6 @@ static inline void bnx2x_set_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid,
 static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp,
                                          struct bnx2x_alloc_pool *pool)
 {
-       if (!pool->page)
-               return;
-
        put_page(pool->page);
 
        pool->page = NULL;
@@ -1015,6 +1012,9 @@ static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
 {
        int i;
 
+       if (!fp->page_pool.page)
+               return;
+
        if (fp->mode == TPA_MODE_DISABLED)
                return;
 
index 6c70c849869043602c2a02e7898f981fc11c5925..3c0f55b3e48ea402959df74c28637a9ca169a382 100644 (file)
@@ -1338,7 +1338,7 @@ static irqreturn_t cgx_fwi_event_handler(int irq, void *data)
 
                /* Release thread waiting for completion  */
                lmac->cmd_pend = false;
-               wake_up_interruptible(&lmac->wq_cmd_cmplt);
+               wake_up(&lmac->wq_cmd_cmplt);
                break;
        case CGX_EVT_ASYNC:
                if (cgx_event_is_linkevent(event))
index b92264d0a77e71075495f5cc0e02c330e3c279bd..1e5aa539750404e14ba40c7581218a2541efce00 100644 (file)
@@ -214,11 +214,12 @@ int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid)
 }
 EXPORT_SYMBOL(otx2_mbox_busy_poll_for_rsp);
 
-void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
+static void otx2_mbox_msg_send_data(struct otx2_mbox *mbox, int devid, u64 data)
 {
        struct otx2_mbox_dev *mdev = &mbox->dev[devid];
        struct mbox_hdr *tx_hdr, *rx_hdr;
        void *hw_mbase = mdev->hwbase;
+       u64 intr_val;
 
        tx_hdr = hw_mbase + mbox->tx_start;
        rx_hdr = hw_mbase + mbox->rx_start;
@@ -254,14 +255,52 @@ void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
 
        spin_unlock(&mdev->mbox_lock);
 
+       /* Check if interrupt pending */
+       intr_val = readq((void __iomem *)mbox->reg_base +
+                    (mbox->trigger | (devid << mbox->tr_shift)));
+
+       intr_val |= data;
        /* The interrupt should be fired after num_msgs is written
         * to the shared memory
         */
-       writeq(1, (void __iomem *)mbox->reg_base +
+       writeq(intr_val, (void __iomem *)mbox->reg_base +
               (mbox->trigger | (devid << mbox->tr_shift)));
 }
+
+void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
+{
+       otx2_mbox_msg_send_data(mbox, devid, MBOX_DOWN_MSG);
+}
 EXPORT_SYMBOL(otx2_mbox_msg_send);
 
+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid)
+{
+       otx2_mbox_msg_send_data(mbox, devid, MBOX_UP_MSG);
+}
+EXPORT_SYMBOL(otx2_mbox_msg_send_up);
+
+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid)
+{
+       u64 data;
+
+       data = readq((void __iomem *)mbox->reg_base +
+                    (mbox->trigger | (devid << mbox->tr_shift)));
+
+       /* If data is non-zero wait for ~1ms and return to caller
+        * whether data has changed to zero or not after the wait.
+        */
+       if (!data)
+               return true;
+
+       usleep_range(950, 1000);
+
+       data = readq((void __iomem *)mbox->reg_base +
+                    (mbox->trigger | (devid << mbox->tr_shift)));
+
+       return data == 0;
+}
+EXPORT_SYMBOL(otx2_mbox_wait_for_zero);
+
 struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
                                            int size, int size_rsp)
 {
index 61ab7f66f053cca307f77fa94302c8453818aef6..eb2a20b5a0d0c6c9cb15cbfcf98a45f253eb12fc 100644 (file)
@@ -16,6 +16,9 @@
 
 #define MBOX_SIZE              SZ_64K
 
+#define MBOX_DOWN_MSG          1
+#define MBOX_UP_MSG            2
+
 /* AF/PF: PF initiated, PF/VF VF initiated */
 #define MBOX_DOWN_RX_START     0
 #define MBOX_DOWN_RX_SIZE      (46 * SZ_1K)
@@ -101,6 +104,7 @@ int otx2_mbox_regions_init(struct otx2_mbox *mbox, void __force **hwbase,
                           struct pci_dev *pdev, void __force *reg_base,
                           int direction, int ndevs, unsigned long *bmap);
 void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid);
 int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
 int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid);
 struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
@@ -118,6 +122,8 @@ static inline struct mbox_msghdr *otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
        return otx2_mbox_alloc_msg_rsp(mbox, devid, size, 0);
 }
 
+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid);
+
 /* Mailbox message types */
 #define MBOX_MSG_MASK                          0xFFFF
 #define MBOX_MSG_INVALID                       0xFFFE
index dfd23580e3b8e1fc88e3597e3eaf04832ad18dc7..d39d86e694ccf7530237a904315a294726cf55f8 100644 (file)
@@ -121,13 +121,17 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event)
 static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
 {
        struct mcs_intr_info *req;
-       int err, pf;
+       int pf;
 
        pf = rvu_get_pf(event->pcifunc);
 
+       mutex_lock(&rvu->mbox_lock);
+
        req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf);
-       if (!req)
+       if (!req) {
+               mutex_unlock(&rvu->mbox_lock);
                return -ENOMEM;
+       }
 
        req->mcs_id = event->mcs_id;
        req->intr_mask = event->intr_mask;
@@ -135,10 +139,11 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
        req->hdr.pcifunc = event->pcifunc;
        req->lmac_id = event->lmac_id;
 
-       otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pf);
-       err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
-       if (err)
-               dev_warn(rvu->dev, "MCS notification to pf %d failed\n", pf);
+       otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
+
+       otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
+
+       mutex_unlock(&rvu->mbox_lock);
 
        return 0;
 }
index 07d4859de53ade0a68ff5fedaed22ec9640e8f96..ff78251f92d4480a72f9c1ce0c268bf8aaa76f4f 100644 (file)
@@ -2119,7 +2119,7 @@ bad_message:
        }
 }
 
-static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
+static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
 {
        struct rvu *rvu = mwork->rvu;
        int offset, err, id, devid;
@@ -2186,6 +2186,9 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
        }
        mw->mbox_wrk[devid].num_msgs = 0;
 
+       if (poll)
+               otx2_mbox_wait_for_zero(mbox, devid);
+
        /* Send mbox responses to VF/PF */
        otx2_mbox_msg_send(mbox, devid);
 }
@@ -2193,15 +2196,18 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
 static inline void rvu_afpf_mbox_handler(struct work_struct *work)
 {
        struct rvu_work *mwork = container_of(work, struct rvu_work, work);
+       struct rvu *rvu = mwork->rvu;
 
-       __rvu_mbox_handler(mwork, TYPE_AFPF);
+       mutex_lock(&rvu->mbox_lock);
+       __rvu_mbox_handler(mwork, TYPE_AFPF, true);
+       mutex_unlock(&rvu->mbox_lock);
 }
 
 static inline void rvu_afvf_mbox_handler(struct work_struct *work)
 {
        struct rvu_work *mwork = container_of(work, struct rvu_work, work);
 
-       __rvu_mbox_handler(mwork, TYPE_AFVF);
+       __rvu_mbox_handler(mwork, TYPE_AFVF, false);
 }
 
 static void __rvu_mbox_up_handler(struct rvu_work *mwork, int type)
@@ -2376,6 +2382,8 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw,
                }
        }
 
+       mutex_init(&rvu->mbox_lock);
+
        mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
        if (!mbox_regions) {
                err = -ENOMEM;
@@ -2525,10 +2533,9 @@ static void rvu_queue_work(struct mbox_wq_info *mw, int first,
        }
 }
 
-static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq)
 {
        struct rvu *rvu = (struct rvu *)rvu_irq;
-       int vfs = rvu->vfs;
        u64 intr;
 
        intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT);
@@ -2542,6 +2549,18 @@ static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
 
        rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr);
 
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+{
+       struct rvu *rvu = (struct rvu *)rvu_irq;
+       int vfs = rvu->vfs;
+       u64 intr;
+
+       /* Sync with mbox memory region */
+       rmb();
+
        /* Handle VF interrupts */
        if (vfs > 64) {
                intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1));
@@ -2886,7 +2905,7 @@ static int rvu_register_interrupts(struct rvu *rvu)
        /* Register mailbox interrupt handler */
        sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox");
        ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX),
-                         rvu_mbox_intr_handler, 0,
+                         rvu_mbox_pf_intr_handler, 0,
                          &rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu);
        if (ret) {
                dev_err(rvu->dev,
index f390525a621772924a83460802840f442cc553d7..35834687e40fe9877f5f575ee17f0ead42ee3726 100644 (file)
@@ -591,6 +591,8 @@ struct rvu {
        spinlock_t              mcs_intrq_lock;
        /* CPT interrupt lock */
        spinlock_t              cpt_intr_lock;
+
+       struct mutex            mbox_lock; /* Serialize mbox up and down msgs */
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
index 38acdc7a73bbec54a8e158e707b3b2d2952898f2..72e060cf6b6181d9ccd22b2f3a126c6b7f063a83 100644 (file)
@@ -232,7 +232,7 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
        struct cgx_link_user_info *linfo;
        struct cgx_link_info_msg *msg;
        unsigned long pfmap;
-       int err, pfid;
+       int pfid;
 
        linfo = &event->link_uinfo;
        pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id);
@@ -255,16 +255,22 @@ static void cgx_notify_pfs(struct cgx_link_event *event, struct rvu *rvu)
                        continue;
                }
 
+               mutex_lock(&rvu->mbox_lock);
+
                /* Send mbox message to PF */
                msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid);
-               if (!msg)
+               if (!msg) {
+                       mutex_unlock(&rvu->mbox_lock);
                        continue;
+               }
+
                msg->link_info = *linfo;
-               otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid);
-               err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
-               if (err)
-                       dev_warn(rvu->dev, "notification to pf %d failed\n",
-                                pfid);
+
+               otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pfid);
+
+               otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pfid);
+
+               mutex_unlock(&rvu->mbox_lock);
        } while (pfmap);
 }
 
index 02d0b707aea5bd6b9dea286180914b5aaba4a51d..a85ac039d779be0681b7339c291cf02a616d1d37 100644 (file)
@@ -1592,7 +1592,7 @@ int otx2_detach_resources(struct mbox *mbox)
        detach->partial = false;
 
        /* Send detach request to AF */
-       otx2_mbox_msg_send(&mbox->mbox, 0);
+       otx2_sync_mbox_msg(mbox);
        mutex_unlock(&mbox->lock);
        return 0;
 }
index 06910307085efa83cc386e8e180805bef0ee539e..7e16a341ec588f2818154827cf7a08cbe9d256a9 100644 (file)
@@ -815,7 +815,7 @@ static inline int otx2_sync_mbox_up_msg(struct mbox *mbox, int devid)
 
        if (!otx2_mbox_nonempty(&mbox->mbox_up, devid))
                return 0;
-       otx2_mbox_msg_send(&mbox->mbox_up, devid);
+       otx2_mbox_msg_send_up(&mbox->mbox_up, devid);
        err = otx2_mbox_wait_for_rsp(&mbox->mbox_up, devid);
        if (err)
                return err;
index e5fe67e7386551e321949dc3b42074067eb4b3a9..b40bd0e467514848fee22f1e32f86cb4c9d129c3 100644 (file)
@@ -292,8 +292,8 @@ static int otx2_pf_flr_init(struct otx2_nic *pf, int num_vfs)
        return 0;
 }
 
-static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
-                           int first, int mdevs, u64 intr, int type)
+static void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
+                              int first, int mdevs, u64 intr)
 {
        struct otx2_mbox_dev *mdev;
        struct otx2_mbox *mbox;
@@ -307,40 +307,26 @@ static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
 
                mbox = &mw->mbox;
                mdev = &mbox->dev[i];
-               if (type == TYPE_PFAF)
-                       otx2_sync_mbox_bbuf(mbox, i);
                hdr = mdev->mbase + mbox->rx_start;
                /* The hdr->num_msgs is set to zero immediately in the interrupt
-                * handler to  ensure that it holds a correct value next time
-                * when the interrupt handler is called.
-                * pf->mbox.num_msgs holds the data for use in pfaf_mbox_handler
-                * pf>mbox.up_num_msgs holds the data for use in
-                * pfaf_mbox_up_handler.
+                * handler to ensure that it holds a correct value next time
+                * when the interrupt handler is called. pf->mw[i].num_msgs
+                * holds the data for use in otx2_pfvf_mbox_handler and
+                * pf->mw[i].up_num_msgs holds the data for use in
+                * otx2_pfvf_mbox_up_handler.
                 */
                if (hdr->num_msgs) {
                        mw[i].num_msgs = hdr->num_msgs;
                        hdr->num_msgs = 0;
-                       if (type == TYPE_PFAF)
-                               memset(mbox->hwbase + mbox->rx_start, 0,
-                                      ALIGN(sizeof(struct mbox_hdr),
-                                            sizeof(u64)));
-
                        queue_work(mbox_wq, &mw[i].mbox_wrk);
                }
 
                mbox = &mw->mbox_up;
                mdev = &mbox->dev[i];
-               if (type == TYPE_PFAF)
-                       otx2_sync_mbox_bbuf(mbox, i);
                hdr = mdev->mbase + mbox->rx_start;
                if (hdr->num_msgs) {
                        mw[i].up_num_msgs = hdr->num_msgs;
                        hdr->num_msgs = 0;
-                       if (type == TYPE_PFAF)
-                               memset(mbox->hwbase + mbox->rx_start, 0,
-                                      ALIGN(sizeof(struct mbox_hdr),
-                                            sizeof(u64)));
-
                        queue_work(mbox_wq, &mw[i].mbox_up_wrk);
                }
        }
@@ -356,8 +342,10 @@ static void otx2_forward_msg_pfvf(struct otx2_mbox_dev *mdev,
        /* Msgs are already copied, trigger VF's mbox irq */
        smp_wmb();
 
+       otx2_mbox_wait_for_zero(pfvf_mbox, devid);
+
        offset = pfvf_mbox->trigger | (devid << pfvf_mbox->tr_shift);
-       writeq(1, (void __iomem *)pfvf_mbox->reg_base + offset);
+       writeq(MBOX_DOWN_MSG, (void __iomem *)pfvf_mbox->reg_base + offset);
 
        /* Restore VF's mbox bounce buffer region address */
        src_mdev->mbase = bbuf_base;
@@ -547,7 +535,7 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
 end:
                offset = mbox->rx_start + msg->next_msgoff;
                if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
-                       __otx2_mbox_reset(mbox, 0);
+                       __otx2_mbox_reset(mbox, vf_idx);
                mdev->msgs_acked++;
        }
 }
@@ -564,8 +552,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
        if (vfs > 64) {
                intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(1));
                otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr);
-               otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr,
-                               TYPE_PFVF);
+               otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr);
                if (intr)
                        trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
                vfs = 64;
@@ -574,7 +561,7 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
        intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0));
        otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(0), intr);
 
-       otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF);
+       otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr);
 
        if (intr)
                trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
@@ -597,8 +584,9 @@ static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs)
        if (!pf->mbox_pfvf)
                return -ENOMEM;
 
-       pf->mbox_pfvf_wq = alloc_ordered_workqueue("otx2_pfvf_mailbox",
-                                                  WQ_HIGHPRI | WQ_MEM_RECLAIM);
+       pf->mbox_pfvf_wq = alloc_workqueue("otx2_pfvf_mailbox",
+                                          WQ_UNBOUND | WQ_HIGHPRI |
+                                          WQ_MEM_RECLAIM, 0);
        if (!pf->mbox_pfvf_wq)
                return -ENOMEM;
 
@@ -821,20 +809,22 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work)
        struct mbox *af_mbox;
        struct otx2_nic *pf;
        int offset, id;
+       u16 num_msgs;
 
        af_mbox = container_of(work, struct mbox, mbox_wrk);
        mbox = &af_mbox->mbox;
        mdev = &mbox->dev[0];
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+       num_msgs = rsp_hdr->num_msgs;
 
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
        pf = af_mbox->pfvf;
 
-       for (id = 0; id < af_mbox->num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
                otx2_process_pfaf_mbox_msg(pf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
-               if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
+               if (mdev->msgs_acked == (num_msgs - 1))
                        __otx2_mbox_reset(mbox, 0);
                mdev->msgs_acked++;
        }
@@ -945,12 +935,14 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
        int offset, id, devid = 0;
        struct mbox_hdr *rsp_hdr;
        struct mbox_msghdr *msg;
+       u16 num_msgs;
 
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+       num_msgs = rsp_hdr->num_msgs;
 
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-       for (id = 0; id < af_mbox->up_num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
 
                devid = msg->pcifunc & RVU_PFVF_FUNC_MASK;
@@ -959,10 +951,11 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
                        otx2_process_mbox_msg_up(pf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
        }
-       if (devid) {
+       /* Forward to VF iff VFs are really present */
+       if (devid && pci_num_vf(pf->pdev)) {
                otx2_forward_vf_mbox_msgs(pf, &pf->mbox.mbox_up,
                                          MBOX_DIR_PFVF_UP, devid - 1,
-                                         af_mbox->up_num_msgs);
+                                         num_msgs);
                return;
        }
 
@@ -972,16 +965,49 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
 static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
 {
        struct otx2_nic *pf = (struct otx2_nic *)pf_irq;
-       struct mbox *mbox;
+       struct mbox *mw = &pf->mbox;
+       struct otx2_mbox_dev *mdev;
+       struct otx2_mbox *mbox;
+       struct mbox_hdr *hdr;
+       u64 mbox_data;
 
        /* Clear the IRQ */
        otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
 
-       mbox = &pf->mbox;
 
-       trace_otx2_msg_interrupt(mbox->mbox.pdev, "AF to PF", BIT_ULL(0));
+       mbox_data = otx2_read64(pf, RVU_PF_PFAF_MBOX0);
+
+       if (mbox_data & MBOX_UP_MSG) {
+               mbox_data &= ~MBOX_UP_MSG;
+               otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
+
+               mbox = &mw->mbox_up;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
+
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(pf->mbox_wq, &mw->mbox_up_wrk);
+
+               trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF",
+                                        BIT_ULL(0));
+       }
+
+       if (mbox_data & MBOX_DOWN_MSG) {
+               mbox_data &= ~MBOX_DOWN_MSG;
+               otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
+
+               mbox = &mw->mbox;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
+
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(pf->mbox_wq, &mw->mbox_wrk);
 
-       otx2_queue_work(mbox, pf->mbox_wq, 0, 1, 1, TYPE_PFAF);
+               trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF",
+                                        BIT_ULL(0));
+       }
 
        return IRQ_HANDLED;
 }
@@ -3087,6 +3113,7 @@ static void otx2_vf_link_event_task(struct work_struct *work)
        struct otx2_vf_config *config;
        struct cgx_link_info_msg *req;
        struct mbox_msghdr *msghdr;
+       struct delayed_work *dwork;
        struct otx2_nic *pf;
        int vf_idx;
 
@@ -3095,10 +3122,24 @@ static void otx2_vf_link_event_task(struct work_struct *work)
        vf_idx = config - config->pf->vf_configs;
        pf = config->pf;
 
+       if (config->intf_down)
+               return;
+
+       mutex_lock(&pf->mbox.lock);
+
+       dwork = &config->link_event_work;
+
+       if (!otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx)) {
+               schedule_delayed_work(dwork, msecs_to_jiffies(100));
+               mutex_unlock(&pf->mbox.lock);
+               return;
+       }
+
        msghdr = otx2_mbox_alloc_msg_rsp(&pf->mbox_pfvf[0].mbox_up, vf_idx,
                                         sizeof(*req), sizeof(struct msg_rsp));
        if (!msghdr) {
                dev_err(pf->dev, "Failed to create VF%d link event\n", vf_idx);
+               mutex_unlock(&pf->mbox.lock);
                return;
        }
 
@@ -3107,7 +3148,11 @@ static void otx2_vf_link_event_task(struct work_struct *work)
        req->hdr.sig = OTX2_MBOX_REQ_SIG;
        memcpy(&req->link_info, &pf->linfo, sizeof(req->link_info));
 
+       otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx);
+
        otx2_sync_mbox_up_msg(&pf->mbox_pfvf[0], vf_idx);
+
+       mutex_unlock(&pf->mbox.lock);
 }
 
 static int otx2_sriov_enable(struct pci_dev *pdev, int numvfs)
index 35e06048356f4d545298b4bfc34ae848168734f1..cf0aa16d754070ebf2d9e05e7146b604674bcbfd 100644 (file)
@@ -89,16 +89,20 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
        struct otx2_mbox *mbox;
        struct mbox *af_mbox;
        int offset, id;
+       u16 num_msgs;
 
        af_mbox = container_of(work, struct mbox, mbox_wrk);
        mbox = &af_mbox->mbox;
        mdev = &mbox->dev[0];
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (af_mbox->num_msgs == 0)
+       num_msgs = rsp_hdr->num_msgs;
+
+       if (num_msgs == 0)
                return;
+
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-       for (id = 0; id < af_mbox->num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
                otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
@@ -151,6 +155,7 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
        struct mbox *vf_mbox;
        struct otx2_nic *vf;
        int offset, id;
+       u16 num_msgs;
 
        vf_mbox = container_of(work, struct mbox, mbox_up_wrk);
        vf = vf_mbox->pfvf;
@@ -158,12 +163,14 @@ static void otx2vf_vfaf_mbox_up_handler(struct work_struct *work)
        mdev = &mbox->dev[0];
 
        rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (vf_mbox->up_num_msgs == 0)
+       num_msgs = rsp_hdr->num_msgs;
+
+       if (num_msgs == 0)
                return;
 
        offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-       for (id = 0; id < vf_mbox->up_num_msgs; id++) {
+       for (id = 0; id < num_msgs; id++) {
                msg = (struct mbox_msghdr *)(mdev->mbase + offset);
                otx2vf_process_mbox_msg_up(vf, msg);
                offset = mbox->rx_start + msg->next_msgoff;
@@ -178,40 +185,48 @@ static irqreturn_t otx2vf_vfaf_mbox_intr_handler(int irq, void *vf_irq)
        struct otx2_mbox_dev *mdev;
        struct otx2_mbox *mbox;
        struct mbox_hdr *hdr;
+       u64 mbox_data;
 
        /* Clear the IRQ */
        otx2_write64(vf, RVU_VF_INT, BIT_ULL(0));
 
+       mbox_data = otx2_read64(vf, RVU_VF_VFPF_MBOX0);
+
        /* Read latest mbox data */
        smp_rmb();
 
-       /* Check for PF => VF response messages */
-       mbox = &vf->mbox.mbox;
-       mdev = &mbox->dev[0];
-       otx2_sync_mbox_bbuf(mbox, 0);
+       if (mbox_data & MBOX_DOWN_MSG) {
+               mbox_data &= ~MBOX_DOWN_MSG;
+               otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+               /* Check for PF => VF response messages */
+               mbox = &vf->mbox.mbox;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
 
-       trace_otx2_msg_interrupt(mbox->pdev, "PF to VF", BIT_ULL(0));
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
 
-       hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (hdr->num_msgs) {
-               vf->mbox.num_msgs = hdr->num_msgs;
-               hdr->num_msgs = 0;
-               memset(mbox->hwbase + mbox->rx_start, 0,
-                      ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-               queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
+               trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF to VF",
+                                        BIT_ULL(0));
        }
-       /* Check for PF => VF notification messages */
-       mbox = &vf->mbox.mbox_up;
-       mdev = &mbox->dev[0];
-       otx2_sync_mbox_bbuf(mbox, 0);
 
-       hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-       if (hdr->num_msgs) {
-               vf->mbox.up_num_msgs = hdr->num_msgs;
-               hdr->num_msgs = 0;
-               memset(mbox->hwbase + mbox->rx_start, 0,
-                      ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-               queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
+       if (mbox_data & MBOX_UP_MSG) {
+               mbox_data &= ~MBOX_UP_MSG;
+               otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+               /* Check for PF => VF notification messages */
+               mbox = &vf->mbox.mbox_up;
+               mdev = &mbox->dev[0];
+               otx2_sync_mbox_bbuf(mbox, 0);
+
+               hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+               if (hdr->num_msgs)
+                       queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
+
+               trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF to VF",
+                                        BIT_ULL(0));
        }
 
        return IRQ_HANDLED;
@@ -760,8 +775,8 @@ static void otx2vf_remove(struct pci_dev *pdev)
        otx2_mcam_flow_del(vf);
        otx2_shutdown_tc(vf);
        otx2_shutdown_qos(vf);
-       otx2vf_disable_mbox_intr(vf);
        otx2_detach_resources(&vf->mbox);
+       otx2vf_disable_mbox_intr(vf);
        free_percpu(vf->hw.lmt_info);
        if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
                qmem_free(vf->dev, vf->dync_lmt);
index de123350bd46b6e55ee5ea83737f79a4bceb6867..caa13b9cedff09ca507f1ed9375d4553adeb9f8a 100644 (file)
@@ -677,8 +677,7 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
        mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
        mcr_new = mcr_cur;
        mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
-                  MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK |
-                  MAC_MCR_RX_FIFO_CLR_DIS;
+                  MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_RX_FIFO_CLR_DIS;
 
        /* Only update control register when needed! */
        if (mcr_new != mcr_cur)
@@ -694,7 +693,7 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
                                           phylink_config);
        u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 
-       mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+       mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
        mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
@@ -803,7 +802,7 @@ static void mtk_mac_link_up(struct phylink_config *config,
        if (rx_pause)
                mcr |= MAC_MCR_FORCE_RX_FC;
 
-       mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN;
+       mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
        mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
index b2a5d9c3733d4823a977cd635d67e707286e9f50..6ce0db3a1a920857016c17b7e7bc4be1f2045a0f 100644 (file)
@@ -994,7 +994,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
                         MTK_PPE_KEEPALIVE_DISABLE) |
              FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) |
              FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE,
-                        MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
+                        MTK_PPE_SCAN_MODE_CHECK_AGE) |
              FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
                         MTK_PPE_ENTRIES_SHIFT);
        if (mtk_is_netsys_v2_or_greater(ppe->eth))
@@ -1090,17 +1090,21 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
 
        mtk_ppe_cache_enable(ppe, false);
 
-       /* disable offload engine */
-       ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN);
-       ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0);
-
        /* disable aging */
        val = MTK_PPE_TB_CFG_AGE_NON_L4 |
              MTK_PPE_TB_CFG_AGE_UNBIND |
              MTK_PPE_TB_CFG_AGE_TCP |
              MTK_PPE_TB_CFG_AGE_UDP |
-             MTK_PPE_TB_CFG_AGE_TCP_FIN;
+             MTK_PPE_TB_CFG_AGE_TCP_FIN |
+                 MTK_PPE_TB_CFG_SCAN_MODE;
        ppe_clear(ppe, MTK_PPE_TB_CFG, val);
 
-       return mtk_ppe_wait_busy(ppe);
+       if (mtk_ppe_wait_busy(ppe))
+               return -ETIMEDOUT;
+
+       /* disable offload engine */
+       ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN);
+       ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0);
+
+       return 0;
 }
index 93295916b1d2b80751637dee4a0006688958c428..5b5d5e4310d127189cfdea18223f02460a6af149 100644 (file)
@@ -571,7 +571,7 @@ static int txgbe_clock_register(struct txgbe *txgbe)
        char clk_name[32];
        struct clk *clk;
 
-       snprintf(clk_name, sizeof(clk_name), "i2c_designware.%d",
+       snprintf(clk_name, sizeof(clk_name), "i2c_dw.%d",
                 pci_dev_id(pdev));
 
        clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 156250000);
index 8297ef681bf5dc6d7c09aacf76c2edc8a59d9a3c..6c6ec947570929536fe321c4063eefd32afb6649 100644 (file)
@@ -2831,8 +2831,8 @@ EXPORT_SYMBOL(genphy_resume);
 int genphy_loopback(struct phy_device *phydev, bool enable)
 {
        if (enable) {
-               u16 val, ctl = BMCR_LOOPBACK;
-               int ret;
+               u16 ctl = BMCR_LOOPBACK;
+               int ret, val;
 
                ctl |= mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
 
index 13d902462d8ec12993f9aa8a0463aa2a21c972ba..bcdfbf61eb66b859b2db7199a06a95619a49dcb5 100644 (file)
@@ -1464,8 +1464,6 @@ static netdev_features_t veth_fix_features(struct net_device *dev,
                if (peer_priv->_xdp_prog)
                        features &= ~NETIF_F_GSO_SOFTWARE;
        }
-       if (priv->_xdp_prog)
-               features |= NETIF_F_GRO;
 
        return features;
 }
@@ -1569,14 +1567,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                }
 
                if (!old_prog) {
-                       if (!veth_gro_requested(dev)) {
-                               /* user-space did not require GRO, but adding
-                                * XDP is supposed to get GRO working
-                                */
-                               dev->features |= NETIF_F_GRO;
-                               netdev_features_change(dev);
-                       }
-
                        peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
                        peer->max_mtu = max_mtu;
                }
@@ -1592,14 +1582,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
                        if (dev->flags & IFF_UP)
                                veth_disable_xdp(dev);
 
-                       /* if user-space did not require GRO, since adding XDP
-                        * enabled it, clear it now
-                        */
-                       if (!veth_gro_requested(dev)) {
-                               dev->features &= ~NETIF_F_GRO;
-                               netdev_features_change(dev);
-                       }
-
                        if (peer) {
                                peer->hw_features |= NETIF_F_GSO_SOFTWARE;
                                peer->max_mtu = ETH_MAX_MTU;
index 80ddaff759d47a00d3749495928d515e8be9ecea..a6c787454a1aebcad356fe44f61e16a5b5a6b8eb 100644 (file)
@@ -382,12 +382,12 @@ vmxnet3_process_xdp(struct vmxnet3_adapter *adapter,
        page = rbi->page;
        dma_sync_single_for_cpu(&adapter->pdev->dev,
                                page_pool_get_dma_addr(page) +
-                               rq->page_pool->p.offset, rcd->len,
+                               rq->page_pool->p.offset, rbi->len,
                                page_pool_get_dma_dir(rq->page_pool));
 
-       xdp_init_buff(&xdp, rbi->len, &rq->xdp_rxq);
+       xdp_init_buff(&xdp, PAGE_SIZE, &rq->xdp_rxq);
        xdp_prepare_buff(&xdp, page_address(page), rq->page_pool->p.offset,
-                        rcd->len, false);
+                        rbi->len, false);
        xdp_buff_clear_frags_flag(&xdp);
 
        xdp_prog = rcu_dereference(rq->adapter->xdp_bpf_prog);
index 960371df470a02e667bb2b6d87c9a9a77728028a..f69b1f579a0ca314fd53f6aa55876b43d795bd49 100644 (file)
@@ -780,7 +780,7 @@ static const struct of_device_id qmc_hdlc_id_table[] = {
        { .compatible = "fsl,qmc-hdlc" },
        {} /* sentinel */
 };
-MODULE_DEVICE_TABLE(of, qmc_hdlc_driver);
+MODULE_DEVICE_TABLE(of, qmc_hdlc_id_table);
 
 static struct platform_driver qmc_hdlc_driver = {
        .driver = {
index deb9636b0ecf8f47e832a0b07e9e049ba19bdf16..3feb36ee5bfb44726eecee6db3b9463c62087a95 100644 (file)
@@ -237,7 +237,6 @@ static const struct net_device_ops netdev_ops = {
        .ndo_open               = wg_open,
        .ndo_stop               = wg_stop,
        .ndo_start_xmit         = wg_xmit,
-       .ndo_get_stats64        = dev_get_tstats64
 };
 
 static void wg_destruct(struct net_device *dev)
@@ -262,7 +261,6 @@ static void wg_destruct(struct net_device *dev)
        rcu_barrier(); /* Wait for all the peers to be actually freed. */
        wg_ratelimiter_uninit();
        memzero_explicit(&wg->static_identity, sizeof(wg->static_identity));
-       free_percpu(dev->tstats);
        kvfree(wg->index_hashtable);
        kvfree(wg->peer_hashtable);
        mutex_unlock(&wg->device_update_lock);
@@ -297,6 +295,7 @@ static void wg_setup(struct net_device *dev)
        dev->hw_enc_features |= WG_NETDEV_FEATURES;
        dev->mtu = ETH_DATA_LEN - overhead;
        dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
+       dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
 
        SET_NETDEV_DEVTYPE(dev, &device_type);
 
@@ -331,14 +330,10 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
        if (!wg->index_hashtable)
                goto err_free_peer_hashtable;
 
-       dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
-       if (!dev->tstats)
-               goto err_free_index_hashtable;
-
        wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s",
                        WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name);
        if (!wg->handshake_receive_wq)
-               goto err_free_tstats;
+               goto err_free_index_hashtable;
 
        wg->handshake_send_wq = alloc_workqueue("wg-kex-%s",
                        WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name);
@@ -397,8 +392,6 @@ err_destroy_handshake_send:
        destroy_workqueue(wg->handshake_send_wq);
 err_destroy_handshake_receive:
        destroy_workqueue(wg->handshake_receive_wq);
-err_free_tstats:
-       free_percpu(dev->tstats);
 err_free_index_hashtable:
        kvfree(wg->index_hashtable);
 err_free_peer_hashtable:
index e220d761b1f27aa31eab3ad1b9211ddfe55eaabd..f7055180ba4aab5a0952357a334217e3cd6af078 100644 (file)
@@ -164,8 +164,8 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx)
        if (!allowedips_node)
                goto no_allowedips;
        if (!ctx->allowedips_seq)
-               ctx->allowedips_seq = peer->device->peer_allowedips.seq;
-       else if (ctx->allowedips_seq != peer->device->peer_allowedips.seq)
+               ctx->allowedips_seq = ctx->wg->peer_allowedips.seq;
+       else if (ctx->allowedips_seq != ctx->wg->peer_allowedips.seq)
                goto no_allowedips;
 
        allowedips_nest = nla_nest_start(skb, WGPEER_A_ALLOWEDIPS);
@@ -255,17 +255,17 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
        if (!peers_nest)
                goto out;
        ret = 0;
-       /* If the last cursor was removed via list_del_init in peer_remove, then
+       lockdep_assert_held(&wg->device_update_lock);
+       /* If the last cursor was removed in peer_remove or peer_remove_all, then
         * we just treat this the same as there being no more peers left. The
         * reason is that seq_nr should indicate to userspace that this isn't a
         * coherent dump anyway, so they'll try again.
         */
        if (list_empty(&wg->peer_list) ||
-           (ctx->next_peer && list_empty(&ctx->next_peer->peer_list))) {
+           (ctx->next_peer && ctx->next_peer->is_dead)) {
                nla_nest_cancel(skb, peers_nest);
                goto out;
        }
-       lockdep_assert_held(&wg->device_update_lock);
        peer = list_prepare_entry(ctx->next_peer, &wg->peer_list, peer_list);
        list_for_each_entry_continue(peer, &wg->peer_list, peer_list) {
                if (get_peer(peer, skb, ctx)) {
index df275b4fccb6d01a3bc22bc5bcc418b569a728e5..eb8851113654f5332219ffde63b61c8c470df759 100644 (file)
@@ -251,7 +251,7 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
 
        if (unlikely(!READ_ONCE(keypair->receiving.is_valid) ||
                  wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) ||
-                 keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) {
+                 READ_ONCE(keypair->receiving_counter.counter) >= REJECT_AFTER_MESSAGES)) {
                WRITE_ONCE(keypair->receiving.is_valid, false);
                return false;
        }
@@ -318,7 +318,7 @@ static bool counter_validate(struct noise_replay_counter *counter, u64 their_cou
                for (i = 1; i <= top; ++i)
                        counter->backtrack[(i + index_current) &
                                ((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0;
-               counter->counter = their_counter;
+               WRITE_ONCE(counter->counter, their_counter);
        }
 
        index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1;
@@ -463,7 +463,7 @@ int wg_packet_rx_poll(struct napi_struct *napi, int budget)
                        net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n",
                                            peer->device->dev->name,
                                            PACKET_CB(skb)->nonce,
-                                           keypair->receiving_counter.counter);
+                                           READ_ONCE(keypair->receiving_counter.counter));
                        goto next;
                }
 
index 739e4eee6b75ca666abe04004184fc451a09ad21..7e9074519ad22d7d6b26a9148f5f65b4e2e79b4f 100644 (file)
@@ -991,7 +991,7 @@ struct qman_portal {
        /* linked-list of CSCN handlers. */
        struct list_head cgr_cbs;
        /* list lock */
-       spinlock_t cgr_lock;
+       raw_spinlock_t cgr_lock;
        struct work_struct congestion_work;
        struct work_struct mr_work;
        char irqname[MAX_IRQNAME];
@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
                /* if the given mask is NULL, assume all CGRs can be seen */
                qman_cgrs_fill(&portal->cgrs[0]);
        INIT_LIST_HEAD(&portal->cgr_cbs);
-       spin_lock_init(&portal->cgr_lock);
+       raw_spin_lock_init(&portal->cgr_lock);
        INIT_WORK(&portal->congestion_work, qm_congestion_task);
        INIT_WORK(&portal->mr_work, qm_mr_process_task);
        portal->bits = 0;
@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
        union qm_mc_result *mcr;
        struct qman_cgr *cgr;
 
-       spin_lock(&p->cgr_lock);
+       /*
+        * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
+        */
+       raw_spin_lock_irq(&p->cgr_lock);
        qm_mc_start(&p->p);
        qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
        if (!qm_mc_result_timeout(&p->p, &mcr)) {
-               spin_unlock(&p->cgr_lock);
+               raw_spin_unlock_irq(&p->cgr_lock);
                dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
                qman_p_irqsource_add(p, QM_PIRQ_CSCI);
                return;
@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
        list_for_each_entry(cgr, &p->cgr_cbs, node)
                if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
                        cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
-       spin_unlock(&p->cgr_lock);
+       raw_spin_unlock_irq(&p->cgr_lock);
        qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
        preempt_enable();
 
        cgr->chan = p->config->channel;
-       spin_lock(&p->cgr_lock);
+       raw_spin_lock_irq(&p->cgr_lock);
 
        if (opts) {
                struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
            qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
                cgr->cb(p, cgr, 1);
 out:
-       spin_unlock(&p->cgr_lock);
+       raw_spin_unlock_irq(&p->cgr_lock);
        put_affine_portal();
        return ret;
 }
@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
                return -EINVAL;
 
        memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
-       spin_lock_irqsave(&p->cgr_lock, irqflags);
+       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
        list_del(&cgr->node);
        /*
         * If there are no other CGR objects for this CGRID in the list,
@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
                /* add back to the list */
                list_add(&cgr->node, &p->cgr_cbs);
 release_lock:
-       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
        put_affine_portal();
        return ret;
 }
@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
        if (!p)
                return -EINVAL;
 
-       spin_lock_irqsave(&p->cgr_lock, irqflags);
+       raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
        ret = qm_modify_cgr(cgr, 0, opts);
-       spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+       raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
        put_affine_portal();
        return ret;
 }
index fb3a9c93ac86af937e3319fc2e445e0f0d9cb4e6..aa4096126553753de4d2201e596b92a8a804bc1c 100644 (file)
@@ -522,17 +522,18 @@ static inline void bitmap_replace(unsigned long *dst,
  *
  * (Bits 0, 1, 2, 3, 4, 5 are copied to the bits 0, 1, 4, 8, 9, 12)
  *
- * A more 'visual' description of the operation:
- * src:  0000000001011010
- *                 ||||||
- *          +------+|||||
- *          |  +----+||||
- *          |  |+----+|||
- *          |  ||   +-+||
- *          |  ||   |  ||
- * mask: ...v..vv...v..vv
- *       ...0..11...0..10
- * dst:  0000001100000010
+ * A more 'visual' description of the operation::
+ *
+ *     src:  0000000001011010
+ *                     ||||||
+ *              +------+|||||
+ *              |  +----+||||
+ *              |  |+----+|||
+ *              |  ||   +-+||
+ *              |  ||   |  ||
+ *     mask: ...v..vv...v..vv
+ *           ...0..11...0..10
+ *     dst:  0000001100000010
  *
  * A relationship exists between bitmap_scatter() and bitmap_gather().
  * bitmap_gather() can be seen as the 'reverse' bitmap_scatter() operation.
@@ -568,16 +569,17 @@ static inline void bitmap_scatter(unsigned long *dst, const unsigned long *src,
  *
  * (Bits 0, 1, 4, 8, 9, 12 are copied to the bits 0, 1, 2, 3, 4, 5)
  *
- * A more 'visual' description of the operation:
- * mask: ...v..vv...v..vv
- * src:  0000001100000010
- *          ^  ^^   ^   0
- *          |  ||   |  10
- *          |  ||   > 010
- *          |  |+--> 1010
- *          |  +--> 11010
- *          +----> 011010
- * dst:  0000000000011010
+ * A more 'visual' description of the operation::
+ *
+ *     mask: ...v..vv...v..vv
+ *     src:  0000001100000010
+ *              ^  ^^   ^   0
+ *              |  ||   |  10
+ *              |  ||   > 010
+ *              |  |+--> 1010
+ *              |  +--> 11010
+ *              +----> 011010
+ *     dst:  0000000000011010
  *
  * A relationship exists between bitmap_gather() and bitmap_scatter(). See
  * bitmap_scatter() for the bitmap scatter detailed operations.
index c6f6ac779b34ef1a8f98853c84a7a2e0192e0e8f..cb37817d6382c29117afd8ce54db6dba94f8c930 100644 (file)
@@ -2072,6 +2072,7 @@ struct net_device {
                struct pcpu_sw_netstats __percpu        *tstats;
                struct pcpu_dstats __percpu             *dstats;
        };
+       unsigned long           state;
        unsigned int            flags;
        unsigned short          hard_header_len;
        netdev_features_t       features;
@@ -2117,7 +2118,6 @@ struct net_device {
         *      part of the usual set specified in Space.c.
         */
 
-       unsigned long           state;
 
        struct list_head        dev_list;
        struct list_head        napi_list;
index 16f519914415ebf5592e75be67e8660339d6b0e7..17d7ed5f3ae6e5c612acd4261be763855069946d 100644 (file)
@@ -247,6 +247,37 @@ do { \
        cond_resched(); \
 } while (0)
 
+/**
+ * rcu_softirq_qs_periodic - Report RCU and RCU-Tasks quiescent states
+ * @old_ts: jiffies at start of processing.
+ *
+ * This helper is for long-running softirq handlers, such as NAPI threads in
+ * networking. The caller should initialize the variable passed in as @old_ts
+ * at the beginning of the softirq handler. When invoked frequently, this macro
+ * will invoke rcu_softirq_qs() every 100 milliseconds thereafter, which will
+ * provide both RCU and RCU-Tasks quiescent states. Note that this macro
+ * modifies its old_ts argument.
+ *
+ * Because regions of code that have disabled softirq act as RCU read-side
+ * critical sections, this macro should be invoked with softirq (and
+ * preemption) enabled.
+ *
+ * The macro is not needed when CONFIG_PREEMPT_RT is defined. RT kernels would
+ * have more chance to invoke schedule() calls and provide necessary quiescent
+ * states. As a contrast, calling cond_resched() only won't achieve the same
+ * effect because cond_resched() does not provide RCU-Tasks quiescent states.
+ */
+#define rcu_softirq_qs_periodic(old_ts) \
+do { \
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT) && \
+           time_after(jiffies, (old_ts) + HZ / 10)) { \
+               preempt_disable(); \
+               rcu_softirq_qs(); \
+               preempt_enable(); \
+               (old_ts) = jiffies; \
+       } \
+} while (0)
+
 /*
  * Infrastructure to implement the synchronize_() primitives in
  * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
index 3023bc2be6a1c126bdbba2a0bc9b1f11d4131735..0c7c67b3a87b2351a3a65408c6d00b6eadf583bb 100644 (file)
@@ -822,9 +822,9 @@ typedef unsigned char *sk_buff_data_t;
  *     @decrypted: Decrypted SKB
  *     @slow_gro: state present at GRO time, slower prepare step required
  *     @mono_delivery_time: When set, skb->tstamp has the
- *             delivery_time in mono clock base (i.e., EDT) or a clock base chosen
- *             by SO_TXTIME. If zero, skb->tstamp has the (rcv) timestamp at
- *             ingress.
+ *             delivery_time in mono clock base (i.e. EDT).  Otherwise, the
+ *             skb->tstamp has the (rcv) timestamp at ingress and
+ *             delivery_time at egress.
  *     @napi_id: id of the NAPI struct this skb came from
  *     @sender_cpu: (aka @napi_id) source CPU in XPS
  *     @alloc_cpu: CPU which did the skb allocation.
@@ -3523,6 +3523,16 @@ int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb,
                         struct bpf_prog *prog);
 bool napi_pp_put_page(struct page *page, bool napi_safe);
 
+static inline void
+skb_page_unref(const struct sk_buff *skb, struct page *page, bool napi_safe)
+{
+#ifdef CONFIG_PAGE_POOL
+       if (skb->pp_recycle && napi_pp_put_page(page, napi_safe))
+               return;
+#endif
+       put_page(page);
+}
+
 static inline void
 napi_frag_unref(skb_frag_t *frag, bool recycle, bool napi_safe)
 {
index cfcb7e2c3813f2dbd3fd5ca9d123a6883713d672..139c330ccf2c3bf995a0c05db14db4f286f7eab6 100644 (file)
@@ -422,13 +422,6 @@ extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
                               struct user_msghdr __user *umsg,
                               struct sockaddr __user *uaddr,
                               unsigned int flags);
-extern int sendmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct iovec **iov);
-extern int recvmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct sockaddr __user **uaddr,
-                              struct iovec **iov);
 extern int __copy_msghdr(struct msghdr *kmsg,
                         struct user_msghdr *umsg,
                         struct sockaddr __user **save_addr);
index 8839133d6f6b78f8d6c1c9d61330043c8874b02d..004e651e6067e723ee2e3fc6d80474e4f9c1c1ba 100644 (file)
@@ -61,7 +61,11 @@ struct request_sock {
        struct request_sock             *dl_next;
        u16                             mss;
        u8                              num_retrans; /* number of retransmits */
-       u8                              syncookie:1; /* syncookie: encode tcpopts in timestamp */
+       u8                              syncookie:1; /* True if
+                                                     * 1) tcpopts needs to be encoded in
+                                                     *    TS of SYN+ACK
+                                                     * 2) ACK is validated by BPF kfunc.
+                                                     */
        u8                              num_timeout:7; /* number of timeouts */
        u32                             ts_recent;
        struct timer_list               rsk_timer;
@@ -144,6 +148,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
        sk_node_init(&req_to_sk(req)->sk_node);
        sk_tx_queue_clear(req_to_sk(req));
        req->saved_syn = NULL;
+       req->syncookie = 0;
        req->timeout = 0;
        req->num_timeout = 0;
        req->num_retrans = 0;
index 9ee8da4774656716718909d2c7d93362d9313ecd..a8e34416e960f5c89d90e0e2981154aa206bac42 100644 (file)
@@ -263,6 +263,7 @@ static int cpu_map_bpf_prog_run(struct bpf_cpu_map_entry *rcpu, void **frames,
 static int cpu_map_kthread_run(void *data)
 {
        struct bpf_cpu_map_entry *rcpu = data;
+       unsigned long last_qs = jiffies;
 
        complete(&rcpu->kthread_running);
        set_current_state(TASK_INTERRUPTIBLE);
@@ -288,10 +289,12 @@ static int cpu_map_kthread_run(void *data)
                        if (__ptr_ring_empty(rcpu->queue)) {
                                schedule();
                                sched = 1;
+                               last_qs = jiffies;
                        } else {
                                __set_current_state(TASK_RUNNING);
                        }
                } else {
+                       rcu_softirq_qs_periodic(last_qs);
                        sched = cond_resched();
                }
 
index 0766a245816bdf70f6609dc7b6d694ae81e7a9e5..9a67003e49db87f3f92b6c6296b3e7a5ca9d9171 100644 (file)
@@ -2245,7 +2245,7 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
        rcu_read_lock();
 again:
        list_for_each_entry_rcu(ptype, ptype_list, list) {
-               if (ptype->ignore_outgoing)
+               if (READ_ONCE(ptype->ignore_outgoing))
                        continue;
 
                /* Never send packets back to the socket
@@ -6743,6 +6743,8 @@ static int napi_threaded_poll(void *data)
        void *have;
 
        while (!napi_thread_wait(napi)) {
+               unsigned long last_qs = jiffies;
+
                for (;;) {
                        bool repoll = false;
 
@@ -6767,6 +6769,7 @@ static int napi_threaded_poll(void *data)
                        if (!repoll)
                                break;
 
+                       rcu_softirq_qs_periodic(last_qs);
                        cond_resched();
                }
        }
@@ -11665,11 +11668,12 @@ static void __init net_dev_struct_check(void)
 
        /* TXRX read-mostly hotpath */
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, lstats);
+       CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, state);
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, flags);
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, hard_header_len);
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, features);
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_txrx, ip6_ptr);
-       CACHELINE_ASSERT_GROUP_SIZE(struct net_device, net_device_read_txrx, 38);
+       CACHELINE_ASSERT_GROUP_SIZE(struct net_device, net_device_read_txrx, 46);
 
        /* RX read-mostly hotpath */
        CACHELINE_ASSERT_GROUP_MEMBER(struct net_device, net_device_read_rx, ptype_specific);
index 499885c8b9cae21e846ca3e310dc6ec767b184eb..593605c1b1ef4d32eab50c7701b329936b447351 100644 (file)
@@ -193,12 +193,13 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
        devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
 
        devlinks_xa_for_each_registered_get(net, index, devlink) {
-               devl_dev_lock(devlink, dev_lock);
-               if (devl_is_registered(devlink) &&
-                   strcmp(devlink->dev->bus->name, busname) == 0 &&
-                   strcmp(dev_name(devlink->dev), devname) == 0)
-                       return devlink;
-               devl_dev_unlock(devlink, dev_lock);
+               if (strcmp(devlink->dev->bus->name, busname) == 0 &&
+                   strcmp(dev_name(devlink->dev), devname) == 0) {
+                       devl_dev_lock(devlink, dev_lock);
+                       if (devl_is_registered(devlink))
+                               return devlink;
+                       devl_dev_unlock(devlink, dev_lock);
+               }
                devlink_put(devlink);
        }
 
index 4b2d46ccfe484f1ae2c21b5b2921a113d59e13f5..118d130d2afd56301c89ea2552bc3f6c625adcfe 100644 (file)
@@ -889,7 +889,7 @@ int devlink_nl_port_new_doit(struct sk_buff *skb, struct genl_info *info)
                err = -ENOMEM;
                goto err_out_port_del;
        }
-       err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
+       err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
                                   info->snd_portid, info->snd_seq, 0, NULL);
        if (WARN_ON_ONCE(err))
                goto err_out_msg_free;
index 6d14d935ee828d025d40ea237884d244cb56eb8e..26329db09210bb38cf3fcf81334ce212c2af0d2e 100644 (file)
@@ -228,6 +228,10 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
         */
        if (ethhdr->h_proto == htons(ETH_P_PRP) ||
            ethhdr->h_proto == htons(ETH_P_HSR)) {
+               /* Check if skb contains hsr_ethhdr */
+               if (skb->mac_len < sizeof(struct hsr_ethhdr))
+                       return NULL;
+
                /* Use the existing sequence_nr from the tag as starting point
                 * for filtering duplicate frames.
                 */
index cb83c8feb746535fe4126f4172ffbafaac58b0d5..9756e657bab97e95407b8907157b138159d68253 100644 (file)
@@ -148,14 +148,21 @@ static struct notifier_block hsr_nb = {
 
 static int __init hsr_init(void)
 {
-       int res;
+       int err;
 
        BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN);
 
-       register_netdevice_notifier(&hsr_nb);
-       res = hsr_netlink_init();
+       err = register_netdevice_notifier(&hsr_nb);
+       if (err)
+               return err;
+
+       err = hsr_netlink_init();
+       if (err) {
+               unregister_netdevice_notifier(&hsr_nb);
+               return err;
+       }
 
-       return res;
+       return 0;
 }
 
 static void __exit hsr_exit(void)
index 4dd9e50406720cfc90d280f61e4616d6a2e58d3c..d33d124218140cfdbf910ce7054c05559c5ecfba 100644 (file)
@@ -95,7 +95,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
                             __alignof__(struct scatterlist));
 }
 
-static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
+static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
 {
        struct crypto_aead *aead = x->data;
        int extralen = 0;
@@ -114,7 +114,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
         */
        if (req->src != req->dst)
                for (sg = sg_next(req->src); sg; sg = sg_next(sg))
-                       put_page(sg_page(sg));
+                       skb_page_unref(skb, sg_page(sg), false);
 }
 
 #ifdef CONFIG_INET_ESPINTCP
@@ -260,7 +260,7 @@ static void esp_output_done(void *data, int err)
        }
 
        tmp = ESP_SKB_CB(skb)->tmp;
-       esp_ssg_unref(x, tmp);
+       esp_ssg_unref(x, tmp, skb);
        kfree(tmp);
 
        if (xo && (xo->flags & XFRM_DEV_RESUME)) {
@@ -639,7 +639,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
        }
 
        if (sg != dsg)
-               esp_ssg_unref(x, tmp);
+               esp_ssg_unref(x, tmp, skb);
 
        if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
                err = esp_output_tail_tcp(x, skb);
index 7498af3201647fd937bf8177f04c200bea178a79..cf88eca5f1b40563e177c6d84dd59416c62c30e5 100644 (file)
@@ -1135,7 +1135,7 @@ error:
                sock_prot_inuse_add(net, sk->sk_prot, -1);
 
                spin_lock(lock);
-               sk_nulls_del_node_init_rcu(sk);
+               __sk_nulls_del_node_init_rcu(sk);
                spin_unlock(lock);
 
                sk->sk_hash = 0;
index 5befa4de5b2416281ad2795713a70d0fd847b0b2..e8de45d34d56a507a4bdcceaccbd5707692b6c0a 100644 (file)
@@ -263,12 +263,12 @@ void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo, bool rearm)
 }
 EXPORT_SYMBOL_GPL(__inet_twsk_schedule);
 
+/* Remove all non full sockets (TIME_WAIT and NEW_SYN_RECV) for dead netns */
 void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family)
 {
-       struct inet_timewait_sock *tw;
-       struct sock *sk;
        struct hlist_nulls_node *node;
        unsigned int slot;
+       struct sock *sk;
 
        for (slot = 0; slot <= hashinfo->ehash_mask; slot++) {
                struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
@@ -277,38 +277,35 @@ restart_rcu:
                rcu_read_lock();
 restart:
                sk_nulls_for_each_rcu(sk, node, &head->chain) {
-                       if (sk->sk_state != TCP_TIME_WAIT) {
-                               /* A kernel listener socket might not hold refcnt for net,
-                                * so reqsk_timer_handler() could be fired after net is
-                                * freed.  Userspace listener and reqsk never exist here.
-                                */
-                               if (unlikely(sk->sk_state == TCP_NEW_SYN_RECV &&
-                                            hashinfo->pernet)) {
-                                       struct request_sock *req = inet_reqsk(sk);
-
-                                       inet_csk_reqsk_queue_drop_and_put(req->rsk_listener, req);
-                               }
+                       int state = inet_sk_state_load(sk);
 
+                       if ((1 << state) & ~(TCPF_TIME_WAIT |
+                                            TCPF_NEW_SYN_RECV))
                                continue;
-                       }
 
-                       tw = inet_twsk(sk);
-                       if ((tw->tw_family != family) ||
-                               refcount_read(&twsk_net(tw)->ns.count))
+                       if (sk->sk_family != family ||
+                           refcount_read(&sock_net(sk)->ns.count))
                                continue;
 
-                       if (unlikely(!refcount_inc_not_zero(&tw->tw_refcnt)))
+                       if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
                                continue;
 
-                       if (unlikely((tw->tw_family != family) ||
-                                    refcount_read(&twsk_net(tw)->ns.count))) {
-                               inet_twsk_put(tw);
+                       if (unlikely(sk->sk_family != family ||
+                                    refcount_read(&sock_net(sk)->ns.count))) {
+                               sock_gen_put(sk);
                                goto restart;
                        }
 
                        rcu_read_unlock();
                        local_bh_disable();
-                       inet_twsk_deschedule_put(tw);
+                       if (state == TCP_TIME_WAIT) {
+                               inet_twsk_deschedule_put(inet_twsk(sk));
+                       } else {
+                               struct request_sock *req = inet_reqsk(sk);
+
+                               inet_csk_reqsk_queue_drop_and_put(req->rsk_listener,
+                                                                 req);
+                       }
                        local_bh_enable();
                        goto restart_rcu;
                }
index 33f93dc730a3359b2a43e3cab447b94bc63597e0..1fe794967211e249016df00dc3c2ae230d71dcff 100644 (file)
@@ -1458,7 +1458,6 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
        skb->priority = (cork->tos != -1) ? cork->priority: READ_ONCE(sk->sk_priority);
        skb->mark = cork->mark;
        skb->tstamp = cork->transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
        /*
         * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
         * on dst refcount
index 42ac434cfcfa677ee58408297f4d3ac05d98b546..dcb11f22cbf2b437405d1b373dd0ebc37d02c9ec 100644 (file)
@@ -357,10 +357,10 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
                goto error;
        skb_reserve(skb, hlen);
 
+       skb->protocol = htons(ETH_P_IP);
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc->mark;
        skb->tstamp = sockc->transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
        skb_dst_set(skb, &rt->dst);
        *rtp = NULL;
 
index 7972ad3d7c73af68d6149ca76f6d12ddf881f3a2..500f665f98cbce4a3d681f8e39ecd368fe4013b1 100644 (file)
@@ -474,6 +474,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
                                  ireq->wscale_ok, &rcv_wscale,
                                  dst_metric(&rt->dst, RTAX_INITRWND));
 
+       /* req->syncookie is set true only if ACK is validated
+        * by BPF kfunc, then, rcv_wscale is already configured.
+        */
        if (!req->syncookie)
                ireq->rcv_wscale = rcv_wscale;
        ireq->ecn_ok &= cookie_ecn_ok(net, &rt->dst);
index 52040b0e2616b479cf3f619a594364951c219eae..f0761f060a8376236983a660eea48a6e0ba94de4 100644 (file)
@@ -398,10 +398,6 @@ void tcp_twsk_purge(struct list_head *net_exit_list, int family)
                        /* Even if tw_refcount == 1, we must clean up kernel reqsk */
                        inet_twsk_purge(net->ipv4.tcp_death_row.hashinfo, family);
                } else if (!purged_once) {
-                       /* The last refcount is decremented in tcp_sk_exit_batch() */
-                       if (refcount_read(&net->ipv4.tcp_death_row.tw_refcount) == 1)
-                               continue;
-
                        inet_twsk_purge(&tcp_hashinfo, family);
                        purged_once = true;
                }
index 6e6efe026cdcc2feab9a1f18fb784042b586f045..7371886d4f9f49c39111cfe95ea5dff7e5198740 100644 (file)
@@ -112,7 +112,7 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
                             __alignof__(struct scatterlist));
 }
 
-static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
+static void esp_ssg_unref(struct xfrm_state *x, void *tmp, struct sk_buff *skb)
 {
        struct crypto_aead *aead = x->data;
        int extralen = 0;
@@ -131,7 +131,7 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
         */
        if (req->src != req->dst)
                for (sg = sg_next(req->src); sg; sg = sg_next(sg))
-                       put_page(sg_page(sg));
+                       skb_page_unref(skb, sg_page(sg), false);
 }
 
 #ifdef CONFIG_INET6_ESPINTCP
@@ -294,7 +294,7 @@ static void esp_output_done(void *data, int err)
        }
 
        tmp = ESP_SKB_CB(skb)->tmp;
-       esp_ssg_unref(x, tmp);
+       esp_ssg_unref(x, tmp, skb);
        kfree(tmp);
 
        esp_output_encap_csum(skb);
@@ -677,7 +677,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
        }
 
        if (sg != dsg)
-               esp_ssg_unref(x, tmp);
+               esp_ssg_unref(x, tmp, skb);
 
        if (!err && x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
                err = esp_output_tail_tcp(x, skb);
index 02eeca5492cd4d894b4acc8ec89bf004e81c0ccb..b9dd3a66e4236fbf67af75c5f98c921b38c18bf6 100644 (file)
@@ -1925,7 +1925,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = cork->base.mark;
        skb->tstamp = cork->base.transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
+
        ip6_cork_steal_dst(skb, cork);
        IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
        if (proto == IPPROTO_ICMPV6) {
index ca49e6617afaff3fe6c5f3a174bbe6d96f94ac62..0d896ca7b589122270b9e85815a64ce37d0d932d 100644 (file)
@@ -622,7 +622,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc->mark;
        skb->tstamp = sockc->transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
+
        skb_put(skb, length);
        skb_reset_network_header(skb);
        iph = ipv6_hdr(skb);
index 8bad0a44a0a6c593b5fcc327e8ae6a5f106c8794..6d8286c299c9d139938ef6751d9958c80d3031e9 100644 (file)
@@ -258,6 +258,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                                  ireq->wscale_ok, &rcv_wscale,
                                  dst_metric(dst, RTAX_INITRWND));
 
+       /* req->syncookie is set true only if ACK is validated
+        * by BPF kfunc, then, rcv_wscale is already configured.
+        */
        if (!req->syncookie)
                ireq->rcv_wscale = rcv_wscale;
        ireq->ecn_ok &= cookie_ecn_ok(net, dst);
index e93f905e60b62e7b54b500be697237616b15f629..5fa3d3540c93c003737fb16ef1e6e7514580e97a 100644 (file)
@@ -1213,7 +1213,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
        if (flags & ~NFT_TABLE_F_MASK)
                return -EOPNOTSUPP;
 
-       if (flags == ctx->table->flags)
+       if (flags == (ctx->table->flags & NFT_TABLE_F_MASK))
                return 0;
 
        if ((nft_table_has_owner(ctx->table) &&
@@ -2631,19 +2631,6 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
                }
        }
 
-       if (nla[NFTA_CHAIN_COUNTERS]) {
-               if (!nft_is_base_chain(chain)) {
-                       err = -EOPNOTSUPP;
-                       goto err_hooks;
-               }
-
-               stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
-               if (IS_ERR(stats)) {
-                       err = PTR_ERR(stats);
-                       goto err_hooks;
-               }
-       }
-
        if (!(table->flags & NFT_TABLE_F_DORMANT) &&
            nft_is_base_chain(chain) &&
            !list_empty(&hook.list)) {
@@ -2658,6 +2645,20 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
        }
 
        unregister = true;
+
+       if (nla[NFTA_CHAIN_COUNTERS]) {
+               if (!nft_is_base_chain(chain)) {
+                       err = -EOPNOTSUPP;
+                       goto err_hooks;
+               }
+
+               stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
+               if (IS_ERR(stats)) {
+                       err = PTR_ERR(stats);
+                       goto err_hooks;
+               }
+       }
+
        err = -ENOMEM;
        trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN,
                                sizeof(struct nft_trans_chain));
index c0ceea068936a64a60f208ddbacb5049847dc71b..df8de50902463738642d4d24b59f12b17b5ff726 100644 (file)
@@ -2329,8 +2329,6 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx,
        if (m) {
                rcu_barrier();
 
-               nft_set_pipapo_match_destroy(ctx, set, m);
-
                for_each_possible_cpu(cpu)
                        pipapo_free_scratch(m, cpu);
                free_percpu(m->scratch);
@@ -2342,8 +2340,7 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx,
        if (priv->clone) {
                m = priv->clone;
 
-               if (priv->dirty)
-                       nft_set_pipapo_match_destroy(ctx, set, m);
+               nft_set_pipapo_match_destroy(ctx, set, m);
 
                for_each_possible_cpu(cpu)
                        pipapo_free_scratch(priv->clone, cpu);
index 61270826b9ac73e66f9011c3230d4668f0bf7c77..18f616f487eaad0f7b31fb074e194c0479f30d77 100644 (file)
@@ -2057,7 +2057,7 @@ retry:
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = READ_ONCE(sk->sk_mark);
        skb->tstamp = sockc.transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
+
        skb_setup_tx_timestamp(skb, sockc.tsflags);
 
        if (unlikely(extra_len == 4))
@@ -2586,7 +2586,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
        skb->priority = READ_ONCE(po->sk.sk_priority);
        skb->mark = READ_ONCE(po->sk.sk_mark);
        skb->tstamp = sockc->transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
        skb_setup_tx_timestamp(skb, sockc->tsflags);
        skb_zcopy_set_nouarg(skb, ph.raw);
 
@@ -3065,7 +3064,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
        skb->priority = READ_ONCE(sk->sk_priority);
        skb->mark = sockc.mark;
        skb->tstamp = sockc.transmit_time;
-       skb->mono_delivery_time = !!skb->tstamp;
 
        if (unlikely(extra_len == 4))
                skb->no_fcs = 1;
@@ -4000,7 +3998,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
                if (val < 0 || val > 1)
                        return -EINVAL;
 
-               po->prot_hook.ignore_outgoing = !!val;
+               WRITE_ONCE(po->prot_hook.ignore_outgoing, !!val);
                return 0;
        }
        case PACKET_TX_HAS_OFF:
@@ -4134,7 +4132,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
                       0);
                break;
        case PACKET_IGNORE_OUTGOING:
-               val = po->prot_hook.ignore_outgoing;
+               val = READ_ONCE(po->prot_hook.ignore_outgoing);
                break;
        case PACKET_ROLLOVER_STATS:
                if (!po->rollover)
index 2899def23865fa47ce55faa7c7eb72fb52bc432b..09a28011065493abc083a84f8f681cd8a8acef4c 100644 (file)
@@ -103,13 +103,12 @@ EXPORT_SYMBOL_GPL(rds_send_path_reset);
 
 static int acquire_in_xmit(struct rds_conn_path *cp)
 {
-       return test_and_set_bit(RDS_IN_XMIT, &cp->cp_flags) == 0;
+       return test_and_set_bit_lock(RDS_IN_XMIT, &cp->cp_flags) == 0;
 }
 
 static void release_in_xmit(struct rds_conn_path *cp)
 {
-       clear_bit(RDS_IN_XMIT, &cp->cp_flags);
-       smp_mb__after_atomic();
+       clear_bit_unlock(RDS_IN_XMIT, &cp->cp_flags);
        /*
         * We don't use wait_on_bit()/wake_up_bit() because our waking is in a
         * hot path and finding waiters is very rare.  We don't want to walk
index 6f765768c49c5374946a652b60e3c961dc389f9e..894b8fa68e5e9546ad2dd17372420976d7eb76c0 100644 (file)
@@ -349,8 +349,8 @@ reload:
                         */
                        remain = more ? INT_MAX : msg_data_left(msg);
                        txb = call->conn->security->alloc_txbuf(call, remain, sk->sk_allocation);
-                       if (IS_ERR(txb)) {
-                               ret = PTR_ERR(txb);
+                       if (!txb) {
+                               ret = -ENOMEM;
                                goto maybe_error;
                        }
                }
index b2a82ab756c248a35b2bd5e9d2e843b6639c558e..e0679658d9de0e62edd777cad0b7e4281cfe2384 100644 (file)
@@ -33,8 +33,8 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_
        total = hoff + sizeof(*whdr) + data_size;
 
        mutex_lock(&call->conn->tx_data_alloc_lock);
-       buf = page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp,
-                                   ~(data_align - 1) & ~(L1_CACHE_BYTES - 1));
+       buf = __page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp,
+                                     ~(data_align - 1) & ~(L1_CACHE_BYTES - 1));
        mutex_unlock(&call->conn->tx_data_alloc_lock);
        if (!buf) {
                kfree(txb);
index 5b595773e59b70acbfe8c743e977a98468469b77..358cf304f4c91203749bac10f6e9154eda0a3778 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/jhash.h>
+#include <linux/module.h>
 #include <linux/sizes.h>
 #include <linux/vmalloc.h>
 #include <net/pkt_cls.h>
@@ -563,6 +564,7 @@ static struct Qdisc_ops fq_pie_qdisc_ops __read_mostly = {
        .dump_stats     = fq_pie_dump_stats,
        .owner          = THIS_MODULE,
 };
+MODULE_ALIAS_NET_SCH("fq_pie");
 
 static int __init fq_pie_module_init(void)
 {
index c5de70efdc866fb1b8ef50a3019962a8e11beeca..a0d54b422186fb5983019791ce688b3685cd18ec 100644 (file)
@@ -997,7 +997,8 @@ static const struct nla_policy entry_policy[TCA_TAPRIO_SCHED_ENTRY_MAX + 1] = {
 };
 
 static const struct nla_policy taprio_tc_policy[TCA_TAPRIO_TC_ENTRY_MAX + 1] = {
-       [TCA_TAPRIO_TC_ENTRY_INDEX]        = { .type = NLA_U32 },
+       [TCA_TAPRIO_TC_ENTRY_INDEX]        = NLA_POLICY_MAX(NLA_U32,
+                                                           TC_QOPT_MAX_QUEUE),
        [TCA_TAPRIO_TC_ENTRY_MAX_SDU]      = { .type = NLA_U32 },
        [TCA_TAPRIO_TC_ENTRY_FP]           = NLA_POLICY_RANGE(NLA_U32,
                                                              TC_FP_EXPRESS,
index 7e9c8fc9a5b4545dcb2c2e423ef609bbd77e29f7..e5f3af49a8b6215189066cbc1481406661b594e5 100644 (file)
@@ -2600,9 +2600,9 @@ out:
        return err;
 }
 
-int sendmsg_copy_msghdr(struct msghdr *msg,
-                       struct user_msghdr __user *umsg, unsigned flags,
-                       struct iovec **iov)
+static int sendmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct iovec **iov)
 {
        int err;
 
@@ -2753,10 +2753,10 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
        return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
 }
 
-int recvmsg_copy_msghdr(struct msghdr *msg,
-                       struct user_msghdr __user *umsg, unsigned flags,
-                       struct sockaddr __user **uaddr,
-                       struct iovec **iov)
+static int recvmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct sockaddr __user **uaddr,
+                              struct iovec **iov)
 {
        ssize_t err;
 
index 653e51ae39648da177b84c82881932e9987eaa99..6346690d5c699d4d9f9b46aeeacaa923c0c32256 100644 (file)
@@ -407,7 +407,8 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
        struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
        struct net_device *dev = x->xso.dev;
 
-       if (!x->type_offload)
+       if (!x->type_offload ||
+           (x->xso.type == XFRM_DEV_OFFLOAD_UNSPECIFIED && x->encap))
                return false;
 
        if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET ||
index 07373c5a7afe4fcf3b46e5c2f1d484a79ce0f415..f4e8eb79c1b82bab31775eb48f399b6ffdbd3280 100644 (file)
@@ -20,6 +20,7 @@ CFLAGS_ethtool:=$(call get_hdr_inc,_LINUX_ETHTOOL_NETLINK_H_,ethtool_netlink.h)
 CFLAGS_handshake:=$(call get_hdr_inc,_LINUX_HANDSHAKE_H,handshake.h)
 CFLAGS_mptcp_pm:=$(call get_hdr_inc,_LINUX_MPTCP_PM_H,mptcp_pm.h)
 CFLAGS_netdev:=$(call get_hdr_inc,_LINUX_NETDEV_H,netdev.h)
+CFLAGS_nlctrl:=$(call get_hdr_inc,__LINUX_GENERIC_NETLINK_H,genetlink.h)
 CFLAGS_nfsd:=$(call get_hdr_inc,_LINUX_NFSD_NETLINK_H,nfsd_netlink.h)
 CFLAGS_ovs_datapath:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
 CFLAGS_ovs_flow:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
index cfcb7e2c3813f2dbd3fd5ca9d123a6883713d672..139c330ccf2c3bf995a0c05db14db4f286f7eab6 100644 (file)
@@ -422,13 +422,6 @@ extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
                               struct user_msghdr __user *umsg,
                               struct sockaddr __user *uaddr,
                               unsigned int flags);
-extern int sendmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct iovec **iov);
-extern int recvmsg_copy_msghdr(struct msghdr *msg,
-                              struct user_msghdr __user *umsg, unsigned flags,
-                              struct sockaddr __user **uaddr,
-                              struct iovec **iov);
 extern int __copy_msghdr(struct msghdr *kmsg,
                         struct user_msghdr *umsg,
                         struct sockaddr __user **save_addr);
index a0bb4524e1e9c66bed9ff99d08232be8c4f409fc..a603f7b0a08f07e5d7ac71cd916791c1a7774572 100755 (executable)
@@ -354,7 +354,7 @@ __ping_ipv4()
 
        # Send 100 packets and verify that at least 100 packets hit the rule,
        # to overcome ARP noise.
-       PING_COUNT=100 PING_TIMEOUT=11 ping_do $dev $dst_ip
+       PING_COUNT=100 PING_TIMEOUT=20 ping_do $dev $dst_ip
        check_err $? "Ping failed"
 
        tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100
@@ -410,7 +410,7 @@ __ping_ipv6()
 
        # Send 100 packets and verify that at least 100 packets hit the rule,
        # to overcome neighbor discovery noise.
-       PING_COUNT=100 PING_TIMEOUT=11 ping6_do $dev $dst_ip
+       PING_COUNT=100 PING_TIMEOUT=20 ping6_do $dev $dst_ip
        check_err $? "Ping failed"
 
        tc_check_at_least_x_packets "dev $rp1 egress" 101 100
index d880df89bc8bd51bca702736bad069aa2639f169..e83fde79f40d0f5bc31353a05714e7fd123fc8f8 100755 (executable)
@@ -457,7 +457,7 @@ __ping_ipv4()
 
        # Send 100 packets and verify that at least 100 packets hit the rule,
        # to overcome ARP noise.
-       PING_COUNT=100 PING_TIMEOUT=11 ping_do $dev $dst_ip
+       PING_COUNT=100 PING_TIMEOUT=20 ping_do $dev $dst_ip
        check_err $? "Ping failed"
 
        tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100
@@ -522,7 +522,7 @@ __ping_ipv6()
 
        # Send 100 packets and verify that at least 100 packets hit the rule,
        # to overcome neighbor discovery noise.
-       PING_COUNT=100 PING_TIMEOUT=11 ping6_do $dev $dst_ip
+       PING_COUNT=100 PING_TIMEOUT=20 ping6_do $dev $dst_ip
        check_err $? "Ping failed"
 
        tc_check_at_least_x_packets "dev $rp1 egress" 101 100
index 9cd5e885e91f74b01007cf14bbdb9808aa04c632..380cb15e942e42f7ef5cc652c0131c4a592d44f2 100755 (executable)
@@ -217,6 +217,7 @@ for family in 4 6; do
        cleanup
 
        create_ns
+       ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
        ip netns exec $NS_DST ethtool -K veth$DST rx-gro-list on
        run_test "GRO frag list" $BM_NET$DST 1 0
        cleanup
@@ -227,6 +228,7 @@ for family in 4 6; do
        # use NAT to circumvent GRO FWD check
        create_ns
        ip -n $NS_DST addr add dev veth$DST $BM_NET$DST_NAT/$SUFFIX
+       ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
        ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on
        ip netns exec $NS_DST $IPT -t nat -I PREROUTING -d $BM_NET$DST_NAT \
                                        -j DNAT --to-destination $BM_NET$DST
@@ -240,6 +242,7 @@ for family in 4 6; do
        cleanup
 
        create_vxlan_pair
+       ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
        ip netns exec $NS_DST ethtool -K veth$DST rx-gro-list on
        run_test "GRO frag list over UDP tunnel" $OL_NET$DST 1 1
        cleanup
@@ -247,6 +250,7 @@ for family in 4 6; do
        # use NAT to circumvent GRO FWD check
        create_vxlan_pair
        ip -n $NS_DST addr add dev $VXDEV$DST $OL_NET$DST_NAT/$SUFFIX
+       ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
        ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on
        ip netns exec $NS_DST $IPT -t nat -I PREROUTING -d $OL_NET$DST_NAT \
                                        -j DNAT --to-destination $OL_NET$DST
index 5ae85def07395b50c07600f4a31b7ff69578bb9f..3a394b43e274bdf51e735e60349b44d7e66e5dc2 100755 (executable)
@@ -249,9 +249,9 @@ cleanup
 create_ns
 ip -n $NS_DST link set dev veth$DST up
 ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp
-chk_gro_flag "gro vs xdp while down - gro flag on" $DST on
+chk_gro_flag "gro vs xdp while down - gro flag off" $DST off
 ip -n $NS_DST link set dev veth$DST down
-chk_gro_flag "                      - after down" $DST on
+chk_gro_flag "                      - after down" $DST off
 ip -n $NS_DST link set dev veth$DST xdp off
 chk_gro_flag "                      - after xdp off" $DST off
 ip -n $NS_DST link set dev veth$DST up
@@ -260,6 +260,21 @@ ip -n $NS_SRC link set dev veth$SRC xdp object ${BPF_FILE} section xdp
 chk_gro_flag "                      - after peer xdp" $DST off
 cleanup
 
+create_ns
+ip -n $NS_DST link set dev veth$DST up
+ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp
+ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
+chk_gro_flag "gro vs xdp while down - gro flag on" $DST on
+ip -n $NS_DST link set dev veth$DST down
+chk_gro_flag "                      - after down" $DST on
+ip -n $NS_DST link set dev veth$DST xdp off
+chk_gro_flag "                      - after xdp off" $DST on
+ip -n $NS_DST link set dev veth$DST up
+chk_gro_flag "                      - after up" $DST on
+ip -n $NS_SRC link set dev veth$SRC xdp object ${BPF_FILE} section xdp
+chk_gro_flag "                      - after peer xdp" $DST on
+cleanup
+
 create_ns
 chk_channels "default channels" $DST 1 1
 
@@ -327,11 +342,14 @@ if [ $CPUS -gt 2 ]; then
 fi
 
 ip -n $NS_DST link set dev veth$DST xdp object ${BPF_FILE} section xdp 2>/dev/null
-chk_gro_flag "with xdp attached - gro flag" $DST on
+chk_gro_flag "with xdp attached - gro flag" $DST off
 chk_gro_flag "        - peer gro flag" $SRC off
 chk_tso_flag "        - tso flag" $SRC off
 chk_tso_flag "        - peer tso flag" $DST on
 ip netns exec $NS_DST ethtool -K veth$DST rx-udp-gro-forwarding on
+chk_gro "        - no aggregation" 10
+ip netns exec $NS_DST ethtool -K veth$DST generic-receive-offload on
+chk_gro_flag "        - gro flag with GRO on" $DST on
 chk_gro "        - aggregation" 1
 
 
index 2fc36efb166dc9a2f692f38aa7642588cd7b54c7..a7f8e8a95625930aa568bb04a79fe9b05770be76 100644 (file)
@@ -3,6 +3,7 @@ CONFIG_ARCH_RV32I=y
 CONFIG_MMU=y
 CONFIG_FPU=y
 CONFIG_SOC_VIRT=y
+CONFIG_RISCV_ISA_FALLBACK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
index dc266f3b191557915c27a870c992e871c399e637..daeb3e5e09658526b24b122b63ed05fa9078d212 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_ARCH_RV64I=y
 CONFIG_MMU=y
 CONFIG_FPU=y
 CONFIG_SOC_VIRT=y
+CONFIG_RISCV_ISA_FALLBACK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y