Merge tag 'drm-fixes-2022-04-29' of git://anongit.freedesktop.org/drm/drm
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Apr 2022 01:00:34 +0000 (18:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 Apr 2022 01:00:34 +0000 (18:00 -0700)
Pull drm fixes from Dave Airlie:
 "Another relatively quiet week, amdgpu leads the way, some i915 display
  fixes, and a single sunxi fix.

  amdgpu:
   - Runtime pm fix
   - DCN memory leak fix in error path
   - SI DPM deadlock fix
   - S0ix fix

  amdkfd:
   - GWS fix
   - GWS support for CRIU

  i915:
   - Fix #5284: Backlight control regression on XMG Core 15 e21
   - Fix black display plane on Acer One AO532h
   - Two smaller display fixes

  sunxi:
   - Single fix removing applying PHYS_OFFSET twice"

* tag 'drm-fixes-2022-04-29' of git://anongit.freedesktop.org/drm/drm:
  drm/amdgpu: keep mmhub clock gating being enabled during s2idle suspend
  drm/amd/pm: fix the deadlock issue observed on SI
  drm/amd/display: Fix memory leak in dcn21_clock_source_create
  drm/amdgpu: don't runtime suspend if there are displays attached (v3)
  drm/amdkfd: CRIU add support for GWS queues
  drm/amdkfd: Fix GWS queue count
  drm/sun4i: Remove obsolete references to PHYS_OFFSET
  drm/i915/fbc: Consult hw.crtc instead of uapi.crtc
  drm/i915: Fix SEL_FETCH_PLANE_*(PIPE_B+) register addresses
  drm/i915: Check EDID for HDR static metadata when choosing blc
  drm/i915: Fix DISP_POS_Y and DISP_HEIGHT defines

158 files changed:
Documentation/devicetree/bindings/net/dsa/realtek.yaml
Documentation/devicetree/bindings/regulator/richtek,rt5190a-regulator.yaml
Documentation/filesystems/f2fs.rst
Documentation/vm/page_owner.rst
MAINTAINERS
arch/arm/mach-exynos/Kconfig
drivers/acpi/processor_idle.c
drivers/block/Kconfig
drivers/block/floppy.c
drivers/cpufreq/qcom-cpufreq-hw.c
drivers/cpufreq/sun50i-cpufreq-nvmem.c
drivers/idle/intel_idle.c
drivers/mtd/nand/raw/mtk_ecc.c
drivers/mtd/nand/raw/qcom_nandc.c
drivers/mtd/nand/raw/sh_flctl.c
drivers/net/dsa/lantiq_gswip.c
drivers/net/dsa/mv88e6xxx/port_hidden.c
drivers/net/dsa/realtek/realtek-mdio.c
drivers/net/dsa/realtek/realtek-smi.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/freescale/enetc/enetc_qos.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_tqp_stats.c
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_virtchnl.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
drivers/net/ethernet/microchip/lan966x/lan966x_mac.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
drivers/net/phy/marvell10g.c
drivers/net/virtio_net.c
drivers/net/wan/cosa.c
drivers/net/wireguard/device.c
drivers/pinctrl/intel/pinctrl-alderlake.c
drivers/pinctrl/mediatek/Kconfig
drivers/pinctrl/pinctrl-pistachio.c
drivers/pinctrl/pinctrl-rockchip.c
drivers/pinctrl/qcom/pinctrl-sm6350.c
drivers/pinctrl/samsung/Kconfig
drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
drivers/pinctrl/stm32/pinctrl-stm32.c
drivers/pinctrl/sunplus/sppctl_sp7021.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dell/dell-laptop.c
drivers/platform/x86/gigabyte-wmi.c
drivers/platform/x86/intel/pmc/core.h
drivers/platform/x86/intel/sdsi.c
drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c
drivers/thermal/Kconfig
drivers/thermal/gov_user_space.c
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
drivers/thermal/thermal_sysfs.c
drivers/video/fbdev/arkfb.c
drivers/video/fbdev/aty/aty128fb.c
drivers/video/fbdev/aty/atyfb_base.c
drivers/video/fbdev/aty/radeon_pm.c
drivers/video/fbdev/aty/radeonfb.h
drivers/video/fbdev/clps711x-fb.c
drivers/video/fbdev/controlfb.c
drivers/video/fbdev/i740fb.c
drivers/video/fbdev/imxfb.c
drivers/video/fbdev/kyro/fbdev.c
drivers/video/fbdev/matrox/matroxfb_base.h
drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
drivers/video/fbdev/mmp/core.c
drivers/video/fbdev/neofb.c
drivers/video/fbdev/omap/hwa742.c
drivers/video/fbdev/omap/lcdc.c
drivers/video/fbdev/omap/sossi.c
drivers/video/fbdev/platinumfb.c
drivers/video/fbdev/pm2fb.c
drivers/video/fbdev/pxafb.c
drivers/video/fbdev/s3fb.c
drivers/video/fbdev/sh_mobile_lcdcfb.c
drivers/video/fbdev/sis/sis_main.c
drivers/video/fbdev/tridentfb.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/valkyriefb.c
drivers/video/fbdev/vt8623fb.c
drivers/video/of_display_timing.c
fs/btrfs/ctree.h
fs/btrfs/dev-replace.c
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/scrub.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.h
fs/btrfs/zoned.h
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/inode.c
fs/f2fs/segment.c
fs/f2fs/super.c
fs/gfs2/file.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_inode.c
fs/xfs/xfs_trans.h
fs/zonefs/super.c
include/linux/kernel.h
include/linux/mtd/mtd.h
include/linux/netdevice.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/ip6_tunnel.h
include/net/ip_tunnels.h
include/net/tcp.h
include/net/xsk_buff_pool.h
include/uapi/linux/fb.h
kernel/kprobes.c
lib/hexdump.c
mm/kasan/quarantine.c
mm/nommu.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sync.c
net/bpf/test_run.c
net/bridge/br_switchdev.c
net/core/dev.c
net/core/lwt_bpf.c
net/dsa/port.c
net/dsa/slave.c
net/ipv4/ip_gre.c
net/ipv4/netfilter/nf_flow_table_ipv4.c [deleted file]
net/ipv4/syncookies.c
net/ipv4/tcp_input.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv6/ip6_gre.c
net/ipv6/netfilter.c
net/ipv6/syncookies.c
net/mctp/device.c
net/netfilter/ipvs/ip_vs_conn.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nft_set_rbtree.c
net/netfilter/nft_socket.c
net/sctp/sm_sideeffect.c
net/smc/af_smc.c
net/smc/smc.h
net/smc/smc_close.c
net/tls/tls_device.c
net/xdp/xsk.c
net/xdp/xsk_buff_pool.c
tools/power/x86/intel-speed-select/Makefile
tools/testing/selftests/wireguard/qemu/arch/i686.config
tools/testing/selftests/wireguard/qemu/arch/x86_64.config

index 8756060..99ee4b5 100644 (file)
@@ -27,32 +27,25 @@ description:
   The realtek-mdio driver is an MDIO driver and it must be inserted inside
   an MDIO node.
 
+  The compatible string is only used to identify which (silicon) family the
+  switch belongs to. Roughly speaking, a family is any set of Realtek switches
+  whose chip identification register(s) have a common location and semantics.
+  The different models in a given family can be automatically disambiguated by
+  parsing the chip identification register(s) according to the given family,
+  avoiding the need for a unique compatible string for each model.
+
 properties:
   compatible:
     enum:
       - realtek,rtl8365mb
-      - realtek,rtl8366
       - realtek,rtl8366rb
-      - realtek,rtl8366s
-      - realtek,rtl8367
-      - realtek,rtl8367b
-      - realtek,rtl8367rb
-      - realtek,rtl8367s
-      - realtek,rtl8368s
-      - realtek,rtl8369
-      - realtek,rtl8370
     description: |
-      realtek,rtl8365mb: 4+1 ports
-      realtek,rtl8366: 5+1 ports
-      realtek,rtl8366rb: 5+1 ports
-      realtek,rtl8366s: 5+1 ports
-      realtek,rtl8367:
-      realtek,rtl8367b:
-      realtek,rtl8367rb: 5+2 ports
-      realtek,rtl8367s: 5+2 ports
-      realtek,rtl8368s: 8 ports
-      realtek,rtl8369: 8+1 ports
-      realtek,rtl8370: 8+2 ports
+      realtek,rtl8365mb:
+        Use with models RTL8363NB, RTL8363NB-VB, RTL8363SC, RTL8363SC-VB,
+        RTL8364NB, RTL8364NB-VB, RTL8365MB, RTL8366SC, RTL8367RB-VB, RTL8367S,
+        RTL8367SB, RTL8370MB, RTL8310SR
+      realtek,rtl8366rb:
+        Use with models RTL8366RB, RTL8366S
 
   mdc-gpios:
     description: GPIO line for the MDC clock line.
@@ -335,7 +328,7 @@ examples:
             #size-cells = <0>;
 
             switch@29 {
-                    compatible = "realtek,rtl8367s";
+                    compatible = "realtek,rtl8365mb";
                     reg = <29>;
 
                     reset-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
index 28725c5..edb411b 100644 (file)
@@ -58,7 +58,7 @@ properties:
         type: object
         $ref: regulator.yaml#
         description: |
-          regulator description for buck1 and buck4.
+          regulator description for buck1 to buck4, and ldo.
 
         properties:
           regulator-allowed-modes:
index 4a2426f..ad8dc8c 100644 (file)
@@ -235,12 +235,6 @@ offgrpjquota                Turn off group journalled quota.
 offprjjquota            Turn off project journalled quota.
 quota                   Enable plain user disk quota accounting.
 noquota                         Disable all plain disk quota option.
-whint_mode=%s           Control which write hints are passed down to block
-                        layer. This supports "off", "user-based", and
-                        "fs-based".  In "off" mode (default), f2fs does not pass
-                        down hints. In "user-based" mode, f2fs tries to pass
-                        down hints given by users. And in "fs-based" mode, f2fs
-                        passes down hints with its policy.
 alloc_mode=%s           Adjust block allocation policy, which supports "reuse"
                         and "default".
 fsync_mode=%s           Control the policy of fsync. Currently supports "posix",
@@ -751,70 +745,6 @@ In order to identify whether the data in the victim segment are valid or not,
 F2FS manages a bitmap. Each bit represents the validity of a block, and the
 bitmap is composed of a bit stream covering whole blocks in main area.
 
-Write-hint Policy
------------------
-
-1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
-
-2) whint_mode=user-based. F2FS tries to pass down hints given by
-users.
-
-===================== ======================== ===================
-User                  F2FS                     Block
-===================== ======================== ===================
-N/A                   META                     WRITE_LIFE_NOT_SET
-N/A                   HOT_NODE                 "
-N/A                   WARM_NODE                "
-N/A                   COLD_NODE                "
-ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
-extension list        "                        "
-
--- buffered io
-WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
-WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
-WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
-WRITE_LIFE_NONE       "                        "
-WRITE_LIFE_MEDIUM     "                        "
-WRITE_LIFE_LONG       "                        "
-
--- direct io
-WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
-WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
-WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
-WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
-WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
-WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
-===================== ======================== ===================
-
-3) whint_mode=fs-based. F2FS passes down hints with its policy.
-
-===================== ======================== ===================
-User                  F2FS                     Block
-===================== ======================== ===================
-N/A                   META                     WRITE_LIFE_MEDIUM;
-N/A                   HOT_NODE                 WRITE_LIFE_NOT_SET
-N/A                   WARM_NODE                "
-N/A                   COLD_NODE                WRITE_LIFE_NONE
-ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
-extension list        "                        "
-
--- buffered io
-WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
-WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
-WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_LONG
-WRITE_LIFE_NONE       "                        "
-WRITE_LIFE_MEDIUM     "                        "
-WRITE_LIFE_LONG       "                        "
-
--- direct io
-WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
-WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
-WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
-WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
-WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
-WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
-===================== ======================== ===================
-
 Fallocate(2) Policy
 -------------------
 
index 65204d7..7e0c3f5 100644 (file)
@@ -110,7 +110,7 @@ Usage
    If you want to sort by the page nums of buf, use the ``-m`` parameter.
    The detailed parameters are:
 
-   fundamental function:
+   fundamental function::
 
        Sort:
                -a              Sort by memory allocation time.
@@ -122,7 +122,7 @@ Usage
                -s              Sort by stack trace.
                -t              Sort by times (default).
 
-   additional function:
+   additional function::
 
        Cull:
                --cull <rules>
@@ -153,6 +153,7 @@ Usage
 
 STANDARD FORMAT SPECIFIERS
 ==========================
+::
 
        KEY             LONG            DESCRIPTION
        p               pid             process ID
index 5e8c2f6..2647adf 100644 (file)
@@ -3913,7 +3913,9 @@ BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
 M:     Michael Chan <michael.chan@broadcom.com>
 L:     netdev@vger.kernel.org
 S:     Supported
+F:     drivers/firmware/broadcom/tee_bnxt_fw.c
 F:     drivers/net/ethernet/broadcom/bnxt/
+F:     include/linux/firmware/broadcom/tee_bnxt_fw.h
 
 BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
 M:     Arend van Spriel <aspriel@gmail.com>
@@ -10237,8 +10239,6 @@ F:      drivers/net/ethernet/sgi/ioc3-eth.c
 IOMAP FILESYSTEM LIBRARY
 M:     Christoph Hellwig <hch@infradead.org>
 M:     Darrick J. Wong <djwong@kernel.org>
-M:     linux-xfs@vger.kernel.org
-M:     linux-fsdevel@vger.kernel.org
 L:     linux-xfs@vger.kernel.org
 L:     linux-fsdevel@vger.kernel.org
 S:     Supported
@@ -13625,6 +13625,7 @@ F:      net/core/drop_monitor.c
 
 NETWORKING DRIVERS
 M:     "David S. Miller" <davem@davemloft.net>
+M:     Eric Dumazet <edumazet@google.com>
 M:     Jakub Kicinski <kuba@kernel.org>
 M:     Paolo Abeni <pabeni@redhat.com>
 L:     netdev@vger.kernel.org
@@ -13672,6 +13673,7 @@ F:      tools/testing/selftests/drivers/net/dsa/
 
 NETWORKING [GENERAL]
 M:     "David S. Miller" <davem@davemloft.net>
+M:     Eric Dumazet <edumazet@google.com>
 M:     Jakub Kicinski <kuba@kernel.org>
 M:     Paolo Abeni <pabeni@redhat.com>
 L:     netdev@vger.kernel.org
@@ -21596,7 +21598,6 @@ F:      drivers/xen/*swiotlb*
 XFS FILESYSTEM
 C:     irc://irc.oftc.net/xfs
 M:     Darrick J. Wong <djwong@kernel.org>
-M:     linux-xfs@vger.kernel.org
 L:     linux-xfs@vger.kernel.org
 S:     Supported
 W:     http://xfs.org/
index f7d9936..a9c1efc 100644 (file)
@@ -17,7 +17,6 @@ menuconfig ARCH_EXYNOS
        select EXYNOS_PMU
        select EXYNOS_SROM
        select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
-       select GPIOLIB
        select HAVE_ARM_ARCH_TIMER if ARCH_EXYNOS5
        select HAVE_ARM_SCU if SMP
        select PINCTRL
index 4556c86..eb95e18 100644 (file)
@@ -96,11 +96,6 @@ static const struct dmi_system_id processor_power_dmi_table[] = {
          DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
          DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
         (void *)1},
-       /* T40 can not handle C3 idle state */
-       { set_max_cstate, "IBM ThinkPad T40", {
-         DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
-         DMI_MATCH(DMI_PRODUCT_NAME, "23737CU")},
-        (void *)2},
        {},
 };
 
@@ -795,7 +790,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
                if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2 ||
                    cx->type == ACPI_STATE_C3) {
                        state->enter_dead = acpi_idle_play_dead;
-                       drv->safe_state_index = count;
+                       if (cx->type != ACPI_STATE_C3)
+                               drv->safe_state_index = count;
                }
                /*
                 * Halt-induced C1 is not good for ->enter_s2idle, because it
index 519b6d3..fdb81f2 100644 (file)
@@ -33,6 +33,22 @@ config BLK_DEV_FD
          To compile this driver as a module, choose M here: the
          module will be called floppy.
 
+config BLK_DEV_FD_RAWCMD
+       bool "Support for raw floppy disk commands (DEPRECATED)"
+       depends on BLK_DEV_FD
+       help
+         If you want to use actual physical floppies and expect to do
+         special low-level hardware accesses to them (access and use
+         non-standard formats, for example), then enable this.
+
+         Note that the code enabled by this option is rarely used and
+         might be unstable or insecure, and distros should not enable it.
+
+         Note: FDRAWCMD is deprecated and will be removed from the kernel
+         in the near future.
+
+         If unsure, say N.
+
 config AMIGA_FLOPPY
        tristate "Amiga floppy support"
        depends on AMIGA
index 8c64753..d5b9ff9 100644 (file)
@@ -2982,6 +2982,8 @@ static const char *drive_name(int type, int drive)
                return "(null)";
 }
 
+#ifdef CONFIG_BLK_DEV_FD_RAWCMD
+
 /* raw commands */
 static void raw_cmd_done(int flag)
 {
@@ -3181,6 +3183,35 @@ static int raw_cmd_ioctl(int cmd, void __user *param)
        return ret;
 }
 
+static int floppy_raw_cmd_ioctl(int type, int drive, int cmd,
+                               void __user *param)
+{
+       int ret;
+
+       pr_warn_once("Note: FDRAWCMD is deprecated and will be removed from the kernel in the near future.\n");
+
+       if (type)
+               return -EINVAL;
+       if (lock_fdc(drive))
+               return -EINTR;
+       set_floppy(drive);
+       ret = raw_cmd_ioctl(cmd, param);
+       if (ret == -EINTR)
+               return -EINTR;
+       process_fd_request();
+       return ret;
+}
+
+#else /* CONFIG_BLK_DEV_FD_RAWCMD */
+
+static int floppy_raw_cmd_ioctl(int type, int drive, int cmd,
+                               void __user *param)
+{
+       return -EOPNOTSUPP;
+}
+
+#endif
+
 static int invalidate_drive(struct block_device *bdev)
 {
        /* invalidate the buffer track to force a reread */
@@ -3369,7 +3400,6 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
 {
        int drive = (long)bdev->bd_disk->private_data;
        int type = ITYPE(drive_state[drive].fd_device);
-       int i;
        int ret;
        int size;
        union inparam {
@@ -3520,16 +3550,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
                outparam = &write_errors[drive];
                break;
        case FDRAWCMD:
-               if (type)
-                       return -EINVAL;
-               if (lock_fdc(drive))
-                       return -EINTR;
-               set_floppy(drive);
-               i = raw_cmd_ioctl(cmd, (void __user *)param);
-               if (i == -EINTR)
-                       return -EINTR;
-               process_fd_request();
-               return i;
+               return floppy_raw_cmd_ioctl(type, drive, cmd, (void __user *)param);
        case FDTWADDLE:
                if (lock_fdc(drive))
                        return -EINTR;
index f9d593f..0253731 100644 (file)
 #define CLK_HW_DIV                     2
 #define LUT_TURBO_IND                  1
 
+#define GT_IRQ_STATUS                  BIT(2)
+
 #define HZ_PER_KHZ                     1000
 
 struct qcom_cpufreq_soc_data {
        u32 reg_enable;
+       u32 reg_domain_state;
        u32 reg_dcvs_ctrl;
        u32 reg_freq_lut;
        u32 reg_volt_lut;
+       u32 reg_intr_clr;
        u32 reg_current_vote;
        u32 reg_perf_state;
        u8 lut_row_size;
@@ -280,37 +284,46 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
        }
 }
 
-static unsigned int qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
+static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
 {
-       unsigned int val = readl_relaxed(data->base + data->soc_data->reg_current_vote);
+       unsigned int lval;
+
+       if (data->soc_data->reg_current_vote)
+               lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff;
+       else
+               lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff;
 
-       return (val & 0x3FF) * 19200;
+       return lval * xo_rate;
 }
 
 static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
 {
        struct cpufreq_policy *policy = data->policy;
-       int cpu = cpumask_first(policy->cpus);
+       int cpu = cpumask_first(policy->related_cpus);
        struct device *dev = get_cpu_device(cpu);
        unsigned long freq_hz, throttled_freq;
        struct dev_pm_opp *opp;
-       unsigned int freq;
 
        /*
         * Get the h/w throttled frequency, normalize it using the
         * registered opp table and use it to calculate thermal pressure.
         */
-       freq = qcom_lmh_get_throttle_freq(data);
-       freq_hz = freq * HZ_PER_KHZ;
+       freq_hz = qcom_lmh_get_throttle_freq(data);
 
        opp = dev_pm_opp_find_freq_floor(dev, &freq_hz);
        if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE)
-               dev_pm_opp_find_freq_ceil(dev, &freq_hz);
+               opp = dev_pm_opp_find_freq_ceil(dev, &freq_hz);
+
+       if (IS_ERR(opp)) {
+               dev_warn(dev, "Can't find the OPP for throttling: %pe!\n", opp);
+       } else {
+               throttled_freq = freq_hz / HZ_PER_KHZ;
 
-       throttled_freq = freq_hz / HZ_PER_KHZ;
+               /* Update thermal pressure (the boost frequencies are accepted) */
+               arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
 
-       /* Update thermal pressure (the boost frequencies are accepted) */
-       arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
+               dev_pm_opp_put(opp);
+       }
 
        /*
         * In the unlikely case policy is unregistered do not enable
@@ -350,6 +363,10 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data)
        disable_irq_nosync(c_data->throttle_irq);
        schedule_delayed_work(&c_data->throttle_work, 0);
 
+       if (c_data->soc_data->reg_intr_clr)
+               writel_relaxed(GT_IRQ_STATUS,
+                              c_data->base + c_data->soc_data->reg_intr_clr);
+
        return IRQ_HANDLED;
 }
 
@@ -365,9 +382,11 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = {
 
 static const struct qcom_cpufreq_soc_data epss_soc_data = {
        .reg_enable = 0x0,
+       .reg_domain_state = 0x20,
        .reg_dcvs_ctrl = 0xb0,
        .reg_freq_lut = 0x100,
        .reg_volt_lut = 0x200,
+       .reg_intr_clr = 0x308,
        .reg_perf_state = 0x320,
        .lut_row_size = 4,
 };
@@ -417,16 +436,39 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
        return 0;
 }
 
-static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data)
+static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy)
+{
+       struct qcom_cpufreq_data *data = policy->driver_data;
+       struct platform_device *pdev = cpufreq_get_driver_data();
+       int ret;
+
+       ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n",
+                       data->irq_name, data->throttle_irq);
+
+       return ret;
+}
+
+static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy)
 {
+       struct qcom_cpufreq_data *data = policy->driver_data;
+
        if (data->throttle_irq <= 0)
-               return;
+               return 0;
 
        mutex_lock(&data->throttle_lock);
        data->cancel_throttle = true;
        mutex_unlock(&data->throttle_lock);
 
        cancel_delayed_work_sync(&data->throttle_work);
+       irq_set_affinity_hint(data->throttle_irq, NULL);
+
+       return 0;
+}
+
+static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data)
+{
        free_irq(data->throttle_irq, data);
 }
 
@@ -583,6 +625,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
        .get            = qcom_cpufreq_hw_get,
        .init           = qcom_cpufreq_hw_cpu_init,
        .exit           = qcom_cpufreq_hw_cpu_exit,
+       .online         = qcom_cpufreq_hw_cpu_online,
+       .offline        = qcom_cpufreq_hw_cpu_offline,
        .register_em    = cpufreq_register_em_with_opp,
        .fast_switch    = qcom_cpufreq_hw_fast_switch,
        .name           = "qcom-cpufreq-hw",
index 2deed8d..75e1bf3 100644 (file)
@@ -98,8 +98,10 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        ret = sun50i_cpufreq_get_efuse(&speed);
-       if (ret)
+       if (ret) {
+               kfree(opp_tables);
                return ret;
+       }
 
        snprintf(name, MAX_NAME_LEN, "speed%d", speed);
 
index b7640cf..47551ab 100644 (file)
@@ -69,7 +69,12 @@ static unsigned int preferred_states_mask;
 static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
 
 static unsigned long auto_demotion_disable_flags;
-static bool disable_promotion_to_c1e;
+
+static enum {
+       C1E_PROMOTION_PRESERVE,
+       C1E_PROMOTION_ENABLE,
+       C1E_PROMOTION_DISABLE
+} c1e_promotion = C1E_PROMOTION_PRESERVE;
 
 struct idle_cpu {
        struct cpuidle_state *state_table;
@@ -1398,8 +1403,6 @@ static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
 static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
 #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */
 
-static void c1e_promotion_enable(void);
-
 /**
  * ivt_idle_state_table_update - Tune the idle states table for Ivy Town.
  *
@@ -1578,17 +1581,14 @@ static void __init spr_idle_state_table_update(void)
        unsigned long long msr;
 
        /* Check if user prefers C1E over C1. */
-       if (preferred_states_mask & BIT(2)) {
-               if (preferred_states_mask & BIT(1))
-                       /* Both can't be enabled, stick to the defaults. */
-                       return;
-
+       if ((preferred_states_mask & BIT(2)) &&
+           !(preferred_states_mask & BIT(1))) {
+               /* Disable C1 and enable C1E. */
                spr_cstates[0].flags |= CPUIDLE_FLAG_UNUSABLE;
                spr_cstates[1].flags &= ~CPUIDLE_FLAG_UNUSABLE;
 
                /* Enable C1E using the "C1E promotion" bit. */
-               c1e_promotion_enable();
-               disable_promotion_to_c1e = false;
+               c1e_promotion = C1E_PROMOTION_ENABLE;
        }
 
        /*
@@ -1754,7 +1754,9 @@ static int intel_idle_cpu_init(unsigned int cpu)
        if (auto_demotion_disable_flags)
                auto_demotion_disable();
 
-       if (disable_promotion_to_c1e)
+       if (c1e_promotion == C1E_PROMOTION_ENABLE)
+               c1e_promotion_enable();
+       else if (c1e_promotion == C1E_PROMOTION_DISABLE)
                c1e_promotion_disable();
 
        return 0;
@@ -1833,7 +1835,8 @@ static int __init intel_idle_init(void)
        if (icpu) {
                cpuidle_state_table = icpu->state_table;
                auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
-               disable_promotion_to_c1e = icpu->disable_promotion_to_c1e;
+               if (icpu->disable_promotion_to_c1e)
+                       c1e_promotion = C1E_PROMOTION_DISABLE;
                if (icpu->use_acpi || force_use_acpi)
                        intel_idle_acpi_cst_extract();
        } else if (!intel_idle_acpi_cst_extract()) {
index e7df3da..49ab344 100644 (file)
@@ -43,6 +43,7 @@
 
 struct mtk_ecc_caps {
        u32 err_mask;
+       u32 err_shift;
        const u8 *ecc_strength;
        const u32 *ecc_regs;
        u8 num_ecc_strength;
@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = {
 };
 
 static const u8 ecc_strength_mt7622[] = {
-       4, 6, 8, 10, 12, 14, 16
+       4, 6, 8, 10, 12
 };
 
 enum mtk_ecc_regs {
@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
        for (i = 0; i < sectors; i++) {
                offset = (i >> 2) << 2;
                err = readl(ecc->regs + ECC_DECENUM0 + offset);
-               err = err >> ((i % 4) * 8);
+               err = err >> ((i % 4) * ecc->caps->err_shift);
                err &= ecc->caps->err_mask;
                if (err == ecc->caps->err_mask) {
                        /* uncorrectable errors */
@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
 
 static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
        .err_mask = 0x3f,
+       .err_shift = 8,
        .ecc_strength = ecc_strength_mt2701,
        .ecc_regs = mt2701_ecc_regs,
        .num_ecc_strength = 20,
@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
 
 static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
        .err_mask = 0x7f,
+       .err_shift = 8,
        .ecc_strength = ecc_strength_mt2712,
        .ecc_regs = mt2712_ecc_regs,
        .num_ecc_strength = 23,
@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
 };
 
 static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
-       .err_mask = 0x3f,
+       .err_mask = 0x1f,
+       .err_shift = 5,
        .ecc_strength = ecc_strength_mt7622,
        .ecc_regs = mt7622_ecc_regs,
-       .num_ecc_strength = 7,
+       .num_ecc_strength = 5,
        .ecc_mode_shift = 4,
        .parity_bits = 13,
        .pg_irq_sel = 0,
index 1a77542..048b255 100644 (file)
@@ -2651,10 +2651,23 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
        ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
 
        mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
+       /* Free the initially allocated BAM transaction for reading the ONFI params */
+       if (nandc->props->is_bam)
+               free_bam_transaction(nandc);
 
        nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
                                     cwperpage);
 
+       /* Now allocate the BAM transaction based on updated max_cwperpage */
+       if (nandc->props->is_bam) {
+               nandc->bam_txn = alloc_bam_transaction(nandc);
+               if (!nandc->bam_txn) {
+                       dev_err(nandc->dev,
+                               "failed to allocate bam transaction\n");
+                       return -ENOMEM;
+               }
+       }
+
        /*
         * DATA_UD_BYTES varies based on whether the read/write command protects
         * spare data with ECC too. We protect spare data by default, so we set
@@ -2955,17 +2968,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
        if (ret)
                return ret;
 
-       if (nandc->props->is_bam) {
-               free_bam_transaction(nandc);
-               nandc->bam_txn = alloc_bam_transaction(nandc);
-               if (!nandc->bam_txn) {
-                       dev_err(nandc->dev,
-                               "failed to allocate bam transaction\n");
-                       nand_cleanup(chip);
-                       return -ENOMEM;
-               }
-       }
-
        ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
        if (ret)
                nand_cleanup(chip);
index b85b9c6..a278829 100644 (file)
@@ -384,7 +384,8 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
        dma_addr_t dma_addr;
        dma_cookie_t cookie;
        uint32_t reg;
-       int ret;
+       int ret = 0;
+       unsigned long time_left;
 
        if (dir == DMA_FROM_DEVICE) {
                chan = flctl->chan_fifo0_rx;
@@ -425,13 +426,14 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf,
                goto out;
        }
 
-       ret =
+       time_left =
        wait_for_completion_timeout(&flctl->dma_complete,
                                msecs_to_jiffies(3000));
 
-       if (ret <= 0) {
+       if (time_left == 0) {
                dmaengine_terminate_all(chan);
                dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n");
+               ret = -ETIMEDOUT;
        }
 
 out:
@@ -441,7 +443,7 @@ out:
 
        dma_unmap_single(chan->device->dev, dma_addr, len, dir);
 
-       /* ret > 0 is success */
+       /* ret == 0 is success */
        return ret;
 }
 
@@ -465,7 +467,7 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
 
        /* initiate DMA transfer */
        if (flctl->chan_fifo0_rx && rlen >= 32 &&
-               flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE) > 0)
+               !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE))
                        goto convert;   /* DMA success */
 
        /* do polling transfer */
@@ -524,7 +526,7 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen,
 
        /* initiate DMA transfer */
        if (flctl->chan_fifo0_tx && rlen >= 32 &&
-               flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE) > 0)
+               !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE))
                        return; /* DMA success */
 
        /* do polling transfer */
index a416240..12c15da 100644 (file)
@@ -1681,9 +1681,6 @@ static void gswip_phylink_mac_config(struct dsa_switch *ds, int port,
                break;
        case PHY_INTERFACE_MODE_RMII:
                miicfg |= GSWIP_MII_CFG_MODE_RMIIM;
-
-               /* Configure the RMII clock as output: */
-               miicfg |= GSWIP_MII_CFG_RMII_CLK;
                break;
        case PHY_INTERFACE_MODE_RGMII:
        case PHY_INTERFACE_MODE_RGMII_ID:
index b49d05f..7a9f9ff 100644 (file)
@@ -40,8 +40,9 @@ int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip)
 {
        int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY);
 
-       return mv88e6xxx_wait_bit(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
-                                 MV88E6XXX_PORT_RESERVED_1A, bit, 0);
+       return mv88e6xxx_port_wait_bit(chip,
+                                      MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
+                                      MV88E6XXX_PORT_RESERVED_1A, bit, 0);
 }
 
 int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
index 31e1f10..c58f49d 100644 (file)
@@ -267,7 +267,6 @@ static const struct of_device_id realtek_mdio_of_match[] = {
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
        { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
-       { .compatible = "realtek,rtl8367s", .data = &rtl8365mb_variant, },
 #endif
        { /* sentinel */ },
 };
index 6cec559..45992f7 100644 (file)
@@ -551,10 +551,6 @@ static const struct of_device_id realtek_smi_of_match[] = {
                .compatible = "realtek,rtl8365mb",
                .data = &rtl8365mb_variant,
        },
-       {
-               .compatible = "realtek,rtl8367s",
-               .data = &rtl8365mb_variant,
-       },
 #endif
        { /* sentinel */ },
 };
index c19b072..962253d 100644 (file)
@@ -14153,10 +14153,6 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
 
        /* Stop Tx */
        bnx2x_tx_disable(bp);
-       /* Delete all NAPI objects */
-       bnx2x_del_all_napi(bp);
-       if (CNIC_LOADED(bp))
-               bnx2x_del_all_napi_cnic(bp);
        netdev_reset_tc(bp->dev);
 
        del_timer_sync(&bp->timer);
@@ -14261,6 +14257,11 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
                bnx2x_drain_tx_queues(bp);
                bnx2x_send_unload_req(bp, UNLOAD_RECOVERY);
                bnx2x_netif_stop(bp, 1);
+               bnx2x_del_all_napi(bp);
+
+               if (CNIC_LOADED(bp))
+                       bnx2x_del_all_napi_cnic(bp);
+
                bnx2x_free_irq(bp);
 
                /* Report UNLOAD_DONE to MCP */
index 9a41145..bf1ec8f 100644 (file)
@@ -2035,6 +2035,11 @@ static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
        return skb;
 }
 
+static void bcmgenet_hide_tsb(struct sk_buff *skb)
+{
+       __skb_pull(skb, sizeof(struct status_64));
+}
+
 static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -2141,6 +2146,8 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        GENET_CB(skb)->last_cb = tx_cb_ptr;
+
+       bcmgenet_hide_tsb(skb);
        skb_tx_timestamp(skb);
 
        /* Decrement total BD count and advance our write pointer */
index 79afb1d..9182631 100644 (file)
@@ -297,10 +297,6 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
        if (tc < 0 || tc >= priv->num_tx_rings)
                return -EINVAL;
 
-       /* Do not support TXSTART and TX CSUM offload simutaniously */
-       if (ndev->features & NETIF_F_CSUM_MASK)
-               return -EBUSY;
-
        /* TSD and Qbv are mutually exclusive in hardware */
        if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
                return -EBUSY;
index 11227f5..9f33ec8 100644 (file)
@@ -3731,7 +3731,7 @@ static int fec_enet_init_stop_mode(struct fec_enet_private *fep,
                                         ARRAY_SIZE(out_val));
        if (ret) {
                dev_dbg(&fep->pdev->dev, "no stop mode property\n");
-               return ret;
+               goto out;
        }
 
        fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np);
index 7edf856..928d934 100644 (file)
@@ -1065,19 +1065,23 @@ int hns_mac_init(struct dsaf_device *dsaf_dev)
        device_for_each_child_node(dsaf_dev->dev, child) {
                ret = fwnode_property_read_u32(child, "reg", &port_id);
                if (ret) {
+                       fwnode_handle_put(child);
                        dev_err(dsaf_dev->dev,
                                "get reg fail, ret=%d!\n", ret);
                        return ret;
                }
                if (port_id >= max_port_num) {
+                       fwnode_handle_put(child);
                        dev_err(dsaf_dev->dev,
                                "reg(%u) out of range!\n", port_id);
                        return -EINVAL;
                }
                mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb),
                                      GFP_KERNEL);
-               if (!mac_cb)
+               if (!mac_cb) {
+                       fwnode_handle_put(child);
                        return -ENOMEM;
+               }
                mac_cb->fw_port = child;
                mac_cb->mac_id = (u8)port_id;
                dsaf_dev->mac_cb[port_id] = mac_cb;
index 0c60f41..f3c9395 100644 (file)
@@ -75,7 +75,7 @@ int hclge_comm_tqps_update_stats(struct hnae3_handle *handle,
                ret = hclge_comm_cmd_send(hw, &desc, 1);
                if (ret) {
                        dev_err(&hw->cmq.csq.pdev->dev,
-                               "failed to get tqp stat, ret = %d, tx = %u.\n",
+                               "failed to get tqp stat, ret = %d, rx = %u.\n",
                                ret, i);
                        return ret;
                }
@@ -89,7 +89,7 @@ int hclge_comm_tqps_update_stats(struct hnae3_handle *handle,
                ret = hclge_comm_cmd_send(hw, &desc, 1);
                if (ret) {
                        dev_err(&hw->cmq.csq.pdev->dev,
-                               "failed to get tqp stat, ret = %d, rx = %u.\n",
+                               "failed to get tqp stat, ret = %d, tx = %u.\n",
                                ret, i);
                        return ret;
                }
index 44d9b56..93aeb61 100644 (file)
@@ -562,12 +562,12 @@ static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf,
 
        for (i = 0; i < ring_num; i++) {
                j = 0;
-               sprintf(result[j++], "%8u", i);
-               sprintf(result[j++], "%9u", ring->tx_copybreak);
-               sprintf(result[j++], "%3u", tx_spare->len);
-               sprintf(result[j++], "%3u", tx_spare->next_to_use);
-               sprintf(result[j++], "%3u", tx_spare->next_to_clean);
-               sprintf(result[j++], "%3u", tx_spare->last_to_clean);
+               sprintf(result[j++], "%u", i);
+               sprintf(result[j++], "%u", ring->tx_copybreak);
+               sprintf(result[j++], "%u", tx_spare->len);
+               sprintf(result[j++], "%u", tx_spare->next_to_use);
+               sprintf(result[j++], "%u", tx_spare->next_to_clean);
+               sprintf(result[j++], "%u", tx_spare->last_to_clean);
                sprintf(result[j++], "%pad", &tx_spare->dma);
                hns3_dbg_fill_content(content, sizeof(content),
                                      tx_spare_info_items,
@@ -598,35 +598,35 @@ static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
        u32 base_add_l, base_add_h;
        u32 j = 0;
 
-       sprintf(result[j++], "%8u", index);
+       sprintf(result[j++], "%u", index);
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_BD_NUM_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_BD_LEN_REG));
 
-       sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_TAIL_REG));
 
-       sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_HEAD_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_FBDNUM_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
-       sprintf(result[j++], "%9u", ring->rx_copybreak);
+       sprintf(result[j++], "%u", ring->rx_copybreak);
 
-       sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_EN_REG) ? "on" : "off");
 
        if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
-               sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
+               sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
                        HNS3_RING_RX_EN_REG) ? "on" : "off");
        else
-               sprintf(result[j++], "%10s", "NA");
+               sprintf(result[j++], "%s", "NA");
 
        base_add_h = readl_relaxed(ring->tqp->io_base +
                                        HNS3_RING_RX_RING_BASEADDR_H_REG);
@@ -700,36 +700,36 @@ static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring,
        u32 base_add_l, base_add_h;
        u32 j = 0;
 
-       sprintf(result[j++], "%8u", index);
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", index);
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_BD_NUM_REG));
 
-       sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_TC_REG));
 
-       sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_TAIL_REG));
 
-       sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_HEAD_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_FBDNUM_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_OFFSET_REG));
 
-       sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_TX_RING_PKTNUM_RECORD_REG));
 
-       sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
+       sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
                HNS3_RING_EN_REG) ? "on" : "off");
 
        if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev))
-               sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base +
+               sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base +
                        HNS3_RING_TX_EN_REG) ? "on" : "off");
        else
-               sprintf(result[j++], "%10s", "NA");
+               sprintf(result[j++], "%s", "NA");
 
        base_add_h = readl_relaxed(ring->tqp->io_base +
                                        HNS3_RING_TX_RING_BASEADDR_H_REG);
@@ -848,15 +848,15 @@ static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv,
 {
        unsigned int j = 0;
 
-       sprintf(result[j++], "%5d", idx);
+       sprintf(result[j++], "%d", idx);
        sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info));
-       sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len));
-       sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.pkt_len));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.size));
        sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id));
-       sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag));
-       sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
-       sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.fd_id));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.vlan_tag));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->rx.ot_vlan_tag));
        sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info));
        if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
                u32 ol_info = le32_to_cpu(desc->rx.ol_info);
@@ -930,19 +930,19 @@ static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv,
 {
        unsigned int j = 0;
 
-       sprintf(result[j++], "%6d", idx);
+       sprintf(result[j++], "%d", idx);
        sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->tx.vlan_tag));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->tx.send_size));
        sprintf(result[j++], "%#x",
                le32_to_cpu(desc->tx.type_cs_vlan_tso_len));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv));
-       sprintf(result[j++], "%10u",
+       sprintf(result[j++], "%u", le16_to_cpu(desc->tx.outer_vlan_tag));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->tx.tv));
+       sprintf(result[j++], "%u",
                le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
        sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs));
        sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
-       sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum));
+       sprintf(result[j++], "%u", le16_to_cpu(desc->tx.mss_hw_csum));
 }
 
 static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
index 14dc12c..a3ee787 100644 (file)
@@ -5203,6 +5203,13 @@ static void hns3_state_init(struct hnae3_handle *handle)
                set_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state);
 }
 
+static void hns3_state_uninit(struct hnae3_handle *handle)
+{
+       struct hns3_nic_priv *priv  = handle->priv;
+
+       clear_bit(HNS3_NIC_STATE_INITED, &priv->state);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
        struct pci_dev *pdev = handle->pdev;
@@ -5320,7 +5327,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
        return ret;
 
 out_reg_netdev_fail:
+       hns3_state_uninit(handle);
        hns3_dbg_uninit(handle);
+       hns3_client_stop(handle);
 out_client_start:
        hns3_free_rx_cpu_rmap(netdev);
        hns3_nic_uninit_irq(priv);
index 6799d16..7998ca6 100644 (file)
@@ -94,6 +94,13 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
        enum hclge_comm_cmd_status status;
        struct hclge_desc desc;
 
+       if (msg_len > HCLGE_MBX_MAX_MSG_SIZE) {
+               dev_err(&hdev->pdev->dev,
+                       "msg data length(=%u) exceeds maximum(=%u)\n",
+                       msg_len, HCLGE_MBX_MAX_MSG_SIZE);
+               return -EMSGSIZE;
+       }
+
        resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data;
 
        hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false);
@@ -176,7 +183,7 @@ static int hclge_get_ring_chain_from_mbx(
        ring_num = req->msg.ring_num;
 
        if (ring_num > HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM)
-               return -ENOMEM;
+               return -EINVAL;
 
        for (i = 0; i < ring_num; i++) {
                if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) {
@@ -587,9 +594,9 @@ static int hclge_set_vf_mtu(struct hclge_vport *vport,
        return hclge_set_vport_mtu(vport, mtu);
 }
 
-static void hclge_get_queue_id_in_pf(struct hclge_vport *vport,
-                                    struct hclge_mbx_vf_to_pf_cmd *mbx_req,
-                                    struct hclge_respond_to_vf_msg *resp_msg)
+static int hclge_get_queue_id_in_pf(struct hclge_vport *vport,
+                                   struct hclge_mbx_vf_to_pf_cmd *mbx_req,
+                                   struct hclge_respond_to_vf_msg *resp_msg)
 {
        struct hnae3_handle *handle = &vport->nic;
        struct hclge_dev *hdev = vport->back;
@@ -599,17 +606,18 @@ static void hclge_get_queue_id_in_pf(struct hclge_vport *vport,
        if (queue_id >= handle->kinfo.num_tqps) {
                dev_err(&hdev->pdev->dev, "Invalid queue id(%u) from VF %u\n",
                        queue_id, mbx_req->mbx_src_vfid);
-               return;
+               return -EINVAL;
        }
 
        qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id);
        memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf));
        resp_msg->len = sizeof(qid_in_pf);
+       return 0;
 }
 
-static void hclge_get_rss_key(struct hclge_vport *vport,
-                             struct hclge_mbx_vf_to_pf_cmd *mbx_req,
-                             struct hclge_respond_to_vf_msg *resp_msg)
+static int hclge_get_rss_key(struct hclge_vport *vport,
+                            struct hclge_mbx_vf_to_pf_cmd *mbx_req,
+                            struct hclge_respond_to_vf_msg *resp_msg)
 {
 #define HCLGE_RSS_MBX_RESP_LEN 8
        struct hclge_dev *hdev = vport->back;
@@ -627,13 +635,14 @@ static void hclge_get_rss_key(struct hclge_vport *vport,
                dev_warn(&hdev->pdev->dev,
                         "failed to get the rss hash key, the index(%u) invalid !\n",
                         index);
-               return;
+               return -EINVAL;
        }
 
        memcpy(resp_msg->data,
               &rss_cfg->rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN],
               HCLGE_RSS_MBX_RESP_LEN);
        resp_msg->len = HCLGE_RSS_MBX_RESP_LEN;
+       return 0;
 }
 
 static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code)
@@ -809,10 +818,10 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
                                        "VF fail(%d) to set mtu\n", ret);
                        break;
                case HCLGE_MBX_GET_QID_IN_PF:
-                       hclge_get_queue_id_in_pf(vport, req, &resp_msg);
+                       ret = hclge_get_queue_id_in_pf(vport, req, &resp_msg);
                        break;
                case HCLGE_MBX_GET_RSS_KEY:
-                       hclge_get_rss_key(vport, req, &resp_msg);
+                       ret = hclge_get_rss_key(vport, req, &resp_msg);
                        break;
                case HCLGE_MBX_GET_LINK_MODE:
                        hclge_get_link_mode(vport, req);
index 7768390..5c5931d 100644 (file)
@@ -3210,13 +3210,8 @@ static void ibmvnic_get_ringparam(struct net_device *netdev,
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
 
-       if (adapter->priv_flags & IBMVNIC_USE_SERVER_MAXES) {
-               ring->rx_max_pending = adapter->max_rx_add_entries_per_subcrq;
-               ring->tx_max_pending = adapter->max_tx_entries_per_subcrq;
-       } else {
-               ring->rx_max_pending = IBMVNIC_MAX_QUEUE_SZ;
-               ring->tx_max_pending = IBMVNIC_MAX_QUEUE_SZ;
-       }
+       ring->rx_max_pending = adapter->max_rx_add_entries_per_subcrq;
+       ring->tx_max_pending = adapter->max_tx_entries_per_subcrq;
        ring->rx_mini_max_pending = 0;
        ring->rx_jumbo_max_pending = 0;
        ring->rx_pending = adapter->req_rx_add_entries_per_subcrq;
@@ -3231,23 +3226,21 @@ static int ibmvnic_set_ringparam(struct net_device *netdev,
                                 struct netlink_ext_ack *extack)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-       int ret;
 
-       ret = 0;
+       if (ring->rx_pending > adapter->max_rx_add_entries_per_subcrq  ||
+           ring->tx_pending > adapter->max_tx_entries_per_subcrq) {
+               netdev_err(netdev, "Invalid request.\n");
+               netdev_err(netdev, "Max tx buffers = %llu\n",
+                          adapter->max_rx_add_entries_per_subcrq);
+               netdev_err(netdev, "Max rx buffers = %llu\n",
+                          adapter->max_tx_entries_per_subcrq);
+               return -EINVAL;
+       }
+
        adapter->desired.rx_entries = ring->rx_pending;
        adapter->desired.tx_entries = ring->tx_pending;
 
-       ret = wait_for_reset(adapter);
-
-       if (!ret &&
-           (adapter->req_rx_add_entries_per_subcrq != ring->rx_pending ||
-            adapter->req_tx_entries_per_subcrq != ring->tx_pending))
-               netdev_info(netdev,
-                           "Could not match full ringsize request. Requested: RX %d, TX %d; Allowed: RX %llu, TX %llu\n",
-                           ring->rx_pending, ring->tx_pending,
-                           adapter->req_rx_add_entries_per_subcrq,
-                           adapter->req_tx_entries_per_subcrq);
-       return ret;
+       return wait_for_reset(adapter);
 }
 
 static void ibmvnic_get_channels(struct net_device *netdev,
@@ -3255,14 +3248,8 @@ static void ibmvnic_get_channels(struct net_device *netdev,
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
 
-       if (adapter->priv_flags & IBMVNIC_USE_SERVER_MAXES) {
-               channels->max_rx = adapter->max_rx_queues;
-               channels->max_tx = adapter->max_tx_queues;
-       } else {
-               channels->max_rx = IBMVNIC_MAX_QUEUES;
-               channels->max_tx = IBMVNIC_MAX_QUEUES;
-       }
-
+       channels->max_rx = adapter->max_rx_queues;
+       channels->max_tx = adapter->max_tx_queues;
        channels->max_other = 0;
        channels->max_combined = 0;
        channels->rx_count = adapter->req_rx_queues;
@@ -3275,22 +3262,11 @@ static int ibmvnic_set_channels(struct net_device *netdev,
                                struct ethtool_channels *channels)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-       int ret;
 
-       ret = 0;
        adapter->desired.rx_queues = channels->rx_count;
        adapter->desired.tx_queues = channels->tx_count;
 
-       ret = wait_for_reset(adapter);
-
-       if (!ret &&
-           (adapter->req_rx_queues != channels->rx_count ||
-            adapter->req_tx_queues != channels->tx_count))
-               netdev_info(netdev,
-                           "Could not match full channels request. Requested: RX %d, TX %d; Allowed: RX %llu, TX %llu\n",
-                           channels->rx_count, channels->tx_count,
-                           adapter->req_rx_queues, adapter->req_tx_queues);
-       return ret;
+       return wait_for_reset(adapter);
 }
 
 static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -3298,43 +3274,32 @@ static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
        struct ibmvnic_adapter *adapter = netdev_priv(dev);
        int i;
 
-       switch (stringset) {
-       case ETH_SS_STATS:
-               for (i = 0; i < ARRAY_SIZE(ibmvnic_stats);
-                               i++, data += ETH_GSTRING_LEN)
-                       memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN);
+       if (stringset != ETH_SS_STATS)
+               return;
 
-               for (i = 0; i < adapter->req_tx_queues; i++) {
-                       snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i);
-                       data += ETH_GSTRING_LEN;
+       for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++, data += ETH_GSTRING_LEN)
+               memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN);
 
-                       snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i);
-                       data += ETH_GSTRING_LEN;
+       for (i = 0; i < adapter->req_tx_queues; i++) {
+               snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i);
+               data += ETH_GSTRING_LEN;
 
-                       snprintf(data, ETH_GSTRING_LEN,
-                                "tx%d_dropped_packets", i);
-                       data += ETH_GSTRING_LEN;
-               }
+               snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i);
+               data += ETH_GSTRING_LEN;
 
-               for (i = 0; i < adapter->req_rx_queues; i++) {
-                       snprintf(data, ETH_GSTRING_LEN, "rx%d_packets", i);
-                       data += ETH_GSTRING_LEN;
+               snprintf(data, ETH_GSTRING_LEN, "tx%d_dropped_packets", i);
+               data += ETH_GSTRING_LEN;
+       }
 
-                       snprintf(data, ETH_GSTRING_LEN, "rx%d_bytes", i);
-                       data += ETH_GSTRING_LEN;
+       for (i = 0; i < adapter->req_rx_queues; i++) {
+               snprintf(data, ETH_GSTRING_LEN, "rx%d_packets", i);
+               data += ETH_GSTRING_LEN;
 
-                       snprintf(data, ETH_GSTRING_LEN, "rx%d_interrupts", i);
-                       data += ETH_GSTRING_LEN;
-               }
-               break;
+               snprintf(data, ETH_GSTRING_LEN, "rx%d_bytes", i);
+               data += ETH_GSTRING_LEN;
 
-       case ETH_SS_PRIV_FLAGS:
-               for (i = 0; i < ARRAY_SIZE(ibmvnic_priv_flags); i++)
-                       strcpy(data + i * ETH_GSTRING_LEN,
-                              ibmvnic_priv_flags[i]);
-               break;
-       default:
-               return;
+               snprintf(data, ETH_GSTRING_LEN, "rx%d_interrupts", i);
+               data += ETH_GSTRING_LEN;
        }
 }
 
@@ -3347,8 +3312,6 @@ static int ibmvnic_get_sset_count(struct net_device *dev, int sset)
                return ARRAY_SIZE(ibmvnic_stats) +
                       adapter->req_tx_queues * NUM_TX_STATS +
                       adapter->req_rx_queues * NUM_RX_STATS;
-       case ETH_SS_PRIV_FLAGS:
-               return ARRAY_SIZE(ibmvnic_priv_flags);
        default:
                return -EOPNOTSUPP;
        }
@@ -3401,26 +3364,6 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev,
        }
 }
 
-static u32 ibmvnic_get_priv_flags(struct net_device *netdev)
-{
-       struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-
-       return adapter->priv_flags;
-}
-
-static int ibmvnic_set_priv_flags(struct net_device *netdev, u32 flags)
-{
-       struct ibmvnic_adapter *adapter = netdev_priv(netdev);
-       bool which_maxes = !!(flags & IBMVNIC_USE_SERVER_MAXES);
-
-       if (which_maxes)
-               adapter->priv_flags |= IBMVNIC_USE_SERVER_MAXES;
-       else
-               adapter->priv_flags &= ~IBMVNIC_USE_SERVER_MAXES;
-
-       return 0;
-}
-
 static const struct ethtool_ops ibmvnic_ethtool_ops = {
        .get_drvinfo            = ibmvnic_get_drvinfo,
        .get_msglevel           = ibmvnic_get_msglevel,
@@ -3434,8 +3377,6 @@ static const struct ethtool_ops ibmvnic_ethtool_ops = {
        .get_sset_count         = ibmvnic_get_sset_count,
        .get_ethtool_stats      = ibmvnic_get_ethtool_stats,
        .get_link_ksettings     = ibmvnic_get_link_ksettings,
-       .get_priv_flags         = ibmvnic_get_priv_flags,
-       .set_priv_flags         = ibmvnic_set_priv_flags,
 };
 
 /* Routines for managing CRQs/sCRQs  */
index 8f5cefb..1310c86 100644 (file)
 
 #define IBMVNIC_RESET_DELAY 100
 
-static const char ibmvnic_priv_flags[][ETH_GSTRING_LEN] = {
-#define IBMVNIC_USE_SERVER_MAXES 0x1
-       "use-server-maxes"
-};
-
 struct ibmvnic_login_buffer {
        __be32 len;
        __be32 version;
@@ -883,7 +878,6 @@ struct ibmvnic_adapter {
        struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl;
        dma_addr_t ip_offload_ctrl_tok;
        u32 msg_enable;
-       u32 priv_flags;
 
        /* Vital Product Data (VPD) */
        struct ibmvnic_vpd *vpd;
index 5b11988..9a0a358 100644 (file)
@@ -6929,12 +6929,15 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
 
        dev_dbg(dev, "rebuilding PF after reset_type=%d\n", reset_type);
 
+#define ICE_EMP_RESET_SLEEP_MS 5000
        if (reset_type == ICE_RESET_EMPR) {
                /* If an EMP reset has occurred, any previously pending flash
                 * update will have completed. We no longer know whether or
                 * not the NVM update EMP reset is restricted.
                 */
                pf->fw_emp_reset_disabled = false;
+
+               msleep(ICE_EMP_RESET_SLEEP_MS);
        }
 
        err = ice_init_all_ctrlq(hw);
index 8915a9d..0c43821 100644 (file)
@@ -1046,8 +1046,8 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs)
 
        if (!num_vfs) {
                if (!pci_vfs_assigned(pdev)) {
-                       ice_mbx_deinit_snapshot(&pf->hw);
                        ice_free_vfs(pf);
+                       ice_mbx_deinit_snapshot(&pf->hw);
                        if (pf->lag)
                                ice_enable_lag(pf->lag);
                        return 0;
index 69ff4b9..b72606c 100644 (file)
@@ -3625,6 +3625,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
                return;
        }
 
+       mutex_lock(&vf->cfg_lock);
+
        /* Check if VF is disabled. */
        if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) {
                err = -EPERM;
@@ -3642,32 +3644,20 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
                        err = -EINVAL;
        }
 
-       if (!ice_vc_is_opcode_allowed(vf, v_opcode)) {
-               ice_vc_send_msg_to_vf(vf, v_opcode,
-                                     VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL,
-                                     0);
-               ice_put_vf(vf);
-               return;
-       }
-
 error_handler:
        if (err) {
                ice_vc_send_msg_to_vf(vf, v_opcode, VIRTCHNL_STATUS_ERR_PARAM,
                                      NULL, 0);
                dev_err(dev, "Invalid message from VF %d, opcode %d, len %d, error %d\n",
                        vf_id, v_opcode, msglen, err);
-               ice_put_vf(vf);
-               return;
+               goto finish;
        }
 
-       /* VF is being configured in another context that triggers a VFR, so no
-        * need to process this message
-        */
-       if (!mutex_trylock(&vf->cfg_lock)) {
-               dev_info(dev, "VF %u is being configured in another context that will trigger a VFR, so there is no need to handle this message\n",
-                        vf->vf_id);
-               ice_put_vf(vf);
-               return;
+       if (!ice_vc_is_opcode_allowed(vf, v_opcode)) {
+               ice_vc_send_msg_to_vf(vf, v_opcode,
+                                     VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL,
+                                     0);
+               goto finish;
        }
 
        switch (v_opcode) {
@@ -3780,6 +3770,7 @@ error_handler:
                         vf_id, v_opcode, err);
        }
 
+finish:
        mutex_unlock(&vf->cfg_lock);
        ice_put_vf(vf);
 }
index e596e1a..69d11ff 100644 (file)
@@ -903,7 +903,8 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
        /* Tx IPsec offload doesn't seem to work on this
         * device, so block these requests for now.
         */
-       if (!(sam->flags & XFRM_OFFLOAD_INBOUND)) {
+       sam->flags = sam->flags & ~XFRM_OFFLOAD_IPV6;
+       if (sam->flags != XFRM_OFFLOAD_INBOUND) {
                err = -EOPNOTSUPP;
                goto err_out;
        }
index 2679111..005e56e 100644 (file)
@@ -346,7 +346,7 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
 
                        lan966x_mac_process_raw_entry(&raw_entries[column],
                                                      mac, &vid, &dest_idx);
-                       if (WARN_ON(dest_idx > lan966x->num_phys_ports))
+                       if (WARN_ON(dest_idx >= lan966x->num_phys_ports))
                                continue;
 
                        /* If the entry in SW is found, then there is nothing
@@ -393,7 +393,7 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row,
 
                lan966x_mac_process_raw_entry(&raw_entries[column],
                                              mac, &vid, &dest_idx);
-               if (WARN_ON(dest_idx > lan966x->num_phys_ports))
+               if (WARN_ON(dest_idx >= lan966x->num_phys_ports))
                        continue;
 
                mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx);
index ee9c607..ca71b62 100644 (file)
@@ -551,7 +551,7 @@ int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
        struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1];
        struct ocelot_port *ocelot_port = ocelot->ports[port];
        struct ocelot_vcap_filter *filter;
-       int err;
+       int err = 0;
        u32 val;
 
        list_for_each_entry(filter, &block->rules, list) {
@@ -570,7 +570,7 @@ int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
        if (vlan_aware)
                err = ocelot_del_vlan_unaware_pvid(ocelot, port,
                                                   ocelot_port->bridge);
-       else
+       else if (ocelot_port->bridge)
                err = ocelot_add_vlan_unaware_pvid(ocelot, port,
                                                   ocelot_port->bridge);
        if (err)
@@ -629,6 +629,13 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
 {
        int err;
 
+       /* Ignore VID 0 added to our RX filter by the 8021q module, since
+        * that collides with OCELOT_STANDALONE_PVID and changes it from
+        * egress-untagged to egress-tagged.
+        */
+       if (!vid)
+               return 0;
+
        err = ocelot_vlan_member_add(ocelot, port, vid, untagged);
        if (err)
                return err;
@@ -651,6 +658,9 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
        bool del_pvid = false;
        int err;
 
+       if (!vid)
+               return 0;
+
        if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
                del_pvid = true;
 
index ac9e6c7..6b447d8 100644 (file)
@@ -65,8 +65,9 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
        struct phy_device *phy_dev = ndev->phydev;
        u32 val;
 
-       writew(SGMII_ADAPTER_DISABLE,
-              sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
+       if (sgmii_adapter_base)
+               writew(SGMII_ADAPTER_DISABLE,
+                      sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
 
        if (splitter_base) {
                val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
@@ -88,10 +89,11 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
                writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
        }
 
-       writew(SGMII_ADAPTER_ENABLE,
-              sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
-       if (phy_dev)
+       if (phy_dev && sgmii_adapter_base) {
+               writew(SGMII_ADAPTER_ENABLE,
+                      sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
                tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed);
+       }
 }
 
 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
index b6fea11..2b7d072 100644 (file)
@@ -880,7 +880,7 @@ static int mv3310_read_status_copper(struct phy_device *phydev)
 
        cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1);
        if (cssr1 < 0)
-               return val;
+               return cssr1;
 
        /* If the link settings are not resolved, mark the link down */
        if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) {
index 87838cb..cbba9d2 100644 (file)
@@ -1005,6 +1005,24 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                         * xdp.data_meta were adjusted
                         */
                        len = xdp.data_end - xdp.data + vi->hdr_len + metasize;
+
+                       /* recalculate headroom if xdp.data or xdp_data_meta
+                        * were adjusted, note that offset should always point
+                        * to the start of the reserved bytes for virtio_net
+                        * header which are followed by xdp.data, that means
+                        * that offset is equal to the headroom (when buf is
+                        * starting at the beginning of the page, otherwise
+                        * there is a base offset inside the page) but it's used
+                        * with a different starting point (buf start) than
+                        * xdp.data (buf start + vnet hdr size). If xdp.data or
+                        * data_meta were adjusted by the xdp prog then the
+                        * headroom size has changed and so has the offset, we
+                        * can use data_hard_start, which points at buf start +
+                        * vnet hdr size, to calculate the new headroom and use
+                        * it later to compute buf start in page_to_skb()
+                        */
+                       headroom = xdp.data - xdp.data_hard_start - metasize;
+
                        /* We can only create skb based on xdp_page. */
                        if (unlikely(xdp_page != page)) {
                                rcu_read_unlock();
@@ -1012,7 +1030,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                                head_skb = page_to_skb(vi, rq, xdp_page, offset,
                                                       len, PAGE_SIZE, false,
                                                       metasize,
-                                                      VIRTIO_XDP_HEADROOM);
+                                                      headroom);
                                return head_skb;
                        }
                        break;
index 23d2954..1e56720 100644 (file)
@@ -349,7 +349,7 @@ static int __init cosa_init(void)
                }
        } else {
                cosa_major = register_chrdev(0, "cosa", &cosa_fops);
-               if (!cosa_major) {
+               if (cosa_major < 0) {
                        pr_warn("unable to register chardev\n");
                        err = -EIO;
                        goto out;
index 0fad133..aa9a7a5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/if_arp.h>
 #include <linux/icmp.h>
 #include <linux/suspend.h>
+#include <net/dst_metadata.h>
 #include <net/icmp.h>
 #include <net/rtnetlink.h>
 #include <net/ip_tunnels.h>
@@ -167,7 +168,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev)
                goto err_peer;
        }
 
-       mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
+       mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
        __skb_queue_head_init(&packets);
        if (!skb_is_gso(skb)) {
index 32ba50e..62dbd1e 100644 (file)
 
 #include "pinctrl-intel.h"
 
-#define ADL_PAD_OWN    0x0a0
-#define ADL_PADCFGLOCK 0x110
-#define ADL_HOSTSW_OWN 0x150
-#define ADL_GPI_IS     0x200
-#define ADL_GPI_IE     0x220
+#define ADL_N_PAD_OWN          0x020
+#define ADL_N_PADCFGLOCK       0x080
+#define ADL_N_HOSTSW_OWN       0x0b0
+#define ADL_N_GPI_IS           0x100
+#define ADL_N_GPI_IE           0x120
+
+#define ADL_S_PAD_OWN          0x0a0
+#define ADL_S_PADCFGLOCK       0x110
+#define ADL_S_HOSTSW_OWN       0x150
+#define ADL_S_GPI_IS           0x200
+#define ADL_S_GPI_IE           0x220
 
 #define ADL_GPP(r, s, e, g)                            \
        {                                               \
                .gpio_base = (g),                       \
        }
 
-#define ADL_COMMUNITY(b, s, e, g)                      \
+#define ADL_N_COMMUNITY(b, s, e, g)                    \
+       {                                               \
+               .barno = (b),                           \
+               .padown_offset = ADL_N_PAD_OWN,         \
+               .padcfglock_offset = ADL_N_PADCFGLOCK,  \
+               .hostown_offset = ADL_N_HOSTSW_OWN,     \
+               .is_offset = ADL_N_GPI_IS,              \
+               .ie_offset = ADL_N_GPI_IE,              \
+               .pin_base = (s),                        \
+               .npins = ((e) - (s) + 1),               \
+               .gpps = (g),                            \
+               .ngpps = ARRAY_SIZE(g),                 \
+       }
+
+#define ADL_S_COMMUNITY(b, s, e, g)                    \
        {                                               \
                .barno = (b),                           \
-               .padown_offset = ADL_PAD_OWN,           \
-               .padcfglock_offset = ADL_PADCFGLOCK,    \
-               .hostown_offset = ADL_HOSTSW_OWN,       \
-               .is_offset = ADL_GPI_IS,                \
-               .ie_offset = ADL_GPI_IE,                \
+               .padown_offset = ADL_S_PAD_OWN,         \
+               .padcfglock_offset = ADL_S_PADCFGLOCK,  \
+               .hostown_offset = ADL_S_HOSTSW_OWN,     \
+               .is_offset = ADL_S_GPI_IS,              \
+               .ie_offset = ADL_S_GPI_IE,              \
                .pin_base = (s),                        \
                .npins = ((e) - (s) + 1),               \
                .gpps = (g),                            \
@@ -342,10 +362,10 @@ static const struct intel_padgroup adln_community5_gpps[] = {
 };
 
 static const struct intel_community adln_communities[] = {
-       ADL_COMMUNITY(0, 0, 66, adln_community0_gpps),
-       ADL_COMMUNITY(1, 67, 168, adln_community1_gpps),
-       ADL_COMMUNITY(2, 169, 248, adln_community4_gpps),
-       ADL_COMMUNITY(3, 249, 256, adln_community5_gpps),
+       ADL_N_COMMUNITY(0, 0, 66, adln_community0_gpps),
+       ADL_N_COMMUNITY(1, 67, 168, adln_community1_gpps),
+       ADL_N_COMMUNITY(2, 169, 248, adln_community4_gpps),
+       ADL_N_COMMUNITY(3, 249, 256, adln_community5_gpps),
 };
 
 static const struct intel_pinctrl_soc_data adln_soc_data = {
@@ -713,11 +733,11 @@ static const struct intel_padgroup adls_community5_gpps[] = {
 };
 
 static const struct intel_community adls_communities[] = {
-       ADL_COMMUNITY(0, 0, 94, adls_community0_gpps),
-       ADL_COMMUNITY(1, 95, 150, adls_community1_gpps),
-       ADL_COMMUNITY(2, 151, 199, adls_community3_gpps),
-       ADL_COMMUNITY(3, 200, 269, adls_community4_gpps),
-       ADL_COMMUNITY(4, 270, 303, adls_community5_gpps),
+       ADL_S_COMMUNITY(0, 0, 94, adls_community0_gpps),
+       ADL_S_COMMUNITY(1, 95, 150, adls_community1_gpps),
+       ADL_S_COMMUNITY(2, 151, 199, adls_community3_gpps),
+       ADL_S_COMMUNITY(3, 200, 269, adls_community4_gpps),
+       ADL_S_COMMUNITY(4, 270, 303, adls_community5_gpps),
 };
 
 static const struct intel_pinctrl_soc_data adls_soc_data = {
index 8dca1ef..40accd1 100644 (file)
@@ -30,6 +30,7 @@ config PINCTRL_MTK_MOORE
        select GENERIC_PINMUX_FUNCTIONS
        select GPIOLIB
        select OF_GPIO
+       select EINT_MTK
        select PINCTRL_MTK_V2
 
 config PINCTRL_MTK_PARIS
index 8d271c6..5de691c 100644 (file)
@@ -1374,10 +1374,10 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl)
                }
 
                irq = irq_of_parse_and_map(child, 0);
-               if (irq < 0) {
-                       dev_err(pctl->dev, "No IRQ for bank %u: %d\n", i, irq);
+               if (!irq) {
+                       dev_err(pctl->dev, "No IRQ for bank %u\n", i);
                        of_node_put(child);
-                       ret = irq;
+                       ret = -EINVAL;
                        goto err;
                }
 
index a1b598b..2cb79e6 100644 (file)
@@ -457,95 +457,110 @@ static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
 
 static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
        {
+               /* gpio1b6_sel */
                .num = 1,
                .pin = 14,
                .reg = 0x28,
                .bit = 12,
                .mask = 0xf
        }, {
+               /* gpio1b7_sel */
                .num = 1,
                .pin = 15,
                .reg = 0x2c,
                .bit = 0,
                .mask = 0x3
        }, {
+               /* gpio1c2_sel */
                .num = 1,
                .pin = 18,
                .reg = 0x30,
                .bit = 4,
                .mask = 0xf
        }, {
+               /* gpio1c3_sel */
                .num = 1,
                .pin = 19,
                .reg = 0x30,
                .bit = 8,
                .mask = 0xf
        }, {
+               /* gpio1c4_sel */
                .num = 1,
                .pin = 20,
                .reg = 0x30,
                .bit = 12,
                .mask = 0xf
        }, {
+               /* gpio1c5_sel */
                .num = 1,
                .pin = 21,
                .reg = 0x34,
                .bit = 0,
                .mask = 0xf
        }, {
+               /* gpio1c6_sel */
                .num = 1,
                .pin = 22,
                .reg = 0x34,
                .bit = 4,
                .mask = 0xf
        }, {
+               /* gpio1c7_sel */
                .num = 1,
                .pin = 23,
                .reg = 0x34,
                .bit = 8,
                .mask = 0xf
        }, {
-               .num = 3,
-               .pin = 12,
-               .reg = 0x68,
-               .bit = 8,
-               .mask = 0xf
-       }, {
-               .num = 3,
-               .pin = 13,
-               .reg = 0x68,
-               .bit = 12,
-               .mask = 0xf
-       }, {
+               /* gpio2a2_sel */
                .num = 2,
                .pin = 2,
-               .reg = 0x608,
-               .bit = 0,
-               .mask = 0x7
+               .reg = 0x40,
+               .bit = 4,
+               .mask = 0x3
        }, {
+               /* gpio2a3_sel */
                .num = 2,
                .pin = 3,
-               .reg = 0x608,
-               .bit = 4,
-               .mask = 0x7
+               .reg = 0x40,
+               .bit = 6,
+               .mask = 0x3
        }, {
+               /* gpio2c0_sel */
                .num = 2,
                .pin = 16,
-               .reg = 0x610,
-               .bit = 8,
-               .mask = 0x7
+               .reg = 0x50,
+               .bit = 0,
+               .mask = 0x3
        }, {
+               /* gpio3b2_sel */
                .num = 3,
                .pin = 10,
-               .reg = 0x610,
-               .bit = 0,
-               .mask = 0x7
+               .reg = 0x68,
+               .bit = 4,
+               .mask = 0x3
        }, {
+               /* gpio3b3_sel */
                .num = 3,
                .pin = 11,
-               .reg = 0x610,
-               .bit = 4,
-               .mask = 0x7
+               .reg = 0x68,
+               .bit = 6,
+               .mask = 0x3
+       }, {
+               /* gpio3b4_sel */
+               .num = 3,
+               .pin = 12,
+               .reg = 0x68,
+               .bit = 8,
+               .mask = 0xf
+       }, {
+               /* gpio3b5_sel */
+               .num = 3,
+               .pin = 13,
+               .reg = 0x68,
+               .bit = 12,
+               .mask = 0xf
        },
 };
 
index 4d37b81..a91a866 100644 (file)
@@ -264,14 +264,14 @@ static const struct pinctrl_pin_desc sm6350_pins[] = {
        PINCTRL_PIN(153, "GPIO_153"),
        PINCTRL_PIN(154, "GPIO_154"),
        PINCTRL_PIN(155, "GPIO_155"),
-       PINCTRL_PIN(156, "SDC1_RCLK"),
-       PINCTRL_PIN(157, "SDC1_CLK"),
-       PINCTRL_PIN(158, "SDC1_CMD"),
-       PINCTRL_PIN(159, "SDC1_DATA"),
-       PINCTRL_PIN(160, "SDC2_CLK"),
-       PINCTRL_PIN(161, "SDC2_CMD"),
-       PINCTRL_PIN(162, "SDC2_DATA"),
-       PINCTRL_PIN(163, "UFS_RESET"),
+       PINCTRL_PIN(156, "UFS_RESET"),
+       PINCTRL_PIN(157, "SDC1_RCLK"),
+       PINCTRL_PIN(158, "SDC1_CLK"),
+       PINCTRL_PIN(159, "SDC1_CMD"),
+       PINCTRL_PIN(160, "SDC1_DATA"),
+       PINCTRL_PIN(161, "SDC2_CLK"),
+       PINCTRL_PIN(162, "SDC2_CMD"),
+       PINCTRL_PIN(163, "SDC2_DATA"),
 };
 
 #define DECLARE_MSM_GPIO_PINS(pin) \
index dfd805e..7b0576f 100644 (file)
@@ -4,14 +4,13 @@
 #
 config PINCTRL_SAMSUNG
        bool
-       depends on OF_GPIO
+       select GPIOLIB
        select PINMUX
        select PINCONF
 
 config PINCTRL_EXYNOS
        bool "Pinctrl common driver part for Samsung Exynos SoCs"
-       depends on OF_GPIO
-       depends on ARCH_EXYNOS || ARCH_S5PV210 || COMPILE_TEST
+       depends on ARCH_EXYNOS || ARCH_S5PV210 || (COMPILE_TEST && OF)
        select PINCTRL_SAMSUNG
        select PINCTRL_EXYNOS_ARM if ARM && (ARCH_EXYNOS || ARCH_S5PV210)
        select PINCTRL_EXYNOS_ARM64 if ARM64 && ARCH_EXYNOS
@@ -26,12 +25,10 @@ config PINCTRL_EXYNOS_ARM64
 
 config PINCTRL_S3C24XX
        bool "Samsung S3C24XX SoC pinctrl driver"
-       depends on OF_GPIO
-       depends on ARCH_S3C24XX || COMPILE_TEST
+       depends on ARCH_S3C24XX || (COMPILE_TEST && OF)
        select PINCTRL_SAMSUNG
 
 config PINCTRL_S3C64XX
        bool "Samsung S3C64XX SoC pinctrl driver"
-       depends on OF_GPIO
-       depends on ARCH_S3C64XX || COMPILE_TEST
+       depends on ARCH_S3C64XX || (COMPILE_TEST && OF)
        select PINCTRL_SAMSUNG
index d291819..cb965cf 100644 (file)
@@ -770,7 +770,7 @@ static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
        EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
 };
 
-const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+static const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
        {
                /* pin-controller instance 0 FSYS0 data */
                .pin_banks      = fsd_pin_banks0,
index 9ed7647..f7c9459 100644 (file)
@@ -225,6 +225,13 @@ static void stm32_gpio_free(struct gpio_chip *chip, unsigned offset)
        pinctrl_gpio_free(chip->base + offset);
 }
 
+static int stm32_gpio_get_noclk(struct gpio_chip *chip, unsigned int offset)
+{
+       struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
+
+       return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
+}
+
 static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct stm32_gpio_bank *bank = gpiochip_get_data(chip);
@@ -232,7 +239,7 @@ static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
 
        clk_enable(bank->clk);
 
-       ret = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
+       ret = stm32_gpio_get_noclk(chip, offset);
 
        clk_disable(bank->clk);
 
@@ -311,8 +318,12 @@ static void stm32_gpio_irq_trigger(struct irq_data *d)
        struct stm32_gpio_bank *bank = d->domain->host_data;
        int level;
 
+       /* Do not access the GPIO if this is not LEVEL triggered IRQ. */
+       if (!(bank->irq_type[d->hwirq] & IRQ_TYPE_LEVEL_MASK))
+               return;
+
        /* If level interrupt type then retrig */
-       level = stm32_gpio_get(&bank->gpio_chip, d->hwirq);
+       level = stm32_gpio_get_noclk(&bank->gpio_chip, d->hwirq);
        if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) ||
            (level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH))
                irq_chip_retrigger_hierarchy(d);
@@ -354,6 +365,7 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
 {
        struct stm32_gpio_bank *bank = irq_data->domain->host_data;
        struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent);
+       unsigned long flags;
        int ret;
 
        ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq);
@@ -367,6 +379,10 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
                return ret;
        }
 
+       flags = irqd_get_trigger_type(irq_data);
+       if (flags & IRQ_TYPE_LEVEL_MASK)
+               clk_enable(bank->clk);
+
        return 0;
 }
 
@@ -374,6 +390,9 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data)
 {
        struct stm32_gpio_bank *bank = irq_data->domain->host_data;
 
+       if (bank->irq_type[irq_data->hwirq] & IRQ_TYPE_LEVEL_MASK)
+               clk_disable(bank->clk);
+
        gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq);
 }
 
index 9748345..cd65776 100644 (file)
@@ -419,7 +419,15 @@ static const struct sppctl_grp sp7021grps_prbp[] = {
        EGRP("PROBE_PORT2", 2, pins_prp2),
 };
 
+/*
+ * Due to compatible reason, the first valid item should start at the third
+ * position of the array. Please keep the first two items of the table
+ * no use (dummy).
+ */
 const struct sppctl_func sppctl_list_funcs[] = {
+       FNCN("", pinmux_type_fpmx, 0x00, 0, 0),
+       FNCN("", pinmux_type_fpmx, 0x00, 0, 0),
+
        FNCN("L2SW_CLK_OUT",        pinmux_type_fpmx, 0x00, 0, 7),
        FNCN("L2SW_MAC_SMI_MDC",    pinmux_type_fpmx, 0x00, 8, 7),
        FNCN("L2SW_LED_FLASH0",     pinmux_type_fpmx, 0x01, 0, 7),
index 2104a26..0e7fbed 100644 (file)
@@ -371,10 +371,14 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
 
        switch (obj->type) {
        case ACPI_TYPE_BUFFER:
-               if (obj->buffer.length > size)
+               if (obj->buffer.length > size) {
                        err = -ENOSPC;
-               if (obj->buffer.length == 0)
+                       break;
+               }
+               if (obj->buffer.length == 0) {
                        err = -ENODATA;
+                       break;
+               }
 
                memcpy(ret_buffer, obj->buffer.pointer, obj->buffer.length);
                break;
@@ -2223,9 +2227,10 @@ static int fan_curve_check_present(struct asus_wmi *asus, bool *available,
 
        err = fan_curve_get_factory_default(asus, fan_dev);
        if (err) {
-               if (err == -ENODEV || err == -ENODATA)
-                       return 0;
-               return err;
+               pr_debug("fan_curve_get_factory_default(0x%08x) failed: %d\n",
+                        fan_dev, err);
+               /* Don't cause probe to fail on devices without fan-curves */
+               return 0;
        }
 
        *available = true;
index 8230e7a..1321687 100644 (file)
@@ -80,6 +80,10 @@ static struct quirk_entry quirk_dell_inspiron_1012 = {
        .kbd_led_not_present = true,
 };
 
+static struct quirk_entry quirk_dell_latitude_7520 = {
+       .kbd_missing_ac_tag = true,
+};
+
 static struct platform_driver platform_driver = {
        .driver = {
                .name = "dell-laptop",
@@ -336,6 +340,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
                },
                .driver_data = &quirk_dell_inspiron_1012,
        },
+       {
+               .callback = dmi_matched,
+               .ident = "Dell Latitude 7520",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 7520"),
+               },
+               .driver_data = &quirk_dell_latitude_7520,
+       },
        { }
 };
 
index 658bab4..e87a931 100644 (file)
@@ -148,6 +148,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550I AORUS PRO AX"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"),
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B660 GAMING X DDR4"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 AORUS ELITE"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"),
index a46d3b5..7a059e0 100644 (file)
@@ -236,7 +236,7 @@ enum ppfear_regs {
 #define ADL_LPM_STATUS_LATCH_EN_OFFSET         0x1704
 #define ADL_LPM_LIVE_STATUS_OFFSET             0x1764
 
-const char *pmc_lpm_modes[] = {
+static const char *pmc_lpm_modes[] = {
        "S0i2.0",
        "S0i2.1",
        "S0i2.2",
index 11d14cc..c830e98 100644 (file)
@@ -51,6 +51,8 @@
 #define MBOX_TIMEOUT_US                        2000
 #define MBOX_TIMEOUT_ACQUIRE_US                1000
 #define MBOX_POLLING_PERIOD_US         100
+#define MBOX_ACQUIRE_NUM_RETRIES       5
+#define MBOX_ACQUIRE_RETRY_DELAY_MS    500
 #define MBOX_MAX_PACKETS               4
 
 #define MBOX_OWNER_NONE                        0x00
@@ -81,7 +83,7 @@ enum sdsi_command {
 
 struct sdsi_mbox_info {
        u64     *payload;
-       u64     *buffer;
+       void    *buffer;
        int     size;
 };
 
@@ -163,9 +165,7 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *inf
        total = 0;
        loop = 0;
        do {
-               int offset = SDSI_SIZE_MAILBOX * loop;
-               void __iomem *addr = priv->mbox_addr + offset;
-               u64 *buf = info->buffer + offset / SDSI_SIZE_CMD;
+               void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop);
                u32 packet_size;
 
                /* Poll on ready bit */
@@ -196,7 +196,7 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *inf
                        break;
                }
 
-               sdsi_memcpy64_fromio(buf, addr, round_up(packet_size, SDSI_SIZE_CMD));
+               sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD));
 
                total += packet_size;
 
@@ -243,8 +243,8 @@ static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *in
                  FIELD_PREP(CTRL_PACKET_SIZE, info->size);
        writeq(control, priv->control_addr);
 
-       /* Poll on run_busy bit */
-       ret = readq_poll_timeout(priv->control_addr, control, !(control & CTRL_RUN_BUSY),
+       /* Poll on ready bit */
+       ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
                                 MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
 
        if (ret)
@@ -263,7 +263,7 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info
 {
        u64 control;
        u32 owner;
-       int ret;
+       int ret, retries = 0;
 
        lockdep_assert_held(&priv->mb_lock);
 
@@ -273,13 +273,29 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info
        if (owner != MBOX_OWNER_NONE)
                return -EBUSY;
 
-       /* Write first qword of payload */
-       writeq(info->payload[0], priv->mbox_addr);
+       /*
+        * If there has been no recent transaction and no one owns the mailbox,
+        * we should acquire it in under 1ms. However, if we've accessed it
+        * recently it may take up to 2.1 seconds to acquire it again.
+        */
+       do {
+               /* Write first qword of payload */
+               writeq(info->payload[0], priv->mbox_addr);
+
+               /* Check for ownership */
+               ret = readq_poll_timeout(priv->control_addr, control,
+                       FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND,
+                       MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US);
+
+               if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE &&
+                   retries++ < MBOX_ACQUIRE_NUM_RETRIES) {
+                       msleep(MBOX_ACQUIRE_RETRY_DELAY_MS);
+                       continue;
+               }
 
-       /* Check for ownership */
-       ret = readq_poll_timeout(priv->control_addr, control,
-                                FIELD_GET(CTRL_OWNER, control) & MBOX_OWNER_INBAND,
-                                MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US);
+               /* Either we got it or someone else did. */
+               break;
+       } while (true);
 
        return ret;
 }
index c61f804..8f9c571 100644 (file)
@@ -212,6 +212,9 @@ static int __init intel_uncore_init(void)
        const struct x86_cpu_id *id;
        int ret;
 
+       if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+               return -ENODEV;
+
        id = x86_match_cpu(intel_uncore_cpu_ids);
        if (!id)
                return -ENODEV;
index e37691e..0e5cc94 100644 (file)
@@ -113,8 +113,10 @@ config THERMAL_DEFAULT_GOV_USER_SPACE
        bool "user_space"
        select THERMAL_GOV_USER_SPACE
        help
-         Select this if you want to let the user space manage the
-         platform thermals.
+         The Userspace governor allows to get trip point crossed
+         notification from the kernel via uevents. It is recommended
+         to use the netlink interface instead which gives richer
+         information about the thermal framework events.
 
 config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR
        bool "power_allocator"
index 64a18e3..a62a4e9 100644 (file)
@@ -17,8 +17,7 @@
 
 static int user_space_bind(struct thermal_zone_device *tz)
 {
-       pr_warn_once("Userspace governor deprecated: use thermal netlink " \
-                    "notification instead\n");
+       pr_info_once("Consider using thermal netlink events interface\n");
 
        return 0;
 }
index 4954800..d97f496 100644 (file)
@@ -68,7 +68,7 @@ static int evaluate_odvp(struct int3400_thermal_priv *priv);
 struct odvp_attr {
        int odvp;
        struct int3400_thermal_priv *priv;
-       struct kobj_attribute attr;
+       struct device_attribute attr;
 };
 
 static ssize_t data_vault_read(struct file *file, struct kobject *kobj,
@@ -311,7 +311,7 @@ end:
        return result;
 }
 
-static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr,
+static ssize_t odvp_show(struct device *dev, struct device_attribute *attr,
                         char *buf)
 {
        struct odvp_attr *odvp_attr;
index f154bad..1c4aac8 100644 (file)
@@ -610,9 +610,6 @@ cur_state_store(struct device *dev, struct device_attribute *attr,
        unsigned long state;
        int result;
 
-       dev_warn_once(&cdev->device,
-                     "Setting cooling device state is deprecated\n");
-       
        if (sscanf(buf, "%ld\n", &state) != 1)
                return -EINVAL;
 
index edf169d..eb3e47c 100644 (file)
@@ -566,6 +566,9 @@ static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        int rv, mem, step;
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        /* Find appropriate format */
        rv = svga_match_format (arkfb_formats, var, NULL);
        if (rv < 0)
index 6ff16d3..b26c812 100644 (file)
@@ -68,7 +68,6 @@
 #ifdef CONFIG_PPC_PMAC
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
-#include <asm/prom.h>
 #include "../macmodes.h"
 #endif
 
index 1aef3d6..a3e6fae 100644 (file)
@@ -79,7 +79,6 @@
 
 #ifdef __powerpc__
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include "../macmodes.h"
 #endif
 #ifdef __sparc__
index b5fbd53..97a5972 100644 (file)
@@ -22,7 +22,6 @@
 
 #ifdef CONFIG_PPC_PMAC
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/pmac_feature.h>
 #endif
 
index 93f403c..91d81b5 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <asm/io.h>
 
-#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#ifdef CONFIG_SPARC
 #include <asm/prom.h>
 #endif
 
index c5d15c6..771ce1f 100644 (file)
@@ -268,8 +268,7 @@ static int clps711x_fb_probe(struct platform_device *pdev)
                goto out_fb_release;
        }
 
-       cfb->syscon =
-               syscon_regmap_lookup_by_compatible("cirrus,ep7209-syscon1");
+       cfb->syscon = syscon_regmap_lookup_by_phandle(np, "syscon");
        if (IS_ERR(cfb->syscon)) {
                ret = PTR_ERR(cfb->syscon);
                goto out_fb_release;
index bd59e7b..aba4611 100644 (file)
@@ -47,9 +47,6 @@
 #include <linux/nvram.h>
 #include <linux/adb.h>
 #include <linux/cuda.h>
-#ifdef CONFIG_PPC_PMAC
-#include <asm/prom.h>
-#endif
 #ifdef CONFIG_BOOTX_TEXT
 #include <asm/btext.h>
 #endif
index 52cce0d..09dd855 100644 (file)
@@ -657,6 +657,9 @@ static int i740fb_decode_var(const struct fb_var_screeninfo *var,
 
 static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+       if (!var->pixclock)
+               return -EINVAL;
+
        switch (var->bits_per_pixel) {
        case 8:
                var->red.offset = var->green.offset = var->blue.offset = 0;
@@ -740,7 +743,7 @@ static int i740fb_set_par(struct fb_info *info)
        if (i)
                return i;
 
-       memset(info->screen_base, 0, info->screen_size);
+       memset_io(info->screen_base, 0, info->screen_size);
 
        vga_protect(par);
 
index 6828875..a2f644c 100644 (file)
@@ -925,10 +925,12 @@ static int imxfb_probe(struct platform_device *pdev)
                                sizeof(struct imx_fb_videomode), GFP_KERNEL);
                if (!fbi->mode) {
                        ret = -ENOMEM;
+                       of_node_put(display_np);
                        goto failed_of_parse;
                }
 
                ret = imxfb_of_read_mode(&pdev->dev, display_np, fbi->mode);
+               of_node_put(display_np);
                if (ret)
                        goto failed_of_parse;
        }
index 25801e8..d57772f 100644 (file)
@@ -494,6 +494,8 @@ static int kyrofb_set_par(struct fb_info *info)
                                    info->var.hsync_len +
                                    info->var.left_margin)) / 1000;
 
+       if (!lineclock)
+               return -EINVAL;
 
        /* time for a frame in ns (precision in 32bpp) */
        frameclock = lineclock * (info->var.yres +
index 759dee9..958be68 100644 (file)
@@ -47,7 +47,6 @@
 #include <asm/unaligned.h>
 
 #if defined(CONFIG_PPC_PMAC)
-#include <asm/prom.h>
 #include "../macmodes.h"
 #endif
 
index 6372133..a7508f5 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #if defined(CONFIG_OF)
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #endif
 #include "mb862xxfb.h"
index 1541272..0370746 100644 (file)
@@ -127,19 +127,18 @@ EXPORT_SYMBOL_GPL(mmp_unregister_panel);
  */
 struct mmp_path *mmp_get_path(const char *name)
 {
-       struct mmp_path *path;
-       int found = 0;
+       struct mmp_path *path = NULL, *iter;
 
        mutex_lock(&disp_lock);
-       list_for_each_entry(path, &path_list, node) {
-               if (!strcmp(name, path->name)) {
-                       found = 1;
+       list_for_each_entry(iter, &path_list, node) {
+               if (!strcmp(name, iter->name)) {
+                       path = iter;
                        break;
                }
        }
        mutex_unlock(&disp_lock);
 
-       return found ? path : NULL;
+       return path;
 }
 EXPORT_SYMBOL_GPL(mmp_get_path);
 
index 966df2a..28d32cb 100644 (file)
@@ -585,7 +585,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
        DBG("neofb_check_var");
 
-       if (var->pixclock && PICOS2KHZ(var->pixclock) > par->maxClock)
+       if (!var->pixclock || PICOS2KHZ(var->pixclock) > par->maxClock)
                return -EINVAL;
 
        /* Is the mode larger than the LCD panel? */
index b191bef..9d9fe5c 100644 (file)
@@ -964,7 +964,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
        if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0)
                goto err3;
        hwa742.extif->set_timings(&hwa742.reg_timings);
-       clk_enable(hwa742.sys_ck);
+       clk_prepare_enable(hwa742.sys_ck);
 
        calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk);
        if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0)
@@ -1023,7 +1023,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
 
        return 0;
 err4:
-       clk_disable(hwa742.sys_ck);
+       clk_disable_unprepare(hwa742.sys_ck);
 err3:
        hwa742.extif->cleanup();
 err2:
@@ -1037,7 +1037,7 @@ static void hwa742_cleanup(void)
        hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED);
        hwa742.extif->cleanup();
        hwa742.int_ctrl->cleanup();
-       clk_disable(hwa742.sys_ck);
+       clk_disable_unprepare(hwa742.sys_ck);
 }
 
 struct lcd_ctrl hwa742_ctrl = {
index 7317c9a..97d20dc 100644 (file)
@@ -711,7 +711,7 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
                dev_err(fbdev->dev, "failed to adjust LCD rate\n");
                goto fail1;
        }
-       clk_enable(lcdc.lcd_ck);
+       clk_prepare_enable(lcdc.lcd_ck);
 
        r = request_irq(OMAP_LCDC_IRQ, lcdc_irq_handler, 0, MODULE_NAME, fbdev);
        if (r) {
@@ -746,7 +746,7 @@ fail4:
 fail3:
        free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
 fail2:
-       clk_disable(lcdc.lcd_ck);
+       clk_disable_unprepare(lcdc.lcd_ck);
 fail1:
        clk_put(lcdc.lcd_ck);
 fail0:
@@ -760,7 +760,7 @@ static void omap_lcdc_cleanup(void)
        free_fbmem();
        omap_free_lcd_dma();
        free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
-       clk_disable(lcdc.lcd_ck);
+       clk_disable_unprepare(lcdc.lcd_ck);
        clk_put(lcdc.lcd_ck);
 }
 
index 80ac67f..b9cb8b3 100644 (file)
@@ -598,7 +598,7 @@ static int sossi_init(struct omapfb_device *fbdev)
        l &= ~CONF_SOSSI_RESET_R;
        omap_writel(l, MOD_CONF_CTRL_1);
 
-       clk_enable(sossi.fck);
+       clk_prepare_enable(sossi.fck);
        l = omap_readl(ARM_IDLECT2);
        l &= ~(1 << 8);                 /* DMACK_REQ */
        omap_writel(l, ARM_IDLECT2);
@@ -649,7 +649,7 @@ static int sossi_init(struct omapfb_device *fbdev)
        return 0;
 
 err:
-       clk_disable(sossi.fck);
+       clk_disable_unprepare(sossi.fck);
        clk_put(sossi.fck);
        return r;
 }
@@ -657,6 +657,7 @@ err:
 static void sossi_cleanup(void)
 {
        omap_lcdc_free_dma_callback();
+       clk_unprepare(sossi.fck);
        clk_put(sossi.fck);
        iounmap(sossi.base);
 }
index ce413a9..5b9e26e 100644 (file)
@@ -30,9 +30,9 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/nvram.h>
+#include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
-#include <asm/prom.h>
 
 #include "macmodes.h"
 #include "platinumfb.h"
index c68725e..d3be2c6 100644 (file)
@@ -1504,9 +1504,7 @@ static const struct fb_ops pm2fb_ops = {
 
 
 /**
- * Device initialisation
- *
- * Initialise and allocate resource for PCI device.
+ * pm2fb_probe - Initialise and allocate resource for PCI device.
  *
  * @pdev:      PCI device.
  * @id:                PCI device ID.
@@ -1711,9 +1709,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 /**
- * Device removal.
- *
- * Release all device resources.
+ * pm2fb_remove - Release all device resources.
  *
  * @pdev:      PCI device to clean up.
  */
index f1551e0..8ad91c2 100644 (file)
@@ -2256,10 +2256,10 @@ static int pxafb_probe(struct platform_device *dev)
                        goto failed;
                for (i = 0; i < inf->num_modes; i++)
                        inf->modes[i] = pdata->modes[i];
+       } else {
+               inf = of_pxafb_of_mach_info(&dev->dev);
        }
 
-       if (!pdata)
-               inf = of_pxafb_of_mach_info(&dev->dev);
        if (IS_ERR_OR_NULL(inf))
                goto failed;
 
index 5c74253..b93c8eb 100644 (file)
@@ -549,6 +549,9 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        int rv, mem, step;
        u16 m, n, r;
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        /* Find appropriate format */
        rv = svga_match_format (s3fb_formats, var, NULL);
 
index aa4ebe3..9a44174 100644 (file)
@@ -531,9 +531,6 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
                ch->tx_dev->ops->display_off(ch->tx_dev);
 }
 
-static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
-                                   struct fb_info *info);
-
 /* -----------------------------------------------------------------------------
  * Format helpers
  */
index 742f629..f28fd69 100644 (file)
@@ -4463,7 +4463,7 @@ static void sisfb_post_sis300(struct pci_dev *pdev)
                SiS_SetReg(SISCR, 0x37, 0x02);
                SiS_SetReg(SISPART2, 0x00, 0x1c);
                v4 = 0x00; v5 = 0x00; v6 = 0x10;
-               if(ivideo->SiS_Pr.UseROM) {
+               if (ivideo->SiS_Pr.UseROM && bios) {
                        v4 = bios[0xf5];
                        v5 = bios[0xf6];
                        v6 = bios[0xf7];
index 4d20cb5..319131b 100644 (file)
@@ -996,6 +996,9 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var,
        int ramdac = 230000; /* 230MHz for most 3D chips */
        debug("enter\n");
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        /* check color depth */
        if (bpp == 24)
                bpp = var->bits_per_pixel = 32;
index b6ec0b8..d280733 100644 (file)
@@ -1650,8 +1650,9 @@ static int dlfb_usb_probe(struct usb_interface *intf,
        const struct device_attribute *attr;
        struct dlfb_data *dlfb;
        struct fb_info *info;
-       int retval = -ENOMEM;
+       int retval;
        struct usb_device *usbdev = interface_to_usbdev(intf);
+       struct usb_endpoint_descriptor *out;
 
        /* usb initialization */
        dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
@@ -1665,6 +1666,12 @@ static int dlfb_usb_probe(struct usb_interface *intf,
        dlfb->udev = usb_get_dev(usbdev);
        usb_set_intfdata(intf, dlfb);
 
+       retval = usb_find_common_endpoints(intf->cur_altsetting, NULL, &out, NULL, NULL);
+       if (retval) {
+               dev_err(&intf->dev, "Device should have at lease 1 bulk endpoint!\n");
+               goto error;
+       }
+
        dev_dbg(&intf->dev, "console enable=%d\n", console);
        dev_dbg(&intf->dev, "fb_defio enable=%d\n", fb_defio);
        dev_dbg(&intf->dev, "shadow enable=%d\n", shadow);
@@ -1674,6 +1681,7 @@ static int dlfb_usb_probe(struct usb_interface *intf,
        if (!dlfb_parse_vendor_descriptor(dlfb, intf)) {
                dev_err(&intf->dev,
                        "firmware not recognized, incompatible device?\n");
+               retval = -ENODEV;
                goto error;
        }
 
@@ -1687,8 +1695,10 @@ static int dlfb_usb_probe(struct usb_interface *intf,
 
        /* allocates framebuffer driver structure, not framebuffer memory */
        info = framebuffer_alloc(0, &dlfb->udev->dev);
-       if (!info)
+       if (!info) {
+               retval = -ENOMEM;
                goto error;
+       }
 
        dlfb->info = info;
        info->par = dlfb;
index 8425afe..a6c9d4f 100644 (file)
 #include <linux/nvram.h>
 #include <linux/adb.h>
 #include <linux/cuda.h>
+#include <linux/of_address.h>
 #ifdef CONFIG_MAC
 #include <asm/macintosh.h>
-#else
-#include <asm/prom.h>
 #endif
 
 #include "macmodes.h"
index 7a959e5..a92a8c6 100644 (file)
@@ -321,6 +321,9 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf
 {
        int rv, mem, step;
 
+       if (!var->pixclock)
+               return -EINVAL;
+
        /* Find appropriate format */
        rv = svga_match_format (vt8623fb_formats, var, NULL);
        if (rv < 0)
index f93b6ab..bebd371 100644 (file)
@@ -199,7 +199,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np)
                struct display_timing *dt;
                int r;
 
-               dt = kzalloc(sizeof(*dt), GFP_KERNEL);
+               dt = kmalloc(sizeof(*dt), GFP_KERNEL);
                if (!dt) {
                        pr_err("%pOF: could not allocate display_timing struct\n",
                                np);
index b7631b8..077c95e 100644 (file)
@@ -1060,6 +1060,7 @@ struct btrfs_fs_info {
         */
        spinlock_t relocation_bg_lock;
        u64 data_reloc_bg;
+       struct mutex zoned_data_reloc_io_lock;
 
        u64 nr_global_roots;
 
index 71fd99b..f262026 100644 (file)
@@ -734,7 +734,12 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
 
        btrfs_wait_ordered_roots(fs_info, U64_MAX, 0, (u64)-1);
 
-       /* Commit dev_replace state and reserve 1 item for it. */
+       /*
+        * Commit dev_replace state and reserve 1 item for it.
+        * This is crucial to ensure we won't miss copying extents for new block
+        * groups that are allocated after we started the device replace, and
+        * must be done after setting up the device replace state.
+        */
        trans = btrfs_start_transaction(root, 1);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
index 126f244..ed8e288 100644 (file)
@@ -3157,6 +3157,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
        mutex_init(&fs_info->reloc_mutex);
        mutex_init(&fs_info->delalloc_root_mutex);
        mutex_init(&fs_info->zoned_meta_io_lock);
+       mutex_init(&fs_info->zoned_data_reloc_io_lock);
        seqlock_init(&fs_info->profiles_lock);
 
        INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
index 724e8fe..33c19f5 100644 (file)
@@ -2658,6 +2658,7 @@ int btrfs_repair_one_sector(struct inode *inode,
 
        repair_bio = btrfs_bio_alloc(1);
        repair_bbio = btrfs_bio(repair_bio);
+       repair_bbio->file_offset = start;
        repair_bio->bi_opf = REQ_OP_READ;
        repair_bio->bi_end_io = failed_bio->bi_end_io;
        repair_bio->bi_iter.bi_sector = failrec->logical >> 9;
@@ -3333,24 +3334,37 @@ static int alloc_new_bio(struct btrfs_inode *inode,
        ret = calc_bio_boundaries(bio_ctrl, inode, file_offset);
        if (ret < 0)
                goto error;
-       if (wbc) {
-               struct block_device *bdev;
 
-               bdev = fs_info->fs_devices->latest_dev->bdev;
-               bio_set_dev(bio, bdev);
-               wbc_init_bio(wbc, bio);
-       }
-       if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
-               struct btrfs_device *device;
+       if (wbc) {
+               /*
+                * For Zone append we need the correct block_device that we are
+                * going to write to set in the bio to be able to respect the
+                * hardware limitation.  Look it up here:
+                */
+               if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
+                       struct btrfs_device *dev;
+
+                       dev = btrfs_zoned_get_device(fs_info, disk_bytenr,
+                                                    fs_info->sectorsize);
+                       if (IS_ERR(dev)) {
+                               ret = PTR_ERR(dev);
+                               goto error;
+                       }
 
-               device = btrfs_zoned_get_device(fs_info, disk_bytenr,
-                                               fs_info->sectorsize);
-               if (IS_ERR(device)) {
-                       ret = PTR_ERR(device);
-                       goto error;
+                       bio_set_dev(bio, dev->bdev);
+               } else {
+                       /*
+                        * Otherwise pick the last added device to support
+                        * cgroup writeback.  For multi-device file systems this
+                        * means blk-cgroup policies have to always be set on the
+                        * last added/replaced device.  This is a bit odd but has
+                        * been like that for a long time.
+                        */
+                       bio_set_dev(bio, fs_info->fs_devices->latest_dev->bdev);
                }
-
-               btrfs_bio(bio)->device = device;
+               wbc_init_bio(wbc, bio);
+       } else {
+               ASSERT(bio_op(bio) != REQ_OP_ZONE_APPEND);
        }
        return 0;
 error:
index 5082b9c..1c8a43e 100644 (file)
@@ -7810,8 +7810,6 @@ static blk_status_t btrfs_check_read_dio_bio(struct btrfs_dio_private *dip,
        const bool csum = !(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM);
        struct bio_vec bvec;
        struct bvec_iter iter;
-       const u64 orig_file_offset = dip->file_offset;
-       u64 start = orig_file_offset;
        u32 bio_offset = 0;
        blk_status_t err = BLK_STS_OK;
 
@@ -7821,6 +7819,8 @@ static blk_status_t btrfs_check_read_dio_bio(struct btrfs_dio_private *dip,
                nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info, bvec.bv_len);
                pgoff = bvec.bv_offset;
                for (i = 0; i < nr_sectors; i++) {
+                       u64 start = bbio->file_offset + bio_offset;
+
                        ASSERT(pgoff < PAGE_SIZE);
                        if (uptodate &&
                            (!csum || !check_data_csum(inode, bbio,
@@ -7833,17 +7833,13 @@ static blk_status_t btrfs_check_read_dio_bio(struct btrfs_dio_private *dip,
                        } else {
                                int ret;
 
-                               ASSERT((start - orig_file_offset) < UINT_MAX);
-                               ret = btrfs_repair_one_sector(inode,
-                                               &bbio->bio,
-                                               start - orig_file_offset,
-                                               bvec.bv_page, pgoff,
+                               ret = btrfs_repair_one_sector(inode, &bbio->bio,
+                                               bio_offset, bvec.bv_page, pgoff,
                                                start, bbio->mirror_num,
                                                submit_dio_repair_bio);
                                if (ret)
                                        err = errno_to_blk_status(ret);
                        }
-                       start += sectorsize;
                        ASSERT(bio_offset + sectorsize > bio_offset);
                        bio_offset += sectorsize;
                        pgoff += sectorsize;
@@ -7870,6 +7866,7 @@ static blk_status_t btrfs_submit_bio_start_direct_io(struct inode *inode,
 static void btrfs_end_dio_bio(struct bio *bio)
 {
        struct btrfs_dio_private *dip = bio->bi_private;
+       struct btrfs_bio *bbio = btrfs_bio(bio);
        blk_status_t err = bio->bi_status;
 
        if (err)
@@ -7880,12 +7877,12 @@ static void btrfs_end_dio_bio(struct bio *bio)
                           bio->bi_iter.bi_size, err);
 
        if (bio_op(bio) == REQ_OP_READ)
-               err = btrfs_check_read_dio_bio(dip, btrfs_bio(bio), !err);
+               err = btrfs_check_read_dio_bio(dip, bbio, !err);
 
        if (err)
                dip->dio_bio->bi_status = err;
 
-       btrfs_record_physical_zoned(dip->inode, dip->file_offset, bio);
+       btrfs_record_physical_zoned(dip->inode, bbio->file_offset, bio);
 
        bio_put(bio);
        btrfs_dio_private_put(dip);
@@ -8046,6 +8043,7 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
                bio = btrfs_bio_clone_partial(dio_bio, clone_offset, clone_len);
                bio->bi_private = dip;
                bio->bi_end_io = btrfs_end_dio_bio;
+               btrfs_bio(bio)->file_offset = file_offset;
 
                if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
                        status = extract_ordered_extent(BTRFS_I(inode), bio,
index 1108956..8cd713d 100644 (file)
@@ -3699,6 +3699,31 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                if (!cache)
                        goto skip;
 
+               ASSERT(cache->start <= chunk_offset);
+               /*
+                * We are using the commit root to search for device extents, so
+                * that means we could have found a device extent item from a
+                * block group that was deleted in the current transaction. The
+                * logical start offset of the deleted block group, stored at
+                * @chunk_offset, might be part of the logical address range of
+                * a new block group (which uses different physical extents).
+                * In this case btrfs_lookup_block_group() has returned the new
+                * block group, and its start address is less than @chunk_offset.
+                *
+                * We skip such new block groups, because it's pointless to
+                * process them, as we won't find their extents because we search
+                * for them using the commit root of the extent tree. For a device
+                * replace it's also fine to skip it, we won't miss copying them
+                * to the target device because we have the write duplication
+                * setup through the regular write path (by btrfs_map_block()),
+                * and we have committed a transaction when we started the device
+                * replace, right after setting up the device replace state.
+                */
+               if (cache->start < chunk_offset) {
+                       btrfs_put_block_group(cache);
+                       goto skip;
+               }
+
                if (sctx->is_dev_replace && btrfs_is_zoned(fs_info)) {
                        spin_lock(&cache->lock);
                        if (!cache->to_copy) {
@@ -3822,7 +3847,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                dev_replace->item_needs_writeback = 1;
                up_write(&dev_replace->rwsem);
 
-               ASSERT(cache->start == chunk_offset);
                ret = scrub_chunk(sctx, cache, scrub_dev, found_key.offset,
                                  dev_extent_len);
 
index 571dae8..09e4f1a 100644 (file)
@@ -3188,6 +3188,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                        ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
                        if (ret) {
                                mutex_unlock(&fs_info->tree_root->log_mutex);
+                               blk_finish_plug(&plug);
                                goto out;
                        }
                }
index bd297f2..f3e28f1 100644 (file)
@@ -328,6 +328,9 @@ struct btrfs_fs_devices {
 struct btrfs_bio {
        unsigned int mirror_num;
 
+       /* for direct I/O */
+       u64 file_offset;
+
        /* @device is for stripe IO submission. */
        struct btrfs_device *device;
        u8 *csum;
index cbf016a..6dee762 100644 (file)
@@ -359,7 +359,7 @@ static inline void btrfs_zoned_data_reloc_lock(struct btrfs_inode *inode)
        struct btrfs_root *root = inode->root;
 
        if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
-               btrfs_inode_lock(&inode->vfs_inode, 0);
+               mutex_lock(&root->fs_info->zoned_data_reloc_io_lock);
 }
 
 static inline void btrfs_zoned_data_reloc_unlock(struct btrfs_inode *inode)
@@ -367,7 +367,7 @@ static inline void btrfs_zoned_data_reloc_unlock(struct btrfs_inode *inode)
        struct btrfs_root *root = inode->root;
 
        if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
-               btrfs_inode_unlock(&inode->vfs_inode, 0);
+               mutex_unlock(&root->fs_info->zoned_data_reloc_io_lock);
 }
 
 #endif
index f5366fe..909085a 100644 (file)
@@ -98,9 +98,9 @@ repeat:
        }
 
        if (unlikely(!PageUptodate(page))) {
-               if (page->index == sbi->metapage_eio_ofs &&
-                       sbi->metapage_eio_cnt++ == MAX_RETRY_META_PAGE_EIO) {
-                       set_ckpt_flags(sbi, CP_ERROR_FLAG);
+               if (page->index == sbi->metapage_eio_ofs) {
+                       if (sbi->metapage_eio_cnt++ == MAX_RETRY_META_PAGE_EIO)
+                               set_ckpt_flags(sbi, CP_ERROR_FLAG);
                } else {
                        sbi->metapage_eio_ofs = page->index;
                        sbi->metapage_eio_cnt = 0;
index 8e0c2e7..9a1a526 100644 (file)
@@ -388,11 +388,23 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr)
        return 0;
 }
 
-static void __attach_io_flag(struct f2fs_io_info *fio, unsigned int io_flag)
+static unsigned int f2fs_io_flags(struct f2fs_io_info *fio)
 {
        unsigned int temp_mask = (1 << NR_TEMP_TYPE) - 1;
-       unsigned int fua_flag = io_flag & temp_mask;
-       unsigned int meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
+       unsigned int fua_flag, meta_flag, io_flag;
+       unsigned int op_flags = 0;
+
+       if (fio->op != REQ_OP_WRITE)
+               return 0;
+       if (fio->type == DATA)
+               io_flag = fio->sbi->data_io_flag;
+       else if (fio->type == NODE)
+               io_flag = fio->sbi->node_io_flag;
+       else
+               return 0;
+
+       fua_flag = io_flag & temp_mask;
+       meta_flag = (io_flag >> NR_TEMP_TYPE) & temp_mask;
 
        /*
         * data/node io flag bits per temp:
@@ -401,9 +413,10 @@ static void __attach_io_flag(struct f2fs_io_info *fio, unsigned int io_flag)
         * Cold | Warm | Hot | Cold | Warm | Hot |
         */
        if ((1 << fio->temp) & meta_flag)
-               fio->op_flags |= REQ_META;
+               op_flags |= REQ_META;
        if ((1 << fio->temp) & fua_flag)
-               fio->op_flags |= REQ_FUA;
+               op_flags |= REQ_FUA;
+       return op_flags;
 }
 
 static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
@@ -413,14 +426,10 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
        sector_t sector;
        struct bio *bio;
 
-       if (fio->type == DATA)
-               __attach_io_flag(fio, sbi->data_io_flag);
-       else if (fio->type == NODE)
-               __attach_io_flag(fio, sbi->node_io_flag);
-
        bdev = f2fs_target_device(sbi, fio->new_blkaddr, &sector);
-       bio = bio_alloc_bioset(bdev, npages, fio->op | fio->op_flags, GFP_NOIO,
-                              &f2fs_bioset);
+       bio = bio_alloc_bioset(bdev, npages,
+                               fio->op | fio->op_flags | f2fs_io_flags(fio),
+                               GFP_NOIO, &f2fs_bioset);
        bio->bi_iter.bi_sector = sector;
        if (is_read_io(fio->op)) {
                bio->bi_end_io = f2fs_read_end_io;
index cd1e65b..8c570de 100644 (file)
@@ -154,7 +154,6 @@ struct f2fs_mount_info {
        int s_jquota_fmt;                       /* Format of quota to use */
 #endif
        /* For which write hints are passed down to block layer */
-       int whint_mode;
        int alloc_mode;                 /* segment allocation policy */
        int fsync_mode;                 /* fsync policy */
        int fs_mode;                    /* fs mode: LFS or ADAPTIVE */
@@ -1334,12 +1333,6 @@ enum {
 };
 
 enum {
-       WHINT_MODE_OFF,         /* not pass down write hints */
-       WHINT_MODE_USER,        /* try to pass down hints given by users */
-       WHINT_MODE_FS,          /* pass down hints with F2FS policy */
-};
-
-enum {
        ALLOC_MODE_DEFAULT,     /* stay default */
        ALLOC_MODE_REUSE,       /* reuse segments as much as possible */
 };
@@ -3657,8 +3650,6 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
 int __init f2fs_create_segment_manager_caches(void);
 void f2fs_destroy_segment_manager_caches(void);
 int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
-enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
-                       enum page_type type, enum temp_type temp);
 unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
                        unsigned int segno);
 unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
index 71f232d..8363923 100644 (file)
@@ -550,7 +550,8 @@ make_now:
        }
        f2fs_set_inode_flags(inode);
 
-       if (file_should_truncate(inode)) {
+       if (file_should_truncate(inode) &&
+                       !is_sbi_flag_set(sbi, SBI_POR_DOING)) {
                ret = f2fs_truncate(inode);
                if (ret)
                        goto bad_inode;
index 22dfeb9..bd9731c 100644 (file)
@@ -3243,101 +3243,6 @@ int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
        }
 }
 
-/* This returns write hints for each segment type. This hints will be
- * passed down to block layer. There are mapping tables which depend on
- * the mount option 'whint_mode'.
- *
- * 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
- *
- * 2) whint_mode=user-based. F2FS tries to pass down hints given by users.
- *
- * User                  F2FS                     Block
- * ----                  ----                     -----
- *                       META                     WRITE_LIFE_NOT_SET
- *                       HOT_NODE                 "
- *                       WARM_NODE                "
- *                       COLD_NODE                "
- * ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
- * extension list        "                        "
- *
- * -- buffered io
- * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
- * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
- * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
- * WRITE_LIFE_NONE       "                        "
- * WRITE_LIFE_MEDIUM     "                        "
- * WRITE_LIFE_LONG       "                        "
- *
- * -- direct io
- * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
- * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
- * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
- * WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
- * WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
- * WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
- *
- * 3) whint_mode=fs-based. F2FS passes down hints with its policy.
- *
- * User                  F2FS                     Block
- * ----                  ----                     -----
- *                       META                     WRITE_LIFE_MEDIUM;
- *                       HOT_NODE                 WRITE_LIFE_NOT_SET
- *                       WARM_NODE                "
- *                       COLD_NODE                WRITE_LIFE_NONE
- * ioctl(COLD)           COLD_DATA                WRITE_LIFE_EXTREME
- * extension list        "                        "
- *
- * -- buffered io
- * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
- * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
- * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_LONG
- * WRITE_LIFE_NONE       "                        "
- * WRITE_LIFE_MEDIUM     "                        "
- * WRITE_LIFE_LONG       "                        "
- *
- * -- direct io
- * WRITE_LIFE_EXTREME    COLD_DATA                WRITE_LIFE_EXTREME
- * WRITE_LIFE_SHORT      HOT_DATA                 WRITE_LIFE_SHORT
- * WRITE_LIFE_NOT_SET    WARM_DATA                WRITE_LIFE_NOT_SET
- * WRITE_LIFE_NONE       "                        WRITE_LIFE_NONE
- * WRITE_LIFE_MEDIUM     "                        WRITE_LIFE_MEDIUM
- * WRITE_LIFE_LONG       "                        WRITE_LIFE_LONG
- */
-
-enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
-                               enum page_type type, enum temp_type temp)
-{
-       if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER) {
-               if (type == DATA) {
-                       if (temp == WARM)
-                               return WRITE_LIFE_NOT_SET;
-                       else if (temp == HOT)
-                               return WRITE_LIFE_SHORT;
-                       else if (temp == COLD)
-                               return WRITE_LIFE_EXTREME;
-               } else {
-                       return WRITE_LIFE_NOT_SET;
-               }
-       } else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS) {
-               if (type == DATA) {
-                       if (temp == WARM)
-                               return WRITE_LIFE_LONG;
-                       else if (temp == HOT)
-                               return WRITE_LIFE_SHORT;
-                       else if (temp == COLD)
-                               return WRITE_LIFE_EXTREME;
-               } else if (type == NODE) {
-                       if (temp == WARM || temp == HOT)
-                               return WRITE_LIFE_NOT_SET;
-                       else if (temp == COLD)
-                               return WRITE_LIFE_NONE;
-               } else if (type == META) {
-                       return WRITE_LIFE_MEDIUM;
-               }
-       }
-       return WRITE_LIFE_NOT_SET;
-}
-
 static int __get_segment_type_2(struct f2fs_io_info *fio)
 {
        if (fio->type == DATA)
index ea939db..4368f90 100644 (file)
@@ -138,7 +138,6 @@ enum {
        Opt_jqfmt_vfsold,
        Opt_jqfmt_vfsv0,
        Opt_jqfmt_vfsv1,
-       Opt_whint,
        Opt_alloc,
        Opt_fsync,
        Opt_test_dummy_encryption,
@@ -214,7 +213,6 @@ static match_table_t f2fs_tokens = {
        {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
        {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
        {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
-       {Opt_whint, "whint_mode=%s"},
        {Opt_alloc, "alloc_mode=%s"},
        {Opt_fsync, "fsync_mode=%s"},
        {Opt_test_dummy_encryption, "test_dummy_encryption=%s"},
@@ -975,22 +973,6 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
                        f2fs_info(sbi, "quota operations not supported");
                        break;
 #endif
-               case Opt_whint:
-                       name = match_strdup(&args[0]);
-                       if (!name)
-                               return -ENOMEM;
-                       if (!strcmp(name, "user-based")) {
-                               F2FS_OPTION(sbi).whint_mode = WHINT_MODE_USER;
-                       } else if (!strcmp(name, "off")) {
-                               F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
-                       } else if (!strcmp(name, "fs-based")) {
-                               F2FS_OPTION(sbi).whint_mode = WHINT_MODE_FS;
-                       } else {
-                               kfree(name);
-                               return -EINVAL;
-                       }
-                       kfree(name);
-                       break;
                case Opt_alloc:
                        name = match_strdup(&args[0]);
                        if (!name)
@@ -1328,12 +1310,6 @@ default_check:
                return -EINVAL;
        }
 
-       /* Not pass down write hints if the number of active logs is lesser
-        * than NR_CURSEG_PERSIST_TYPE.
-        */
-       if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_PERSIST_TYPE)
-               F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
-
        if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) {
                f2fs_err(sbi, "Allow to mount readonly mode only");
                return -EROFS;
@@ -1978,10 +1954,6 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
                seq_puts(seq, ",prjquota");
 #endif
        f2fs_show_quota_options(seq, sbi->sb);
-       if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_USER)
-               seq_printf(seq, ",whint_mode=%s", "user-based");
-       else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
-               seq_printf(seq, ",whint_mode=%s", "fs-based");
 
        fscrypt_show_test_dummy_encryption(seq, ',', sbi->sb);
 
@@ -2033,7 +2005,6 @@ static void default_options(struct f2fs_sb_info *sbi)
                F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE;
 
        F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
-       F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
        F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
        F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
        F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
@@ -2314,8 +2285,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
                need_stop_gc = true;
        }
 
-       if (*flags & SB_RDONLY ||
-               F2FS_OPTION(sbi).whint_mode != org_mount_opt.whint_mode) {
+       if (*flags & SB_RDONLY) {
                sync_inodes_sb(sb);
 
                set_sbi_flag(sbi, SBI_IS_DIRTY);
index 22b41ac..48f0132 100644 (file)
@@ -899,10 +899,10 @@ retry:
        ret = gfs2_glock_nq(gh);
        if (ret)
                goto out_uninit;
-retry_under_glock:
        /* Silently fall back to buffered I/O when writing beyond EOF */
        if (iocb->ki_pos + iov_iter_count(from) > i_size_read(&ip->i_inode))
                goto out;
+retry_under_glock:
 
        from->nofault = true;
        ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
@@ -991,8 +991,6 @@ retry_under_glock:
                if (leftover != window_size) {
                        if (gfs2_holder_queued(&gh))
                                goto retry_under_glock;
-                       if (written)
-                               goto out_uninit;
                        goto retry;
                }
        }
@@ -1069,8 +1067,6 @@ retry_under_glock:
                        from->count = min(from->count, window_size - leftover);
                        if (gfs2_holder_queued(gh))
                                goto retry_under_glock;
-                       if (read && !(iocb->ki_flags & IOCB_DIRECT))
-                               goto out_uninit;
                        goto retry;
                }
        }
index e1afb9e..bf4e608 100644 (file)
@@ -406,7 +406,7 @@ xfs_buf_alloc_pages(
 STATIC int
 _xfs_buf_map_pages(
        struct xfs_buf          *bp,
-       uint                    flags)
+       xfs_buf_flags_t         flags)
 {
        ASSERT(bp->b_flags & _XBF_PAGES);
        if (bp->b_page_count == 1) {
@@ -868,7 +868,7 @@ xfs_buf_read_uncached(
        struct xfs_buftarg      *target,
        xfs_daddr_t             daddr,
        size_t                  numblks,
-       int                     flags,
+       xfs_buf_flags_t         flags,
        struct xfs_buf          **bpp,
        const struct xfs_buf_ops *ops)
 {
@@ -903,7 +903,7 @@ int
 xfs_buf_get_uncached(
        struct xfs_buftarg      *target,
        size_t                  numblks,
-       int                     flags,
+       xfs_buf_flags_t         flags,
        struct xfs_buf          **bpp)
 {
        int                     error;
index edcb625..1ee3056 100644 (file)
@@ -22,28 +22,28 @@ struct xfs_buf;
 
 #define XFS_BUF_DADDR_NULL     ((xfs_daddr_t) (-1LL))
 
-#define XBF_READ        (1 << 0) /* buffer intended for reading from device */
-#define XBF_WRITE       (1 << 1) /* buffer intended for writing to device */
-#define XBF_READ_AHEAD  (1 << 2) /* asynchronous read-ahead */
-#define XBF_NO_IOACCT   (1 << 3) /* bypass I/O accounting (non-LRU bufs) */
-#define XBF_ASYNC       (1 << 4) /* initiator will not wait for completion */
-#define XBF_DONE        (1 << 5) /* all pages in the buffer uptodate */
-#define XBF_STALE       (1 << 6) /* buffer has been staled, do not find it */
-#define XBF_WRITE_FAIL  (1 << 7) /* async writes have failed on this buffer */
+#define XBF_READ        (1u << 0) /* buffer intended for reading from device */
+#define XBF_WRITE       (1u << 1) /* buffer intended for writing to device */
+#define XBF_READ_AHEAD  (1u << 2) /* asynchronous read-ahead */
+#define XBF_NO_IOACCT   (1u << 3) /* bypass I/O accounting (non-LRU bufs) */
+#define XBF_ASYNC       (1u << 4) /* initiator will not wait for completion */
+#define XBF_DONE        (1u << 5) /* all pages in the buffer uptodate */
+#define XBF_STALE       (1u << 6) /* buffer has been staled, do not find it */
+#define XBF_WRITE_FAIL  (1u << 7) /* async writes have failed on this buffer */
 
 /* buffer type flags for write callbacks */
-#define _XBF_INODES     (1 << 16)/* inode buffer */
-#define _XBF_DQUOTS     (1 << 17)/* dquot buffer */
-#define _XBF_LOGRECOVERY        (1 << 18)/* log recovery buffer */
+#define _XBF_INODES     (1u << 16)/* inode buffer */
+#define _XBF_DQUOTS     (1u << 17)/* dquot buffer */
+#define _XBF_LOGRECOVERY (1u << 18)/* log recovery buffer */
 
 /* flags used only internally */
-#define _XBF_PAGES      (1 << 20)/* backed by refcounted pages */
-#define _XBF_KMEM       (1 << 21)/* backed by heap memory */
-#define _XBF_DELWRI_Q   (1 << 22)/* buffer on a delwri queue */
+#define _XBF_PAGES      (1u << 20)/* backed by refcounted pages */
+#define _XBF_KMEM       (1u << 21)/* backed by heap memory */
+#define _XBF_DELWRI_Q   (1u << 22)/* buffer on a delwri queue */
 
 /* flags used only as arguments to access routines */
-#define XBF_TRYLOCK     (1 << 30)/* lock requested, but do not wait */
-#define XBF_UNMAPPED    (1 << 31)/* do not map the buffer */
+#define XBF_TRYLOCK     (1u << 30)/* lock requested, but do not wait */
+#define XBF_UNMAPPED    (1u << 31)/* do not map the buffer */
 
 typedef unsigned int xfs_buf_flags_t;
 
@@ -58,7 +58,7 @@ typedef unsigned int xfs_buf_flags_t;
        { XBF_WRITE_FAIL,       "WRITE_FAIL" }, \
        { _XBF_INODES,          "INODES" }, \
        { _XBF_DQUOTS,          "DQUOTS" }, \
-       { _XBF_LOGRECOVERY,             "LOG_RECOVERY" }, \
+       { _XBF_LOGRECOVERY,     "LOG_RECOVERY" }, \
        { _XBF_PAGES,           "PAGES" }, \
        { _XBF_KMEM,            "KMEM" }, \
        { _XBF_DELWRI_Q,        "DELWRI_Q" }, \
@@ -247,11 +247,11 @@ xfs_buf_readahead(
        return xfs_buf_readahead_map(target, &map, 1, ops);
 }
 
-int xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags,
-               struct xfs_buf **bpp);
+int xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks,
+               xfs_buf_flags_t flags, struct xfs_buf **bpp);
 int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr,
-                         size_t numblks, int flags, struct xfs_buf **bpp,
-                         const struct xfs_buf_ops *ops);
+               size_t numblks, xfs_buf_flags_t flags, struct xfs_buf **bpp,
+               const struct xfs_buf_ops *ops);
 int _xfs_buf_read(struct xfs_buf *bp, xfs_buf_flags_t flags);
 void xfs_buf_hold(struct xfs_buf *bp);
 
index 9de6205..39ae53e 100644 (file)
@@ -2594,14 +2594,13 @@ xfs_ifree_cluster(
 }
 
 /*
- * This is called to return an inode to the inode free list.
- * The inode should already be truncated to 0 length and have
- * no pages associated with it.  This routine also assumes that
- * the inode is already a part of the transaction.
+ * This is called to return an inode to the inode free list.  The inode should
+ * already be truncated to 0 length and have no pages associated with it.  This
+ * routine also assumes that the inode is already a part of the transaction.
  *
- * The on-disk copy of the inode will have been added to the list
- * of unlinked inodes in the AGI. We need to remove the inode from
- * that list atomically with respect to freeing it here.
+ * The on-disk copy of the inode will have been added to the list of unlinked
+ * inodes in the AGI. We need to remove the inode from that list atomically with
+ * respect to freeing it here.
  */
 int
 xfs_ifree(
@@ -2623,13 +2622,16 @@ xfs_ifree(
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
 
        /*
-        * Pull the on-disk inode from the AGI unlinked list.
+        * Free the inode first so that we guarantee that the AGI lock is going
+        * to be taken before we remove the inode from the unlinked list. This
+        * makes the AGI lock -> unlinked list modification order the same as
+        * used in O_TMPFILE creation.
         */
-       error = xfs_iunlink_remove(tp, pag, ip);
+       error = xfs_difree(tp, pag, ip->i_ino, &xic);
        if (error)
-               goto out;
+               return error;
 
-       error = xfs_difree(tp, pag, ip->i_ino, &xic);
+       error = xfs_iunlink_remove(tp, pag, ip);
        if (error)
                goto out;
 
index de17784..0c82673 100644 (file)
@@ -175,7 +175,7 @@ xfs_trans_get_buf(
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
        int                     numblks,
-       uint                    flags,
+       xfs_buf_flags_t         flags,
        struct xfs_buf          **bpp)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
index 3614c78..e20e7c8 100644 (file)
@@ -35,6 +35,17 @@ static inline int zonefs_zone_mgmt(struct inode *inode,
 
        lockdep_assert_held(&zi->i_truncate_mutex);
 
+       /*
+        * With ZNS drives, closing an explicitly open zone that has not been
+        * written will change the zone state to "closed", that is, the zone
+        * will remain active. Since this can then cause failure of explicit
+        * open operation on other zones if the drive active zone resources
+        * are exceeded, make sure that the zone does not remain active by
+        * resetting it.
+        */
+       if (op == REQ_OP_ZONE_CLOSE && !zi->i_wpoffset)
+               op = REQ_OP_ZONE_RESET;
+
        trace_zonefs_zone_mgmt(inode, op);
        ret = blkdev_zone_mgmt(inode->i_sb->s_bdev, op, zi->i_zsector,
                               zi->i_zone_size >> SECTOR_SHIFT, GFP_NOFS);
@@ -1142,6 +1153,7 @@ static struct inode *zonefs_alloc_inode(struct super_block *sb)
        inode_init_once(&zi->i_vnode);
        mutex_init(&zi->i_truncate_mutex);
        zi->i_wr_refcnt = 0;
+       zi->i_flags = 0;
 
        return &zi->i_vnode;
 }
@@ -1293,12 +1305,13 @@ static void zonefs_init_dir_inode(struct inode *parent, struct inode *inode,
        inc_nlink(parent);
 }
 
-static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
-                                  enum zonefs_ztype type)
+static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
+                                 enum zonefs_ztype type)
 {
        struct super_block *sb = inode->i_sb;
        struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
        struct zonefs_inode_info *zi = ZONEFS_I(inode);
+       int ret = 0;
 
        inode->i_ino = zone->start >> sbi->s_zone_sectors_shift;
        inode->i_mode = S_IFREG | sbi->s_perm;
@@ -1323,6 +1336,22 @@ static void zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
        sb->s_maxbytes = max(zi->i_max_size, sb->s_maxbytes);
        sbi->s_blocks += zi->i_max_size >> sb->s_blocksize_bits;
        sbi->s_used_blocks += zi->i_wpoffset >> sb->s_blocksize_bits;
+
+       /*
+        * For sequential zones, make sure that any open zone is closed first
+        * to ensure that the initial number of open zones is 0, in sync with
+        * the open zone accounting done when the mount option
+        * ZONEFS_MNTOPT_EXPLICIT_OPEN is used.
+        */
+       if (type == ZONEFS_ZTYPE_SEQ &&
+           (zone->cond == BLK_ZONE_COND_IMP_OPEN ||
+            zone->cond == BLK_ZONE_COND_EXP_OPEN)) {
+               mutex_lock(&zi->i_truncate_mutex);
+               ret = zonefs_zone_mgmt(inode, REQ_OP_ZONE_CLOSE);
+               mutex_unlock(&zi->i_truncate_mutex);
+       }
+
+       return ret;
 }
 
 static struct dentry *zonefs_create_inode(struct dentry *parent,
@@ -1332,6 +1361,7 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
        struct inode *dir = d_inode(parent);
        struct dentry *dentry;
        struct inode *inode;
+       int ret;
 
        dentry = d_alloc_name(parent, name);
        if (!dentry)
@@ -1342,10 +1372,16 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
                goto dput;
 
        inode->i_ctime = inode->i_mtime = inode->i_atime = dir->i_ctime;
-       if (zone)
-               zonefs_init_file_inode(inode, zone, type);
-       else
+       if (zone) {
+               ret = zonefs_init_file_inode(inode, zone, type);
+               if (ret) {
+                       iput(inode);
+                       goto dput;
+               }
+       } else {
                zonefs_init_dir_inode(dir, inode, type);
+       }
+
        d_add(dentry, inode);
        dir->i_size++;
 
index a890428..fe6efb2 100644 (file)
@@ -285,7 +285,7 @@ static inline char *hex_byte_pack_upper(char *buf, u8 byte)
        return buf;
 }
 
-extern int hex_to_bin(char ch);
+extern int hex_to_bin(unsigned char ch);
 extern int __must_check hex2bin(u8 *dst, const char *src, size_t count);
 extern char *bin2hex(char *dst, const void *src, size_t count);
 
index 151607e..955aee1 100644 (file)
@@ -389,10 +389,8 @@ struct mtd_info {
        /* List of partitions attached to this MTD device */
        struct list_head partitions;
 
-       union {
-               struct mtd_part part;
-               struct mtd_master master;
-       };
+       struct mtd_part part;
+       struct mtd_master master;
 };
 
 static inline struct mtd_info *mtd_get_master(struct mtd_info *mtd)
index 59e27a2..b1fbe21 100644 (file)
@@ -199,10 +199,10 @@ struct net_device_stats {
  * Try to fit them in a single cache line, for dev_get_stats() sake.
  */
 struct net_device_core_stats {
-       local_t         rx_dropped;
-       local_t         tx_dropped;
-       local_t         rx_nohandler;
-} __aligned(4 * sizeof(local_t));
+       unsigned long   rx_dropped;
+       unsigned long   tx_dropped;
+       unsigned long   rx_nohandler;
+} __aligned(4 * sizeof(unsigned long));
 
 #include <linux/cache.h>
 #include <linux/skbuff.h>
@@ -3843,15 +3843,15 @@ static __always_inline bool __is_skb_forwardable(const struct net_device *dev,
        return false;
 }
 
-struct net_device_core_stats *netdev_core_stats_alloc(struct net_device *dev);
+struct net_device_core_stats __percpu *netdev_core_stats_alloc(struct net_device *dev);
 
-static inline struct net_device_core_stats *dev_core_stats(struct net_device *dev)
+static inline struct net_device_core_stats __percpu *dev_core_stats(struct net_device *dev)
 {
        /* This READ_ONCE() pairs with the write in netdev_core_stats_alloc() */
        struct net_device_core_stats __percpu *p = READ_ONCE(dev->core_stats);
 
        if (likely(p))
-               return this_cpu_ptr(p);
+               return p;
 
        return netdev_core_stats_alloc(dev);
 }
@@ -3859,14 +3859,11 @@ static inline struct net_device_core_stats *dev_core_stats(struct net_device *de
 #define DEV_CORE_STATS_INC(FIELD)                                              \
 static inline void dev_core_stats_##FIELD##_inc(struct net_device *dev)                \
 {                                                                              \
-       struct net_device_core_stats *p;                                        \
+       struct net_device_core_stats __percpu *p;                               \
                                                                                \
-       preempt_disable();                                                      \
        p = dev_core_stats(dev);                                                \
-                                                                               \
        if (p)                                                                  \
-               local_inc(&p->FIELD);                                           \
-       preempt_enable();                                                       \
+               this_cpu_inc(p->FIELD);                                         \
 }
 DEV_CORE_STATS_INC(rx_dropped)
 DEV_CORE_STATS_INC(tx_dropped)
index 5cb095b..69ef31c 100644 (file)
@@ -578,6 +578,7 @@ enum {
 #define HCI_ERROR_CONNECTION_TIMEOUT   0x08
 #define HCI_ERROR_REJ_LIMITED_RESOURCES        0x0d
 #define HCI_ERROR_REJ_BAD_ADDR         0x0f
+#define HCI_ERROR_INVALID_PARAMETERS   0x12
 #define HCI_ERROR_REMOTE_USER_TERM     0x13
 #define HCI_ERROR_REMOTE_LOW_RESOURCES 0x14
 #define HCI_ERROR_REMOTE_POWER_OFF     0x15
index d537774..8abd082 100644 (file)
@@ -1156,7 +1156,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 
 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
 
-void hci_le_conn_failed(struct hci_conn *conn, u8 status);
+void hci_conn_failed(struct hci_conn *conn, u8 status);
 
 /*
  * hci_conn_get() and hci_conn_put() are used to control the life-time of an
index a38c4f1..74b369b 100644 (file)
@@ -58,7 +58,7 @@ struct ip6_tnl {
 
        /* These fields used only by GRE */
        __u32 i_seqno;  /* The last seen seqno  */
-       __u32 o_seqno;  /* The last output seqno */
+       atomic_t o_seqno;       /* The last output seqno */
        int hlen;       /* tun_hlen + encap_hlen */
        int tun_hlen;   /* Precalculated header length */
        int encap_hlen; /* Encap header length (FOU,GUE) */
index 88dee57..c24fa93 100644 (file)
@@ -116,7 +116,7 @@ struct ip_tunnel {
 
        /* These four fields used only by GRE */
        u32             i_seqno;        /* The last seen seqno  */
-       u32             o_seqno;        /* The last output seqno */
+       atomic_t        o_seqno;        /* The last output seqno */
        int             tun_hlen;       /* Precalculated header length */
 
        /* These four fields used only by ERSPAN */
index 70ca4a5..cc12950 100644 (file)
@@ -480,6 +480,7 @@ int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
                      u32 cookie);
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb);
 struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+                                           const struct tcp_request_sock_ops *af_ops,
                                            struct sock *sk, struct sk_buff *skb);
 #ifdef CONFIG_SYN_COOKIES
 
@@ -620,6 +621,7 @@ void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req);
 void tcp_reset(struct sock *sk, struct sk_buff *skb);
 void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb);
 void tcp_fin(struct sock *sk);
+void tcp_check_space(struct sock *sk);
 
 /* tcp_timer.c */
 void tcp_init_xmit_timers(struct sock *);
@@ -1042,6 +1044,7 @@ struct rate_sample {
        int  losses;            /* number of packets marked lost upon ACK */
        u32  acked_sacked;      /* number of packets newly (S)ACKed upon ACK */
        u32  prior_in_flight;   /* in flight before this ACK */
+       u32  last_end_seq;      /* end_seq of most recently ACKed packet */
        bool is_app_limited;    /* is sample from packet with bubble in pipe? */
        bool is_retrans;        /* is sample from retransmission? */
        bool is_ack_delayed;    /* is this (likely) a delayed ACK? */
@@ -1164,6 +1167,11 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost,
                  bool is_sack_reneg, struct rate_sample *rs);
 void tcp_rate_check_app_limited(struct sock *sk);
 
+static inline bool tcp_skb_sent_after(u64 t1, u64 t2, u32 seq1, u32 seq2)
+{
+       return t1 > t2 || (t1 == t2 && after(seq1, seq2));
+}
+
 /* These functions determine how the current flow behaves in respect of SACK
  * handling. SACK is negotiated with the peer, and therefore it can vary
  * between different flows.
index 5554ee7..647722e 100644 (file)
@@ -97,6 +97,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool, struct net_device *dev,
                  u16 queue_id, u16 flags);
 int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem,
                         struct net_device *dev, u16 queue_id);
+int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs);
 void xp_destroy(struct xsk_buff_pool *pool);
 void xp_get_pool(struct xsk_buff_pool *pool);
 bool xp_put_pool(struct xsk_buff_pool *pool);
index 4c14e8b..3a49913 100644 (file)
@@ -182,7 +182,7 @@ struct fb_fix_screeninfo {
  *
  * For pseudocolor: offset and length should be the same for all color
  * components. Offset specifies the position of the least significant bit
- * of the pallette index in a pixel value. Length indicates the number
+ * of the palette index in a pixel value. Length indicates the number
  * of available palette entries (i.e. # of entries = 1 << length).
  */
 struct fb_bitfield {
index dbe57df..dd58c0b 100644 (file)
@@ -2126,7 +2126,7 @@ static void kretprobe_rethook_handler(struct rethook_node *rh, void *data,
        struct kprobe_ctlblk *kcb;
 
        /* The data must NOT be null. This means rethook data structure is broken. */
-       if (WARN_ON_ONCE(!data))
+       if (WARN_ON_ONCE(!data) || !rp->handler)
                return;
 
        __this_cpu_write(current_kprobe, &rp->kp);
index 9301578..06833d4 100644 (file)
@@ -22,15 +22,33 @@ EXPORT_SYMBOL(hex_asc_upper);
  *
  * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
  * input.
+ *
+ * This function is used to load cryptographic keys, so it is coded in such a
+ * way that there are no conditions or memory accesses that depend on data.
+ *
+ * Explanation of the logic:
+ * (ch - '9' - 1) is negative if ch <= '9'
+ * ('0' - 1 - ch) is negative if ch >= '0'
+ * we "and" these two values, so the result is negative if ch is in the range
+ *     '0' ... '9'
+ * we are only interested in the sign, so we do a shift ">> 8"; note that right
+ *     shift of a negative value is implementation-defined, so we cast the
+ *     value to (unsigned) before the shift --- we have 0xffffff if ch is in
+ *     the range '0' ... '9', 0 otherwise
+ * we "and" this value with (ch - '0' + 1) --- we have a value 1 ... 10 if ch is
+ *     in the range '0' ... '9', 0 otherwise
+ * we add this value to -1 --- we have a value 0 ... 9 if ch is in the range '0'
+ *     ... '9', -1 otherwise
+ * the next line is similar to the previous one, but we need to decode both
+ *     uppercase and lowercase letters, so we use (ch & 0xdf), which converts
+ *     lowercase to uppercase
  */
-int hex_to_bin(char ch)
+int hex_to_bin(unsigned char ch)
 {
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       ch = tolower(ch);
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       return -1;
+       unsigned char cu = ch & 0xdf;
+       return -1 +
+               ((ch - '0' +  1) & (unsigned)((ch - '9' - 1) & ('0' - 1 - ch)) >> 8) +
+               ((cu - 'A' + 11) & (unsigned)((cu - 'F' - 1) & ('A' - 1 - cu)) >> 8);
 }
 EXPORT_SYMBOL(hex_to_bin);
 
@@ -45,10 +63,13 @@ EXPORT_SYMBOL(hex_to_bin);
 int hex2bin(u8 *dst, const char *src, size_t count)
 {
        while (count--) {
-               int hi = hex_to_bin(*src++);
-               int lo = hex_to_bin(*src++);
+               int hi, lo;
 
-               if ((hi < 0) || (lo < 0))
+               hi = hex_to_bin(*src++);
+               if (unlikely(hi < 0))
+                       return -EINVAL;
+               lo = hex_to_bin(*src++);
+               if (unlikely(lo < 0))
                        return -EINVAL;
 
                *dst++ = (hi << 4) | lo;
index 08291ed..0a9def8 100644 (file)
@@ -315,6 +315,13 @@ static void per_cpu_remove_cache(void *arg)
        struct qlist_head *q;
 
        q = this_cpu_ptr(&cpu_quarantine);
+       /*
+        * Ensure the ordering between the writing to q->offline and
+        * per_cpu_remove_cache.  Prevent cpu_quarantine from being corrupted
+        * by interrupt.
+        */
+       if (READ_ONCE(q->offline))
+               return;
        qlist_move_cache(q, &to_free, cache);
        qlist_free_all(&to_free, cache);
 }
index 55a9e48..9d7afc2 100644 (file)
@@ -226,6 +226,8 @@ void *vmalloc(unsigned long size)
 }
 EXPORT_SYMBOL(vmalloc);
 
+void *vmalloc_huge(unsigned long size, gfp_t gfp_mask) __weak __alias(__vmalloc);
+
 /*
  *     vzalloc - allocate virtually contiguous memory with zero fill
  *
index 84312c8..fe803be 100644 (file)
@@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work)
                /* Disable LE Advertising */
                le_disable_advertising(hdev);
                hci_dev_lock(hdev);
-               hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
+               hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
                hci_dev_unlock(hdev);
                return;
        }
@@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type)
 EXPORT_SYMBOL(hci_get_route);
 
 /* This function requires the caller holds hdev->lock */
-void hci_le_conn_failed(struct hci_conn *conn, u8 status)
+static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 {
        struct hci_dev *hdev = conn->hdev;
        struct hci_conn_params *params;
@@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
                params->conn = NULL;
        }
 
-       conn->state = BT_CLOSED;
-
        /* If the status indicates successful cancellation of
         * the attempt (i.e. Unknown Connection Id) there's no point of
         * notifying failure since we'll go back to keep trying to
@@ -899,10 +897,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
                mgmt_connect_failed(hdev, &conn->dst, conn->type,
                                    conn->dst_type, status);
 
-       hci_connect_cfm(conn, status);
-
-       hci_conn_del(conn);
-
        /* Since we may have temporarily stopped the background scanning in
         * favor of connection establishment, we should restart it.
         */
@@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
        hci_enable_advertising(hdev);
 }
 
+/* This function requires the caller holds hdev->lock */
+void hci_conn_failed(struct hci_conn *conn, u8 status)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       bt_dev_dbg(hdev, "status 0x%2.2x", status);
+
+       switch (conn->type) {
+       case LE_LINK:
+               hci_le_conn_failed(conn, status);
+               break;
+       case ACL_LINK:
+               mgmt_connect_failed(hdev, &conn->dst, conn->type,
+                                   conn->dst_type, status);
+               break;
+       }
+
+       conn->state = BT_CLOSED;
+       hci_connect_cfm(conn, status);
+       hci_conn_del(conn);
+}
+
 static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
 {
        struct hci_conn *conn = data;
index abaabfa..6645166 100644 (file)
@@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
        bt_dev_dbg(hdev, "status 0x%2.2x", status);
 
        /* All connection failure handling is taken care of by the
-        * hci_le_conn_failed function which is triggered by the HCI
+        * hci_conn_failed function which is triggered by the HCI
         * request completion callbacks used for connecting.
         */
        if (status)
@@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
        bt_dev_dbg(hdev, "status 0x%2.2x", status);
 
        /* All connection failure handling is taken care of by the
-        * hci_le_conn_failed function which is triggered by the HCI
+        * hci_conn_failed function which is triggered by the HCI
         * request completion callbacks used for connecting.
         */
        if (status)
@@ -3067,18 +3067,20 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 {
        struct hci_ev_conn_complete *ev = data;
        struct hci_conn *conn;
+       u8 status = ev->status;
 
-       if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
-               bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for invalid handle");
-               return;
-       }
-
-       bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+       bt_dev_dbg(hdev, "status 0x%2.2x", status);
 
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
        if (!conn) {
+               /* In case of error status and there is no connection pending
+                * just unlock as there is nothing to cleanup.
+                */
+               if (ev->status)
+                       goto unlock;
+
                /* Connection may not exist if auto-connected. Check the bredr
                 * allowlist to see if this device is allowed to auto connect.
                 * If link is an ACL type, create a connection class
@@ -3122,8 +3124,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       if (!ev->status) {
+       if (!status) {
                conn->handle = __le16_to_cpu(ev->handle);
+               if (conn->handle > HCI_CONN_HANDLE_MAX) {
+                       bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
+                                  conn->handle, HCI_CONN_HANDLE_MAX);
+                       status = HCI_ERROR_INVALID_PARAMETERS;
+                       goto done;
+               }
 
                if (conn->type == ACL_LINK) {
                        conn->state = BT_CONFIG;
@@ -3164,19 +3172,14 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
                        hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
                                     &cp);
                }
-       } else {
-               conn->state = BT_CLOSED;
-               if (conn->type == ACL_LINK)
-                       mgmt_connect_failed(hdev, &conn->dst, conn->type,
-                                           conn->dst_type, ev->status);
        }
 
        if (conn->type == ACL_LINK)
                hci_sco_setup(conn, ev->status);
 
-       if (ev->status) {
-               hci_connect_cfm(conn, ev->status);
-               hci_conn_del(conn);
+done:
+       if (status) {
+               hci_conn_failed(conn, status);
        } else if (ev->link_type == SCO_LINK) {
                switch (conn->setting & SCO_AIRMODE_MASK) {
                case SCO_AIRMODE_CVSD:
@@ -3185,7 +3188,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
                        break;
                }
 
-               hci_connect_cfm(conn, ev->status);
+               hci_connect_cfm(conn, status);
        }
 
 unlock:
@@ -4676,6 +4679,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
 {
        struct hci_ev_sync_conn_complete *ev = data;
        struct hci_conn *conn;
+       u8 status = ev->status;
 
        switch (ev->link_type) {
        case SCO_LINK:
@@ -4690,12 +4694,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
                return;
        }
 
-       if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
-               bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete for invalid handle");
-               return;
-       }
-
-       bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+       bt_dev_dbg(hdev, "status 0x%2.2x", status);
 
        hci_dev_lock(hdev);
 
@@ -4729,9 +4728,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
                goto unlock;
        }
 
-       switch (ev->status) {
+       switch (status) {
        case 0x00:
                conn->handle = __le16_to_cpu(ev->handle);
+               if (conn->handle > HCI_CONN_HANDLE_MAX) {
+                       bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x",
+                                  conn->handle, HCI_CONN_HANDLE_MAX);
+                       status = HCI_ERROR_INVALID_PARAMETERS;
+                       conn->state = BT_CLOSED;
+                       break;
+               }
+
                conn->state  = BT_CONNECTED;
                conn->type   = ev->link_type;
 
@@ -4775,8 +4782,8 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
                }
        }
 
-       hci_connect_cfm(conn, ev->status);
-       if (ev->status)
+       hci_connect_cfm(conn, status);
+       if (status)
                hci_conn_del(conn);
 
 unlock:
@@ -5527,11 +5534,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
        struct smp_irk *irk;
        u8 addr_type;
 
-       if (handle > HCI_CONN_HANDLE_MAX) {
-               bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle");
-               return;
-       }
-
        hci_dev_lock(hdev);
 
        /* All controllers implicitly stop advertising in the event of a
@@ -5541,6 +5543,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 
        conn = hci_lookup_le_connect(hdev);
        if (!conn) {
+               /* In case of error status and there is no connection pending
+                * just unlock as there is nothing to cleanup.
+                */
+               if (status)
+                       goto unlock;
+
                conn = hci_conn_add(hdev, LE_LINK, bdaddr, role);
                if (!conn) {
                        bt_dev_err(hdev, "no memory for new connection");
@@ -5603,8 +5611,14 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 
        conn->dst_type = ev_bdaddr_type(hdev, conn->dst_type, NULL);
 
+       if (handle > HCI_CONN_HANDLE_MAX) {
+               bt_dev_err(hdev, "Invalid handle: 0x%4.4x > 0x%4.4x", handle,
+                          HCI_CONN_HANDLE_MAX);
+               status = HCI_ERROR_INVALID_PARAMETERS;
+       }
+
        if (status) {
-               hci_le_conn_failed(conn, status);
+               hci_conn_failed(conn, status);
                goto unlock;
        }
 
index 8f4c569..13600bf 100644 (file)
@@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
 static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
                               u8 reason)
 {
+       int err;
+
        switch (conn->state) {
        case BT_CONNECTED:
        case BT_CONFIG:
                return hci_disconnect_sync(hdev, conn, reason);
        case BT_CONNECT:
-               return hci_connect_cancel_sync(hdev, conn);
+               err = hci_connect_cancel_sync(hdev, conn);
+               /* Cleanup hci_conn object if it cannot be cancelled as it
+                * likelly means the controller and host stack are out of sync.
+                */
+               if (err)
+                       hci_conn_failed(conn, err);
+
+               return err;
        case BT_CONNECT2:
                return hci_reject_conn_sync(hdev, conn, reason);
        default:
index e7b9c26..af709c1 100644 (file)
@@ -108,6 +108,7 @@ struct xdp_test_data {
        struct page_pool *pp;
        struct xdp_frame **frames;
        struct sk_buff **skbs;
+       struct xdp_mem_info mem;
        u32 batch_size;
        u32 frame_cnt;
 };
@@ -147,7 +148,6 @@ static void xdp_test_run_init_page(struct page *page, void *arg)
 
 static int xdp_test_run_setup(struct xdp_test_data *xdp, struct xdp_buff *orig_ctx)
 {
-       struct xdp_mem_info mem = {};
        struct page_pool *pp;
        int err = -ENOMEM;
        struct page_pool_params pp_params = {
@@ -174,7 +174,7 @@ static int xdp_test_run_setup(struct xdp_test_data *xdp, struct xdp_buff *orig_c
        }
 
        /* will copy 'mem.id' into pp->xdp_mem_id */
-       err = xdp_reg_mem_model(&mem, MEM_TYPE_PAGE_POOL, pp);
+       err = xdp_reg_mem_model(&xdp->mem, MEM_TYPE_PAGE_POOL, pp);
        if (err)
                goto err_mmodel;
 
@@ -202,6 +202,7 @@ err_skbs:
 
 static void xdp_test_run_teardown(struct xdp_test_data *xdp)
 {
+       xdp_unreg_mem_model(&xdp->mem);
        page_pool_destroy(xdp->pp);
        kfree(xdp->frames);
        kfree(xdp->skbs);
index 8cc44c3..18affda 100644 (file)
@@ -353,6 +353,8 @@ static int br_switchdev_vlan_attr_replay(struct net_device *br_dev,
        attr.orig_dev = br_dev;
 
        vg = br_vlan_group(br);
+       if (!vg)
+               return 0;
 
        list_for_each_entry(v, &vg->vlan_list, vlist) {
                if (v->msti) {
index 8c6c084..1461c2d 100644 (file)
@@ -10304,7 +10304,7 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
 }
 EXPORT_SYMBOL(netdev_stats_to_stats64);
 
-struct net_device_core_stats *netdev_core_stats_alloc(struct net_device *dev)
+struct net_device_core_stats __percpu *netdev_core_stats_alloc(struct net_device *dev)
 {
        struct net_device_core_stats __percpu *p;
 
@@ -10315,11 +10315,7 @@ struct net_device_core_stats *netdev_core_stats_alloc(struct net_device *dev)
                free_percpu(p);
 
        /* This READ_ONCE() pairs with the cmpxchg() above */
-       p = READ_ONCE(dev->core_stats);
-       if (!p)
-               return NULL;
-
-       return this_cpu_ptr(p);
+       return READ_ONCE(dev->core_stats);
 }
 EXPORT_SYMBOL(netdev_core_stats_alloc);
 
@@ -10356,9 +10352,9 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
 
                for_each_possible_cpu(i) {
                        core_stats = per_cpu_ptr(p, i);
-                       storage->rx_dropped += local_read(&core_stats->rx_dropped);
-                       storage->tx_dropped += local_read(&core_stats->tx_dropped);
-                       storage->rx_nohandler += local_read(&core_stats->rx_nohandler);
+                       storage->rx_dropped += READ_ONCE(core_stats->rx_dropped);
+                       storage->tx_dropped += READ_ONCE(core_stats->tx_dropped);
+                       storage->rx_nohandler += READ_ONCE(core_stats->rx_nohandler);
                }
        }
        return storage;
index 349480e..8b6b5e7 100644 (file)
@@ -159,10 +159,8 @@ static int bpf_output(struct net *net, struct sock *sk, struct sk_buff *skb)
        return dst->lwtstate->orig_output(net, sk, skb);
 }
 
-static int xmit_check_hhlen(struct sk_buff *skb)
+static int xmit_check_hhlen(struct sk_buff *skb, int hh_len)
 {
-       int hh_len = skb_dst(skb)->dev->hard_header_len;
-
        if (skb_headroom(skb) < hh_len) {
                int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb));
 
@@ -274,6 +272,7 @@ static int bpf_xmit(struct sk_buff *skb)
 
        bpf = bpf_lwt_lwtunnel(dst->lwtstate);
        if (bpf->xmit.prog) {
+               int hh_len = dst->dev->hard_header_len;
                __be16 proto = skb->protocol;
                int ret;
 
@@ -291,7 +290,7 @@ static int bpf_xmit(struct sk_buff *skb)
                        /* If the header was expanded, headroom might be too
                         * small for L2 header to come, expand as needed.
                         */
-                       ret = xmit_check_hhlen(skb);
+                       ret = xmit_check_hhlen(skb, hh_len);
                        if (unlikely(ret))
                                return ret;
 
index 32d472a..cdc56ba 100644 (file)
@@ -1620,8 +1620,10 @@ int dsa_port_link_register_of(struct dsa_port *dp)
                        if (ds->ops->phylink_mac_link_down)
                                ds->ops->phylink_mac_link_down(ds, port,
                                        MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
+                       of_node_put(phy_np);
                        return dsa_port_phylink_register(dp);
                }
+               of_node_put(phy_np);
                return 0;
        }
 
index 41c69a6..8022d50 100644 (file)
@@ -285,7 +285,7 @@ static void dsa_port_manage_cpu_flood(struct dsa_port *dp)
                if (other_dp->slave->flags & IFF_ALLMULTI)
                        flags.val |= BR_MCAST_FLOOD;
                if (other_dp->slave->flags & IFF_PROMISC)
-                       flags.val |= BR_FLOOD;
+                       flags.val |= BR_FLOOD | BR_MCAST_FLOOD;
        }
 
        err = dsa_port_pre_bridge_flags(dp, flags, NULL);
index 365caeb..aacee9d 100644 (file)
@@ -459,14 +459,12 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
                       __be16 proto)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
-
-       if (tunnel->parms.o_flags & TUNNEL_SEQ)
-               tunnel->o_seqno++;
+       __be16 flags = tunnel->parms.o_flags;
 
        /* Push GRE header. */
        gre_build_header(skb, tunnel->tun_hlen,
-                        tunnel->parms.o_flags, proto, tunnel->parms.o_key,
-                        htonl(tunnel->o_seqno));
+                        flags, proto, tunnel->parms.o_key,
+                        (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno)) : 0);
 
        ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
 }
@@ -504,7 +502,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
                (TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
        gre_build_header(skb, tunnel_hlen, flags, proto,
                         tunnel_id_to_key32(tun_info->key.tun_id),
-                        (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++) : 0);
+                        (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno)) : 0);
 
        ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, tunnel_hlen);
 
@@ -581,7 +579,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        gre_build_header(skb, 8, TUNNEL_SEQ,
-                        proto, 0, htonl(tunnel->o_seqno++));
+                        proto, 0, htonl(atomic_fetch_inc(&tunnel->o_seqno)));
 
        ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, tunnel_hlen);
 
diff --git a/net/ipv4/netfilter/nf_flow_table_ipv4.c b/net/ipv4/netfilter/nf_flow_table_ipv4.c
deleted file mode 100644 (file)
index e69de29..0000000
index 2cb3b85..f33c31d 100644 (file)
@@ -281,6 +281,7 @@ bool cookie_ecn_ok(const struct tcp_options_received *tcp_opt,
 EXPORT_SYMBOL(cookie_ecn_ok);
 
 struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+                                           const struct tcp_request_sock_ops *af_ops,
                                            struct sock *sk,
                                            struct sk_buff *skb)
 {
@@ -297,6 +298,10 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
                return NULL;
 
        treq = tcp_rsk(req);
+
+       /* treq->af_specific might be used to perform TCP_MD5 lookup */
+       treq->af_specific = af_ops;
+
        treq->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
 #if IS_ENABLED(CONFIG_MPTCP)
        treq->is_mptcp = sk_is_mptcp(sk);
@@ -364,7 +369,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
                goto out;
 
        ret = NULL;
-       req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops, sk, skb);
+       req = cookie_tcp_reqsk_alloc(&tcp_request_sock_ops,
+                                    &tcp_request_sock_ipv4_ops, sk, skb);
        if (!req)
                goto out;
 
index 2088f93..60f99e9 100644 (file)
@@ -3867,7 +3867,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
                tcp_process_tlp_ack(sk, ack, flag);
 
        if (tcp_ack_is_dubious(sk, flag)) {
-               if (!(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP))) {
+               if (!(flag & (FLAG_SND_UNA_ADVANCED |
+                             FLAG_NOT_DUP | FLAG_DSACKING_ACK))) {
                        num_dupack = 1;
                        /* Consider if pure acks were aggregated in tcp_add_backlog() */
                        if (!(flag & FLAG_DATA))
@@ -5454,7 +5455,17 @@ static void tcp_new_space(struct sock *sk)
        INDIRECT_CALL_1(sk->sk_write_space, sk_stream_write_space, sk);
 }
 
-static void tcp_check_space(struct sock *sk)
+/* Caller made space either from:
+ * 1) Freeing skbs in rtx queues (after tp->snd_una has advanced)
+ * 2) Sent skbs from output queue (and thus advancing tp->snd_nxt)
+ *
+ * We might be able to generate EPOLLOUT to the application if:
+ * 1) Space consumed in output/rtx queues is below sk->sk_sndbuf/2
+ * 2) notsent amount (tp->write_seq - tp->snd_nxt) became
+ *    small enough that tcp_stream_memory_free() decides it
+ *    is time to generate EPOLLOUT.
+ */
+void tcp_check_space(struct sock *sk)
 {
        /* pairs with tcp_poll() */
        smp_mb();
index 6366df7..6854bb1 100644 (file)
@@ -531,7 +531,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
        newtp->tsoffset = treq->ts_off;
 #ifdef CONFIG_TCP_MD5SIG
        newtp->md5sig_info = NULL;      /*XXX*/
-       if (newtp->af_specific->md5_lookup(sk, newsk))
+       if (treq->af_specific->req_md5_lookup(sk, req_to_sk(req)))
                newtp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED;
 #endif
        if (skb->len >= TCP_MSS_DEFAULT + newtp->tcp_header_len)
index 9ede847..1ca2f28 100644 (file)
@@ -82,6 +82,7 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
 
        NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPORIGDATASENT,
                      tcp_skb_pcount(skb));
+       tcp_check_space(sk);
 }
 
 /* SND.NXT, if window was not shrunk or the amount of shrunk was less than one
index fbab921..9a8e014 100644 (file)
@@ -74,27 +74,32 @@ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
  *
  * If an ACK (s)acks multiple skbs (e.g., stretched-acks), this function is
  * called multiple times. We favor the information from the most recently
- * sent skb, i.e., the skb with the highest prior_delivered count.
+ * sent skb, i.e., the skb with the most recently sent time and the highest
+ * sequence.
  */
 void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
                            struct rate_sample *rs)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
+       u64 tx_tstamp;
 
        if (!scb->tx.delivered_mstamp)
                return;
 
+       tx_tstamp = tcp_skb_timestamp_us(skb);
        if (!rs->prior_delivered ||
-           after(scb->tx.delivered, rs->prior_delivered)) {
+           tcp_skb_sent_after(tx_tstamp, tp->first_tx_mstamp,
+                              scb->end_seq, rs->last_end_seq)) {
                rs->prior_delivered_ce  = scb->tx.delivered_ce;
                rs->prior_delivered  = scb->tx.delivered;
                rs->prior_mstamp     = scb->tx.delivered_mstamp;
                rs->is_app_limited   = scb->tx.is_app_limited;
                rs->is_retrans       = scb->sacked & TCPCB_RETRANS;
+               rs->last_end_seq     = scb->end_seq;
 
                /* Record send time of most recently ACKed packet: */
-               tp->first_tx_mstamp  = tcp_skb_timestamp_us(skb);
+               tp->first_tx_mstamp  = tx_tstamp;
                /* Find the duration of the "send phase" of this window: */
                rs->interval_us = tcp_stamp_us_delta(tp->first_tx_mstamp,
                                                     scb->tx.first_tx_mstamp);
index 9762367..5136959 100644 (file)
@@ -724,6 +724,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
 {
        struct ip6_tnl *tunnel = netdev_priv(dev);
        __be16 protocol;
+       __be16 flags;
 
        if (dev->type == ARPHRD_ETHER)
                IPCB(skb)->flags = 0;
@@ -739,7 +740,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
        if (tunnel->parms.collect_md) {
                struct ip_tunnel_info *tun_info;
                const struct ip_tunnel_key *key;
-               __be16 flags;
                int tun_hlen;
 
                tun_info = skb_tunnel_info_txcheck(skb);
@@ -766,19 +766,19 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
                gre_build_header(skb, tun_hlen,
                                 flags, protocol,
                                 tunnel_id_to_key32(tun_info->key.tun_id),
-                                (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++)
+                                (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno))
                                                      : 0);
 
        } else {
-               if (tunnel->parms.o_flags & TUNNEL_SEQ)
-                       tunnel->o_seqno++;
-
                if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen))
                        return -ENOMEM;
 
-               gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
+               flags = tunnel->parms.o_flags;
+
+               gre_build_header(skb, tunnel->tun_hlen, flags,
                                 protocol, tunnel->parms.o_key,
-                                htonl(tunnel->o_seqno));
+                                (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno))
+                                                     : 0);
        }
 
        return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
@@ -1056,7 +1056,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
        /* Push GRE header. */
        proto = (t->parms.erspan_ver == 1) ? htons(ETH_P_ERSPAN)
                                           : htons(ETH_P_ERSPAN2);
-       gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(t->o_seqno++));
+       gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(atomic_fetch_inc(&t->o_seqno)));
 
        /* TooBig packet may have updated dst->dev's mtu */
        if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
index 1da3324..8ce60ab 100644 (file)
@@ -24,14 +24,13 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
 {
        const struct ipv6hdr *iph = ipv6_hdr(skb);
        struct sock *sk = sk_to_full_sk(sk_partial);
+       struct net_device *dev = skb_dst(skb)->dev;
        struct flow_keys flkeys;
        unsigned int hh_len;
        struct dst_entry *dst;
        int strict = (ipv6_addr_type(&iph->daddr) &
                      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
        struct flowi6 fl6 = {
-               .flowi6_oif = sk && sk->sk_bound_dev_if ? sk->sk_bound_dev_if :
-                       strict ? skb_dst(skb)->dev->ifindex : 0,
                .flowi6_mark = skb->mark,
                .flowi6_uid = sock_net_uid(net, sk),
                .daddr = iph->daddr,
@@ -39,6 +38,13 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
        };
        int err;
 
+       if (sk && sk->sk_bound_dev_if)
+               fl6.flowi6_oif = sk->sk_bound_dev_if;
+       else if (strict)
+               fl6.flowi6_oif = dev->ifindex;
+       else
+               fl6.flowi6_oif = l3mdev_master_ifindex(dev);
+
        fib6_rules_early_flow_dissect(net, skb, &fl6, &flkeys);
        dst = ip6_route_output(net, sk, &fl6);
        err = dst->error;
index d1b61d0..9cc123f 100644 (file)
@@ -170,7 +170,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                goto out;
 
        ret = NULL;
-       req = cookie_tcp_reqsk_alloc(&tcp6_request_sock_ops, sk, skb);
+       req = cookie_tcp_reqsk_alloc(&tcp6_request_sock_ops,
+                                    &tcp_request_sock_ipv6_ops, sk, skb);
        if (!req)
                goto out;
 
index f49be88..99a3bda 100644 (file)
@@ -313,6 +313,7 @@ void mctp_dev_hold(struct mctp_dev *mdev)
 void mctp_dev_put(struct mctp_dev *mdev)
 {
        if (mdev && refcount_dec_and_test(&mdev->refs)) {
+               kfree(mdev->addrs);
                dev_put(mdev->dev);
                kfree_rcu(mdev, rcu);
        }
@@ -441,7 +442,6 @@ static void mctp_unregister(struct net_device *dev)
 
        mctp_route_remove_dev(mdev);
        mctp_neigh_remove_dev(mdev);
-       kfree(mdev->addrs);
 
        mctp_dev_put(mdev);
 }
index 2c467c4..fb67f1c 100644 (file)
@@ -1495,7 +1495,7 @@ int __init ip_vs_conn_init(void)
        pr_info("Connection hash table configured "
                "(size=%d, memory=%ldKbytes)\n",
                ip_vs_conn_tab_size,
-               (long)(ip_vs_conn_tab_size*sizeof(struct list_head))/1024);
+               (long)(ip_vs_conn_tab_size*sizeof(*ip_vs_conn_tab))/1024);
        IP_VS_DBG(0, "Each connection entry needs %zd bytes at least\n",
                  sizeof(struct ip_vs_conn));
 
index 8ec55cd..204a5cd 100644 (file)
@@ -556,24 +556,14 @@ static bool tcp_in_window(struct nf_conn *ct,
                        }
 
                }
-       } else if (((state->state == TCP_CONNTRACK_SYN_SENT
-                    && dir == IP_CT_DIR_ORIGINAL)
-                  || (state->state == TCP_CONNTRACK_SYN_RECV
-                    && dir == IP_CT_DIR_REPLY))
-                  && after(end, sender->td_end)) {
+       } else if (tcph->syn &&
+                  after(end, sender->td_end) &&
+                  (state->state == TCP_CONNTRACK_SYN_SENT ||
+                   state->state == TCP_CONNTRACK_SYN_RECV)) {
                /*
                 * RFC 793: "if a TCP is reinitialized ... then it need
                 * not wait at all; it must only be sure to use sequence
                 * numbers larger than those recently used."
-                */
-               sender->td_end =
-               sender->td_maxend = end;
-               sender->td_maxwin = (win == 0 ? 1 : win);
-
-               tcp_options(skb, dataoff, tcph, sender);
-       } else if (tcph->syn && dir == IP_CT_DIR_REPLY &&
-                  state->state == TCP_CONNTRACK_SYN_SENT) {
-               /* Retransmitted syn-ack, or syn (simultaneous open).
                 *
                 * Re-init state for this direction, just like for the first
                 * syn(-ack) reply, it might differ in seq, ack or tcp options.
@@ -581,7 +571,8 @@ static bool tcp_in_window(struct nf_conn *ct,
                tcp_init_sender(sender, receiver,
                                skb, dataoff, tcph,
                                end, win);
-               if (!tcph->ack)
+
+               if (dir == IP_CT_DIR_REPLY && !tcph->ack)
                        return true;
        }
 
index 3e1afd1..55aa55b 100644 (file)
@@ -823,7 +823,7 @@ static struct ctl_table nf_ct_sysctl_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec_jiffies,
        },
-#if IS_ENABLED(CONFIG_NFT_FLOW_OFFLOAD)
+#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
        [NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_OFFLOAD] = {
                .procname       = "nf_flowtable_udp_timeout",
                .maxlen         = sizeof(unsigned int),
index d600a56..7325bee 100644 (file)
@@ -349,7 +349,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
                                *ext = &rbe->ext;
                                return -EEXIST;
                        } else {
-                               p = &parent->rb_left;
+                               overlap = false;
+                               if (nft_rbtree_interval_end(rbe))
+                                       p = &parent->rb_left;
+                               else
+                                       p = &parent->rb_right;
                        }
                }
 
index 6d9e8e0..05ae5a3 100644 (file)
@@ -54,6 +54,32 @@ nft_sock_get_eval_cgroupv2(u32 *dest, struct sock *sk, const struct nft_pktinfo
 }
 #endif
 
+static struct sock *nft_socket_do_lookup(const struct nft_pktinfo *pkt)
+{
+       const struct net_device *indev = nft_in(pkt);
+       const struct sk_buff *skb = pkt->skb;
+       struct sock *sk = NULL;
+
+       if (!indev)
+               return NULL;
+
+       switch (nft_pf(pkt)) {
+       case NFPROTO_IPV4:
+               sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, indev);
+               break;
+#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
+       case NFPROTO_IPV6:
+               sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, indev);
+               break;
+#endif
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+
+       return sk;
+}
+
 static void nft_socket_eval(const struct nft_expr *expr,
                            struct nft_regs *regs,
                            const struct nft_pktinfo *pkt)
@@ -67,20 +93,7 @@ static void nft_socket_eval(const struct nft_expr *expr,
                sk = NULL;
 
        if (!sk)
-               switch(nft_pf(pkt)) {
-               case NFPROTO_IPV4:
-                       sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, nft_in(pkt));
-                       break;
-#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
-               case NFPROTO_IPV6:
-                       sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, nft_in(pkt));
-                       break;
-#endif
-               default:
-                       WARN_ON_ONCE(1);
-                       regs->verdict.code = NFT_BREAK;
-                       return;
-               }
+               sk = nft_socket_do_lookup(pkt);
 
        if (!sk) {
                regs->verdict.code = NFT_BREAK;
@@ -224,6 +237,16 @@ static bool nft_socket_reduce(struct nft_regs_track *track,
        return nft_expr_reduce_bitwise(track, expr);
 }
 
+static int nft_socket_validate(const struct nft_ctx *ctx,
+                              const struct nft_expr *expr,
+                              const struct nft_data **data)
+{
+       return nft_chain_validate_hooks(ctx->chain,
+                                       (1 << NF_INET_PRE_ROUTING) |
+                                       (1 << NF_INET_LOCAL_IN) |
+                                       (1 << NF_INET_LOCAL_OUT));
+}
+
 static struct nft_expr_type nft_socket_type;
 static const struct nft_expr_ops nft_socket_ops = {
        .type           = &nft_socket_type,
@@ -231,6 +254,7 @@ static const struct nft_expr_ops nft_socket_ops = {
        .eval           = nft_socket_eval,
        .init           = nft_socket_init,
        .dump           = nft_socket_dump,
+       .validate       = nft_socket_validate,
        .reduce         = nft_socket_reduce,
 };
 
index b3815b5..463c4a5 100644 (file)
@@ -458,6 +458,10 @@ void sctp_generate_reconf_event(struct timer_list *t)
                goto out_unlock;
        }
 
+       /* This happens when the response arrives after the timer is triggered. */
+       if (!asoc->strreset_chunk)
+               goto out_unlock;
+
        error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
                           SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_RECONF),
                           asoc->state, asoc->ep, asoc,
index fc7b6eb..fce16b9 100644 (file)
@@ -243,11 +243,27 @@ struct proto smc_proto6 = {
 };
 EXPORT_SYMBOL_GPL(smc_proto6);
 
+static void smc_fback_restore_callbacks(struct smc_sock *smc)
+{
+       struct sock *clcsk = smc->clcsock->sk;
+
+       write_lock_bh(&clcsk->sk_callback_lock);
+       clcsk->sk_user_data = NULL;
+
+       smc_clcsock_restore_cb(&clcsk->sk_state_change, &smc->clcsk_state_change);
+       smc_clcsock_restore_cb(&clcsk->sk_data_ready, &smc->clcsk_data_ready);
+       smc_clcsock_restore_cb(&clcsk->sk_write_space, &smc->clcsk_write_space);
+       smc_clcsock_restore_cb(&clcsk->sk_error_report, &smc->clcsk_error_report);
+
+       write_unlock_bh(&clcsk->sk_callback_lock);
+}
+
 static void smc_restore_fallback_changes(struct smc_sock *smc)
 {
        if (smc->clcsock->file) { /* non-accepted sockets have no file yet */
                smc->clcsock->file->private_data = smc->sk.sk_socket;
                smc->clcsock->file = NULL;
+               smc_fback_restore_callbacks(smc);
        }
 }
 
@@ -373,6 +389,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
        sk->sk_prot->hash(sk);
        sk_refcnt_debug_inc(sk);
        mutex_init(&smc->clcsock_release_lock);
+       smc_init_saved_callbacks(smc);
 
        return sk;
 }
@@ -744,47 +761,73 @@ out:
 
 static void smc_fback_state_change(struct sock *clcsk)
 {
-       struct smc_sock *smc =
-               smc_clcsock_user_data(clcsk);
+       struct smc_sock *smc;
 
-       if (!smc)
-               return;
-       smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_state_change);
+       read_lock_bh(&clcsk->sk_callback_lock);
+       smc = smc_clcsock_user_data(clcsk);
+       if (smc)
+               smc_fback_forward_wakeup(smc, clcsk,
+                                        smc->clcsk_state_change);
+       read_unlock_bh(&clcsk->sk_callback_lock);
 }
 
 static void smc_fback_data_ready(struct sock *clcsk)
 {
-       struct smc_sock *smc =
-               smc_clcsock_user_data(clcsk);
+       struct smc_sock *smc;
 
-       if (!smc)
-               return;
-       smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_data_ready);
+       read_lock_bh(&clcsk->sk_callback_lock);
+       smc = smc_clcsock_user_data(clcsk);
+       if (smc)
+               smc_fback_forward_wakeup(smc, clcsk,
+                                        smc->clcsk_data_ready);
+       read_unlock_bh(&clcsk->sk_callback_lock);
 }
 
 static void smc_fback_write_space(struct sock *clcsk)
 {
-       struct smc_sock *smc =
-               smc_clcsock_user_data(clcsk);
+       struct smc_sock *smc;
 
-       if (!smc)
-               return;
-       smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_write_space);
+       read_lock_bh(&clcsk->sk_callback_lock);
+       smc = smc_clcsock_user_data(clcsk);
+       if (smc)
+               smc_fback_forward_wakeup(smc, clcsk,
+                                        smc->clcsk_write_space);
+       read_unlock_bh(&clcsk->sk_callback_lock);
 }
 
 static void smc_fback_error_report(struct sock *clcsk)
 {
-       struct smc_sock *smc =
-               smc_clcsock_user_data(clcsk);
+       struct smc_sock *smc;
 
-       if (!smc)
-               return;
-       smc_fback_forward_wakeup(smc, clcsk, smc->clcsk_error_report);
+       read_lock_bh(&clcsk->sk_callback_lock);
+       smc = smc_clcsock_user_data(clcsk);
+       if (smc)
+               smc_fback_forward_wakeup(smc, clcsk,
+                                        smc->clcsk_error_report);
+       read_unlock_bh(&clcsk->sk_callback_lock);
+}
+
+static void smc_fback_replace_callbacks(struct smc_sock *smc)
+{
+       struct sock *clcsk = smc->clcsock->sk;
+
+       write_lock_bh(&clcsk->sk_callback_lock);
+       clcsk->sk_user_data = (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
+
+       smc_clcsock_replace_cb(&clcsk->sk_state_change, smc_fback_state_change,
+                              &smc->clcsk_state_change);
+       smc_clcsock_replace_cb(&clcsk->sk_data_ready, smc_fback_data_ready,
+                              &smc->clcsk_data_ready);
+       smc_clcsock_replace_cb(&clcsk->sk_write_space, smc_fback_write_space,
+                              &smc->clcsk_write_space);
+       smc_clcsock_replace_cb(&clcsk->sk_error_report, smc_fback_error_report,
+                              &smc->clcsk_error_report);
+
+       write_unlock_bh(&clcsk->sk_callback_lock);
 }
 
 static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
 {
-       struct sock *clcsk;
        int rc = 0;
 
        mutex_lock(&smc->clcsock_release_lock);
@@ -792,10 +835,7 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
                rc = -EBADF;
                goto out;
        }
-       clcsk = smc->clcsock->sk;
 
-       if (smc->use_fallback)
-               goto out;
        smc->use_fallback = true;
        smc->fallback_rsn = reason_code;
        smc_stat_fallback(smc);
@@ -810,18 +850,7 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
                 * in smc sk->sk_wq and they should be woken up
                 * as clcsock's wait queue is woken up.
                 */
-               smc->clcsk_state_change = clcsk->sk_state_change;
-               smc->clcsk_data_ready = clcsk->sk_data_ready;
-               smc->clcsk_write_space = clcsk->sk_write_space;
-               smc->clcsk_error_report = clcsk->sk_error_report;
-
-               clcsk->sk_state_change = smc_fback_state_change;
-               clcsk->sk_data_ready = smc_fback_data_ready;
-               clcsk->sk_write_space = smc_fback_write_space;
-               clcsk->sk_error_report = smc_fback_error_report;
-
-               smc->clcsock->sk->sk_user_data =
-                       (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
+               smc_fback_replace_callbacks(smc);
        }
 out:
        mutex_unlock(&smc->clcsock_release_lock);
@@ -1475,6 +1504,8 @@ static void smc_connect_work(struct work_struct *work)
                smc->sk.sk_state = SMC_CLOSED;
                if (rc == -EPIPE || rc == -EAGAIN)
                        smc->sk.sk_err = EPIPE;
+               else if (rc == -ECONNREFUSED)
+                       smc->sk.sk_err = ECONNREFUSED;
                else if (signal_pending(current))
                        smc->sk.sk_err = -sock_intr_errno(timeo);
                sock_put(&smc->sk); /* passive closing */
@@ -1594,6 +1625,19 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
         * function; switch it back to the original sk_data_ready function
         */
        new_clcsock->sk->sk_data_ready = lsmc->clcsk_data_ready;
+
+       /* if new clcsock has also inherited the fallback-specific callback
+        * functions, switch them back to the original ones.
+        */
+       if (lsmc->use_fallback) {
+               if (lsmc->clcsk_state_change)
+                       new_clcsock->sk->sk_state_change = lsmc->clcsk_state_change;
+               if (lsmc->clcsk_write_space)
+                       new_clcsock->sk->sk_write_space = lsmc->clcsk_write_space;
+               if (lsmc->clcsk_error_report)
+                       new_clcsock->sk->sk_error_report = lsmc->clcsk_error_report;
+       }
+
        (*new_smc)->clcsock = new_clcsock;
 out:
        return rc;
@@ -2353,17 +2397,20 @@ out:
 
 static void smc_clcsock_data_ready(struct sock *listen_clcsock)
 {
-       struct smc_sock *lsmc =
-               smc_clcsock_user_data(listen_clcsock);
+       struct smc_sock *lsmc;
 
+       read_lock_bh(&listen_clcsock->sk_callback_lock);
+       lsmc = smc_clcsock_user_data(listen_clcsock);
        if (!lsmc)
-               return;
+               goto out;
        lsmc->clcsk_data_ready(listen_clcsock);
        if (lsmc->sk.sk_state == SMC_LISTEN) {
                sock_hold(&lsmc->sk); /* sock_put in smc_tcp_listen_work() */
                if (!queue_work(smc_tcp_ls_wq, &lsmc->tcp_listen_work))
                        sock_put(&lsmc->sk);
        }
+out:
+       read_unlock_bh(&listen_clcsock->sk_callback_lock);
 }
 
 static int smc_listen(struct socket *sock, int backlog)
@@ -2395,10 +2442,12 @@ static int smc_listen(struct socket *sock, int backlog)
        /* save original sk_data_ready function and establish
         * smc-specific sk_data_ready function
         */
-       smc->clcsk_data_ready = smc->clcsock->sk->sk_data_ready;
-       smc->clcsock->sk->sk_data_ready = smc_clcsock_data_ready;
+       write_lock_bh(&smc->clcsock->sk->sk_callback_lock);
        smc->clcsock->sk->sk_user_data =
                (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
+       smc_clcsock_replace_cb(&smc->clcsock->sk->sk_data_ready,
+                              smc_clcsock_data_ready, &smc->clcsk_data_ready);
+       write_unlock_bh(&smc->clcsock->sk->sk_callback_lock);
 
        /* save original ops */
        smc->ori_af_ops = inet_csk(smc->clcsock->sk)->icsk_af_ops;
@@ -2413,7 +2462,11 @@ static int smc_listen(struct socket *sock, int backlog)
 
        rc = kernel_listen(smc->clcsock, backlog);
        if (rc) {
-               smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
+               write_lock_bh(&smc->clcsock->sk->sk_callback_lock);
+               smc_clcsock_restore_cb(&smc->clcsock->sk->sk_data_ready,
+                                      &smc->clcsk_data_ready);
+               smc->clcsock->sk->sk_user_data = NULL;
+               write_unlock_bh(&smc->clcsock->sk->sk_callback_lock);
                goto out;
        }
        sk->sk_max_ack_backlog = backlog;
index ea06205..5ed765e 100644 (file)
@@ -288,12 +288,41 @@ static inline struct smc_sock *smc_sk(const struct sock *sk)
        return (struct smc_sock *)sk;
 }
 
+static inline void smc_init_saved_callbacks(struct smc_sock *smc)
+{
+       smc->clcsk_state_change = NULL;
+       smc->clcsk_data_ready   = NULL;
+       smc->clcsk_write_space  = NULL;
+       smc->clcsk_error_report = NULL;
+}
+
 static inline struct smc_sock *smc_clcsock_user_data(const struct sock *clcsk)
 {
        return (struct smc_sock *)
               ((uintptr_t)clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY);
 }
 
+/* save target_cb in saved_cb, and replace target_cb with new_cb */
+static inline void smc_clcsock_replace_cb(void (**target_cb)(struct sock *),
+                                         void (*new_cb)(struct sock *),
+                                         void (**saved_cb)(struct sock *))
+{
+       /* only save once */
+       if (!*saved_cb)
+               *saved_cb = *target_cb;
+       *target_cb = new_cb;
+}
+
+/* restore target_cb to saved_cb, and reset saved_cb to NULL */
+static inline void smc_clcsock_restore_cb(void (**target_cb)(struct sock *),
+                                         void (**saved_cb)(struct sock *))
+{
+       if (!*saved_cb)
+               return;
+       *target_cb = *saved_cb;
+       *saved_cb = NULL;
+}
+
 extern struct workqueue_struct *smc_hs_wq;     /* wq for handshake work */
 extern struct workqueue_struct *smc_close_wq;  /* wq for close work */
 
index 676cb23..31db743 100644 (file)
@@ -214,8 +214,11 @@ again:
                sk->sk_state = SMC_CLOSED;
                sk->sk_state_change(sk); /* wake up accept */
                if (smc->clcsock && smc->clcsock->sk) {
-                       smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
+                       write_lock_bh(&smc->clcsock->sk->sk_callback_lock);
+                       smc_clcsock_restore_cb(&smc->clcsock->sk->sk_data_ready,
+                                              &smc->clcsk_data_ready);
                        smc->clcsock->sk->sk_user_data = NULL;
+                       write_unlock_bh(&smc->clcsock->sk->sk_callback_lock);
                        rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
                }
                smc_close_cleanup_listen(sk);
index 12f7b56..af875ad 100644 (file)
@@ -483,11 +483,13 @@ handle_error:
                copy = min_t(size_t, size, (pfrag->size - pfrag->offset));
                copy = min_t(size_t, copy, (max_open_record_len - record->len));
 
-               rc = tls_device_copy_data(page_address(pfrag->page) +
-                                         pfrag->offset, copy, msg_iter);
-               if (rc)
-                       goto handle_error;
-               tls_append_frag(record, pfrag, copy);
+               if (copy) {
+                       rc = tls_device_copy_data(page_address(pfrag->page) +
+                                                 pfrag->offset, copy, msg_iter);
+                       if (rc)
+                               goto handle_error;
+                       tls_append_frag(record, pfrag, copy);
+               }
 
                size -= copy;
                if (!size) {
index 2c34cae..3a93480 100644 (file)
@@ -639,7 +639,7 @@ static int __xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len
        if (sk_can_busy_loop(sk))
                sk_busy_loop(sk, 1); /* only support non-blocking sockets */
 
-       if (xsk_no_wakeup(sk))
+       if (xs->zc && xsk_no_wakeup(sk))
                return 0;
 
        pool = xs->pool;
@@ -967,6 +967,19 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 
                        xp_get_pool(umem_xs->pool);
                        xs->pool = umem_xs->pool;
+
+                       /* If underlying shared umem was created without Tx
+                        * ring, allocate Tx descs array that Tx batching API
+                        * utilizes
+                        */
+                       if (xs->tx && !xs->pool->tx_descs) {
+                               err = xp_alloc_tx_descs(xs->pool, xs);
+                               if (err) {
+                                       xp_put_pool(xs->pool);
+                                       sockfd_put(sock);
+                                       goto out_unlock;
+                               }
+                       }
                }
 
                xdp_get_umem(umem_xs->umem);
index af040ff..87bdd71 100644 (file)
@@ -42,6 +42,16 @@ void xp_destroy(struct xsk_buff_pool *pool)
        kvfree(pool);
 }
 
+int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs)
+{
+       pool->tx_descs = kvcalloc(xs->tx->nentries, sizeof(*pool->tx_descs),
+                                 GFP_KERNEL);
+       if (!pool->tx_descs)
+               return -ENOMEM;
+
+       return 0;
+}
+
 struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
                                                struct xdp_umem *umem)
 {
@@ -59,11 +69,9 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
        if (!pool->heads)
                goto out;
 
-       if (xs->tx) {
-               pool->tx_descs = kcalloc(xs->tx->nentries, sizeof(*pool->tx_descs), GFP_KERNEL);
-               if (!pool->tx_descs)
+       if (xs->tx)
+               if (xp_alloc_tx_descs(pool, xs))
                        goto out;
-       }
 
        pool->chunk_mask = ~((u64)umem->chunk_size - 1);
        pool->addrs_cnt = umem->size;
index 846f785..7221f2f 100644 (file)
@@ -42,7 +42,7 @@ ISST_IN := $(OUTPUT)intel-speed-select-in.o
 $(ISST_IN): prepare FORCE
        $(Q)$(MAKE) $(build)=intel-speed-select
 $(OUTPUT)intel-speed-select: $(ISST_IN)
-       $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+       $(QUIET_LINK)$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
 
 clean:
        rm -f $(ALL_PROGRAMS)