Merge tag 'm68k-for-v4.19-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Aug 2018 15:42:46 +0000 (08:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Aug 2018 15:42:46 +0000 (08:42 -0700)
Pull m68k fix from Geert Uytterhoeven:
 "Just a single fix for a bug introduced during the merge window: fix
  wrong date and time on PMU-based Macs"

* tag 'm68k-for-v4.19-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k/mac: Use correct PMU response format

181 files changed:
Documentation/ABI/testing/sysfs-driver-xen-blkback
Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt
Documentation/hwmon/ina2xx
Documentation/i2c/DMA-considerations
MAINTAINERS
Makefile
arch/arm64/crypto/ghash-ce-glue.c
arch/arm64/crypto/sm4-ce-glue.c
arch/nios2/Kconfig.debug
arch/powerpc/Kconfig
arch/riscv/include/asm/tlb.h
arch/riscv/kernel/sys_riscv.c
arch/x86/crypto/aesni-intel_asm.S
block/blk-wbt.c
block/bsg.c
block/elevator.c
drivers/ata/pata_ftide010.c
drivers/base/power/clock_ops.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkfront.c
drivers/bluetooth/Kconfig
drivers/bluetooth/btmtkuart.c
drivers/cdrom/cdrom.c
drivers/cpuidle/governors/menu.c
drivers/crypto/caam/caamalg_qi.c
drivers/crypto/caam/caampkc.c
drivers/crypto/caam/jr.c
drivers/crypto/cavium/nitrox/nitrox_dev.h
drivers/crypto/cavium/nitrox/nitrox_lib.c
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c
drivers/crypto/chelsio/chtls/chtls.h
drivers/crypto/chelsio/chtls/chtls_main.c
drivers/crypto/vmx/aes_cbc.c
drivers/crypto/vmx/aes_xts.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/kv_dpm.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lspcon.c
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
drivers/gpu/drm/mediatek/mtk_disp_rdma.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.h
drivers/gpu/drm/mediatek/mtk_drm_ddp.c
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/hwmon/adt7475.c
drivers/hwmon/ina2xx.c
drivers/hwmon/nct6775.c
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/busses/i2c-designware-master.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/i2c-core-base.c
drivers/mmc/core/queue.c
drivers/mmc/core/queue.h
drivers/mmc/host/android-goldfish.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
drivers/mtd/nand/raw/denali.c
drivers/mtd/nand/raw/docg4.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/intel/e1000/e1000_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_controlq.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_nvm.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_switch.h
drivers/net/ethernet/intel/ice/ice_txrx.h
drivers/net/ethernet/intel/ice/ice_type.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/netronome/nfp/flower/action.c
drivers/net/ethernet/qlogic/qed/qed_init_ops.c
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_mcp.h
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
drivers/net/ethernet/qlogic/qede/qede_filter.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/usb/r8152.c
drivers/nvme/host/pci.c
drivers/nvme/target/core.c
drivers/nvme/target/fcloop.c
drivers/thermal/of-thermal.c
drivers/thermal/qoriq_thermal.c
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_thermal.c
drivers/vhost/vhost.c
fs/isofs/inode.c
fs/notify/mark.c
fs/quota/quota.c
fs/udf/super.c
include/linux/i2c.h
include/linux/platform_data/ina2xx.h
include/linux/quota.h
include/net/act_api.h
include/net/pkt_cls.h
kernel/bpf/hashtab.c
kernel/bpf/sockmap.c
lib/rhashtable.c
net/dsa/slave.c
net/ipv4/tcp_bbr.c
net/ipv4/tcp_ipv4.c
net/ipv6/addrconf.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_vti.c
net/ipv6/route.c
net/ncsi/ncsi-netlink.c
net/rds/tcp.c
net/sched/act_api.c
net/sched/act_bpf.c
net/sched/act_connmark.c
net/sched/act_csum.c
net/sched/act_gact.c
net/sched/act_ife.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_sample.c
net/sched/act_simple.c
net/sched/act_skbedit.c
net/sched/act_skbmod.c
net/sched/act_tunnel_key.c
net/sched/act_vlan.c
net/sched/cls_u32.c
net/sched/sch_cake.c
net/tls/tls_main.c
net/xdp/xdp_umem.c
tools/bpf/bpftool/map_perf_ring.c

index 8bb43b66eb55a1f8c0cbac1917301b2e96a55bbc..4e7babb3ba1fecc673018253d4adbb860e0cb8a4 100644 (file)
@@ -15,3 +15,13 @@ Description:
                 blkback. If the frontend tries to use more than
                 max_persistent_grants, the LRU kicks in and starts
                 removing 5% of max_persistent_grants every 100ms.
+
+What:           /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
+Date:           August 2018
+KernelVersion:  4.19
+Contact:        Roger Pau Monné <roger.pau@citrix.com>
+Description:
+                How long a persistent grant is allowed to remain
+                allocated without being in use. The time is in
+                seconds, 0 means indefinitely long.
+                The default is 60 seconds.
index b0a8af51c388c51f544b4b4cc391563a08e82ca9..265b223cd9780158a8415e96ce7dfb16c192237a 100644 (file)
@@ -11,7 +11,7 @@ The RISC-V supervisor ISA manual specifies three interrupt sources that are
 attached to every HLIC: software interrupts, the timer interrupt, and external
 interrupts.  Software interrupts are used to send IPIs between cores.  The
 timer interrupt comes from an architecturally mandated real-time timer that is
-controller via Supervisor Binary Interface (SBI) calls and CSR reads.  External
+controlled via Supervisor Binary Interface (SBI) calls and CSR reads.  External
 interrupts connect all other device interrupts to the HLIC, which are routed
 via the platform-level interrupt controller (PLIC).
 
@@ -25,7 +25,15 @@ in the system.
 
 Required properties:
 - compatible : "riscv,cpu-intc"
-- #interrupt-cells : should be <1>
+- #interrupt-cells : should be <1>.  The interrupt sources are defined by the
+  RISC-V supervisor ISA manual, with only the following three interrupts being
+  defined for supervisor mode:
+    - Source 1 is the supervisor software interrupt, which can be sent by an SBI
+      call and is reserved for use by software.
+    - Source 5 is the supervisor timer interrupt, which can be configured by
+      SBI calls and implements a one-shot timer.
+    - Source 9 is the supervisor external interrupt, which chains to all other
+      device interrupts.
 - interrupt-controller : Identifies the node as an interrupt controller
 
 Furthermore, this interrupt-controller MUST be embedded inside the cpu
@@ -38,7 +46,7 @@ An example device tree entry for a HLIC is show below.
                ...
                cpu1-intc: interrupt-controller {
                        #interrupt-cells = <1>;
-                       compatible = "riscv,cpu-intc", "sifive,fu540-c000-cpu-intc";
+                       compatible = "sifive,fu540-c000-cpu-intc", "riscv,cpu-intc";
                        interrupt-controller;
                };
        };
index 72d16f08e431c674c62738641d7c28926d6331cb..b8df81f6d6bcf995e098ebb4dce0a57a483bba66 100644 (file)
@@ -32,7 +32,7 @@ Supported chips:
     Datasheet: Publicly available at the Texas Instruments website
                http://www.ti.com/
 
-Author: Lothar Felten <l-felten@ti.com>
+Author: Lothar Felten <lothar.felten@gmail.com>
 
 Description
 -----------
index 966610aa4620fa8ce19e52fffd2d44c5a2128367..203002054120568135a01f7e4ab343a5223279bd 100644 (file)
@@ -50,10 +50,14 @@ bounce buffer. But you don't need to care about that detail, just use the
 returned buffer. If NULL is returned, the threshold was not met or a bounce
 buffer could not be allocated. Fall back to PIO in that case.
 
-In any case, a buffer obtained from above needs to be released. It ensures data
-is copied back to the message and a potentially used bounce buffer is freed::
+In any case, a buffer obtained from above needs to be released. Another helper
+function ensures a potentially used bounce buffer is freed::
 
-       i2c_release_dma_safe_msg_buf(msg, dma_buf);
+       i2c_put_dma_safe_msg_buf(dma_buf, msg, xferred);
+
+The last argument 'xferred' controls if the buffer is synced back to the
+message or not. No syncing is needed in cases setting up DMA had an error and
+there was no data transferred.
 
 The bounce buffer handling from the core is generic and simple. It will always
 allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
index a5b256b259057c564f76c508e0fcf648e47938d7..9ad052aeac39be98b3cb1d390e043f2c7583fd67 100644 (file)
@@ -8255,9 +8255,9 @@ F:        drivers/ata/pata_arasan_cf.c
 
 LIBATA PATA DRIVERS
 M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-M:     Jens Axboe <kernel.dk>
+M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/pata_*.c
 F:     drivers/ata/ata_generic.c
@@ -8275,7 +8275,7 @@ LIBATA SATA AHCI PLATFORM devices support
 M:     Hans de Goede <hdegoede@redhat.com>
 M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/ahci_platform.c
 F:     drivers/ata/libahci_platform.c
@@ -8291,7 +8291,7 @@ F:        drivers/ata/sata_promise.*
 LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
 M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/
 F:     include/linux/ata.h
index 2b458801ba7418a9897bce84a116105f2f87a18c..a34a9283ee9088c70c80db56bf38fdc7514d83e4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -807,6 +807,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 # disable pointer signed / unsigned warnings in gcc 4.0
 KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
 
+# disable stringop warnings in gcc 8+
+KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
+
 # disable invalid "can't wrap" optimizations for signed / pointers
 KBUILD_CFLAGS  += $(call cc-option,-fno-strict-overflow)
 
index 6e9f33d14930eb045d293c4df7952afa555b56fa..067d8937d5af1e74a69ae7b14b1b0306a53fe087 100644 (file)
@@ -417,7 +417,7 @@ static int gcm_encrypt(struct aead_request *req)
                __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
                put_unaligned_be32(2, iv + GCM_IV_SIZE);
 
-               while (walk.nbytes >= AES_BLOCK_SIZE) {
+               while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
                        int blocks = walk.nbytes / AES_BLOCK_SIZE;
                        u8 *dst = walk.dst.virt.addr;
                        u8 *src = walk.src.virt.addr;
@@ -437,11 +437,18 @@ static int gcm_encrypt(struct aead_request *req)
                                        NULL);
 
                        err = skcipher_walk_done(&walk,
-                                                walk.nbytes % AES_BLOCK_SIZE);
+                                                walk.nbytes % (2 * AES_BLOCK_SIZE));
                }
-               if (walk.nbytes)
+               if (walk.nbytes) {
                        __aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv,
                                            nrounds);
+                       if (walk.nbytes > AES_BLOCK_SIZE) {
+                               crypto_inc(iv, AES_BLOCK_SIZE);
+                               __aes_arm64_encrypt(ctx->aes_key.key_enc,
+                                                   ks + AES_BLOCK_SIZE, iv,
+                                                   nrounds);
+                       }
+               }
        }
 
        /* handle the tail */
@@ -545,7 +552,7 @@ static int gcm_decrypt(struct aead_request *req)
                __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
                put_unaligned_be32(2, iv + GCM_IV_SIZE);
 
-               while (walk.nbytes >= AES_BLOCK_SIZE) {
+               while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
                        int blocks = walk.nbytes / AES_BLOCK_SIZE;
                        u8 *dst = walk.dst.virt.addr;
                        u8 *src = walk.src.virt.addr;
@@ -564,11 +571,21 @@ static int gcm_decrypt(struct aead_request *req)
                        } while (--blocks > 0);
 
                        err = skcipher_walk_done(&walk,
-                                                walk.nbytes % AES_BLOCK_SIZE);
+                                                walk.nbytes % (2 * AES_BLOCK_SIZE));
                }
-               if (walk.nbytes)
+               if (walk.nbytes) {
+                       if (walk.nbytes > AES_BLOCK_SIZE) {
+                               u8 *iv2 = iv + AES_BLOCK_SIZE;
+
+                               memcpy(iv2, iv, AES_BLOCK_SIZE);
+                               crypto_inc(iv2, AES_BLOCK_SIZE);
+
+                               __aes_arm64_encrypt(ctx->aes_key.key_enc, iv2,
+                                                   iv2, nrounds);
+                       }
                        __aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv,
                                            nrounds);
+               }
        }
 
        /* handle the tail */
index b7fb5274b250134253173384ff643578f5c06a29..0c4fc223f22575fbf76ff66d3e077249d86ad8c1 100644 (file)
@@ -69,5 +69,5 @@ static void __exit sm4_ce_mod_fini(void)
        crypto_unregister_alg(&sm4_ce_alg);
 }
 
-module_cpu_feature_match(SM3, sm4_ce_mod_init);
+module_cpu_feature_match(SM4, sm4_ce_mod_init);
 module_exit(sm4_ce_mod_fini);
index 7a49f0d28d14c106ea9300c8e54ad18aa6471e0b..f1da8a7b17ff49b4965f4f5d9e647b9e1d1e258d 100644 (file)
@@ -3,15 +3,6 @@
 config TRACE_IRQFLAGS_SUPPORT
        def_bool y
 
-config DEBUG_STACK_USAGE
-       bool "Enable stack utilization instrumentation"
-       depends on DEBUG_KERNEL
-       help
-         Enables the display of the minimum amount of free stack which each
-         task has ever had available in the sysrq-T and sysrq-P debug output.
-
-         This option will slow down process creation somewhat.
-
 config EARLY_PRINTK
        bool "Activate early kernel debugging"
        default y
index db0b6eebbfa5b55a6f7c4f55b1d489bcf158d974..a80669209155383343ba8adbb90b3e8427e2afdb 100644 (file)
@@ -177,7 +177,6 @@ config PPC
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_MMAP_RND_BITS
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
-       select HAVE_ARCH_PREL32_RELOCATIONS
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
        select HAVE_CBPF_JIT                    if !PPC64
index c229509288ea2d77c9efe72cfb1ccb0105371296..439dc7072e05bf37a722bb983b69dabed39651fa 100644 (file)
 #ifndef _ASM_RISCV_TLB_H
 #define _ASM_RISCV_TLB_H
 
+struct mmu_gather;
+
+static void tlb_flush(struct mmu_gather *tlb);
+
 #include <asm-generic/tlb.h>
 
 static inline void tlb_flush(struct mmu_gather *tlb)
index 568026ccf6e8712fa59dc3d1e216924f6d1c5c4d..fb03a4482ad60ac7ca66f86429897275020c5ffd 100644 (file)
@@ -65,24 +65,11 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
        uintptr_t, flags)
 {
-#ifdef CONFIG_SMP
-       struct mm_struct *mm = current->mm;
-       bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0;
-#endif
-
        /* Check the reserved flags. */
        if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL))
                return -EINVAL;
 
-       /*
-        * Without CONFIG_SMP flush_icache_mm is a just a flush_icache_all(),
-        * which generates unused variable warnings all over this function.
-        */
-#ifdef CONFIG_SMP
-       flush_icache_mm(mm, local);
-#else
-       flush_icache_all();
-#endif
+       flush_icache_mm(current->mm, flags & SYS_RISCV_FLUSH_ICACHE_LOCAL);
 
        return 0;
 }
index 9bd139569b410d9e41cff15fb36aeb366930be95..cb2deb61c5d96dc53aabdeb7bd880ed436f75db7 100644 (file)
@@ -223,34 +223,34 @@ ALL_F:      .octa 0xffffffffffffffffffffffffffffffff
        pcmpeqd TWOONE(%rip), \TMP2
        pand    POLY(%rip), \TMP2
        pxor    \TMP2, \TMP3
-       movdqa  \TMP3, HashKey(%arg2)
+       movdqu  \TMP3, HashKey(%arg2)
 
        movdqa     \TMP3, \TMP5
        pshufd     $78, \TMP3, \TMP1
        pxor       \TMP3, \TMP1
-       movdqa     \TMP1, HashKey_k(%arg2)
+       movdqu     \TMP1, HashKey_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^2<<1 (mod poly)
-       movdqa     \TMP5, HashKey_2(%arg2)
+       movdqu     \TMP5, HashKey_2(%arg2)
 # HashKey_2 = HashKey^2<<1 (mod poly)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_2_k(%arg2)
+       movdqu     \TMP1, HashKey_2_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^3<<1 (mod poly)
-       movdqa     \TMP5, HashKey_3(%arg2)
+       movdqu     \TMP5, HashKey_3(%arg2)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_3_k(%arg2)
+       movdqu     \TMP1, HashKey_3_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^3<<1 (mod poly)
-       movdqa     \TMP5, HashKey_4(%arg2)
+       movdqu     \TMP5, HashKey_4(%arg2)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_4_k(%arg2)
+       movdqu     \TMP1, HashKey_4_k(%arg2)
 .endm
 
 # GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
@@ -271,7 +271,7 @@ ALL_F:      .octa 0xffffffffffffffffffffffffffffffff
        movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
 
        PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
-       movdqa HashKey(%arg2), %xmm13
+       movdqu HashKey(%arg2), %xmm13
 
        CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
        %xmm4, %xmm5, %xmm6
@@ -997,7 +997,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pshufd    $78, \XMM5, \TMP6
        pxor      \XMM5, \TMP6
        paddd     ONE(%rip), \XMM0              # INCR CNT
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP4           # TMP4 = a1*b1
        movdqa    \XMM0, \XMM1
        paddd     ONE(%rip), \XMM0              # INCR CNT
@@ -1016,7 +1016,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pxor      (%arg1), \XMM2
        pxor      (%arg1), \XMM3
        pxor      (%arg1), \XMM4
-       movdqa    HashKey_4_k(%arg2), \TMP5
+       movdqu    HashKey_4_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP6           # TMP6 = (a1+a0)*(b1+b0)
        movaps 0x10(%arg1), \TMP1
        AESENC    \TMP1, \XMM1              # Round 1
@@ -1031,7 +1031,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM6, \TMP1
        pshufd    $78, \XMM6, \TMP2
        pxor      \XMM6, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1           # TMP1 = a1 * b1
        movaps 0x30(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 3
@@ -1044,7 +1044,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_3_k(%arg2), \TMP5
+       movdqu    HashKey_3_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x50(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 5
@@ -1058,7 +1058,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM7, \TMP1
        pshufd    $78, \XMM7, \TMP2
        pxor      \XMM7, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
 
         # Multiply TMP5 * HashKey using karatsuba
 
@@ -1074,7 +1074,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_2_k(%arg2), \TMP5
+       movdqu    HashKey_2_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x80(%arg1), \TMP3
        AESENC    \TMP3, \XMM1             # Round 8
@@ -1092,7 +1092,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM8, \TMP1
        pshufd    $78, \XMM8, \TMP2
        pxor      \XMM8, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1          # TMP1 = a1*b1
        movaps 0x90(%arg1), \TMP3
        AESENC    \TMP3, \XMM1            # Round 9
@@ -1121,7 +1121,7 @@ aes_loop_par_enc_done\@:
        AESENCLAST \TMP3, \XMM2
        AESENCLAST \TMP3, \XMM3
        AESENCLAST \TMP3, \XMM4
-       movdqa    HashKey_k(%arg2), \TMP5
+       movdqu    HashKey_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2          # TMP2 = (a1+a0)*(b1+b0)
        movdqu    (%arg4,%r11,1), \TMP3
        pxor      \TMP3, \XMM1                 # Ciphertext/Plaintext XOR EK
@@ -1205,7 +1205,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pshufd    $78, \XMM5, \TMP6
        pxor      \XMM5, \TMP6
        paddd     ONE(%rip), \XMM0              # INCR CNT
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP4           # TMP4 = a1*b1
        movdqa    \XMM0, \XMM1
        paddd     ONE(%rip), \XMM0              # INCR CNT
@@ -1224,7 +1224,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pxor      (%arg1), \XMM2
        pxor      (%arg1), \XMM3
        pxor      (%arg1), \XMM4
-       movdqa    HashKey_4_k(%arg2), \TMP5
+       movdqu    HashKey_4_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP6           # TMP6 = (a1+a0)*(b1+b0)
        movaps 0x10(%arg1), \TMP1
        AESENC    \TMP1, \XMM1              # Round 1
@@ -1239,7 +1239,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM6, \TMP1
        pshufd    $78, \XMM6, \TMP2
        pxor      \XMM6, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1           # TMP1 = a1 * b1
        movaps 0x30(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 3
@@ -1252,7 +1252,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_3_k(%arg2), \TMP5
+       movdqu    HashKey_3_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x50(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 5
@@ -1266,7 +1266,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM7, \TMP1
        pshufd    $78, \XMM7, \TMP2
        pxor      \XMM7, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
 
         # Multiply TMP5 * HashKey using karatsuba
 
@@ -1282,7 +1282,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_2_k(%arg2), \TMP5
+       movdqu    HashKey_2_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x80(%arg1), \TMP3
        AESENC    \TMP3, \XMM1             # Round 8
@@ -1300,7 +1300,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM8, \TMP1
        pshufd    $78, \XMM8, \TMP2
        pxor      \XMM8, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1          # TMP1 = a1*b1
        movaps 0x90(%arg1), \TMP3
        AESENC    \TMP3, \XMM1            # Round 9
@@ -1329,7 +1329,7 @@ aes_loop_par_dec_done\@:
        AESENCLAST \TMP3, \XMM2
        AESENCLAST \TMP3, \XMM3
        AESENCLAST \TMP3, \XMM4
-       movdqa    HashKey_k(%arg2), \TMP5
+       movdqu    HashKey_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2          # TMP2 = (a1+a0)*(b1+b0)
        movdqu    (%arg4,%r11,1), \TMP3
        pxor      \TMP3, \XMM1                 # Ciphertext/Plaintext XOR EK
@@ -1405,10 +1405,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM1, \TMP6
        pshufd    $78, \XMM1, \TMP2
        pxor      \XMM1, \TMP2
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP6       # TMP6 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM1       # XMM1 = a0*b0
-       movdqa    HashKey_4_k(%arg2), \TMP4
+       movdqu    HashKey_4_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        movdqa    \XMM1, \XMMDst
        movdqa    \TMP2, \XMM1              # result in TMP6, XMMDst, XMM1
@@ -1418,10 +1418,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM2, \TMP1
        pshufd    $78, \XMM2, \TMP2
        pxor      \XMM2, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1       # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM2       # XMM2 = a0*b0
-       movdqa    HashKey_3_k(%arg2), \TMP4
+       movdqu    HashKey_3_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM2, \XMMDst
@@ -1433,10 +1433,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM3, \TMP1
        pshufd    $78, \XMM3, \TMP2
        pxor      \XMM3, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1       # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM3       # XMM3 = a0*b0
-       movdqa    HashKey_2_k(%arg2), \TMP4
+       movdqu    HashKey_2_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM3, \XMMDst
@@ -1446,10 +1446,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM4, \TMP1
        pshufd    $78, \XMM4, \TMP2
        pxor      \XMM4, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1        # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM4       # XMM4 = a0*b0
-       movdqa    HashKey_k(%arg2), \TMP4
+       movdqu    HashKey_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM4, \XMMDst
index 84507d3e9a981d5e4888c9b3783f0155f992adba..8e20a0677dcf69b6e523b571099fede8c9904d78 100644 (file)
@@ -123,16 +123,11 @@ static void rwb_wake_all(struct rq_wb *rwb)
        }
 }
 
-static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
+static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw,
+                        enum wbt_flags wb_acct)
 {
-       struct rq_wb *rwb = RQWB(rqos);
-       struct rq_wait *rqw;
        int inflight, limit;
 
-       if (!(wb_acct & WBT_TRACKED))
-               return;
-
-       rqw = get_rq_wait(rwb, wb_acct);
        inflight = atomic_dec_return(&rqw->inflight);
 
        /*
@@ -166,10 +161,22 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
                int diff = limit - inflight;
 
                if (!inflight || diff >= rwb->wb_background / 2)
-                       wake_up(&rqw->wait);
+                       wake_up_all(&rqw->wait);
        }
 }
 
+static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
+{
+       struct rq_wb *rwb = RQWB(rqos);
+       struct rq_wait *rqw;
+
+       if (!(wb_acct & WBT_TRACKED))
+               return;
+
+       rqw = get_rq_wait(rwb, wb_acct);
+       wbt_rqw_done(rwb, rqw, wb_acct);
+}
+
 /*
  * Called on completion of a request. Note that it's also called when
  * a request is merged, when the request gets freed.
@@ -481,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
        return limit;
 }
 
+struct wbt_wait_data {
+       struct wait_queue_entry wq;
+       struct task_struct *task;
+       struct rq_wb *rwb;
+       struct rq_wait *rqw;
+       unsigned long rw;
+       bool got_token;
+};
+
+static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode,
+                            int wake_flags, void *key)
+{
+       struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data,
+                                                       wq);
+
+       /*
+        * If we fail to get a budget, return -1 to interrupt the wake up
+        * loop in __wake_up_common.
+        */
+       if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw)))
+               return -1;
+
+       data->got_token = true;
+       list_del_init(&curr->entry);
+       wake_up_process(data->task);
+       return 1;
+}
+
 /*
  * Block if we will exceed our limit, or if we are currently waiting for
  * the timer to kick off queuing again.
@@ -491,19 +526,40 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
        __acquires(lock)
 {
        struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
-       DECLARE_WAITQUEUE(wait, current);
+       struct wbt_wait_data data = {
+               .wq = {
+                       .func   = wbt_wake_function,
+                       .entry  = LIST_HEAD_INIT(data.wq.entry),
+               },
+               .task = current,
+               .rwb = rwb,
+               .rqw = rqw,
+               .rw = rw,
+       };
        bool has_sleeper;
 
        has_sleeper = wq_has_sleeper(&rqw->wait);
        if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
                return;
 
-       add_wait_queue_exclusive(&rqw->wait, &wait);
+       prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
+               if (data.got_token)
+                       break;
 
-               if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
+               if (!has_sleeper &&
+                   rq_wait_inc_below(rqw, get_limit(rwb, rw))) {
+                       finish_wait(&rqw->wait, &data.wq);
+
+                       /*
+                        * We raced with wbt_wake_function() getting a token,
+                        * which means we now have two. Put our local token
+                        * and wake anyone else potentially waiting for one.
+                        */
+                       if (data.got_token)
+                               wbt_rqw_done(rwb, rqw, wb_acct);
                        break;
+               }
 
                if (lock) {
                        spin_unlock_irq(lock);
@@ -511,11 +567,11 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
                        spin_lock_irq(lock);
                } else
                        io_schedule();
+
                has_sleeper = false;
        } while (1);
 
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&rqw->wait, &wait);
+       finish_wait(&rqw->wait, &data.wq);
 }
 
 static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
@@ -580,11 +636,6 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock)
                return;
        }
 
-       if (current_is_kswapd())
-               flags |= WBT_KSWAPD;
-       if (bio_op(bio) == REQ_OP_DISCARD)
-               flags |= WBT_DISCARD;
-
        __wbt_wait(rwb, flags, bio->bi_opf, lock);
 
        if (!blk_stat_is_active(rwb->cb))
index db588add6ba6622b1495446b05f19ce0e5720bf8..9a442c23a715e2f8b53b8bb4209af912a3f45af3 100644 (file)
@@ -37,7 +37,7 @@ struct bsg_device {
        struct request_queue *queue;
        spinlock_t lock;
        struct hlist_node dev_list;
-       atomic_t ref_count;
+       refcount_t ref_count;
        char name[20];
        int max_queue;
 };
@@ -252,7 +252,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
        mutex_lock(&bsg_mutex);
 
-       if (!atomic_dec_and_test(&bd->ref_count)) {
+       if (!refcount_dec_and_test(&bd->ref_count)) {
                mutex_unlock(&bsg_mutex);
                return 0;
        }
@@ -290,7 +290,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 
        bd->queue = rq;
 
-       atomic_set(&bd->ref_count, 1);
+       refcount_set(&bd->ref_count, 1);
        hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
 
        strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
@@ -308,7 +308,7 @@ static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
 
        hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
                if (bd->queue == q) {
-                       atomic_inc(&bd->ref_count);
+                       refcount_inc(&bd->ref_count);
                        goto found;
                }
        }
index 5ea6e7d600e46edcd1eec808324640ab8b7099ed..6a06b5d040e5dd8ffab230a3f3ae74bfa6935233 100644 (file)
@@ -895,8 +895,7 @@ int elv_register(struct elevator_type *e)
        spin_lock(&elv_list_lock);
        if (elevator_find(e->elevator_name, e->uses_mq)) {
                spin_unlock(&elv_list_lock);
-               if (e->icq_cache)
-                       kmem_cache_destroy(e->icq_cache);
+               kmem_cache_destroy(e->icq_cache);
                return -EBUSY;
        }
        list_add_tail(&e->list, &elv_list);
index 5d4b72e21161a888c44997b448f602cef99a6709..569a4a662dcd4deb9d9edb0dbca4001f798bcab5 100644 (file)
@@ -256,14 +256,12 @@ static struct ata_port_operations pata_ftide010_port_ops = {
        .qc_issue       = ftide010_qc_issue,
 };
 
-static struct ata_port_info ftide010_port_info[] = {
-       {
-               .flags          = ATA_FLAG_SLAVE_POSS,
-               .mwdma_mask     = ATA_MWDMA2,
-               .udma_mask      = ATA_UDMA6,
-               .pio_mask       = ATA_PIO4,
-               .port_ops       = &pata_ftide010_port_ops,
-       },
+static struct ata_port_info ftide010_port_info = {
+       .flags          = ATA_FLAG_SLAVE_POSS,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA6,
+       .pio_mask       = ATA_PIO4,
+       .port_ops       = &pata_ftide010_port_ops,
 };
 
 #if IS_ENABLED(CONFIG_SATA_GEMINI)
@@ -349,6 +347,7 @@ static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
 }
 
 static int pata_ftide010_gemini_init(struct ftide010 *ftide,
+                                    struct ata_port_info *pi,
                                     bool is_ata1)
 {
        struct device *dev = ftide->dev;
@@ -373,7 +372,13 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
 
        /* Flag port as SATA-capable */
        if (gemini_sata_bridge_enabled(sg, is_ata1))
-               ftide010_port_info[0].flags |= ATA_FLAG_SATA;
+               pi->flags |= ATA_FLAG_SATA;
+
+       /* This device has broken DMA, only PIO works */
+       if (of_machine_is_compatible("itian,sq201")) {
+               pi->mwdma_mask = 0;
+               pi->udma_mask = 0;
+       }
 
        /*
         * We assume that a simple 40-wire cable is used in the PATA mode.
@@ -435,6 +440,7 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
 }
 #else
 static int pata_ftide010_gemini_init(struct ftide010 *ftide,
+                                    struct ata_port_info *pi,
                                     bool is_ata1)
 {
        return -ENOTSUPP;
@@ -446,7 +452,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
-       const struct ata_port_info pi = ftide010_port_info[0];
+       struct ata_port_info pi = ftide010_port_info;
        const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ftide010 *ftide;
        struct resource *res;
@@ -490,6 +496,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
                 * are ATA0. This will also set up the cable types.
                 */
                ret = pata_ftide010_gemini_init(ftide,
+                               &pi,
                                (res->start == 0x63400000));
                if (ret)
                        goto err_dis_clk;
index 8e2e4757adcb02c9cd07a0b868a45e0bb3baa3eb..5a42ae4078c27febf8194901d8fa0e30b43bd1aa 100644 (file)
@@ -185,7 +185,7 @@ EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
 int of_pm_clk_add_clks(struct device *dev)
 {
        struct clk **clks;
-       unsigned int i, count;
+       int i, count;
        int ret;
 
        if (!dev || !dev->of_node)
index b55b245e805205a07266c9d745b96e4716ed3009..fd1e19f1a49f5803ca6dd5d939ec41ec592af077 100644 (file)
@@ -83,6 +83,18 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
 MODULE_PARM_DESC(max_persistent_grants,
                  "Maximum number of grants to map persistently");
 
+/*
+ * How long a persistent grant is allowed to remain allocated without being in
+ * use. The time is in seconds, 0 means indefinitely long.
+ */
+
+static unsigned int xen_blkif_pgrant_timeout = 60;
+module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
+                  uint, 0644);
+MODULE_PARM_DESC(persistent_grant_unused_seconds,
+                "Time in seconds an unused persistent grant is allowed to "
+                "remain allocated. Default is 60, 0 means unlimited.");
+
 /*
  * Maximum number of rings/queues blkback supports, allow as many queues as there
  * are CPUs if user has not specified a value.
@@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
 /* Number of free pages to remove on each call to gnttab_free_pages */
 #define NUM_BATCH_FREE_PAGES 10
 
+static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
+{
+       return xen_blkif_pgrant_timeout &&
+              (jiffies - persistent_gnt->last_used >=
+               HZ * xen_blkif_pgrant_timeout);
+}
+
 static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
 {
        unsigned long flags;
@@ -236,8 +255,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
                }
        }
 
-       bitmap_zero(persistent_gnt->flags, PERSISTENT_GNT_FLAGS_SIZE);
-       set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
+       persistent_gnt->active = true;
        /* Add new node and rebalance tree. */
        rb_link_node(&(persistent_gnt->node), parent, new);
        rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
@@ -261,11 +279,11 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
                else if (gref > data->gnt)
                        node = node->rb_right;
                else {
-                       if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) {
+                       if (data->active) {
                                pr_alert_ratelimited("requesting a grant already in use\n");
                                return NULL;
                        }
-                       set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
+                       data->active = true;
                        atomic_inc(&ring->persistent_gnt_in_use);
                        return data;
                }
@@ -276,10 +294,10 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
 static void put_persistent_gnt(struct xen_blkif_ring *ring,
                                struct persistent_gnt *persistent_gnt)
 {
-       if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+       if (!persistent_gnt->active)
                pr_alert_ratelimited("freeing a grant already unused\n");
-       set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
-       clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
+       persistent_gnt->last_used = jiffies;
+       persistent_gnt->active = false;
        atomic_dec(&ring->persistent_gnt_in_use);
 }
 
@@ -371,26 +389,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
        struct persistent_gnt *persistent_gnt;
        struct rb_node *n;
        unsigned int num_clean, total;
-       bool scan_used = false, clean_used = false;
+       bool scan_used = false;
        struct rb_root *root;
 
-       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
-           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
-           !ring->blkif->vbd.overflow_max_grants)) {
-               goto out;
-       }
-
        if (work_busy(&ring->persistent_purge_work)) {
                pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
                goto out;
        }
 
-       num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
-       num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
-       num_clean = min(ring->persistent_gnt_c, num_clean);
-       if ((num_clean == 0) ||
-           (num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use))))
-               goto out;
+       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
+           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
+           !ring->blkif->vbd.overflow_max_grants)) {
+               num_clean = 0;
+       } else {
+               num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
+               num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
+                           num_clean;
+               num_clean = min(ring->persistent_gnt_c, num_clean);
+               pr_debug("Going to purge at least %u persistent grants\n",
+                        num_clean);
+       }
 
        /*
         * At this point, we can assure that there will be no calls
@@ -401,9 +419,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
          * number of grants.
         */
 
-       total = num_clean;
-
-       pr_debug("Going to purge %u persistent grants\n", num_clean);
+       total = 0;
 
        BUG_ON(!list_empty(&ring->persistent_purge_list));
        root = &ring->persistent_gnts;
@@ -412,46 +428,37 @@ purge_list:
                BUG_ON(persistent_gnt->handle ==
                        BLKBACK_INVALID_HANDLE);
 
-               if (clean_used) {
-                       clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
+               if (persistent_gnt->active)
                        continue;
-               }
-
-               if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+               if (!scan_used && !persistent_gnt_timeout(persistent_gnt))
                        continue;
-               if (!scan_used &&
-                   (test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags)))
+               if (scan_used && total >= num_clean)
                        continue;
 
                rb_erase(&persistent_gnt->node, root);
                list_add(&persistent_gnt->remove_node,
                         &ring->persistent_purge_list);
-               if (--num_clean == 0)
-                       goto finished;
+               total++;
        }
        /*
-        * If we get here it means we also need to start cleaning
+        * Check whether we also need to start cleaning
         * grants that were used since last purge in order to cope
         * with the requested num
         */
-       if (!scan_used && !clean_used) {
-               pr_debug("Still missing %u purged frames\n", num_clean);
+       if (!scan_used && total < num_clean) {
+               pr_debug("Still missing %u purged frames\n", num_clean - total);
                scan_used = true;
                goto purge_list;
        }
-finished:
-       if (!clean_used) {
-               pr_debug("Finished scanning for grants to clean, removing used flag\n");
-               clean_used = true;
-               goto purge_list;
-       }
 
-       ring->persistent_gnt_c -= (total - num_clean);
-       ring->blkif->vbd.overflow_max_grants = 0;
+       if (total) {
+               ring->persistent_gnt_c -= total;
+               ring->blkif->vbd.overflow_max_grants = 0;
 
-       /* We can defer this work */
-       schedule_work(&ring->persistent_purge_work);
-       pr_debug("Purged %u/%u\n", (total - num_clean), total);
+               /* We can defer this work */
+               schedule_work(&ring->persistent_purge_work);
+               pr_debug("Purged %u/%u\n", num_clean, total);
+       }
 
 out:
        return;
index ecb35fe8ca8dbb54f36a85513a09064819acd67a..1d3002d773f7adb151dcf79adf18f919e461290a 100644 (file)
@@ -233,16 +233,6 @@ struct xen_vbd {
 
 struct backend_info;
 
-/* Number of available flags */
-#define PERSISTENT_GNT_FLAGS_SIZE      2
-/* This persistent grant is currently in use */
-#define PERSISTENT_GNT_ACTIVE          0
-/*
- * This persistent grant has been used, this flag is set when we remove the
- * PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
- */
-#define PERSISTENT_GNT_WAS_ACTIVE      1
-
 /* Number of requests that we can fit in a ring */
 #define XEN_BLKIF_REQS_PER_PAGE                32
 
@@ -250,7 +240,8 @@ struct persistent_gnt {
        struct page *page;
        grant_ref_t gnt;
        grant_handle_t handle;
-       DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
+       unsigned long last_used;
+       bool active;
        struct rb_node node;
        struct list_head remove_node;
 };
@@ -278,7 +269,6 @@ struct xen_blkif_ring {
        wait_queue_head_t       pending_free_wq;
 
        /* Tree to store persistent grants. */
-       spinlock_t              pers_gnts_lock;
        struct rb_root          persistent_gnts;
        unsigned int            persistent_gnt_c;
        atomic_t                persistent_gnt_in_use;
index 8986adab9bf58540bd8d2ab0744d317fba6c23a0..a71d817e900ddc07ff45d240f0ae290ff408b6cd 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/scatterlist.h>
 #include <linux/bitmap.h>
 #include <linux/list.h>
+#include <linux/workqueue.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -121,6 +122,8 @@ static inline struct blkif_req *blkif_req(struct request *rq)
 
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
+static struct delayed_work blkfront_work;
+static LIST_HEAD(info_list);
 
 /*
  * Maximum number of segments in indirect requests, the actual value used by
@@ -216,6 +219,7 @@ struct blkfront_info
        /* Save uncomplete reqs and bios for migration. */
        struct list_head requests;
        struct bio_list bio_list;
+       struct list_head info_list;
 };
 
 static unsigned int nr_minors;
@@ -1759,6 +1763,12 @@ abort_transaction:
        return err;
 }
 
+static void free_info(struct blkfront_info *info)
+{
+       list_del(&info->info_list);
+       kfree(info);
+}
+
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
                           struct blkfront_info *info)
@@ -1880,7 +1890,10 @@ again:
  destroy_blkring:
        blkif_free(info, 0);
 
-       kfree(info);
+       mutex_lock(&blkfront_mutex);
+       free_info(info);
+       mutex_unlock(&blkfront_mutex);
+
        dev_set_drvdata(&dev->dev, NULL);
 
        return err;
@@ -1991,6 +2004,10 @@ static int blkfront_probe(struct xenbus_device *dev,
        info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
        dev_set_drvdata(&dev->dev, info);
 
+       mutex_lock(&blkfront_mutex);
+       list_add(&info->info_list, &info_list);
+       mutex_unlock(&blkfront_mutex);
+
        return 0;
 }
 
@@ -2301,6 +2318,12 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
        if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
                indirect_segments = 0;
        info->max_indirect_segments = indirect_segments;
+
+       if (info->feature_persistent) {
+               mutex_lock(&blkfront_mutex);
+               schedule_delayed_work(&blkfront_work, HZ * 10);
+               mutex_unlock(&blkfront_mutex);
+       }
 }
 
 /*
@@ -2482,7 +2505,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
        mutex_unlock(&info->mutex);
 
        if (!bdev) {
-               kfree(info);
+               mutex_lock(&blkfront_mutex);
+               free_info(info);
+               mutex_unlock(&blkfront_mutex);
                return 0;
        }
 
@@ -2502,7 +2527,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
        if (info && !bdev->bd_openers) {
                xlvbd_release_gendisk(info);
                disk->private_data = NULL;
-               kfree(info);
+               mutex_lock(&blkfront_mutex);
+               free_info(info);
+               mutex_unlock(&blkfront_mutex);
        }
 
        mutex_unlock(&bdev->bd_mutex);
@@ -2585,7 +2612,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
                dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
                xlvbd_release_gendisk(info);
                disk->private_data = NULL;
-               kfree(info);
+               free_info(info);
        }
 
 out:
@@ -2618,6 +2645,61 @@ static struct xenbus_driver blkfront_driver = {
        .is_ready = blkfront_is_ready,
 };
 
+static void purge_persistent_grants(struct blkfront_info *info)
+{
+       unsigned int i;
+       unsigned long flags;
+
+       for (i = 0; i < info->nr_rings; i++) {
+               struct blkfront_ring_info *rinfo = &info->rinfo[i];
+               struct grant *gnt_list_entry, *tmp;
+
+               spin_lock_irqsave(&rinfo->ring_lock, flags);
+
+               if (rinfo->persistent_gnts_c == 0) {
+                       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
+                       continue;
+               }
+
+               list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
+                                        node) {
+                       if (gnt_list_entry->gref == GRANT_INVALID_REF ||
+                           gnttab_query_foreign_access(gnt_list_entry->gref))
+                               continue;
+
+                       list_del(&gnt_list_entry->node);
+                       gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
+                       rinfo->persistent_gnts_c--;
+                       __free_page(gnt_list_entry->page);
+                       kfree(gnt_list_entry);
+               }
+
+               spin_unlock_irqrestore(&rinfo->ring_lock, flags);
+       }
+}
+
+static void blkfront_delay_work(struct work_struct *work)
+{
+       struct blkfront_info *info;
+       bool need_schedule_work = false;
+
+       mutex_lock(&blkfront_mutex);
+
+       list_for_each_entry(info, &info_list, info_list) {
+               if (info->feature_persistent) {
+                       need_schedule_work = true;
+                       mutex_lock(&info->mutex);
+                       purge_persistent_grants(info);
+                       mutex_unlock(&info->mutex);
+               }
+       }
+
+       if (need_schedule_work)
+               schedule_delayed_work(&blkfront_work, HZ * 10);
+
+       mutex_unlock(&blkfront_mutex);
+}
+
 static int __init xlblk_init(void)
 {
        int ret;
@@ -2626,6 +2708,15 @@ static int __init xlblk_init(void)
        if (!xen_domain())
                return -ENODEV;
 
+       if (!xen_has_pv_disk_devices())
+               return -ENODEV;
+
+       if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
+               pr_warn("xen_blk: can't get major %d with name %s\n",
+                       XENVBD_MAJOR, DEV_NAME);
+               return -ENODEV;
+       }
+
        if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
                xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
@@ -2641,14 +2732,7 @@ static int __init xlblk_init(void)
                xen_blkif_max_queues = nr_cpus;
        }
 
-       if (!xen_has_pv_disk_devices())
-               return -ENODEV;
-
-       if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
-               printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n",
-                      XENVBD_MAJOR, DEV_NAME);
-               return -ENODEV;
-       }
+       INIT_DELAYED_WORK(&blkfront_work, blkfront_delay_work);
 
        ret = xenbus_register_frontend(&blkfront_driver);
        if (ret) {
@@ -2663,6 +2747,8 @@ module_init(xlblk_init);
 
 static void __exit xlblk_exit(void)
 {
+       cancel_delayed_work_sync(&blkfront_work);
+
        xenbus_unregister_driver(&blkfront_driver);
        unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
        kfree(minors);
index 2df11cc08a460a893e2ebcb7af510f70bd6e792a..845b0314ce3a7f599360d6c7e3d73c14a5fc2bbb 100644 (file)
@@ -200,6 +200,7 @@ config BT_HCIUART_RTL
        depends on BT_HCIUART
        depends on BT_HCIUART_SERDEV
        depends on GPIOLIB
+       depends on ACPI
        select BT_HCIUART_3WIRE
        select BT_RTL
        help
index ed2a5c7cb77fa0304ed7f3639631c3b9c8eb597e..4593baff2bc944f5a003bb666520062f768f52e5 100644 (file)
@@ -144,8 +144,10 @@ static int mtk_setup_fw(struct hci_dev *hdev)
        fw_size = fw->size;
 
        /* The size of patch header is 30 bytes, should be skip */
-       if (fw_size < 30)
-               return -EINVAL;
+       if (fw_size < 30) {
+               err = -EINVAL;
+               goto free_fw;
+       }
 
        fw_size -= 30;
        fw_ptr += 30;
@@ -172,8 +174,8 @@ static int mtk_setup_fw(struct hci_dev *hdev)
                fw_ptr += dlen;
        }
 
+free_fw:
        release_firmware(fw);
-
        return err;
 }
 
index 113fc6edb2b03718166b2e42854d777a2f18f798..a5d5a96479bfe813449c7527024c52bf0d79c1b8 100644 (file)
@@ -2546,7 +2546,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
        if (!CDROM_CAN(CDC_SELECT_DISC) ||
            (arg == CDSL_CURRENT || arg == CDSL_NONE))
                return cdi->ops->drive_status(cdi, CDSL_CURRENT);
-       if (((int)arg >= cdi->capacity))
+       if (arg >= cdi->capacity)
                return -EINVAL;
        return cdrom_slot_status(cdi, arg);
 }
index 110483f0e3fbad97c1304b633b5d55c940e1fe70..e26a40971b263ed5f5cb113c938f4d9f84109862 100644 (file)
@@ -379,9 +379,20 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                if (idx == -1)
                        idx = i; /* first enabled state */
                if (s->target_residency > data->predicted_us) {
-                       if (!tick_nohz_tick_stopped())
+                       if (data->predicted_us < TICK_USEC)
                                break;
 
+                       if (!tick_nohz_tick_stopped()) {
+                               /*
+                                * If the state selected so far is shallow,
+                                * waking up early won't hurt, so retain the
+                                * tick in that case and let the governor run
+                                * again in the next iteration of the loop.
+                                */
+                               expected_interval = drv->states[idx].target_residency;
+                               break;
+                       }
+
                        /*
                         * If the state selected so far is shallow and this
                         * state's target residency matches the time till the
index 6e61cc93c2b0da3be9d2f68bf8e063deaf122054..d7aa7d7ff102fab24aa86bd1d13190348973a1bf 100644 (file)
@@ -679,10 +679,8 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
        int ret = 0;
 
        if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
-               crypto_ablkcipher_set_flags(ablkcipher,
-                                           CRYPTO_TFM_RES_BAD_KEY_LEN);
                dev_err(jrdev, "key size mismatch\n");
-               return -EINVAL;
+               goto badkey;
        }
 
        ctx->cdata.keylen = keylen;
@@ -715,7 +713,7 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
        return ret;
 badkey:
        crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
-       return 0;
+       return -EINVAL;
 }
 
 /*
index 578ea63a31098e46a7e32554f2c7acff5f8137cd..f26d62e5533a7a5a622d6e2f0661dcb3d0ebdc40 100644 (file)
@@ -71,8 +71,8 @@ static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc,
        dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
+       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
 }
 
 static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
@@ -90,8 +90,8 @@ static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
        dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
+       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
 }
 
 /* RSA Job Completion handler */
@@ -417,13 +417,13 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
                goto unmap_p;
        }
 
-       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
+       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp1_dma)) {
                dev_err(dev, "Unable to map RSA tmp1 memory\n");
                goto unmap_q;
        }
 
-       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
+       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp2_dma)) {
                dev_err(dev, "Unable to map RSA tmp2 memory\n");
                goto unmap_tmp1;
@@ -451,7 +451,7 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
        return 0;
 
 unmap_tmp1:
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
 unmap_q:
        dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
 unmap_p:
@@ -504,13 +504,13 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
                goto unmap_dq;
        }
 
-       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
+       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp1_dma)) {
                dev_err(dev, "Unable to map RSA tmp1 memory\n");
                goto unmap_qinv;
        }
 
-       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
+       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp2_dma)) {
                dev_err(dev, "Unable to map RSA tmp2 memory\n");
                goto unmap_tmp1;
@@ -538,7 +538,7 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
        return 0;
 
 unmap_tmp1:
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
 unmap_qinv:
        dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
 unmap_dq:
index f4f258075b895a8c55fbd836d35b1b6b399beed8..acdd72016ffe154fab70f8de0ff43f6251b50e28 100644 (file)
@@ -190,7 +190,8 @@ static void caam_jr_dequeue(unsigned long devarg)
                BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
 
                /* Unmap just-run descriptor so we can post-process */
-               dma_unmap_single(dev, jrp->outring[hw_idx].desc,
+               dma_unmap_single(dev,
+                                caam_dma_to_cpu(jrp->outring[hw_idx].desc),
                                 jrp->entinfo[sw_idx].desc_size,
                                 DMA_TO_DEVICE);
 
index 9a476bb6d4c7eace932edb09b040098eccee7aa0..af596455b420f60d68096b8f2d4e9c71745785fc 100644 (file)
@@ -35,6 +35,7 @@ struct nitrox_cmdq {
        /* requests in backlog queues */
        atomic_t backlog_count;
 
+       int write_idx;
        /* command size 32B/64B */
        u8 instr_size;
        u8 qno;
@@ -87,7 +88,7 @@ struct nitrox_bh {
        struct bh_data *slc;
 };
 
-/* NITROX-5 driver state */
+/* NITROX-V driver state */
 #define NITROX_UCODE_LOADED    0
 #define NITROX_READY           1
 
index ebe267379ac95ede190832e8a9c0a1df174e6866..4d31df07777f63129715175f7aa4bc84b50fe49b 100644 (file)
@@ -36,6 +36,7 @@ static int cmdq_common_init(struct nitrox_cmdq *cmdq)
        cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
        cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
        cmdq->qsize = (qsize + PKT_IN_ALIGN);
+       cmdq->write_idx = 0;
 
        spin_lock_init(&cmdq->response_lock);
        spin_lock_init(&cmdq->cmdq_lock);
index deaefd532aaa155755faba33bba5fbee7b11430f..4a362fc22f6287638f749dfeacde20bc62517896 100644 (file)
  *   Invalid flag options in AES-CCM IV.
  */
 
+static inline int incr_index(int index, int count, int max)
+{
+       if ((index + count) >= max)
+               index = index + count - max;
+       else
+               index += count;
+
+       return index;
+}
+
 /**
  * dma_free_sglist - unmap and free the sg lists.
  * @ndev: N5 device
@@ -426,30 +436,29 @@ static void post_se_instr(struct nitrox_softreq *sr,
                          struct nitrox_cmdq *cmdq)
 {
        struct nitrox_device *ndev = sr->ndev;
-       union nps_pkt_in_instr_baoff_dbell pkt_in_baoff_dbell;
-       u64 offset;
+       int idx;
        u8 *ent;
 
        spin_lock_bh(&cmdq->cmdq_lock);
 
-       /* get the next write offset */
-       offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(cmdq->qno);
-       pkt_in_baoff_dbell.value = nitrox_read_csr(ndev, offset);
+       idx = cmdq->write_idx;
        /* copy the instruction */
-       ent = cmdq->head + pkt_in_baoff_dbell.s.aoff;
+       ent = cmdq->head + (idx * cmdq->instr_size);
        memcpy(ent, &sr->instr, cmdq->instr_size);
-       /* flush the command queue updates */
-       dma_wmb();
 
-       sr->tstamp = jiffies;
        atomic_set(&sr->status, REQ_POSTED);
        response_list_add(sr, cmdq);
+       sr->tstamp = jiffies;
+       /* flush the command queue updates */
+       dma_wmb();
 
        /* Ring doorbell with count 1 */
        writeq(1, cmdq->dbell_csr_addr);
        /* orders the doorbell rings */
        mmiowb();
 
+       cmdq->write_idx = incr_index(idx, 1, ndev->qlen);
+
        spin_unlock_bh(&cmdq->cmdq_lock);
 }
 
@@ -459,6 +468,9 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
        struct nitrox_softreq *sr, *tmp;
        int ret = 0;
 
+       if (!atomic_read(&cmdq->backlog_count))
+               return 0;
+
        spin_lock_bh(&cmdq->backlog_lock);
 
        list_for_each_entry_safe(sr, tmp, &cmdq->backlog_head, backlog) {
@@ -466,7 +478,7 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
 
                /* submit until space available */
                if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
-                       ret = -EBUSY;
+                       ret = -ENOSPC;
                        break;
                }
                /* delete from backlog list */
@@ -491,23 +503,20 @@ static int nitrox_enqueue_request(struct nitrox_softreq *sr)
 {
        struct nitrox_cmdq *cmdq = sr->cmdq;
        struct nitrox_device *ndev = sr->ndev;
-       int ret = -EBUSY;
+
+       /* try to post backlog requests */
+       post_backlog_cmds(cmdq);
 
        if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
                if (!(sr->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-                       return -EAGAIN;
-
+                       return -ENOSPC;
+               /* add to backlog list */
                backlog_list_add(sr, cmdq);
-       } else {
-               ret = post_backlog_cmds(cmdq);
-               if (ret) {
-                       backlog_list_add(sr, cmdq);
-                       return ret;
-               }
-               post_se_instr(sr, cmdq);
-               ret = -EINPROGRESS;
+               return -EBUSY;
        }
-       return ret;
+       post_se_instr(sr, cmdq);
+
+       return -EINPROGRESS;
 }
 
 /**
@@ -624,11 +633,9 @@ int nitrox_process_se_request(struct nitrox_device *ndev,
         */
        sr->instr.fdata[0] = *((u64 *)&req->gph);
        sr->instr.fdata[1] = 0;
-       /* flush the soft_req changes before posting the cmd */
-       wmb();
 
        ret = nitrox_enqueue_request(sr);
-       if (ret == -EAGAIN)
+       if (ret == -ENOSPC)
                goto send_fail;
 
        return ret;
index a53a0e6ba024e8175338859c634c81e94859cd13..7725b6ee14efb2ecc89d9c0822aa19903284d3f5 100644 (file)
@@ -96,6 +96,10 @@ enum csk_flags {
        CSK_CONN_INLINE,        /* Connection on HW */
 };
 
+enum chtls_cdev_state {
+       CHTLS_CDEV_STATE_UP = 1
+};
+
 struct listen_ctx {
        struct sock *lsk;
        struct chtls_dev *cdev;
@@ -146,6 +150,7 @@ struct chtls_dev {
        unsigned int send_page_order;
        int max_host_sndbuf;
        struct key_map kmap;
+       unsigned int cdev_state;
 };
 
 struct chtls_hws {
index 9b07f9165658beeb07a29edc4e00c3849176d2ec..f59b044ebd25528864d055c04b90f67b83248eac 100644 (file)
@@ -160,6 +160,7 @@ static void chtls_register_dev(struct chtls_dev *cdev)
        tlsdev->hash = chtls_create_hash;
        tlsdev->unhash = chtls_destroy_hash;
        tls_register_device(&cdev->tlsdev);
+       cdev->cdev_state = CHTLS_CDEV_STATE_UP;
 }
 
 static void chtls_unregister_dev(struct chtls_dev *cdev)
@@ -281,8 +282,10 @@ static void chtls_free_all_uld(void)
        struct chtls_dev *cdev, *tmp;
 
        mutex_lock(&cdev_mutex);
-       list_for_each_entry_safe(cdev, tmp, &cdev_list, list)
-               chtls_free_uld(cdev);
+       list_for_each_entry_safe(cdev, tmp, &cdev_list, list) {
+               if (cdev->cdev_state == CHTLS_CDEV_STATE_UP)
+                       chtls_free_uld(cdev);
+       }
        mutex_unlock(&cdev_mutex);
 }
 
index 5285ece4f33a36df39bfd18068dd14ce6a1213db..b71895871be3f1f2ec0b15d19d4087a16f40016f 100644 (file)
@@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
                ret = crypto_skcipher_encrypt(req);
                skcipher_request_zero(req);
        } else {
-               preempt_disable();
-               pagefault_disable();
-               enable_kernel_vsx();
-
                blkcipher_walk_init(&walk, dst, src, nbytes);
                ret = blkcipher_walk_virt(desc, &walk);
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        aes_p8_cbc_encrypt(walk.src.virt.addr,
                                           walk.dst.virt.addr,
                                           nbytes & AES_BLOCK_MASK,
                                           &ctx->enc_key, walk.iv, 1);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
+
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
 
        return ret;
@@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
                ret = crypto_skcipher_decrypt(req);
                skcipher_request_zero(req);
        } else {
-               preempt_disable();
-               pagefault_disable();
-               enable_kernel_vsx();
-
                blkcipher_walk_init(&walk, dst, src, nbytes);
                ret = blkcipher_walk_virt(desc, &walk);
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        aes_p8_cbc_encrypt(walk.src.virt.addr,
                                           walk.dst.virt.addr,
                                           nbytes & AES_BLOCK_MASK,
                                           &ctx->dec_key, walk.iv, 0);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
+
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
 
        return ret;
index 8bd9aff0f55fba6639b67147cf97c2fcfce12bfc..e9954a7d46944d36cd2aeffdfd8202b54c793d71 100644 (file)
@@ -116,32 +116,39 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
                ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
                skcipher_request_zero(req);
        } else {
+               blkcipher_walk_init(&walk, dst, src, nbytes);
+
+               ret = blkcipher_walk_virt(desc, &walk);
+
                preempt_disable();
                pagefault_disable();
                enable_kernel_vsx();
 
-               blkcipher_walk_init(&walk, dst, src, nbytes);
-
-               ret = blkcipher_walk_virt(desc, &walk);
                iv = walk.iv;
                memset(tweak, 0, AES_BLOCK_SIZE);
                aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
 
+               disable_kernel_vsx();
+               pagefault_enable();
+               preempt_enable();
+
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        if (enc)
                                aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
                                                nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
                        else
                                aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
                                                nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
 
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
        return ret;
 }
index 502b94fb116a7070af89ce51da182c3a936e48a0..b6e9df11115d358734d686af7b26a9eec0a6de64 100644 (file)
@@ -1012,13 +1012,9 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
                if (r)
                        return r;
 
-               if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE) {
-                       parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT;
-                       if (!parser->ctx->preamble_presented) {
-                               parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
-                               parser->ctx->preamble_presented = true;
-                       }
-               }
+               if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
+                       parser->job->preamble_status |=
+                               AMDGPU_PREAMBLE_IB_PRESENT;
 
                if (parser->ring && parser->ring != ring)
                        return -EINVAL;
@@ -1207,26 +1203,24 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
        int r;
 
+       job = p->job;
+       p->job = NULL;
+
+       r = drm_sched_job_init(&job->base, entity, p->filp);
+       if (r)
+               goto error_unlock;
+
+       /* No memory allocation is allowed while holding the mn lock */
        amdgpu_mn_lock(p->mn);
        amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
                struct amdgpu_bo *bo = e->robj;
 
                if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
-                       amdgpu_mn_unlock(p->mn);
-                       return -ERESTARTSYS;
+                       r = -ERESTARTSYS;
+                       goto error_abort;
                }
        }
 
-       job = p->job;
-       p->job = NULL;
-
-       r = drm_sched_job_init(&job->base, entity, p->filp);
-       if (r) {
-               amdgpu_job_free(job);
-               amdgpu_mn_unlock(p->mn);
-               return r;
-       }
-
        job->owner = p->filp;
        p->fence = dma_fence_get(&job->base.s_fence->finished);
 
@@ -1241,6 +1235,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
        amdgpu_cs_post_dependencies(p);
 
+       if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) &&
+           !p->ctx->preamble_presented) {
+               job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
+               p->ctx->preamble_presented = true;
+       }
+
        cs->out.handle = seq;
        job->uf_sequence = seq;
 
@@ -1258,6 +1258,15 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
        amdgpu_mn_unlock(p->mn);
 
        return 0;
+
+error_abort:
+       dma_fence_put(&job->base.s_fence->finished);
+       job->base.s_fence = NULL;
+
+error_unlock:
+       amdgpu_job_free(job);
+       amdgpu_mn_unlock(p->mn);
+       return r;
 }
 
 int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
index 5518e623fed21046791c42e026383526f8cf8adb..51b5e977ca885ef1f7d7df49698f3c6843bab437 100644 (file)
@@ -164,8 +164,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
                return r;
        }
 
+       need_ctx_switch = ring->current_ctx != fence_ctx;
        if (ring->funcs->emit_pipeline_sync && job &&
            ((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) ||
+            (amdgpu_sriov_vf(adev) && need_ctx_switch) ||
             amdgpu_vm_need_pipeline_sync(ring, job))) {
                need_pipe_sync = true;
                dma_fence_put(tmp);
@@ -196,7 +198,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
        }
 
        skip_preamble = ring->current_ctx == fence_ctx;
-       need_ctx_switch = ring->current_ctx != fence_ctx;
        if (job && ring->funcs->emit_cntxcntl) {
                if (need_ctx_switch)
                        status |= AMDGPU_HAVE_CTX_SWITCH;
index 8f98629fbe5936858a3c77b3546fd106577f7254..7b4e657a95c700561298346654118a9915c8caec 100644 (file)
@@ -1932,14 +1932,6 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
                        amdgpu_fence_wait_empty(ring);
        }
 
-       mutex_lock(&adev->pm.mutex);
-       /* update battery/ac status */
-       if (power_supply_is_system_supplied() > 0)
-               adev->pm.ac_power = true;
-       else
-               adev->pm.ac_power = false;
-       mutex_unlock(&adev->pm.mutex);
-
        if (adev->powerplay.pp_funcs->dispatch_tasks) {
                if (!amdgpu_device_has_dc_support(adev)) {
                        mutex_lock(&adev->pm.mutex);
index ece0ac703e277282992422865f9945ce06ca5f0c..b17771dd5ce732620e8c058f788516b7ef9b6fee 100644 (file)
@@ -172,6 +172,7 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
         * is validated on next vm use to avoid fault.
         * */
        list_move_tail(&base->vm_status, &vm->evicted);
+       base->moved = true;
 }
 
 /**
@@ -369,7 +370,6 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
        uint64_t addr;
        int r;
 
-       addr = amdgpu_bo_gpu_offset(bo);
        entries = amdgpu_bo_size(bo) / 8;
 
        if (pte_support_ats) {
@@ -401,6 +401,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
        if (r)
                goto error;
 
+       addr = amdgpu_bo_gpu_offset(bo);
        if (ats_entries) {
                uint64_t ats_value;
 
@@ -2483,28 +2484,52 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
  * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
  *
  * @adev: amdgpu_device pointer
- * @vm_size: the default vm size if it's set auto
+ * @min_vm_size: the minimum vm size in GB if it's set auto
  * @fragment_size_default: Default PTE fragment size
  * @max_level: max VMPT level
  * @max_bits: max address space size in bits
  *
  */
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                           uint32_t fragment_size_default, unsigned max_level,
                           unsigned max_bits)
 {
+       unsigned int max_size = 1 << (max_bits - 30);
+       unsigned int vm_size;
        uint64_t tmp;
 
        /* adjust vm size first */
        if (amdgpu_vm_size != -1) {
-               unsigned max_size = 1 << (max_bits - 30);
-
                vm_size = amdgpu_vm_size;
                if (vm_size > max_size) {
                        dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",
                                 amdgpu_vm_size, max_size);
                        vm_size = max_size;
                }
+       } else {
+               struct sysinfo si;
+               unsigned int phys_ram_gb;
+
+               /* Optimal VM size depends on the amount of physical
+                * RAM available. Underlying requirements and
+                * assumptions:
+                *
+                *  - Need to map system memory and VRAM from all GPUs
+                *     - VRAM from other GPUs not known here
+                *     - Assume VRAM <= system memory
+                *  - On GFX8 and older, VM space can be segmented for
+                *    different MTYPEs
+                *  - Need to allow room for fragmentation, guard pages etc.
+                *
+                * This adds up to a rough guess of system memory x3.
+                * Round up to power of two to maximize the available
+                * VM size with the given page table size.
+                */
+               si_meminfo(&si);
+               phys_ram_gb = ((uint64_t)si.totalram * si.mem_unit +
+                              (1 << 30) - 1) >> 30;
+               vm_size = roundup_pow_of_two(
+                       min(max(phys_ram_gb * 3, min_vm_size), max_size));
        }
 
        adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;
index 67a15d439ac006f97b48ffe7e74544d6688bf452..9fa9df0c5e7f9a19d1f9aed6e0430ea78aac8675 100644 (file)
@@ -321,7 +321,7 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
 void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                      struct amdgpu_bo_va *bo_va);
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                           uint32_t fragment_size_default, unsigned max_level,
                           unsigned max_bits);
 int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
index 5cd45210113f645062750e4ef54ffd4e7dc14da7..5a9534a82d40911cebb02462ba0cc5a995a5bfca 100644 (file)
@@ -5664,6 +5664,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
        if (amdgpu_sriov_vf(adev))
                return 0;
 
+       if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG |
+                               AMD_PG_SUPPORT_RLC_SMU_HS |
+                               AMD_PG_SUPPORT_CP |
+                               AMD_PG_SUPPORT_GFX_DMG))
+               adev->gfx.rlc.funcs->enter_safe_mode(adev);
        switch (adev->asic_type) {
        case CHIP_CARRIZO:
        case CHIP_STONEY:
@@ -5713,7 +5718,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
        default:
                break;
        }
-
+       if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG |
+                               AMD_PG_SUPPORT_RLC_SMU_HS |
+                               AMD_PG_SUPPORT_CP |
+                               AMD_PG_SUPPORT_GFX_DMG))
+               adev->gfx.rlc.funcs->exit_safe_mode(adev);
        return 0;
 }
 
index 75317f283c6967d2de4daaaf5dca4cfdaf9922b7..ad151fefa41f1ed1d6f19ae1783b13b1b76b4f2e 100644 (file)
@@ -632,12 +632,6 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-static void gmc_v6_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 static void gmc_v6_0_vm_decode_fault(struct amdgpu_device *adev,
                                     u32 status, u32 addr, u32 mc_client)
 {
@@ -935,8 +929,9 @@ static int gmc_v6_0_sw_fini(void *handle)
 
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
-       gmc_v6_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 36dc367c4b45ea86a5a5b575ba357f9717ec92b0..f8d8a3a73e42b31397b97f743ab187da2732cd89 100644 (file)
@@ -746,19 +746,6 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-/**
- * gmc_v7_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v7_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 /**
  * gmc_v7_0_vm_decode_fault - print human readable fault info
  *
@@ -1095,8 +1082,9 @@ static int gmc_v7_0_sw_fini(void *handle)
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        kfree(adev->gmc.vm_fault_info);
-       gmc_v7_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 70fc97b59b4f2dcf157b49885c8356fedfca05a3..9333109b210de810119f0d15d94ec5d125a84cf7 100644 (file)
@@ -968,19 +968,6 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-/**
- * gmc_v8_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v8_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 /**
  * gmc_v8_0_vm_decode_fault - print human readable fault info
  *
@@ -1199,8 +1186,9 @@ static int gmc_v8_0_sw_fini(void *handle)
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        kfree(adev->gmc.vm_fault_info);
-       gmc_v8_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 399a5db27649728686868550502089391f3b0807..72f8018fa2a836572b9c898785bb99deecc1ca91 100644 (file)
@@ -942,26 +942,12 @@ static int gmc_v9_0_sw_init(void *handle)
        return 0;
 }
 
-/**
- * gmc_v9_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v9_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 static int gmc_v9_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
-       gmc_v9_0_gart_fini(adev);
 
        /*
        * TODO:
@@ -974,7 +960,9 @@ static int gmc_v9_0_sw_fini(void *handle)
        */
        amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
 
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
 
        return 0;
 }
index 3f57f6463dc880c797429d9f3080894b929e5eff..cb79a93c2eb73a5f23fb008cee50e80325ada627 100644 (file)
@@ -65,8 +65,6 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,
                                            int min_temp, int max_temp);
 static int kv_init_fps_limits(struct amdgpu_device *adev);
 
-static void kv_dpm_powergate_uvd(void *handle, bool gate);
-static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate);
 static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate);
 static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate);
 
@@ -1354,8 +1352,6 @@ static int kv_dpm_enable(struct amdgpu_device *adev)
                return ret;
        }
 
-       kv_update_current_ps(adev, adev->pm.dpm.boot_ps);
-
        if (adev->irq.installed &&
            amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) {
                ret = kv_set_thermal_temperature_range(adev, KV_TEMP_RANGE_MIN, KV_TEMP_RANGE_MAX);
@@ -1374,6 +1370,8 @@ static int kv_dpm_enable(struct amdgpu_device *adev)
 
 static void kv_dpm_disable(struct amdgpu_device *adev)
 {
+       struct kv_power_info *pi = kv_get_pi(adev);
+
        amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
                       AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);
        amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
@@ -1387,8 +1385,10 @@ static void kv_dpm_disable(struct amdgpu_device *adev)
        /* powerup blocks */
        kv_dpm_powergate_acp(adev, false);
        kv_dpm_powergate_samu(adev, false);
-       kv_dpm_powergate_vce(adev, false);
-       kv_dpm_powergate_uvd(adev, false);
+       if (pi->caps_vce_pg) /* power on the VCE block */
+               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+       if (pi->caps_uvd_pg) /* power on the UVD block */
+               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerON);
 
        kv_enable_smc_cac(adev, false);
        kv_enable_didt(adev, false);
@@ -1551,7 +1551,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
        int ret;
 
        if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) {
-               kv_dpm_powergate_vce(adev, false);
                if (pi->caps_stable_p_state)
                        pi->vce_boot_level = table->count - 1;
                else
@@ -1573,7 +1572,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
                kv_enable_vce_dpm(adev, true);
        } else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {
                kv_enable_vce_dpm(adev, false);
-               kv_dpm_powergate_vce(adev, true);
        }
 
        return 0;
@@ -1702,24 +1700,32 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate)
        }
 }
 
-static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate)
+static void kv_dpm_powergate_vce(void *handle, bool gate)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        struct kv_power_info *pi = kv_get_pi(adev);
-
-       if (pi->vce_power_gated == gate)
-               return;
+       int ret;
 
        pi->vce_power_gated = gate;
 
-       if (!pi->caps_vce_pg)
-               return;
-
-       if (gate)
-               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
-       else
-               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+       if (gate) {
+               /* stop the VCE block */
+               ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
+                                                            AMD_PG_STATE_GATE);
+               kv_enable_vce_dpm(adev, false);
+               if (pi->caps_vce_pg) /* power off the VCE block */
+                       amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
+       } else {
+               if (pi->caps_vce_pg) /* power on the VCE block */
+                       amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+               kv_enable_vce_dpm(adev, true);
+               /* re-init the VCE block */
+               ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
+                                                            AMD_PG_STATE_UNGATE);
+       }
 }
 
+
 static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)
 {
        struct kv_power_info *pi = kv_get_pi(adev);
@@ -3061,7 +3067,7 @@ static int kv_dpm_hw_init(void *handle)
        else
                adev->pm.dpm_enabled = true;
        mutex_unlock(&adev->pm.mutex);
-
+       amdgpu_pm_compute_clocks(adev);
        return ret;
 }
 
@@ -3313,6 +3319,9 @@ static int kv_set_powergating_by_smu(void *handle,
        case AMD_IP_BLOCK_TYPE_UVD:
                kv_dpm_powergate_uvd(handle, gate);
                break;
+       case AMD_IP_BLOCK_TYPE_VCE:
+               kv_dpm_powergate_vce(handle, gate);
+               break;
        default:
                break;
        }
index db327b4125626d411e155de18bfeb28f4efb92b4..1de96995e6900c934c91cf610160768b6c08cd37 100644 (file)
@@ -6887,7 +6887,6 @@ static int si_dpm_enable(struct amdgpu_device *adev)
 
        si_enable_auto_throttle_source(adev, AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
        si_thermal_start_thermal_controller(adev);
-       ni_update_current_ps(adev, boot_ps);
 
        return 0;
 }
@@ -7763,7 +7762,7 @@ static int si_dpm_hw_init(void *handle)
        else
                adev->pm.dpm_enabled = true;
        mutex_unlock(&adev->pm.mutex);
-
+       amdgpu_pm_compute_clocks(adev);
        return ret;
 }
 
index fbe878ae1e8c579cc6e2571e30e95400ba477cad..4ba0003a9d329545a59e1b8050bcecf922a5e55d 100644 (file)
@@ -480,12 +480,20 @@ void pp_rv_set_display_requirement(struct pp_smu *pp,
 {
        struct dc_context *ctx = pp->ctx;
        struct amdgpu_device *adev = ctx->driver_context;
+       void *pp_handle = adev->powerplay.pp_handle;
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+       struct pp_display_clock_request clock = {0};
 
-       if (!pp_funcs || !pp_funcs->display_configuration_changed)
+       if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
                return;
 
-       amdgpu_dpm_display_configuration_changed(adev);
+       clock.clock_type = amd_pp_dcf_clock;
+       clock.clock_freq_in_khz = req->hard_min_dcefclk_khz;
+       pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+
+       clock.clock_type = amd_pp_f_clock;
+       clock.clock_freq_in_khz = req->hard_min_fclk_khz;
+       pp_funcs->display_clock_voltage_request(pp_handle, &clock);
 }
 
 void pp_rv_set_wm_ranges(struct pp_smu *pp,
index 567867915d32d84cb6bb68d3e4da33842de9b2e4..37eaf72ace549d6f132b9fc5933da434fc164396 100644 (file)
@@ -754,8 +754,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
                         * fail-safe mode
                         */
                        if (dc_is_hdmi_signal(link->connector_signal) ||
-                           dc_is_dvi_signal(link->connector_signal))
+                           dc_is_dvi_signal(link->connector_signal)) {
+                               if (prev_sink != NULL)
+                                       dc_sink_release(prev_sink);
+
                                return false;
+                       }
                default:
                        break;
                }
index 11d834f942205f37c10c1a95a345b8908cb3411f..98358b4b36dea7e13177bdf38554ffaad4f994e9 100644 (file)
@@ -199,7 +199,6 @@ vma_create(struct drm_i915_gem_object *obj,
                vma->flags |= I915_VMA_GGTT;
                list_add(&vma->obj_link, &obj->vma_list);
        } else {
-               i915_ppgtt_get(i915_vm_to_ppgtt(vm));
                list_add_tail(&vma->obj_link, &obj->vma_list);
        }
 
@@ -807,9 +806,6 @@ static void __i915_vma_destroy(struct i915_vma *vma)
        if (vma->obj)
                rb_erase(&vma->obj_node, &vma->obj->vma_tree);
 
-       if (!i915_vma_is_ggtt(vma))
-               i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
-
        rbtree_postorder_for_each_entry_safe(iter, n, &vma->active, node) {
                GEM_BUG_ON(i915_gem_active_isset(&iter->base));
                kfree(iter);
index b725835b47efc5116b53e3f27eeb6e0fcdbb65b4..769f3f5866611174cbabeca5e4d1fbb0711b9b86 100644 (file)
@@ -962,9 +962,6 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv)
 {
        int ret;
 
-       if (INTEL_INFO(dev_priv)->num_pipes == 0)
-               return;
-
        ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops);
        if (ret < 0) {
                DRM_ERROR("failed to add audio component (%d)\n", ret);
index ed3fa1c8a98342d549ec8bf5b027b3b783affa08..4a3c8ee9a9732cccc4e1ce1cc42197b0c662cc73 100644 (file)
@@ -2988,6 +2988,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
        int w = drm_rect_width(&plane_state->base.src) >> 16;
        int h = drm_rect_height(&plane_state->base.src) >> 16;
        int dst_x = plane_state->base.dst.x1;
+       int dst_w = drm_rect_width(&plane_state->base.dst);
        int pipe_src_w = crtc_state->pipe_src_w;
        int max_width = skl_max_plane_width(fb, 0, rotation);
        int max_height = 4096;
@@ -3009,10 +3010,10 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
         * screen may cause FIFO underflow and display corruption.
         */
        if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
-           (dst_x + w < 4 || dst_x > pipe_src_w - 4)) {
+           (dst_x + dst_w < 4 || dst_x > pipe_src_w - 4)) {
                DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
-                             dst_x + w < 4 ? "end" : "start",
-                             dst_x + w < 4 ? dst_x + w : dst_x,
+                             dst_x + dst_w < 4 ? "end" : "start",
+                             dst_x + dst_w < 4 ? dst_x + dst_w : dst_x,
                              4, pipe_src_w - 4);
                return -ERANGE;
        }
index a9076402dcb0864ab6b7c6c4ea1d8346c95e949b..192972a7d287e9fd5ff9aeb599d6730007383500 100644 (file)
@@ -943,8 +943,12 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *intel_dig_port,
 
        ret = i2c_transfer(adapter, &msg, 1);
        if (ret == 1)
-               return 0;
-       return ret >= 0 ? -EIO : ret;
+               ret = 0;
+       else if (ret >= 0)
+               ret = -EIO;
+
+       kfree(write_buf);
+       return ret;
 }
 
 static
index 5dae16ccd9f1015fe80abc2c41d98937f3aaef89..3e085c5f2b81bfa87daf161bd96e3eb01da5d4ac 100644 (file)
@@ -74,7 +74,7 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
        DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
                      lspcon_mode_name(mode));
 
-       wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 100);
+       wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
        if (current_mode != mode)
                DRM_ERROR("LSPCON mode hasn't settled\n");
 
index 978782a776292e6d954755cc71786bd98b5d81ac..28d191192945b0690fd76eb9aa97a1bb3637215f 100644 (file)
@@ -132,6 +132,11 @@ static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
        writel(0x0, comp->regs + DISP_REG_OVL_RST);
 }
 
+static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
+{
+       return 4;
+}
+
 static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
 {
        unsigned int reg;
@@ -157,6 +162,11 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
 
 static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 {
+       /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
+        * is defined in mediatek HW data sheet.
+        * The alphabet order in XXX is no relation to data
+        * arrangement in memory.
+        */
        switch (fmt) {
        default:
        case DRM_FORMAT_RGB565:
@@ -221,6 +231,7 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
        .stop = mtk_ovl_stop,
        .enable_vblank = mtk_ovl_enable_vblank,
        .disable_vblank = mtk_ovl_disable_vblank,
+       .layer_nr = mtk_ovl_layer_nr,
        .layer_on = mtk_ovl_layer_on,
        .layer_off = mtk_ovl_layer_off,
        .layer_config = mtk_ovl_layer_config,
index 585943c81e1f8818de1a6bb481f6adb90c8ad308..b0a5cffe345ab77f90e443ca88bfac52d62804a4 100644 (file)
 #define RDMA_REG_UPDATE_INT                            BIT(0)
 #define DISP_REG_RDMA_GLOBAL_CON               0x0010
 #define RDMA_ENGINE_EN                                 BIT(0)
+#define RDMA_MODE_MEMORY                               BIT(1)
 #define DISP_REG_RDMA_SIZE_CON_0               0x0014
+#define RDMA_MATRIX_ENABLE                             BIT(17)
+#define RDMA_MATRIX_INT_MTX_SEL                                GENMASK(23, 20)
+#define RDMA_MATRIX_INT_MTX_BT601_to_RGB               (6 << 20)
 #define DISP_REG_RDMA_SIZE_CON_1               0x0018
 #define DISP_REG_RDMA_TARGET_LINE              0x001c
+#define DISP_RDMA_MEM_CON                      0x0024
+#define MEM_MODE_INPUT_FORMAT_RGB565                   (0x000 << 4)
+#define MEM_MODE_INPUT_FORMAT_RGB888                   (0x001 << 4)
+#define MEM_MODE_INPUT_FORMAT_RGBA8888                 (0x002 << 4)
+#define MEM_MODE_INPUT_FORMAT_ARGB8888                 (0x003 << 4)
+#define MEM_MODE_INPUT_FORMAT_UYVY                     (0x004 << 4)
+#define MEM_MODE_INPUT_FORMAT_YUYV                     (0x005 << 4)
+#define MEM_MODE_INPUT_SWAP                            BIT(8)
+#define DISP_RDMA_MEM_SRC_PITCH                        0x002c
+#define DISP_RDMA_MEM_GMC_SETTING_0            0x0030
 #define DISP_REG_RDMA_FIFO_CON                 0x0040
 #define RDMA_FIFO_UNDERFLOW_EN                         BIT(31)
 #define RDMA_FIFO_PSEUDO_SIZE(bytes)                   (((bytes) / 16) << 16)
 #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes)                ((bytes) / 16)
 #define RDMA_FIFO_SIZE(rdma)                   ((rdma)->data->fifo_size)
+#define DISP_RDMA_MEM_START_ADDR               0x0f00
+
+#define RDMA_MEM_GMC                           0x40402020
 
 struct mtk_disp_rdma_data {
        unsigned int fifo_size;
@@ -138,12 +155,87 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
        writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
 }
 
+static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
+                                    unsigned int fmt)
+{
+       /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
+        * is defined in mediatek HW data sheet.
+        * The alphabet order in XXX is no relation to data
+        * arrangement in memory.
+        */
+       switch (fmt) {
+       default:
+       case DRM_FORMAT_RGB565:
+               return MEM_MODE_INPUT_FORMAT_RGB565;
+       case DRM_FORMAT_BGR565:
+               return MEM_MODE_INPUT_FORMAT_RGB565 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_RGB888:
+               return MEM_MODE_INPUT_FORMAT_RGB888;
+       case DRM_FORMAT_BGR888:
+               return MEM_MODE_INPUT_FORMAT_RGB888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_RGBX8888:
+       case DRM_FORMAT_RGBA8888:
+               return MEM_MODE_INPUT_FORMAT_ARGB8888;
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_BGRA8888:
+               return MEM_MODE_INPUT_FORMAT_ARGB8888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               return MEM_MODE_INPUT_FORMAT_RGBA8888;
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
+               return MEM_MODE_INPUT_FORMAT_RGBA8888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_UYVY:
+               return MEM_MODE_INPUT_FORMAT_UYVY;
+       case DRM_FORMAT_YUYV:
+               return MEM_MODE_INPUT_FORMAT_YUYV;
+       }
+}
+
+static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp)
+{
+       return 1;
+}
+
+static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
+                                 struct mtk_plane_state *state)
+{
+       struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+       struct mtk_plane_pending_state *pending = &state->pending;
+       unsigned int addr = pending->addr;
+       unsigned int pitch = pending->pitch & 0xffff;
+       unsigned int fmt = pending->format;
+       unsigned int con;
+
+       con = rdma_fmt_convert(rdma, fmt);
+       writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON);
+
+       if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) {
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_ENABLE, RDMA_MATRIX_ENABLE);
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_INT_MTX_SEL,
+                                RDMA_MATRIX_INT_MTX_BT601_to_RGB);
+       } else {
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_ENABLE, 0);
+       }
+
+       writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
+       writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);
+       writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0);
+       rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON,
+                        RDMA_MODE_MEMORY, RDMA_MODE_MEMORY);
+}
+
 static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
        .config = mtk_rdma_config,
        .start = mtk_rdma_start,
        .stop = mtk_rdma_stop,
        .enable_vblank = mtk_rdma_enable_vblank,
        .disable_vblank = mtk_rdma_disable_vblank,
+       .layer_nr = mtk_rdma_layer_nr,
+       .layer_config = mtk_rdma_layer_config,
 };
 
 static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
index 2d6aa150a9ff08f0c0be658593abe1114d44a514..0b976dfd04df0b0c8b71bb0c6b2c471027a2e552 100644 (file)
@@ -45,7 +45,8 @@ struct mtk_drm_crtc {
        bool                            pending_needs_vblank;
        struct drm_pending_vblank_event *event;
 
-       struct drm_plane                planes[OVL_LAYER_NR];
+       struct drm_plane                *planes;
+       unsigned int                    layer_nr;
        bool                            pending_planes;
 
        void __iomem                    *config_regs;
@@ -171,9 +172,9 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
-       mtk_ddp_comp_enable_vblank(ovl, &mtk_crtc->base);
+       mtk_ddp_comp_enable_vblank(comp, &mtk_crtc->base);
 
        return 0;
 }
@@ -181,9 +182,9 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
-       mtk_ddp_comp_disable_vblank(ovl);
+       mtk_ddp_comp_disable_vblank(comp);
 }
 
 static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
@@ -286,7 +287,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
        }
 
        /* Initially configure all planes */
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -334,7 +335,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
        struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        unsigned int i;
 
        /*
@@ -343,7 +344,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
         * queue update module registers on vblank.
         */
        if (state->pending_config) {
-               mtk_ddp_comp_config(ovl, state->pending_width,
+               mtk_ddp_comp_config(comp, state->pending_width,
                                    state->pending_height,
                                    state->pending_vrefresh, 0);
 
@@ -351,14 +352,14 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
        }
 
        if (mtk_crtc->pending_planes) {
-               for (i = 0; i < OVL_LAYER_NR; i++) {
+               for (i = 0; i < mtk_crtc->layer_nr; i++) {
                        struct drm_plane *plane = &mtk_crtc->planes[i];
                        struct mtk_plane_state *plane_state;
 
                        plane_state = to_mtk_plane_state(plane->state);
 
                        if (plane_state->pending.config) {
-                               mtk_ddp_comp_layer_config(ovl, i, plane_state);
+                               mtk_ddp_comp_layer_config(comp, i, plane_state);
                                plane_state->pending.config = false;
                        }
                }
@@ -370,12 +371,12 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
                                       struct drm_crtc_state *old_state)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        int ret;
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 
-       ret = mtk_smi_larb_get(ovl->larb_dev);
+       ret = mtk_smi_larb_get(comp->larb_dev);
        if (ret) {
                DRM_ERROR("Failed to get larb: %d\n", ret);
                return;
@@ -383,7 +384,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 
        ret = mtk_crtc_ddp_hw_init(mtk_crtc);
        if (ret) {
-               mtk_smi_larb_put(ovl->larb_dev);
+               mtk_smi_larb_put(comp->larb_dev);
                return;
        }
 
@@ -395,7 +396,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
                                        struct drm_crtc_state *old_state)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        int i;
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
@@ -403,7 +404,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
                return;
 
        /* Set all pending plane state to disabled */
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -418,7 +419,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 
        drm_crtc_vblank_off(crtc);
        mtk_crtc_ddp_hw_fini(mtk_crtc);
-       mtk_smi_larb_put(ovl->larb_dev);
+       mtk_smi_larb_put(comp->larb_dev);
 
        mtk_crtc->enabled = false;
 }
@@ -450,7 +451,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 
        if (mtk_crtc->event)
                mtk_crtc->pending_needs_vblank = true;
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -516,7 +517,7 @@ err_cleanup_crtc:
        return ret;
 }
 
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
+void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
        struct mtk_drm_private *priv = crtc->dev->dev_private;
@@ -598,7 +599,12 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                mtk_crtc->ddp_comp[i] = comp;
        }
 
-       for (zpos = 0; zpos < OVL_LAYER_NR; zpos++) {
+       mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
+       mtk_crtc->planes = devm_kzalloc(dev, mtk_crtc->layer_nr *
+                                       sizeof(struct drm_plane),
+                                       GFP_KERNEL);
+
+       for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
                type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
                                (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
                                                DRM_PLANE_TYPE_OVERLAY;
@@ -609,7 +615,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        }
 
        ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0],
-                               &mtk_crtc->planes[1], pipe);
+                               mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] :
+                               NULL, pipe);
        if (ret < 0)
                goto unprepare;
        drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
index 9d9410c67ae9eb2026181b4a361e5c4e5707028d..091adb2087ebad132742195a4490e09efae4f427 100644 (file)
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_plane.h"
 
-#define OVL_LAYER_NR   4
 #define MTK_LUT_SIZE   512
 #define MTK_MAX_BPC    10
 #define MTK_MIN_BPC    3
 
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl);
+void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
                        const enum mtk_ddp_comp_id *path,
                        unsigned int path_len);
index 87e4191c250ebea7f3f0acb3ca23d3fcb9a9639c..546b3e3b300ba8c6b8a4dc67bfe8c400d5b48de9 100644 (file)
 #define OVL1_MOUT_EN_COLOR1            0x1
 #define GAMMA_MOUT_EN_RDMA1            0x1
 #define RDMA0_SOUT_DPI0                        0x2
+#define RDMA0_SOUT_DPI1                        0x3
+#define RDMA0_SOUT_DSI1                        0x1
 #define RDMA0_SOUT_DSI2                        0x4
 #define RDMA0_SOUT_DSI3                        0x5
 #define RDMA1_SOUT_DPI0                        0x2
 #define DPI0_SEL_IN_RDMA2              0x3
 #define DPI1_SEL_IN_RDMA1              (0x1 << 8)
 #define DPI1_SEL_IN_RDMA2              (0x3 << 8)
+#define DSI0_SEL_IN_RDMA1              0x1
+#define DSI0_SEL_IN_RDMA2              0x4
 #define DSI1_SEL_IN_RDMA1              0x1
 #define DSI1_SEL_IN_RDMA2              0x4
 #define DSI2_SEL_IN_RDMA1              (0x1 << 16)
@@ -224,6 +228,12 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
                *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
                value = RDMA0_SOUT_DPI0;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DPI1;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DSI1;
        } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
                *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
                value = RDMA0_SOUT_DSI2;
@@ -282,6 +292,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
                *addr = DISP_REG_CONFIG_DPI_SEL_IN;
                value = DPI1_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA1;
        } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
                *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
                value = DSI1_SEL_IN_RDMA1;
@@ -297,8 +310,11 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
                *addr = DISP_REG_CONFIG_DPI_SEL_IN;
                value = DPI1_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
                *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
                value = DSI1_SEL_IN_RDMA2;
        } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
                *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
index 7413ffeb3c9d8bee1ca6bb825eb7a54391c7d013..8399229e6ad2661b77a52a5d9f30eb7502ee2879 100644 (file)
@@ -78,6 +78,7 @@ struct mtk_ddp_comp_funcs {
        void (*stop)(struct mtk_ddp_comp *comp);
        void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
        void (*disable_vblank)(struct mtk_ddp_comp *comp);
+       unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
        void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
        void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
        void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
@@ -128,6 +129,14 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
                comp->funcs->disable_vblank(comp);
 }
 
+static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
+{
+       if (comp->funcs && comp->funcs->layer_nr)
+               return comp->funcs->layer_nr(comp);
+
+       return 0;
+}
+
 static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,
                                         unsigned int idx)
 {
index 39721119713bc29d6cba63e2947d6be1ddc439cd..47ec604289b712148fdfa740a2d6c64ca4d0810f 100644 (file)
@@ -381,7 +381,7 @@ static int mtk_drm_bind(struct device *dev)
 err_deinit:
        mtk_drm_kms_deinit(drm);
 err_free:
-       drm_dev_unref(drm);
+       drm_dev_put(drm);
        return ret;
 }
 
@@ -390,7 +390,7 @@ static void mtk_drm_unbind(struct device *dev)
        struct mtk_drm_private *private = dev_get_drvdata(dev);
 
        drm_dev_unregister(private->drm);
-       drm_dev_unref(private->drm);
+       drm_dev_put(private->drm);
        private->drm = NULL;
 }
 
@@ -564,7 +564,7 @@ static int mtk_drm_remove(struct platform_device *pdev)
 
        drm_dev_unregister(drm);
        mtk_drm_kms_deinit(drm);
-       drm_dev_unref(drm);
+       drm_dev_put(drm);
 
        component_master_del(&pdev->dev, &mtk_drm_ops);
        pm_runtime_disable(&pdev->dev);
@@ -580,29 +580,24 @@ static int mtk_drm_sys_suspend(struct device *dev)
 {
        struct mtk_drm_private *private = dev_get_drvdata(dev);
        struct drm_device *drm = private->drm;
+       int ret;
 
-       drm_kms_helper_poll_disable(drm);
-
-       private->suspend_state = drm_atomic_helper_suspend(drm);
-       if (IS_ERR(private->suspend_state)) {
-               drm_kms_helper_poll_enable(drm);
-               return PTR_ERR(private->suspend_state);
-       }
-
+       ret = drm_mode_config_helper_suspend(drm);
        DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n");
-       return 0;
+
+       return ret;
 }
 
 static int mtk_drm_sys_resume(struct device *dev)
 {
        struct mtk_drm_private *private = dev_get_drvdata(dev);
        struct drm_device *drm = private->drm;
+       int ret;
 
-       drm_atomic_helper_resume(drm, private->suspend_state);
-       drm_kms_helper_poll_enable(drm);
-
+       ret = drm_mode_config_helper_resume(drm);
        DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n");
-       return 0;
+
+       return ret;
 }
 #endif
 
index 90837f7c7d0f3203ee64de86dcccd8a1e7cc26ad..f4c7516eb9891fa923a2a736bfcc45ef9b84a6b9 100644 (file)
@@ -302,14 +302,18 @@ static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
        return clamp_val(reg, 0, 1023) & (0xff << 2);
 }
 
-static u16 adt7475_read_word(struct i2c_client *client, int reg)
+static int adt7475_read_word(struct i2c_client *client, int reg)
 {
-       u16 val;
+       int val1, val2;
 
-       val = i2c_smbus_read_byte_data(client, reg);
-       val |= (i2c_smbus_read_byte_data(client, reg + 1) << 8);
+       val1 = i2c_smbus_read_byte_data(client, reg);
+       if (val1 < 0)
+               return val1;
+       val2 = i2c_smbus_read_byte_data(client, reg + 1);
+       if (val2 < 0)
+               return val2;
 
-       return val;
+       return val1 | (val2 << 8);
 }
 
 static void adt7475_write_word(struct i2c_client *client, int reg, u16 val)
@@ -962,13 +966,14 @@ static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
 {
        struct adt7475_data *data = adt7475_update_device(dev);
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       int i = clamp_val(data->range[sattr->index] & 0xf, 0,
-                         ARRAY_SIZE(pwmfreq_table) - 1);
+       int idx;
 
        if (IS_ERR(data))
                return PTR_ERR(data);
+       idx = clamp_val(data->range[sattr->index] & 0xf, 0,
+                       ARRAY_SIZE(pwmfreq_table) - 1);
 
-       return sprintf(buf, "%d\n", pwmfreq_table[i]);
+       return sprintf(buf, "%d\n", pwmfreq_table[idx]);
 }
 
 static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -1004,6 +1009,10 @@ static ssize_t pwm_use_point2_pwm_at_crit_show(struct device *dev,
                                        char *buf)
 {
        struct adt7475_data *data = adt7475_update_device(dev);
+
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+
        return sprintf(buf, "%d\n", !!(data->config4 & CONFIG4_MAXDUTY));
 }
 
index e9e6aeabbf842ffd941e0476a185884adac85147..71d3445ba869c85654ae3dcaf3a5460e8fadb268 100644 (file)
@@ -17,7 +17,7 @@
  * Bi-directional Current/Power Monitor with I2C Interface
  * Datasheet: http://www.ti.com/product/ina230
  *
- * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
  * Thanks to Jan Volkering
  *
  * This program is free software; you can redistribute it and/or modify
@@ -329,6 +329,15 @@ static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
        return 0;
 }
 
+static ssize_t ina2xx_show_shunt(struct device *dev,
+                             struct device_attribute *da,
+                             char *buf)
+{
+       struct ina2xx_data *data = dev_get_drvdata(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%li\n", data->rshunt);
+}
+
 static ssize_t ina2xx_store_shunt(struct device *dev,
                                  struct device_attribute *da,
                                  const char *buf, size_t count)
@@ -403,7 +412,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
 
 /* shunt resistance */
 static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR,
-                         ina2xx_show_value, ina2xx_store_shunt,
+                         ina2xx_show_shunt, ina2xx_store_shunt,
                          INA2XX_CALIBRATION);
 
 /* update interval (ina226 only) */
index c6bd61e4695abc01a7ed909f1d27f6944c45e246..944f5b63aecd706228ebcd3a128e3ec488bf63ba 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/bitops.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 #include "lm75.h"
 
 #define USE_ALTERNATE
@@ -2689,6 +2690,7 @@ store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
                return err;
        if (val > NUM_TEMP)
                return -EINVAL;
+       val = array_index_nospec(val, NUM_TEMP + 1);
        if (val && (!(data->have_temp & BIT(val - 1)) ||
                    !data->temp_src[val - 1]))
                return -EINVAL;
index 6ec65adaba49569ab7b9775f856859a0fcfbd967..c33dcfb87993b531d40c0f2cdb4954b08f47668a 100644 (file)
@@ -110,8 +110,8 @@ static int sclhi(struct i2c_algo_bit_data *adap)
        }
 #ifdef DEBUG
        if (jiffies != start && i2c_debug >= 3)
-               pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
-                        "high\n", jiffies - start);
+               pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go high\n",
+                        jiffies - start);
 #endif
 
 done:
@@ -171,8 +171,9 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
                setsda(adap, sb);
                udelay((adap->udelay + 1) / 2);
                if (sclhi(adap) < 0) { /* timed out */
-                       bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
-                               "timeout at bit #%d\n", (int)c, i);
+                       bit_dbg(1, &i2c_adap->dev,
+                               "i2c_outb: 0x%02x, timeout at bit #%d\n",
+                               (int)c, i);
                        return -ETIMEDOUT;
                }
                /* FIXME do arbitration here:
@@ -185,8 +186,8 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
        }
        sdahi(adap);
        if (sclhi(adap) < 0) { /* timeout */
-               bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
-                       "timeout at ack\n", (int)c);
+               bit_dbg(1, &i2c_adap->dev,
+                       "i2c_outb: 0x%02x, timeout at ack\n", (int)c);
                return -ETIMEDOUT;
        }
 
@@ -215,8 +216,9 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
        sdahi(adap);
        for (i = 0; i < 8; i++) {
                if (sclhi(adap) < 0) { /* timeout */
-                       bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
-                               "#%d\n", 7 - i);
+                       bit_dbg(1, &i2c_adap->dev,
+                               "i2c_inb: timeout at bit #%d\n",
+                               7 - i);
                        return -ETIMEDOUT;
                }
                indata *= 2;
@@ -265,8 +267,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!scl) {
-               printk(KERN_WARNING "%s: SCL unexpected low "
-                      "while pulling SDA low!\n", name);
+               printk(KERN_WARNING
+                      "%s: SCL unexpected low while pulling SDA low!\n",
+                      name);
                goto bailout;
        }
 
@@ -278,8 +281,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!scl) {
-               printk(KERN_WARNING "%s: SCL unexpected low "
-                      "while pulling SDA high!\n", name);
+               printk(KERN_WARNING
+                      "%s: SCL unexpected low while pulling SDA high!\n",
+                      name);
                goto bailout;
        }
 
@@ -291,8 +295,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!sda) {
-               printk(KERN_WARNING "%s: SDA unexpected low "
-                      "while pulling SCL low!\n", name);
+               printk(KERN_WARNING
+                      "%s: SDA unexpected low while pulling SCL low!\n",
+                      name);
                goto bailout;
        }
 
@@ -304,8 +309,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!sda) {
-               printk(KERN_WARNING "%s: SDA unexpected low "
-                      "while pulling SCL high!\n", name);
+               printk(KERN_WARNING
+                      "%s: SDA unexpected low while pulling SCL high!\n",
+                      name);
                goto bailout;
        }
 
@@ -352,8 +358,8 @@ static int try_address(struct i2c_adapter *i2c_adap,
                i2c_start(adap);
        }
        if (i && ret)
-               bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
-                       "0x%02x: %s\n", i + 1,
+               bit_dbg(1, &i2c_adap->dev,
+                       "Used %d tries to %s client at 0x%02x: %s\n", i + 1,
                        addr & 1 ? "read from" : "write to", addr >> 1,
                        ret == 1 ? "success" : "failed, timeout?");
        return ret;
@@ -442,8 +448,9 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
                                if (!(flags & I2C_M_NO_RD_ACK))
                                        acknak(i2c_adap, 0);
-                               dev_err(&i2c_adap->dev, "readbytes: invalid "
-                                       "block length (%d)\n", inval);
+                               dev_err(&i2c_adap->dev,
+                                       "readbytes: invalid block length (%d)\n",
+                                       inval);
                                return -EPROTO;
                        }
                        /* The original count value accounts for the extra
@@ -506,8 +513,8 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        return -ENXIO;
                }
                if (flags & I2C_M_RD) {
-                       bit_dbg(3, &i2c_adap->dev, "emitting repeated "
-                               "start condition\n");
+                       bit_dbg(3, &i2c_adap->dev,
+                               "emitting repeated start condition\n");
                        i2c_repstart(adap);
                        /* okay, now switch into reading mode */
                        addr |= 0x01;
@@ -564,8 +571,8 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
                        }
                        ret = bit_doAddress(i2c_adap, pmsg);
                        if ((ret != 0) && !nak_ok) {
-                               bit_dbg(1, &i2c_adap->dev, "NAK from "
-                                       "device addr 0x%02x msg #%d\n",
+                               bit_dbg(1, &i2c_adap->dev,
+                                       "NAK from device addr 0x%02x msg #%d\n",
                                        msgs[i].addr, i);
                                goto bailout;
                        }
index e18442b9973ae69d27e193478b9b6a9777d6a10b..94d94b4a9a0d989d932101422eb87feeb9cf7525 100644 (file)
@@ -708,7 +708,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
        i2c_set_adapdata(adap, dev);
 
        if (dev->pm_disabled) {
-               dev_pm_syscore_device(dev->dev, true);
                irq_flags = IRQF_NO_SUSPEND;
        } else {
                irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND;
index 1a8d2da5b000988c82f8f084f90f9576e7e758d8..b5750fd851251e74b0558576774da4a82d81c757 100644 (file)
@@ -434,6 +434,9 @@ static int dw_i2c_plat_suspend(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
+       if (i_dev->pm_disabled)
+               return 0;
+
        i_dev->disable(i_dev);
        i2c_dw_prepare_clk(i_dev, false);
 
@@ -444,7 +447,9 @@ static int dw_i2c_plat_resume(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       i2c_dw_prepare_clk(i_dev, true);
+       if (!i_dev->pm_disabled)
+               i2c_dw_prepare_clk(i_dev, true);
+
        i_dev->init(i_dev);
 
        return 0;
index 941c223f64914450fc2e2d76a293cd6202441b0b..04b60a349d7ed6edf44e8f75dd524969a30cf853 100644 (file)
@@ -1415,6 +1415,13 @@ static void i801_add_tco(struct i801_priv *priv)
 }
 
 #ifdef CONFIG_ACPI
+static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv,
+                                     acpi_physical_address address)
+{
+       return address >= priv->smba &&
+              address <= pci_resource_end(priv->pci_dev, SMBBAR);
+}
+
 static acpi_status
 i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
                     u64 *value, void *handler_context, void *region_context)
@@ -1430,7 +1437,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
         */
        mutex_lock(&priv->acpi_lock);
 
-       if (!priv->acpi_reserved) {
+       if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
                priv->acpi_reserved = true;
 
                dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
index 439e8778f849852f1a38cbf274502c4710e0065e..818cab14e87c5ea47e5c6daaa7b76c818465df52 100644 (file)
@@ -507,8 +507,6 @@ static void sh_mobile_i2c_dma_callback(void *data)
        pd->pos = pd->msg->len;
        pd->stop_after_dma = true;
 
-       i2c_release_dma_safe_msg_buf(pd->msg, pd->dma_buf);
-
        iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
 }
 
@@ -602,8 +600,8 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
        dma_async_issue_pending(chan);
 }
 
-static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
-                   bool do_init)
+static void start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
+                    bool do_init)
 {
        if (do_init) {
                /* Initialize channel registers */
@@ -627,7 +625,6 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
 
        /* Enable all interrupts to begin with */
        iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
-       return 0;
 }
 
 static int poll_dte(struct sh_mobile_i2c_data *pd)
@@ -698,9 +695,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;
                pd->stop_after_dma = false;
 
-               err = start_ch(pd, msg, do_start);
-               if (err)
-                       break;
+               start_ch(pd, msg, do_start);
 
                if (do_start)
                        i2c_op(pd, OP_START, 0);
@@ -709,6 +704,10 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                timeout = wait_event_timeout(pd->wait,
                                       pd->sr & (ICSR_TACK | SW_DONE),
                                       adapter->timeout);
+
+               /* 'stop_after_dma' tells if DMA transfer was complete */
+               i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, pd->stop_after_dma);
+
                if (!timeout) {
                        dev_err(pd->dev, "Transfer request timed out\n");
                        if (pd->dma_direction != DMA_NONE)
index f15737763608b0d6c0473fc11f29991f7bfc692a..9ee9a15e71347629d024709a17b9a6bb04fca8aa 100644 (file)
@@ -2293,21 +2293,22 @@ u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold)
 EXPORT_SYMBOL_GPL(i2c_get_dma_safe_msg_buf);
 
 /**
- * i2c_release_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
- * @msg: the message to be synced with
+ * i2c_put_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
  * @buf: the buffer obtained from i2c_get_dma_safe_msg_buf(). May be NULL.
+ * @msg: the message which the buffer corresponds to
+ * @xferred: bool saying if the message was transferred
  */
-void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf)
+void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred)
 {
        if (!buf || buf == msg->buf)
                return;
 
-       if (msg->flags & I2C_M_RD)
+       if (xferred && msg->flags & I2C_M_RD)
                memcpy(msg->buf, buf, msg->len);
 
        kfree(buf);
 }
-EXPORT_SYMBOL_GPL(i2c_release_dma_safe_msg_buf);
+EXPORT_SYMBOL_GPL(i2c_put_dma_safe_msg_buf);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
index 648eb6743ed58890f356212ed60a81ca5e6dd43c..6edffeed99534935f320b5b3d6e941dad15a968d 100644 (file)
@@ -238,10 +238,6 @@ static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req,
        mmc_exit_request(mq->queue, req);
 }
 
-/*
- * We use BLK_MQ_F_BLOCKING and have only 1 hardware queue, which means requests
- * will not be dispatched in parallel.
- */
 static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                                    const struct blk_mq_queue_data *bd)
 {
@@ -264,7 +260,7 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
 
        spin_lock_irq(q->queue_lock);
 
-       if (mq->recovery_needed) {
+       if (mq->recovery_needed || mq->busy) {
                spin_unlock_irq(q->queue_lock);
                return BLK_STS_RESOURCE;
        }
@@ -291,6 +287,9 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                break;
        }
 
+       /* Parallel dispatch of requests is not supported at the moment */
+       mq->busy = true;
+
        mq->in_flight[issue_type] += 1;
        get_card = (mmc_tot_in_flight(mq) == 1);
        cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
@@ -333,9 +332,12 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                mq->in_flight[issue_type] -= 1;
                if (mmc_tot_in_flight(mq) == 0)
                        put_card = true;
+               mq->busy = false;
                spin_unlock_irq(q->queue_lock);
                if (put_card)
                        mmc_put_card(card, &mq->ctx);
+       } else {
+               WRITE_ONCE(mq->busy, false);
        }
 
        return ret;
index 17e59d50b4960298630404e7dbe4a687eb8e9a19..9bf3c924507552caf0bf50a3118944e0390bc044 100644 (file)
@@ -81,6 +81,7 @@ struct mmc_queue {
        unsigned int            cqe_busy;
 #define MMC_CQE_DCMD_BUSY      BIT(0)
 #define MMC_CQE_QUEUE_FULL     BIT(1)
+       bool                    busy;
        bool                    use_cqe;
        bool                    recovery_needed;
        bool                    in_recovery;
index 294de177632c6e25a2024d42f8fbdd926043a80f..61e4e2a213c9637f73faeda61dc585c7922faab8 100644 (file)
@@ -217,7 +217,7 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
                         * We don't really have DMA, so we need
                         * to copy from our platform driver buffer
                         */
-                       sg_copy_to_buffer(data->sg, 1, host->virt_base,
+                       sg_copy_from_buffer(data->sg, 1, host->virt_base,
                                        data->sg->length);
                }
                host->data->bytes_xfered += data->sg->length;
@@ -393,7 +393,7 @@ static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host,
                 * We don't really have DMA, so we need to copy to our
                 * platform driver buffer
                 */
-               sg_copy_from_buffer(data->sg, 1, host->virt_base,
+               sg_copy_to_buffer(data->sg, 1, host->virt_base,
                                data->sg->length);
        }
 }
index 5aa2c9404e926db1af2e17452a64cf5a08e4156b..be53044086c76f7291224c33ed10c734ece7e897 100644 (file)
@@ -1976,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
        do {
                value = atmci_readl(host, ATMCI_RDR);
                if (likely(offset + 4 <= sg->length)) {
-                       sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset);
+                       sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset);
 
                        offset += 4;
                        nbytes += 4;
@@ -1993,7 +1993,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                } else {
                        unsigned int remaining = sg->length - offset;
 
-                       sg_pcopy_to_buffer(sg, 1, &value, remaining, offset);
+                       sg_pcopy_from_buffer(sg, 1, &value, remaining, offset);
                        nbytes += remaining;
 
                        flush_dcache_page(sg_page(sg));
@@ -2003,7 +2003,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                                goto done;
 
                        offset = 4 - remaining;
-                       sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining,
+                       sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining,
                                        offset, 0);
                        nbytes += offset;
                }
@@ -2042,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
 
        do {
                if (likely(offset + 4 <= sg->length)) {
-                       sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset);
+                       sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset);
                        atmci_writel(host, ATMCI_TDR, value);
 
                        offset += 4;
@@ -2059,7 +2059,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
                        unsigned int remaining = sg->length - offset;
 
                        value = 0;
-                       sg_pcopy_from_buffer(sg, 1, &value, remaining, offset);
+                       sg_pcopy_to_buffer(sg, 1, &value, remaining, offset);
                        nbytes += remaining;
 
                        host->sg = sg = sg_next(sg);
@@ -2070,7 +2070,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
                        }
 
                        offset = 4 - remaining;
-                       sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining,
+                       sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining,
                                        offset, 0);
                        atmci_writel(host, ATMCI_TDR, value);
                        nbytes += offset;
index 35cc0de6be67a5159a572612ab028ae43d1a84bc..ca0b43973769c9f80b4771914b5b74016b54bf84 100644 (file)
 /* DM_CM_RST */
 #define RST_DTRANRST1          BIT(9)
 #define RST_DTRANRST0          BIT(8)
-#define RST_RESERVED_BITS      GENMASK_ULL(32, 0)
+#define RST_RESERVED_BITS      GENMASK_ULL(31, 0)
 
 /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
 #define INFO1_CLEAR            0
+#define INFO1_MASK_CLEAR       GENMASK_ULL(31, 0)
 #define INFO1_DTRANEND1                BIT(17)
 #define INFO1_DTRANEND0                BIT(16)
 
 /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+#define INFO2_MASK_CLEAR       GENMASK_ULL(31, 0)
 #define INFO2_DTRANERR1                BIT(17)
 #define INFO2_DTRANERR0                BIT(16)
 
@@ -252,6 +254,12 @@ renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
 {
        struct renesas_sdhi *priv = host_to_priv(host);
 
+       /* Disable DMAC interrupts, we don't use them */
+       renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK,
+                                           INFO1_MASK_CLEAR);
+       renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO2_MASK,
+                                           INFO2_MASK_CLEAR);
+
        /* Each value is set to non-zero to assume "enabling" each DMA */
        host->chan_rx = host->chan_tx = (void *)0xdeadbeaf;
 
index ca18612c42014288d48c9ac8180a4b5be88e9a06..67b2065e7a19cace554463a74871ab676c221906 100644 (file)
@@ -1338,6 +1338,11 @@ int denali_init(struct denali_nand_info *denali)
 
        denali_enable_irq(denali);
        denali_reset_banks(denali);
+       if (!denali->max_banks) {
+               /* Error out earlier if no chip is found for some reasons. */
+               ret = -ENODEV;
+               goto disable_irq;
+       }
 
        denali->active_bank = DENALI_INVALID_BANK;
 
index a3f04315c05c54e6332a269603184cac0fc89dd4..427fcbc1b71c0551a107b0d8734bdec808a792c4 100644 (file)
@@ -1218,7 +1218,7 @@ static int docg4_resume(struct platform_device *pdev)
        return 0;
 }
 
-static void __init init_mtd_structs(struct mtd_info *mtd)
+static void init_mtd_structs(struct mtd_info *mtd)
 {
        /* initialize mtd and nand data structures */
 
@@ -1290,7 +1290,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
 
 }
 
-static int __init read_id_reg(struct mtd_info *mtd)
+static int read_id_reg(struct mtd_info *mtd)
 {
        struct nand_chip *nand = mtd_to_nand(mtd);
        struct docg4_priv *doc = nand_get_controller_data(nand);
index 139d96c5a02355f557d586f5edcab1712c048036..092c817f8f11cdda48fe8233fb04b7de2a76586a 100644 (file)
@@ -110,16 +110,14 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
                                 struct tcf_exts *tc_exts)
 {
        const struct tc_action *tc_act;
-       LIST_HEAD(tc_actions);
-       int rc;
+       int i, rc;
 
        if (!tcf_exts_has_actions(tc_exts)) {
                netdev_info(bp->dev, "no actions");
                return -EINVAL;
        }
 
-       tcf_exts_to_list(tc_exts, &tc_actions);
-       list_for_each_entry(tc_act, &tc_actions, list) {
+       tcf_exts_for_each_action(i, tc_act, tc_exts) {
                /* Drop action */
                if (is_tcf_gact_shot(tc_act)) {
                        actions->flags |= BNXT_TC_ACTION_FLAG_DROP;
index dc09f9a8a49bb160e29a829cfaa740a36fde2223..c6707ea2d75198c1157c5e675975d9319e150a9a 100644 (file)
@@ -482,11 +482,6 @@ static int macb_mii_probe(struct net_device *dev)
 
        if (np) {
                if (of_phy_is_fixed_link(np)) {
-                       if (of_phy_register_fixed_link(np) < 0) {
-                               dev_err(&bp->pdev->dev,
-                                       "broken fixed-link specification\n");
-                               return -ENODEV;
-                       }
                        bp->phy_node = of_node_get(np);
                } else {
                        bp->phy_node = of_parse_phandle(np, "phy-handle", 0);
@@ -569,7 +564,7 @@ static int macb_mii_init(struct macb *bp)
 {
        struct macb_platform_data *pdata;
        struct device_node *np;
-       int err;
+       int err = -ENXIO;
 
        /* Enable management port */
        macb_writel(bp, NCR, MACB_BIT(MPE));
@@ -592,12 +587,23 @@ static int macb_mii_init(struct macb *bp)
        dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
 
        np = bp->pdev->dev.of_node;
-       if (pdata)
-               bp->mii_bus->phy_mask = pdata->phy_mask;
+       if (np && of_phy_is_fixed_link(np)) {
+               if (of_phy_register_fixed_link(np) < 0) {
+                       dev_err(&bp->pdev->dev,
+                               "broken fixed-link specification %pOF\n", np);
+                       goto err_out_free_mdiobus;
+               }
+
+               err = mdiobus_register(bp->mii_bus);
+       } else {
+               if (pdata)
+                       bp->mii_bus->phy_mask = pdata->phy_mask;
+
+               err = of_mdiobus_register(bp->mii_bus, np);
+       }
 
-       err = of_mdiobus_register(bp->mii_bus, np);
        if (err)
-               goto err_out_free_mdiobus;
+               goto err_out_free_fixed_link;
 
        err = macb_mii_probe(bp->dev);
        if (err)
@@ -607,6 +613,7 @@ static int macb_mii_init(struct macb *bp)
 
 err_out_unregister_bus:
        mdiobus_unregister(bp->mii_bus);
+err_out_free_fixed_link:
        if (np && of_phy_is_fixed_link(np))
                of_phy_deregister_fixed_link(np);
 err_out_free_mdiobus:
@@ -2028,14 +2035,17 @@ static void macb_reset_hw(struct macb *bp)
 {
        struct macb_queue *queue;
        unsigned int q;
+       u32 ctrl = macb_readl(bp, NCR);
 
        /* Disable RX and TX (XXX: Should we halt the transmission
         * more gracefully?)
         */
-       macb_writel(bp, NCR, 0);
+       ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
 
        /* Clear the stats registers (XXX: Update stats first?) */
-       macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
+       ctrl |= MACB_BIT(CLRSTAT);
+
+       macb_writel(bp, NCR, ctrl);
 
        /* Clear all status flags */
        macb_writel(bp, TSR, -1);
@@ -2223,7 +2233,7 @@ static void macb_init_hw(struct macb *bp)
        }
 
        /* Enable TX and RX */
-       macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
+       macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE));
 }
 
 /* The hash address register is 64 bits long and takes up two
index 623f73dd7738dbbb01b8f49649a4507d641b1d9a..c116f96956fe9370c7927070ee6c9196ba26582b 100644 (file)
@@ -417,10 +417,9 @@ static void cxgb4_process_flow_actions(struct net_device *in,
                                       struct ch_filter_specification *fs)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
+       int i;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, cls->exts) {
                if (is_tcf_gact_ok(a)) {
                        fs->action = FILTER_PASS;
                } else if (is_tcf_gact_shot(a)) {
@@ -591,10 +590,9 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
        bool act_redir = false;
        bool act_pedit = false;
        bool act_vlan = false;
-       LIST_HEAD(actions);
+       int i;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, cls->exts) {
                if (is_tcf_gact_ok(a)) {
                        /* Do nothing */
                } else if (is_tcf_gact_shot(a)) {
index 18eb2aedd4cb0a2659a479f7f50c62f13f32c78d..c7d2b4dc7568e72e56a393171a42769ac46e6177 100644 (file)
@@ -93,14 +93,13 @@ static int fill_action_fields(struct adapter *adap,
        unsigned int num_actions = 0;
        const struct tc_action *a;
        struct tcf_exts *exts;
-       LIST_HEAD(actions);
+       int i;
 
        exts = cls->knode.exts;
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                /* Don't allow more than one action per rule. */
                if (num_actions)
                        return -EINVAL;
index fa5b30f547f6620a6e761860be6afa341dc185c8..cad52bd331f7b295853b4d2765ad5b1ebd37b0d9 100644 (file)
@@ -220,10 +220,10 @@ struct hnae_desc_cb {
 
        /* priv data for the desc, e.g. skb when use with ip stack*/
        void *priv;
-       u16 page_offset;
-       u16 reuse_flag;
+       u32 page_offset;
+       u32 length;     /* length of the buffer */
 
-       u16 length;     /* length of the buffer */
+       u16 reuse_flag;
 
        /* desc type, used by the ring user to mark the type of the priv data */
        u16 type;
index 9f2b552aee33998680c2dc2c72e81c28f99209f5..02a0ba20fad55f43c0e3cd8531bc38f60f790827 100644 (file)
@@ -406,113 +406,13 @@ out_net_tx_busy:
        return NETDEV_TX_BUSY;
 }
 
-/**
- * hns_nic_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
- * @data: pointer to the start of the headers
- * @max: total length of section to find headers in
- *
- * This function is meant to determine the length of headers that will
- * be recognized by hardware for LRO, GRO, and RSC offloads.  The main
- * motivation of doing this is to only perform one pull for IPv4 TCP
- * packets so that we can do basic things like calculating the gso_size
- * based on the average data per packet.
- **/
-static unsigned int hns_nic_get_headlen(unsigned char *data, u32 flag,
-                                       unsigned int max_size)
-{
-       unsigned char *network;
-       u8 hlen;
-
-       /* this should never happen, but better safe than sorry */
-       if (max_size < ETH_HLEN)
-               return max_size;
-
-       /* initialize network frame pointer */
-       network = data;
-
-       /* set first protocol and move network header forward */
-       network += ETH_HLEN;
-
-       /* handle any vlan tag if present */
-       if (hnae_get_field(flag, HNS_RXD_VLAN_M, HNS_RXD_VLAN_S)
-               == HNS_RX_FLAG_VLAN_PRESENT) {
-               if ((typeof(max_size))(network - data) > (max_size - VLAN_HLEN))
-                       return max_size;
-
-               network += VLAN_HLEN;
-       }
-
-       /* handle L3 protocols */
-       if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
-               == HNS_RX_FLAG_L3ID_IPV4) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct iphdr)))
-                       return max_size;
-
-               /* access ihl as a u8 to avoid unaligned access on ia64 */
-               hlen = (network[0] & 0x0F) << 2;
-
-               /* verify hlen meets minimum size requirements */
-               if (hlen < sizeof(struct iphdr))
-                       return network - data;
-
-               /* record next protocol if header is present */
-       } else if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
-               == HNS_RX_FLAG_L3ID_IPV6) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct ipv6hdr)))
-                       return max_size;
-
-               /* record next protocol */
-               hlen = sizeof(struct ipv6hdr);
-       } else {
-               return network - data;
-       }
-
-       /* relocate pointer to start of L4 header */
-       network += hlen;
-
-       /* finally sort out TCP/UDP */
-       if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
-               == HNS_RX_FLAG_L4ID_TCP) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct tcphdr)))
-                       return max_size;
-
-               /* access doff as a u8 to avoid unaligned access on ia64 */
-               hlen = (network[12] & 0xF0) >> 2;
-
-               /* verify hlen meets minimum size requirements */
-               if (hlen < sizeof(struct tcphdr))
-                       return network - data;
-
-               network += hlen;
-       } else if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
-               == HNS_RX_FLAG_L4ID_UDP) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct udphdr)))
-                       return max_size;
-
-               network += sizeof(struct udphdr);
-       }
-
-       /* If everything has gone correctly network should be the
-        * data section of the packet and will be the end of the header.
-        * If not then it probably represents the end of the last recognized
-        * header.
-        */
-       if ((typeof(max_size))(network - data) < max_size)
-               return network - data;
-       else
-               return max_size;
-}
-
 static void hns_nic_reuse_page(struct sk_buff *skb, int i,
                               struct hnae_ring *ring, int pull_len,
                               struct hnae_desc_cb *desc_cb)
 {
        struct hnae_desc *desc;
-       int truesize, size;
+       u32 truesize;
+       int size;
        int last_offset;
        bool twobufs;
 
@@ -530,7 +430,7 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
        }
 
        skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
-                       size - pull_len, truesize - pull_len);
+                       size - pull_len, truesize);
 
         /* avoid re-using remote pages,flag default unreuse */
        if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id()))
@@ -695,7 +595,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
        } else {
                ring->stats.seg_pkt_cnt++;
 
-               pull_len = hns_nic_get_headlen(va, bnum_flag, HNS_RX_HEAD_SIZE);
+               pull_len = eth_get_headlen(va, HNS_RX_HEAD_SIZE);
                memcpy(__skb_put(skb, pull_len), va,
                       ALIGN(pull_len, sizeof(long)));
 
index 3554dca7a680a2c970b37313222e517199007e82..955c4ab18b03bb300ec7beb8f8bcf953e817b2fc 100644 (file)
@@ -2019,7 +2019,8 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
                                struct hns3_desc_cb *desc_cb)
 {
        struct hns3_desc *desc;
-       int truesize, size;
+       u32 truesize;
+       int size;
        int last_offset;
        bool twobufs;
 
index a02a96aee2a2bfdcb9ebb49ea56b40546df83ae8..cb450d7ec8c1665a9ae690a3e3a9b78843976cf4 100644 (file)
@@ -284,11 +284,11 @@ struct hns3_desc_cb {
 
        /* priv data for the desc, e.g. skb when use with ip stack*/
        void *priv;
-       u16 page_offset;
-       u16 reuse_flag;
-
+       u32 page_offset;
        u32 length;     /* length of the buffer */
 
+       u16 reuse_flag;
+
        /* desc type, used by the ring user to mark the type of the priv data */
        u16 type;
 };
index bdb3f8e65ed470e314bf6b4f9b3b3b4e41b93e0f..2569a168334cbc6785f9e2909f5a68ac6450c9d6 100644 (file)
@@ -624,14 +624,14 @@ static int e1000_set_ringparam(struct net_device *netdev,
                adapter->tx_ring = tx_old;
                e1000_free_all_rx_resources(adapter);
                e1000_free_all_tx_resources(adapter);
-               kfree(tx_old);
-               kfree(rx_old);
                adapter->rx_ring = rxdr;
                adapter->tx_ring = txdr;
                err = e1000_up(adapter);
                if (err)
                        goto err_setup;
        }
+       kfree(tx_old);
+       kfree(rx_old);
 
        clear_bit(__E1000_RESETTING, &adapter->flags);
        return 0;
@@ -644,7 +644,8 @@ err_setup_rx:
 err_alloc_rx:
        kfree(txdr);
 err_alloc_tx:
-       e1000_up(adapter);
+       if (netif_running(adapter->netdev))
+               e1000_up(adapter);
 err_setup:
        clear_bit(__E1000_RESETTING, &adapter->flags);
        return err;
index abcd096ede14022ac6e022536a2db02de7e023da..5ff6caa83948c2c14a6b85070ddaba54e0c50c3a 100644 (file)
@@ -2013,7 +2013,7 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
        for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
                i40e_add_stat_strings(&data, i40e_gstrings_pfc_stats, i);
 
-       WARN_ONCE(p - data != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
+       WARN_ONCE(data - p != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
                  "stat strings count mismatch!");
 }
 
index f2c622e78802a751dc549e03b811825596d1a587..ac685ad4d8773125b059f1209d2b60747996b39b 100644 (file)
@@ -5122,15 +5122,17 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
                                       u8 *bw_share)
 {
        struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
+       struct i40e_pf *pf = vsi->back;
        i40e_status ret;
        int i;
 
-       if (vsi->back->flags & I40E_FLAG_TC_MQPRIO)
+       /* There is no need to reset BW when mqprio mode is on.  */
+       if (pf->flags & I40E_FLAG_TC_MQPRIO)
                return 0;
-       if (!vsi->mqprio_qopt.qopt.hw) {
+       if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
                ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
                if (ret)
-                       dev_info(&vsi->back->pdev->dev,
+                       dev_info(&pf->pdev->dev,
                                 "Failed to reset tx rate for vsi->seid %u\n",
                                 vsi->seid);
                return ret;
@@ -5139,12 +5141,11 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
        for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
                bw_data.tc_bw_credits[i] = bw_share[i];
 
-       ret = i40e_aq_config_vsi_tc_bw(&vsi->back->hw, vsi->seid, &bw_data,
-                                      NULL);
+       ret = i40e_aq_config_vsi_tc_bw(&pf->hw, vsi->seid, &bw_data, NULL);
        if (ret) {
-               dev_info(&vsi->back->pdev->dev,
+               dev_info(&pf->pdev->dev,
                         "AQ command Config VSI BW allocation per TC failed = %d\n",
-                        vsi->back->hw.aq.asq_last_status);
+                        pf->hw.aq.asq_last_status);
                return -EINVAL;
        }
 
index d8b5fff581e717e189ffe8f50dff4215ce8ec805..868f4a1d0f724379534791f74127261bba0c9682 100644 (file)
@@ -89,6 +89,13 @@ extern const char ice_drv_ver[];
 #define ice_for_each_rxq(vsi, i) \
        for ((i) = 0; (i) < (vsi)->num_rxq; (i)++)
 
+/* Macros for each allocated tx/rx ring whether used or not in a VSI */
+#define ice_for_each_alloc_txq(vsi, i) \
+       for ((i) = 0; (i) < (vsi)->alloc_txq; (i)++)
+
+#define ice_for_each_alloc_rxq(vsi, i) \
+       for ((i) = 0; (i) < (vsi)->alloc_rxq; (i)++)
+
 struct ice_tc_info {
        u16 qoffset;
        u16 qcount;
@@ -189,9 +196,9 @@ struct ice_vsi {
        struct list_head tmp_sync_list;         /* MAC filters to be synced */
        struct list_head tmp_unsync_list;       /* MAC filters to be unsynced */
 
-       bool irqs_ready;
-       bool current_isup;               /* Sync 'link up' logging */
-       bool stat_offsets_loaded;
+       u8 irqs_ready;
+       u8 current_isup;                 /* Sync 'link up' logging */
+       u8 stat_offsets_loaded;
 
        /* queue information */
        u8 tx_mapping_mode;              /* ICE_MAP_MODE_[CONTIG|SCATTER] */
@@ -262,7 +269,7 @@ struct ice_pf {
        struct ice_hw_port_stats stats;
        struct ice_hw_port_stats stats_prev;
        struct ice_hw hw;
-       bool stat_prev_loaded;  /* has previous stats been loaded */
+       u8 stat_prev_loaded;    /* has previous stats been loaded */
        char int_name[ICE_INT_NAME_STR_LEN];
 };
 
index 7541ec2270b3708d4e5e9362d0ae8a1f5e09318d..a0614f472658ac5305c6aff1e589d99dbdd1634a 100644 (file)
@@ -329,19 +329,19 @@ struct ice_aqc_vsi_props {
        /* VLAN section */
        __le16 pvid; /* VLANS include priority bits */
        u8 pvlan_reserved[2];
-       u8 port_vlan_flags;
-#define ICE_AQ_VSI_PVLAN_MODE_S        0
-#define ICE_AQ_VSI_PVLAN_MODE_M        (0x3 << ICE_AQ_VSI_PVLAN_MODE_S)
-#define ICE_AQ_VSI_PVLAN_MODE_UNTAGGED 0x1
-#define ICE_AQ_VSI_PVLAN_MODE_TAGGED   0x2
-#define ICE_AQ_VSI_PVLAN_MODE_ALL      0x3
+       u8 vlan_flags;
+#define ICE_AQ_VSI_VLAN_MODE_S 0
+#define ICE_AQ_VSI_VLAN_MODE_M (0x3 << ICE_AQ_VSI_VLAN_MODE_S)
+#define ICE_AQ_VSI_VLAN_MODE_UNTAGGED  0x1
+#define ICE_AQ_VSI_VLAN_MODE_TAGGED    0x2
+#define ICE_AQ_VSI_VLAN_MODE_ALL       0x3
 #define ICE_AQ_VSI_PVLAN_INSERT_PVID   BIT(2)
-#define ICE_AQ_VSI_PVLAN_EMOD_S        3
-#define ICE_AQ_VSI_PVLAN_EMOD_M        (0x3 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH (0x0 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR_UP   (0x1 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR      (0x2 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_NOTHING  (0x3 << ICE_AQ_VSI_PVLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_S         3
+#define ICE_AQ_VSI_VLAN_EMOD_M         (0x3 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR_BOTH  (0x0 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR_UP    (0x1 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR       (0x2 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_NOTHING   (0x3 << ICE_AQ_VSI_VLAN_EMOD_S)
        u8 pvlan_reserved2[3];
        /* ingress egress up sections */
        __le32 ingress_table; /* bitmap, 3 bits per up */
@@ -594,6 +594,7 @@ struct ice_sw_rule_lg_act {
 #define ICE_LG_ACT_GENERIC_OFFSET_M    (0x7 << ICE_LG_ACT_GENERIC_OFFSET_S)
 #define ICE_LG_ACT_GENERIC_PRIORITY_S  22
 #define ICE_LG_ACT_GENERIC_PRIORITY_M  (0x7 << ICE_LG_ACT_GENERIC_PRIORITY_S)
+#define ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX        7
 
        /* Action = 7 - Set Stat count */
 #define ICE_LG_ACT_STAT_COUNT          0x7
index 71d032cc5fa7d7ee8d6af579ca3d0e7813de05b5..661beea6af795cd72abf3e609347c89b21d9902d 100644 (file)
@@ -45,6 +45,9 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
 /**
  * ice_clear_pf_cfg - Clear PF configuration
  * @hw: pointer to the hardware structure
+ *
+ * Clears any existing PF configuration (VSIs, VSI lists, switch rules, port
+ * configuration, flow director filters, etc.).
  */
 enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
 {
@@ -1483,7 +1486,7 @@ enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up)
        struct ice_phy_info *phy_info;
        enum ice_status status = 0;
 
-       if (!pi)
+       if (!pi || !link_up)
                return ICE_ERR_PARAM;
 
        phy_info = &pi->phy;
@@ -1619,20 +1622,23 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
        }
 
        /* LUT size is only valid for Global and PF table types */
-       if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128) {
-               flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG <<
-                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                        ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512) {
+       switch (lut_size) {
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
+               break;
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
                flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
                          ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else if ((lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K) &&
-                  (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF)) {
-               flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
-                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                        ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else {
+               break;
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
+               if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
+                       flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
+                                 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
+                                ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
+                       break;
+               }
+               /* fall-through */
+       default:
                status = ICE_ERR_PARAM;
                goto ice_aq_get_set_rss_lut_exit;
        }
index 7c511f144ed60d92c16f0f526cfb5b03a3c2a59e..62be72fdc8f30c283b2385216f41ff15b87dc628 100644 (file)
@@ -597,10 +597,14 @@ static enum ice_status ice_init_check_adminq(struct ice_hw *hw)
        return 0;
 
 init_ctrlq_free_rq:
-       ice_shutdown_rq(hw, cq);
-       ice_shutdown_sq(hw, cq);
-       mutex_destroy(&cq->sq_lock);
-       mutex_destroy(&cq->rq_lock);
+       if (cq->rq.head) {
+               ice_shutdown_rq(hw, cq);
+               mutex_destroy(&cq->rq_lock);
+       }
+       if (cq->sq.head) {
+               ice_shutdown_sq(hw, cq);
+               mutex_destroy(&cq->sq_lock);
+       }
        return status;
 }
 
@@ -706,10 +710,14 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
                return;
        }
 
-       ice_shutdown_sq(hw, cq);
-       ice_shutdown_rq(hw, cq);
-       mutex_destroy(&cq->sq_lock);
-       mutex_destroy(&cq->rq_lock);
+       if (cq->sq.head) {
+               ice_shutdown_sq(hw, cq);
+               mutex_destroy(&cq->sq_lock);
+       }
+       if (cq->rq.head) {
+               ice_shutdown_rq(hw, cq);
+               mutex_destroy(&cq->rq_lock);
+       }
 }
 
 /**
@@ -1057,8 +1065,11 @@ ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
 
 clean_rq_elem_out:
        /* Set pending if needed, unlock and return */
-       if (pending)
+       if (pending) {
+               /* re-read HW head to calculate actual pending messages */
+               ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);
                *pending = (u16)((ntc > ntu ? cq->rq.count : 0) + (ntu - ntc));
+       }
 clean_rq_elem_err:
        mutex_unlock(&cq->rq_lock);
 
index 1db304c01d100604560a5d4ac8216b093a7f92d6..c71a9b528d6d558eca4a97a4511e445b00aa5bf1 100644 (file)
@@ -26,7 +26,7 @@ static int ice_q_stats_len(struct net_device *netdev)
 {
        struct ice_netdev_priv *np = netdev_priv(netdev);
 
-       return ((np->vsi->num_txq + np->vsi->num_rxq) *
+       return ((np->vsi->alloc_txq + np->vsi->alloc_rxq) *
                (sizeof(struct ice_q_stats) / sizeof(u64)));
 }
 
@@ -218,7 +218,7 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                        p += ETH_GSTRING_LEN;
                }
 
-               ice_for_each_txq(vsi, i) {
+               ice_for_each_alloc_txq(vsi, i) {
                        snprintf(p, ETH_GSTRING_LEN,
                                 "tx-queue-%u.tx_packets", i);
                        p += ETH_GSTRING_LEN;
@@ -226,7 +226,7 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                        p += ETH_GSTRING_LEN;
                }
 
-               ice_for_each_rxq(vsi, i) {
+               ice_for_each_alloc_rxq(vsi, i) {
                        snprintf(p, ETH_GSTRING_LEN,
                                 "rx-queue-%u.rx_packets", i);
                        p += ETH_GSTRING_LEN;
@@ -253,6 +253,24 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
 {
        switch (sset) {
        case ETH_SS_STATS:
+               /* The number (and order) of strings reported *must* remain
+                * constant for a given netdevice. This function must not
+                * report a different number based on run time parameters
+                * (such as the number of queues in use, or the setting of
+                * a private ethtool flag). This is due to the nature of the
+                * ethtool stats API.
+                *
+                * User space programs such as ethtool must make 3 separate
+                * ioctl requests, one for size, one for the strings, and
+                * finally one for the stats. Since these cross into
+                * user space, changes to the number or size could result in
+                * undefined memory access or incorrect string<->value
+                * correlations for statistics.
+                *
+                * Even if it appears to be safe, changes to the size or
+                * order of strings will suffer from race conditions and are
+                * not safe.
+                */
                return ICE_ALL_STATS_LEN(netdev);
        default:
                return -EOPNOTSUPP;
@@ -280,18 +298,26 @@ ice_get_ethtool_stats(struct net_device *netdev,
        /* populate per queue stats */
        rcu_read_lock();
 
-       ice_for_each_txq(vsi, j) {
+       ice_for_each_alloc_txq(vsi, j) {
                ring = READ_ONCE(vsi->tx_rings[j]);
-               if (!ring)
-                       continue;
-               data[i++] = ring->stats.pkts;
-               data[i++] = ring->stats.bytes;
+               if (ring) {
+                       data[i++] = ring->stats.pkts;
+                       data[i++] = ring->stats.bytes;
+               } else {
+                       data[i++] = 0;
+                       data[i++] = 0;
+               }
        }
 
-       ice_for_each_rxq(vsi, j) {
+       ice_for_each_alloc_rxq(vsi, j) {
                ring = READ_ONCE(vsi->rx_rings[j]);
-               data[i++] = ring->stats.pkts;
-               data[i++] = ring->stats.bytes;
+               if (ring) {
+                       data[i++] = ring->stats.pkts;
+                       data[i++] = ring->stats.bytes;
+               } else {
+                       data[i++] = 0;
+                       data[i++] = 0;
+               }
        }
 
        rcu_read_unlock();
@@ -519,7 +545,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
                goto done;
        }
 
-       for (i = 0; i < vsi->num_txq; i++) {
+       for (i = 0; i < vsi->alloc_txq; i++) {
                /* clone ring and setup updated count */
                tx_rings[i] = *vsi->tx_rings[i];
                tx_rings[i].count = new_tx_cnt;
@@ -551,7 +577,7 @@ process_rx:
                goto done;
        }
 
-       for (i = 0; i < vsi->num_rxq; i++) {
+       for (i = 0; i < vsi->alloc_rxq; i++) {
                /* clone ring and setup updated count */
                rx_rings[i] = *vsi->rx_rings[i];
                rx_rings[i].count = new_rx_cnt;
index 499904874b3ff863554c315add28a03f3a260eeb..6076fc87df9d28d81d3cc40d6b1ee7f042667b7f 100644 (file)
 #define PFINT_FW_CTL_CAUSE_ENA_S       30
 #define PFINT_FW_CTL_CAUSE_ENA_M       BIT(PFINT_FW_CTL_CAUSE_ENA_S)
 #define PFINT_OICR                     0x0016CA00
-#define PFINT_OICR_HLP_RDY_S           14
-#define PFINT_OICR_HLP_RDY_M           BIT(PFINT_OICR_HLP_RDY_S)
-#define PFINT_OICR_CPM_RDY_S           15
-#define PFINT_OICR_CPM_RDY_M           BIT(PFINT_OICR_CPM_RDY_S)
 #define PFINT_OICR_ECC_ERR_S           16
 #define PFINT_OICR_ECC_ERR_M           BIT(PFINT_OICR_ECC_ERR_S)
 #define PFINT_OICR_MAL_DETECT_S                19
 #define PFINT_OICR_GRST_M              BIT(PFINT_OICR_GRST_S)
 #define PFINT_OICR_PCI_EXCEPTION_S     21
 #define PFINT_OICR_PCI_EXCEPTION_M     BIT(PFINT_OICR_PCI_EXCEPTION_S)
-#define PFINT_OICR_GPIO_S              22
-#define PFINT_OICR_GPIO_M              BIT(PFINT_OICR_GPIO_S)
-#define PFINT_OICR_STORM_DETECT_S      24
-#define PFINT_OICR_STORM_DETECT_M      BIT(PFINT_OICR_STORM_DETECT_S)
 #define PFINT_OICR_HMC_ERR_S           26
 #define PFINT_OICR_HMC_ERR_M           BIT(PFINT_OICR_HMC_ERR_S)
 #define PFINT_OICR_PE_CRITERR_S                28
index d23a91665b463799a6a3e4445d3c681a2400fb15..068dbc740b7667ce98541921a57108503e825594 100644 (file)
@@ -265,6 +265,7 @@ enum ice_rx_flex_desc_status_error_0_bits {
 struct ice_rlan_ctx {
        u16 head;
        u16 cpuid; /* bigger than needed, see above for reason */
+#define ICE_RLAN_BASE_S 7
        u64 base;
        u16 qlen;
 #define ICE_RLAN_CTX_DBUF_S 7
index 5299caf55a7f2b44772988d9f4eeb70b27c51cc4..f1e80eed2fd6d9f94eab163acb4d178d83ba4af2 100644 (file)
@@ -901,7 +901,7 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
                case ice_aqc_opc_get_link_status:
                        if (ice_handle_link_event(pf))
                                dev_err(&pf->pdev->dev,
-                                       "Could not handle link event");
+                                       "Could not handle link event\n");
                        break;
                default:
                        dev_dbg(&pf->pdev->dev,
@@ -916,6 +916,21 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
        return pending && (i == ICE_DFLT_IRQ_WORK);
 }
 
+/**
+ * ice_ctrlq_pending - check if there is a difference between ntc and ntu
+ * @hw: pointer to hardware info
+ * @cq: control queue information
+ *
+ * returns true if there are pending messages in a queue, false if there aren't
+ */
+static bool ice_ctrlq_pending(struct ice_hw *hw, struct ice_ctl_q_info *cq)
+{
+       u16 ntu;
+
+       ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);
+       return cq->rq.next_to_clean != ntu;
+}
+
 /**
  * ice_clean_adminq_subtask - clean the AdminQ rings
  * @pf: board private structure
@@ -923,7 +938,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
 static void ice_clean_adminq_subtask(struct ice_pf *pf)
 {
        struct ice_hw *hw = &pf->hw;
-       u32 val;
 
        if (!test_bit(__ICE_ADMINQ_EVENT_PENDING, pf->state))
                return;
@@ -933,9 +947,13 @@ static void ice_clean_adminq_subtask(struct ice_pf *pf)
 
        clear_bit(__ICE_ADMINQ_EVENT_PENDING, pf->state);
 
-       /* re-enable Admin queue interrupt causes */
-       val = rd32(hw, PFINT_FW_CTL);
-       wr32(hw, PFINT_FW_CTL, (val | PFINT_FW_CTL_CAUSE_ENA_M));
+       /* There might be a situation where new messages arrive to a control
+        * queue between processing the last message and clearing the
+        * EVENT_PENDING bit. So before exiting, check queue head again (using
+        * ice_ctrlq_pending) and process new messages if any.
+        */
+       if (ice_ctrlq_pending(hw, &hw->adminq))
+               __ice_clean_ctrlq(pf, ICE_CTL_Q_ADMIN);
 
        ice_flush(hw);
 }
@@ -1295,11 +1313,8 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
                qcount = numq_tc;
        }
 
-       /* find higher power-of-2 of qcount */
-       pow = ilog2(qcount);
-
-       if (!is_power_of_2(qcount))
-               pow++;
+       /* find the (rounded up) power-of-2 of qcount */
+       pow = order_base_2(qcount);
 
        for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
                if (!(vsi->tc_cfg.ena_tc & BIT(i))) {
@@ -1352,14 +1367,15 @@ static void ice_set_dflt_vsi_ctx(struct ice_vsi_ctx *ctxt)
        ctxt->info.sw_flags = ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
        /* Traffic from VSI can be sent to LAN */
        ctxt->info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA;
-       /* Allow all packets untagged/tagged */
-       ctxt->info.port_vlan_flags = ((ICE_AQ_VSI_PVLAN_MODE_ALL &
-                                      ICE_AQ_VSI_PVLAN_MODE_M) >>
-                                     ICE_AQ_VSI_PVLAN_MODE_S);
-       /* Show VLAN/UP from packets in Rx descriptors */
-       ctxt->info.port_vlan_flags |= ((ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH &
-                                       ICE_AQ_VSI_PVLAN_EMOD_M) >>
-                                      ICE_AQ_VSI_PVLAN_EMOD_S);
+
+       /* By default bits 3 and 4 in vlan_flags are 0's which results in legacy
+        * behavior (show VLAN, DEI, and UP) in descriptor. Also, allow all
+        * packets untagged/tagged.
+        */
+       ctxt->info.vlan_flags = ((ICE_AQ_VSI_VLAN_MODE_ALL &
+                                 ICE_AQ_VSI_VLAN_MODE_M) >>
+                                ICE_AQ_VSI_VLAN_MODE_S);
+
        /* Have 1:1 UP mapping for both ingress/egress tables */
        table |= ICE_UP_TABLE_TRANSLATE(0, 0);
        table |= ICE_UP_TABLE_TRANSLATE(1, 1);
@@ -1688,15 +1704,12 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
        wr32(hw, PFINT_OICR_ENA, 0);    /* disable all */
        rd32(hw, PFINT_OICR);           /* read to clear */
 
-       val = (PFINT_OICR_HLP_RDY_M |
-              PFINT_OICR_CPM_RDY_M |
-              PFINT_OICR_ECC_ERR_M |
+       val = (PFINT_OICR_ECC_ERR_M |
               PFINT_OICR_MAL_DETECT_M |
               PFINT_OICR_GRST_M |
               PFINT_OICR_PCI_EXCEPTION_M |
-              PFINT_OICR_GPIO_M |
-              PFINT_OICR_STORM_DETECT_M |
-              PFINT_OICR_HMC_ERR_M);
+              PFINT_OICR_HMC_ERR_M |
+              PFINT_OICR_PE_CRITERR_M);
 
        wr32(hw, PFINT_OICR_ENA, val);
 
@@ -2058,15 +2071,13 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
 skip_req_irq:
        ice_ena_misc_vector(pf);
 
-       val = (pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
-             (ICE_RX_ITR & PFINT_OICR_CTL_ITR_INDX_M) |
-             PFINT_OICR_CTL_CAUSE_ENA_M;
+       val = ((pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
+              PFINT_OICR_CTL_CAUSE_ENA_M);
        wr32(hw, PFINT_OICR_CTL, val);
 
        /* This enables Admin queue Interrupt causes */
-       val = (pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
-             (ICE_RX_ITR & PFINT_FW_CTL_ITR_INDX_M) |
-             PFINT_FW_CTL_CAUSE_ENA_M;
+       val = ((pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
+              PFINT_FW_CTL_CAUSE_ENA_M);
        wr32(hw, PFINT_FW_CTL, val);
 
        itr_gran = hw->itr_gran_200;
@@ -3246,8 +3257,10 @@ static void ice_clear_interrupt_scheme(struct ice_pf *pf)
        if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
                ice_dis_msix(pf);
 
-       devm_kfree(&pf->pdev->dev, pf->irq_tracker);
-       pf->irq_tracker = NULL;
+       if (pf->irq_tracker) {
+               devm_kfree(&pf->pdev->dev, pf->irq_tracker);
+               pf->irq_tracker = NULL;
+       }
 }
 
 /**
@@ -3271,7 +3284,7 @@ static int ice_probe(struct pci_dev *pdev,
 
        err = pcim_iomap_regions(pdev, BIT(ICE_BAR0), pci_name(pdev));
        if (err) {
-               dev_err(&pdev->dev, "I/O map error %d\n", err);
+               dev_err(&pdev->dev, "BAR0 I/O map error %d\n", err);
                return err;
        }
 
@@ -3720,10 +3733,10 @@ static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
        enum ice_status status;
 
        /* Here we are configuring the VSI to let the driver add VLAN tags by
-        * setting port_vlan_flags to ICE_AQ_VSI_PVLAN_MODE_ALL. The actual VLAN
-        * tag insertion happens in the Tx hot path, in ice_tx_map.
+        * setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
+        * insertion happens in the Tx hot path, in ice_tx_map.
         */
-       ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_MODE_ALL;
+       ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
 
        ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
        ctxt.vsi_num = vsi->vsi_num;
@@ -3735,7 +3748,7 @@ static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
                return -EIO;
        }
 
-       vsi->info.port_vlan_flags = ctxt.info.port_vlan_flags;
+       vsi->info.vlan_flags = ctxt.info.vlan_flags;
        return 0;
 }
 
@@ -3757,12 +3770,15 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
         */
        if (ena) {
                /* Strip VLAN tag from Rx packet and put it in the desc */
-               ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH;
+               ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
        } else {
                /* Disable stripping. Leave tag in packet */
-               ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_EMOD_NOTHING;
+               ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
        }
 
+       /* Allow all packets untagged/tagged */
+       ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
+
        ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
        ctxt.vsi_num = vsi->vsi_num;
 
@@ -3773,7 +3789,7 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
                return -EIO;
        }
 
-       vsi->info.port_vlan_flags = ctxt.info.port_vlan_flags;
+       vsi->info.vlan_flags = ctxt.info.vlan_flags;
        return 0;
 }
 
@@ -3986,7 +4002,7 @@ static int ice_setup_rx_ctx(struct ice_ring *ring)
        /* clear the context structure first */
        memset(&rlan_ctx, 0, sizeof(rlan_ctx));
 
-       rlan_ctx.base = ring->dma >> 7;
+       rlan_ctx.base = ring->dma >> ICE_RLAN_BASE_S;
 
        rlan_ctx.qlen = ring->count;
 
@@ -4098,11 +4114,12 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)
 {
        int err;
 
-       ice_set_rx_mode(vsi->netdev);
-
-       err = ice_restore_vlan(vsi);
-       if (err)
-               return err;
+       if (vsi->netdev) {
+               ice_set_rx_mode(vsi->netdev);
+               err = ice_restore_vlan(vsi);
+               if (err)
+                       return err;
+       }
 
        err = ice_vsi_cfg_txqs(vsi);
        if (!err)
@@ -4868,7 +4885,7 @@ int ice_down(struct ice_vsi *vsi)
  */
 static int ice_vsi_setup_tx_rings(struct ice_vsi *vsi)
 {
-       int i, err;
+       int i, err = 0;
 
        if (!vsi->num_txq) {
                dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Tx queues\n",
@@ -4893,7 +4910,7 @@ static int ice_vsi_setup_tx_rings(struct ice_vsi *vsi)
  */
 static int ice_vsi_setup_rx_rings(struct ice_vsi *vsi)
 {
-       int i, err;
+       int i, err = 0;
 
        if (!vsi->num_rxq) {
                dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Rx queues\n",
@@ -5235,7 +5252,7 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
        u8 count = 0;
 
        if (new_mtu == netdev->mtu) {
-               netdev_warn(netdev, "mtu is already %d\n", netdev->mtu);
+               netdev_warn(netdev, "mtu is already %u\n", netdev->mtu);
                return 0;
        }
 
index 92da0a626ce0b38395633ff90df504f8f88f40c8..295a8cd87fc16565148bf6cbb7713c02a71454f9 100644 (file)
@@ -131,9 +131,8 @@ ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
  *
  * This function will request NVM ownership.
  */
-static enum
-ice_status ice_acquire_nvm(struct ice_hw *hw,
-                          enum ice_aq_res_access_type access)
+static enum ice_status
+ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
 {
        if (hw->nvm.blank_nvm_mode)
                return 0;
index 2e6c1d92cc8884b2bb9755483f82c421b5d9e6f1..eeae199469b6e7f17f680276bb83f77534cbe555 100644 (file)
@@ -1576,8 +1576,7 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_id, u8 tc,
                        return status;
        }
 
-       if (owner == ICE_SCHED_NODE_OWNER_LAN)
-               vsi->max_lanq[tc] = new_numqs;
+       vsi->max_lanq[tc] = new_numqs;
 
        return status;
 }
index 723d15f1e90b4abbb4db585734940bfc874d4712..6b7ec2ae5ad6798818a9d5947e8071aba410ffff 100644 (file)
@@ -645,14 +645,14 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
        act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
        lg_act->pdata.lg_act.act[1] = cpu_to_le32(act);
 
-       act = (7 << ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_VALUE_M;
+       act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
+              ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
 
        /* Third action Marker value */
        act |= ICE_LG_ACT_GENERIC;
        act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
                ICE_LG_ACT_GENERIC_VALUE_M;
 
-       act |= (0 << ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_VALUE_M;
        lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);
 
        /* call the fill switch rule to fill the lookup tx rx structure */
index 6f4a0d159dbfdc2bfb1fe5fbd5fa355dc5503832..9b8ec128ee31f57ea2c2498a0fa55bde139ca7b9 100644 (file)
@@ -17,7 +17,7 @@ struct ice_vsi_ctx {
        u16 vsis_unallocated;
        u16 flags;
        struct ice_aqc_vsi_props info;
-       bool alloc_from_pool;
+       u8 alloc_from_pool;
 };
 
 enum ice_sw_fwd_act_type {
@@ -94,8 +94,8 @@ struct ice_fltr_info {
        u8 qgrp_size;
 
        /* Rule creations populate these indicators basing on the switch type */
-       bool lb_en;     /* Indicate if packet can be looped back */
-       bool lan_en;    /* Indicate if packet can be forwarded to the uplink */
+       u8 lb_en;       /* Indicate if packet can be looped back */
+       u8 lan_en;      /* Indicate if packet can be forwarded to the uplink */
 };
 
 /* Bookkeeping structure to hold bitmap of VSIs corresponding to VSI list id */
index 567067b650c4129acafbea94388731f7ad315ba6..31bc998fe2006f7fa515a4b05917abdae50cb7c0 100644 (file)
@@ -143,7 +143,7 @@ struct ice_ring {
        u16 next_to_use;
        u16 next_to_clean;
 
-       bool ring_active;               /* is ring online or not */
+       u8 ring_active;                 /* is ring online or not */
 
        /* stats structs */
        struct ice_q_stats      stats;
index 99c8a9a71b5e4f433a89d575c92fcd34e59ab6ae..97c366e0ca596facaec70c7f1bb4ddc8b81e8774 100644 (file)
@@ -83,7 +83,7 @@ struct ice_link_status {
        u64 phy_type_low;
        u16 max_frame_size;
        u16 link_speed;
-       bool lse_ena;   /* Link Status Event notification */
+       u8 lse_ena;     /* Link Status Event notification */
        u8 link_info;
        u8 an_info;
        u8 ext_info;
@@ -101,7 +101,7 @@ struct ice_phy_info {
        struct ice_link_status link_info_old;
        u64 phy_type_low;
        enum ice_media_type media_type;
-       bool get_link_info;
+       u8 get_link_info;
 };
 
 /* Common HW capabilities for SW use */
@@ -167,7 +167,7 @@ struct ice_nvm_info {
        u32 oem_ver;              /* OEM version info */
        u16 sr_words;             /* Shadow RAM size in words */
        u16 ver;                  /* NVM package version */
-       bool blank_nvm_mode;      /* is NVM empty (no FW present) */
+       u8 blank_nvm_mode;        /* is NVM empty (no FW present) */
 };
 
 /* Max number of port to queue branches w.r.t topology */
@@ -181,7 +181,7 @@ struct ice_sched_node {
        struct ice_aqc_txsched_elem_data info;
        u32 agg_id;                     /* aggregator group id */
        u16 vsi_id;
-       bool in_use;                    /* suspended or in use */
+       u8 in_use;                      /* suspended or in use */
        u8 tx_sched_layer;              /* Logical Layer (1-9) */
        u8 num_children;
        u8 tc_num;
@@ -218,7 +218,7 @@ struct ice_sched_vsi_info {
 struct ice_sched_tx_policy {
        u16 max_num_vsis;
        u8 max_num_lan_qs_per_tc[ICE_MAX_TRAFFIC_CLASS];
-       bool rdma_ena;
+       u8 rdma_ena;
 };
 
 struct ice_port_info {
@@ -243,7 +243,7 @@ struct ice_port_info {
        struct list_head agg_list;      /* lists all aggregator */
        u8 lport;
 #define ICE_LPORT_MASK         0xff
-       bool is_vf;
+       u8 is_vf;
 };
 
 struct ice_switch_info {
@@ -287,7 +287,7 @@ struct ice_hw {
        u8 max_cgds;
        u8 sw_entry_point_layer;
 
-       bool evb_veb;           /* true for VEB, false for VEPA */
+       u8 evb_veb;             /* true for VEB, false for VEPA */
        struct ice_bus_info bus;
        struct ice_nvm_info nvm;
        struct ice_hw_dev_caps dev_caps;        /* device capabilities */
@@ -318,7 +318,7 @@ struct ice_hw {
        u8 itr_gran_100;
        u8 itr_gran_50;
        u8 itr_gran_25;
-       bool ucast_shared;      /* true if VSIs can share unicast addr */
+       u8 ucast_shared;        /* true if VSIs can share unicast addr */
 
 };
 
index f92f7918112de063700f12de3462a482999c8bb3..5acf3b743876a485f61002658dccba47a0ca3d59 100644 (file)
@@ -1649,7 +1649,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
        if (hw->phy.type == e1000_phy_m88)
                igb_phy_disable_receiver(adapter);
 
-       mdelay(500);
+       msleep(500);
        return 0;
 }
 
index d03c2f0d759260df50e9d71da5758912326e804f..a32c576c1e656c0102989413cad114d1d8f03771 100644 (file)
@@ -3873,7 +3873,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
 
        adapter->mac_table = kcalloc(hw->mac.rar_entry_count,
                                     sizeof(struct igb_mac_addr),
-                                    GFP_ATOMIC);
+                                    GFP_KERNEL);
        if (!adapter->mac_table)
                return -ENOMEM;
 
@@ -3883,7 +3883,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
 
        /* Setup and initialize a copy of the hw vlan table array */
        adapter->shadow_vfta = kcalloc(E1000_VLAN_FILTER_TBL_SIZE, sizeof(u32),
-                                      GFP_ATOMIC);
+                                      GFP_KERNEL);
        if (!adapter->shadow_vfta)
                return -ENOMEM;
 
@@ -5816,7 +5816,8 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
 
        if (skb->ip_summed != CHECKSUM_PARTIAL) {
 csum_failed:
-               if (!(first->tx_flags & IGB_TX_FLAGS_VLAN))
+               if (!(first->tx_flags & IGB_TX_FLAGS_VLAN) &&
+                   !tx_ring->launchtime_enable)
                        return;
                goto no_csum;
        }
index 43664adf7a3c120d024889ac59f42e2da5d5b1ae..d3e72d0f66ef428b08e4bd88508e05b734bc43a4 100644 (file)
@@ -771,14 +771,13 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
        rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc);
        rxdr->size = ALIGN(rxdr->size, 4096);
 
-       rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
-                                       GFP_KERNEL);
+       rxdr->desc = dma_zalloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
+                                        GFP_KERNEL);
 
        if (!rxdr->desc) {
                vfree(rxdr->buffer_info);
                return -ENOMEM;
        }
-       memset(rxdr->desc, 0, rxdr->size);
 
        rxdr->next_to_clean = 0;
        rxdr->next_to_use = 0;
index 94b3165ff543055621326783d330da1f7b4272e7..ccd852ad62a4b109ff26ea40e7587024f8b0d198 100644 (file)
@@ -192,7 +192,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
        }
 
        /* alloc the udl from per cpu ddp pool */
-       ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
+       ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_KERNEL, &ddp->udp);
        if (!ddp->udl) {
                e_err(drv, "failed allocated ddp context\n");
                goto out_noddp_unmap;
@@ -760,7 +760,7 @@ int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter)
                return 0;
 
        /* Extra buffer to be shared by all DDPs for HW work around */
-       buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC);
+       buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;
 
index 447098005490926f67e5fb32f7c84b798e387eab..9a23d33a47ed52bfeb10d79d970e114ee4702d6e 100644 (file)
@@ -6201,7 +6201,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
 
        adapter->mac_table = kcalloc(hw->mac.num_rar_entries,
                                     sizeof(struct ixgbe_mac_addr),
-                                    GFP_ATOMIC);
+                                    GFP_KERNEL);
        if (!adapter->mac_table)
                return -ENOMEM;
 
@@ -6620,8 +6620,18 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        if (adapter->xdp_prog) {
-               e_warn(probe, "MTU cannot be changed while XDP program is loaded\n");
-               return -EPERM;
+               int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN +
+                                    VLAN_HLEN;
+               int i;
+
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       struct ixgbe_ring *ring = adapter->rx_ring[i];
+
+                       if (new_frame_size > ixgbe_rx_bufsz(ring)) {
+                               e_warn(probe, "Requested MTU size is not supported with XDP\n");
+                               return -EINVAL;
+                       }
+               }
        }
 
        /*
@@ -8983,6 +8993,15 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 
 #ifdef CONFIG_IXGBE_DCB
        if (tc) {
+               if (adapter->xdp_prog) {
+                       e_warn(probe, "DCB is not supported with XDP\n");
+
+                       ixgbe_init_interrupt_scheme(adapter);
+                       if (netif_running(dev))
+                               ixgbe_open(dev);
+                       return -EINVAL;
+               }
+
                netdev_set_num_tc(dev, tc);
                ixgbe_set_prio_tc_map(adapter);
 
@@ -9171,14 +9190,12 @@ static int parse_tc_actions(struct ixgbe_adapter *adapter,
                            struct tcf_exts *exts, u64 *action, u8 *queue)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
+       int i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
-
+       tcf_exts_for_each_action(i, a, exts) {
                /* Drop action */
                if (is_tcf_gact_shot(a)) {
                        *action = IXGBE_FDIR_DROP_QUEUE;
@@ -9936,6 +9953,11 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
        int tcs = adapter->hw_tcs ? : 1;
        int pool, err;
 
+       if (adapter->xdp_prog) {
+               e_warn(probe, "L2FW offload is not supported with XDP\n");
+               return ERR_PTR(-EINVAL);
+       }
+
        /* The hardware supported by ixgbe only filters on the destination MAC
         * address. In order to avoid issues we only support offloading modes
         * where the hardware can actually provide the functionality.
index 6f59933cdff7d5ff13620ced894036ddeb3052c3..3c6f01c41b788eb45730e49083f2025c7c0683f1 100644 (file)
@@ -53,6 +53,11 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
        struct ixgbe_hw *hw = &adapter->hw;
        int i;
 
+       if (adapter->xdp_prog) {
+               e_warn(probe, "SRIOV is not supported with XDP\n");
+               return -EINVAL;
+       }
+
        /* Enable VMDq flag so device will be set in VM mode */
        adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED |
                          IXGBE_FLAG_VMDQ_ENABLED;
@@ -688,8 +693,13 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
        struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
+       u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);
        u8 num_tcs = adapter->hw_tcs;
+       u32 reg_val;
+       u32 queue;
+       u32 word;
 
        /* remove VLAN filters beloning to this VF */
        ixgbe_clear_vf_vlans(adapter, vf);
@@ -726,6 +736,27 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 
        /* reset VF api back to unknown */
        adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10;
+
+       /* Restart each queue for given VF */
+       for (queue = 0; queue < q_per_pool; queue++) {
+               unsigned int reg_idx = (vf * q_per_pool) + queue;
+
+               reg_val = IXGBE_READ_REG(hw, IXGBE_PVFTXDCTL(reg_idx));
+
+               /* Re-enabling only configured queues */
+               if (reg_val) {
+                       reg_val |= IXGBE_TXDCTL_ENABLE;
+                       IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), reg_val);
+                       reg_val &= ~IXGBE_TXDCTL_ENABLE;
+                       IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), reg_val);
+               }
+       }
+
+       /* Clear VF's mailbox memory */
+       for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++)
+               IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0);
+
+       IXGBE_WRITE_FLUSH(hw);
 }
 
 static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
index 44cfb2021145b9be9284c3862c52abf5c5ba6f82..41bcbb337e837ff1dbeb8e6061ae92e9d050350c 100644 (file)
@@ -2518,6 +2518,7 @@ enum {
 /* Translated register #defines */
 #define IXGBE_PVFTDH(P)                (0x06010 + (0x40 * (P)))
 #define IXGBE_PVFTDT(P)                (0x06018 + (0x40 * (P)))
+#define IXGBE_PVFTXDCTL(P)     (0x06028 + (0x40 * (P)))
 #define IXGBE_PVFTDWBAL(P)     (0x06038 + (0x40 * (P)))
 #define IXGBE_PVFTDWBAH(P)     (0x0603C + (0x40 * (P)))
 
index 9131a1376e7dc540cc0238b0cf980bc54c9c19ae..9fed54017659de3b0f58a1287a7eff605c077f6c 100644 (file)
@@ -1982,14 +1982,15 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
                goto out_ok;
 
        modify_ip_header = false;
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
+               int k;
+
                if (!is_tcf_pedit(a))
                        continue;
 
                nkeys = tcf_pedit_nkeys(a);
-               for (i = 0; i < nkeys; i++) {
-                       htype = tcf_pedit_htype(a, i);
+               for (k = 0; k < nkeys; k++) {
+                       htype = tcf_pedit_htype(a, k);
                        if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 ||
                            htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) {
                                modify_ip_header = true;
@@ -2053,15 +2054,14 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        const struct tc_action *a;
        LIST_HEAD(actions);
        u32 action = 0;
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
        attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
                        if (MLX5_CAP_FLOWTABLE(priv->mdev,
@@ -2666,7 +2666,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        LIST_HEAD(actions);
        bool encap = false;
        u32 action = 0;
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
@@ -2674,8 +2674,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        attr->in_rep = rpriv->rep;
        attr->in_mdev = priv->mdev;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
                                  MLX5_FLOW_CONTEXT_ACTION_COUNT;
index 6070d1591d1e77885185fa43e261ec4a80b5ae01..930700413b1d07dd8a62ffbabf47aea995d062cf 100644 (file)
@@ -1346,8 +1346,7 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
                return -ENOMEM;
        mall_tc_entry->cookie = f->cookie;
 
-       tcf_exts_to_list(f->exts, &actions);
-       a = list_first_entry(&actions, struct tc_action, list);
+       a = tcf_exts_first_action(f->exts);
 
        if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
                struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;
index 3ae9301967410bca24e601e888b8b270b25c8e82..3cdb7aca90b72492f02fd4bce2c35ad6de76eaa9 100644 (file)
@@ -414,6 +414,8 @@ mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
 void
 mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
 void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
+void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
+                                struct net_device *dev);
 
 /* spectrum_kvdl.c */
 enum mlxsw_sp_kvdl_entry_type {
index ebd1b24ebaa5dd48df775d9a0704bd81b8ed09df..8d211972c5e90fbe1a24dc32edf6f371ff018bd4 100644 (file)
@@ -21,8 +21,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
                                         struct netlink_ext_ack *extack)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return 0;
@@ -32,8 +31,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
        if (err)
                return err;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_ok(a)) {
                        err = mlxsw_sp_acl_rulei_act_terminate(rulei);
                        if (err) {
index 3a96307f51b055e4bcf0693704118fd9d4e90995..2ab9cf25a08ae19788d28ffddaa8698ba2213152 100644 (file)
@@ -6234,6 +6234,17 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
        mlxsw_sp_vr_put(mlxsw_sp, vr);
 }
 
+void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
+                                struct net_device *dev)
+{
+       struct mlxsw_sp_rif *rif;
+
+       rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
+       if (!rif)
+               return;
+       mlxsw_sp_rif_destroy(rif);
+}
+
 static void
 mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
                                 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
index 0d8444aaba01ae7e5eddc58ef7dbc87ee5d1cb7b..db715da7bab7746c58ed23b48048d8a4917ca10d 100644 (file)
@@ -127,6 +127,24 @@ bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
        return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
 }
 
+static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
+                                                   void *data)
+{
+       struct mlxsw_sp *mlxsw_sp = data;
+
+       mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
+       return 0;
+}
+
+static void mlxsw_sp_bridge_device_rifs_destroy(struct mlxsw_sp *mlxsw_sp,
+                                               struct net_device *dev)
+{
+       mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
+       netdev_walk_all_upper_dev_rcu(dev,
+                                     mlxsw_sp_bridge_device_upper_rif_destroy,
+                                     mlxsw_sp);
+}
+
 static struct mlxsw_sp_bridge_device *
 mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
                              struct net_device *br_dev)
@@ -165,6 +183,8 @@ static void
 mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
                               struct mlxsw_sp_bridge_device *bridge_device)
 {
+       mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
+                                           bridge_device->dev);
        list_del(&bridge_device->list);
        if (bridge_device->vlan_enabled)
                bridge->vlan_enabled_exists = false;
index 0ba0356ec4e6dcd47977436bfe228891c0114b55..9044496803e627e8a992fbcac23eb8e0201e1e76 100644 (file)
@@ -796,11 +796,10 @@ int nfp_flower_compile_action(struct nfp_app *app,
                              struct net_device *netdev,
                              struct nfp_fl_payload *nfp_flow)
 {
-       int act_len, act_cnt, err, tun_out_cnt, out_cnt;
+       int act_len, act_cnt, err, tun_out_cnt, out_cnt, i;
        enum nfp_flower_tun_type tun_type;
        const struct tc_action *a;
        u32 csum_updated = 0;
-       LIST_HEAD(actions);
 
        memset(nfp_flow->action_data, 0, NFP_FL_MAX_A_SIZ);
        nfp_flow->meta.act_len = 0;
@@ -810,8 +809,7 @@ int nfp_flower_compile_action(struct nfp_app *app,
        tun_out_cnt = 0;
        out_cnt = 0;
 
-       tcf_exts_to_list(flow->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, flow->exts) {
                err = nfp_flower_loop_action(app, a, flow, nfp_flow, &act_len,
                                             netdev, &tun_type, &tun_out_cnt,
                                             &out_cnt, &csum_updated);
index d9ab5add27a8bf06af92247b60158e6de2e316be..34193c2f169961a37617b84e675ee78df473d085 100644 (file)
@@ -407,7 +407,7 @@ static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
 
        if (i == QED_INIT_MAX_POLL_COUNT) {
                DP_ERR(p_hwfn,
-                      "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparsion %08x)]\n",
+                      "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
                       addr, le32_to_cpu(cmd->expected_val),
                       val, le32_to_cpu(cmd->op_data));
        }
index d89a0e22f6e4307896cae0383889c7b5b8f05c22..5d37ec7e9b0b7b2bc3785ec00ce2e23314b7c955 100644 (file)
@@ -48,7 +48,7 @@
 #include "qed_reg_addr.h"
 #include "qed_sriov.h"
 
-#define CHIP_MCP_RESP_ITER_US 10
+#define QED_MCP_RESP_ITER_US   10
 
 #define QED_DRV_MB_MAX_RETRIES (500 * 1000)    /* Account for 5 sec */
 #define QED_MCP_RESET_RETRIES  (50 * 1000)     /* Account for 500 msec */
@@ -183,18 +183,57 @@ int qed_mcp_free(struct qed_hwfn *p_hwfn)
        return 0;
 }
 
+/* Maximum of 1 sec to wait for the SHMEM ready indication */
+#define QED_MCP_SHMEM_RDY_MAX_RETRIES  20
+#define QED_MCP_SHMEM_RDY_ITER_MS      50
+
 static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        struct qed_mcp_info *p_info = p_hwfn->mcp_info;
+       u8 cnt = QED_MCP_SHMEM_RDY_MAX_RETRIES;
+       u8 msec = QED_MCP_SHMEM_RDY_ITER_MS;
        u32 drv_mb_offsize, mfw_mb_offsize;
        u32 mcp_pf_id = MCP_PF_ID(p_hwfn);
 
        p_info->public_base = qed_rd(p_hwfn, p_ptt, MISC_REG_SHARED_MEM_ADDR);
-       if (!p_info->public_base)
-               return 0;
+       if (!p_info->public_base) {
+               DP_NOTICE(p_hwfn,
+                         "The address of the MCP scratch-pad is not configured\n");
+               return -EINVAL;
+       }
 
        p_info->public_base |= GRCBASE_MCP;
 
+       /* Get the MFW MB address and number of supported messages */
+       mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
+                               SECTION_OFFSIZE_ADDR(p_info->public_base,
+                                                    PUBLIC_MFW_MB));
+       p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
+       p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt,
+                                           p_info->mfw_mb_addr +
+                                           offsetof(struct public_mfw_mb,
+                                                    sup_msgs));
+
+       /* The driver can notify that there was an MCP reset, and might read the
+        * SHMEM values before the MFW has completed initializing them.
+        * To avoid this, the "sup_msgs" field in the MFW mailbox is used as a
+        * data ready indication.
+        */
+       while (!p_info->mfw_mb_length && --cnt) {
+               msleep(msec);
+               p_info->mfw_mb_length =
+                       (u16)qed_rd(p_hwfn, p_ptt,
+                                   p_info->mfw_mb_addr +
+                                   offsetof(struct public_mfw_mb, sup_msgs));
+       }
+
+       if (!cnt) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to get the SHMEM ready notification after %d msec\n",
+                         QED_MCP_SHMEM_RDY_MAX_RETRIES * msec);
+               return -EBUSY;
+       }
+
        /* Calculate the driver and MFW mailbox address */
        drv_mb_offsize = qed_rd(p_hwfn, p_ptt,
                                SECTION_OFFSIZE_ADDR(p_info->public_base,
@@ -204,13 +243,6 @@ static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                   "drv_mb_offsiz = 0x%x, drv_mb_addr = 0x%x mcp_pf_id = 0x%x\n",
                   drv_mb_offsize, p_info->drv_mb_addr, mcp_pf_id);
 
-       /* Set the MFW MB address */
-       mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
-                               SECTION_OFFSIZE_ADDR(p_info->public_base,
-                                                    PUBLIC_MFW_MB));
-       p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
-       p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt, p_info->mfw_mb_addr);
-
        /* Get the current driver mailbox sequence before sending
         * the first command
         */
@@ -285,9 +317,15 @@ static void qed_mcp_reread_offsets(struct qed_hwfn *p_hwfn,
 
 int qed_mcp_reset(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 org_mcp_reset_seq, seq, delay = CHIP_MCP_RESP_ITER_US, cnt = 0;
+       u32 org_mcp_reset_seq, seq, delay = QED_MCP_RESP_ITER_US, cnt = 0;
        int rc = 0;
 
+       if (p_hwfn->mcp_info->b_block_cmd) {
+               DP_NOTICE(p_hwfn,
+                         "The MFW is not responsive. Avoid sending MCP_RESET mailbox command.\n");
+               return -EBUSY;
+       }
+
        /* Ensure that only a single thread is accessing the mailbox */
        spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
 
@@ -413,14 +451,41 @@ static void __qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                   (p_mb_params->cmd | seq_num), p_mb_params->param);
 }
 
+static void qed_mcp_cmd_set_blocking(struct qed_hwfn *p_hwfn, bool block_cmd)
+{
+       p_hwfn->mcp_info->b_block_cmd = block_cmd;
+
+       DP_INFO(p_hwfn, "%s sending of mailbox commands to the MFW\n",
+               block_cmd ? "Block" : "Unblock");
+}
+
+static void qed_mcp_print_cpu_info(struct qed_hwfn *p_hwfn,
+                                  struct qed_ptt *p_ptt)
+{
+       u32 cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2;
+       u32 delay = QED_MCP_RESP_ITER_US;
+
+       cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
+       cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
+       cpu_pc_0 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+       udelay(delay);
+       cpu_pc_1 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+       udelay(delay);
+       cpu_pc_2 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+
+       DP_NOTICE(p_hwfn,
+                 "MCP CPU info: mode 0x%08x, state 0x%08x, pc {0x%08x, 0x%08x, 0x%08x}\n",
+                 cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2);
+}
+
 static int
 _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                       struct qed_ptt *p_ptt,
                       struct qed_mcp_mb_params *p_mb_params,
-                      u32 max_retries, u32 delay)
+                      u32 max_retries, u32 usecs)
 {
+       u32 cnt = 0, msecs = DIV_ROUND_UP(usecs, 1000);
        struct qed_mcp_cmd_elem *p_cmd_elem;
-       u32 cnt = 0;
        u16 seq_num;
        int rc = 0;
 
@@ -443,7 +508,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                        goto err;
 
                spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
-               udelay(delay);
+
+               if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+                       msleep(msecs);
+               else
+                       udelay(usecs);
        } while (++cnt < max_retries);
 
        if (cnt >= max_retries) {
@@ -472,7 +541,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                 * The spinlock stays locked until the list element is removed.
                 */
 
-               udelay(delay);
+               if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+                       msleep(msecs);
+               else
+                       udelay(usecs);
+
                spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
 
                if (p_cmd_elem->b_is_completed)
@@ -491,11 +564,15 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                DP_NOTICE(p_hwfn,
                          "The MFW failed to respond to command 0x%08x [param 0x%08x].\n",
                          p_mb_params->cmd, p_mb_params->param);
+               qed_mcp_print_cpu_info(p_hwfn, p_ptt);
 
                spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
                qed_mcp_cmd_del_elem(p_hwfn, p_cmd_elem);
                spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
 
+               if (!QED_MB_FLAGS_IS_SET(p_mb_params, AVOID_BLOCK))
+                       qed_mcp_cmd_set_blocking(p_hwfn, true);
+
                return -EAGAIN;
        }
 
@@ -507,7 +584,7 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                   "MFW mailbox: response 0x%08x param 0x%08x [after %d.%03d ms]\n",
                   p_mb_params->mcp_resp,
                   p_mb_params->mcp_param,
-                  (cnt * delay) / 1000, (cnt * delay) % 1000);
+                  (cnt * usecs) / 1000, (cnt * usecs) % 1000);
 
        /* Clear the sequence number from the MFW response */
        p_mb_params->mcp_resp &= FW_MSG_CODE_MASK;
@@ -525,7 +602,7 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
 {
        size_t union_data_size = sizeof(union drv_union_data);
        u32 max_retries = QED_DRV_MB_MAX_RETRIES;
-       u32 delay = CHIP_MCP_RESP_ITER_US;
+       u32 usecs = QED_MCP_RESP_ITER_US;
 
        /* MCP not initialized */
        if (!qed_mcp_is_init(p_hwfn)) {
@@ -533,6 +610,13 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                return -EBUSY;
        }
 
+       if (p_hwfn->mcp_info->b_block_cmd) {
+               DP_NOTICE(p_hwfn,
+                         "The MFW is not responsive. Avoid sending mailbox command 0x%08x [param 0x%08x].\n",
+                         p_mb_params->cmd, p_mb_params->param);
+               return -EBUSY;
+       }
+
        if (p_mb_params->data_src_size > union_data_size ||
            p_mb_params->data_dst_size > union_data_size) {
                DP_ERR(p_hwfn,
@@ -542,8 +626,13 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                return -EINVAL;
        }
 
+       if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP)) {
+               max_retries = DIV_ROUND_UP(max_retries, 1000);
+               usecs *= 1000;
+       }
+
        return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params, max_retries,
-                                     delay);
+                                     usecs);
 }
 
 int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
@@ -761,6 +850,7 @@ __qed_mcp_load_req(struct qed_hwfn *p_hwfn,
        mb_params.data_src_size = sizeof(load_req);
        mb_params.p_data_dst = &load_rsp;
        mb_params.data_dst_size = sizeof(load_rsp);
+       mb_params.flags = QED_MB_FLAG_CAN_SLEEP | QED_MB_FLAG_AVOID_BLOCK;
 
        DP_VERBOSE(p_hwfn, QED_MSG_SP,
                   "Load Request: param 0x%08x [init_hw %d, drv_type %d, hsi_ver %d, pda 0x%04x]\n",
@@ -982,7 +1072,8 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
 
 int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 wol_param, mcp_resp, mcp_param;
+       struct qed_mcp_mb_params mb_params;
+       u32 wol_param;
 
        switch (p_hwfn->cdev->wol_config) {
        case QED_OV_WOL_DISABLED:
@@ -1000,8 +1091,12 @@ int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                wol_param = DRV_MB_PARAM_UNLOAD_WOL_MCP;
        }
 
-       return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_UNLOAD_REQ, wol_param,
-                          &mcp_resp, &mcp_param);
+       memset(&mb_params, 0, sizeof(mb_params));
+       mb_params.cmd = DRV_MSG_CODE_UNLOAD_REQ;
+       mb_params.param = wol_param;
+       mb_params.flags = QED_MB_FLAG_CAN_SLEEP | QED_MB_FLAG_AVOID_BLOCK;
+
+       return qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
 }
 
 int qed_mcp_unload_done(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
@@ -2077,31 +2172,65 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
        return rc;
 }
 
+/* A maximal 100 msec waiting time for the MCP to halt */
+#define QED_MCP_HALT_SLEEP_MS          10
+#define QED_MCP_HALT_MAX_RETRIES       10
+
 int qed_mcp_halt(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 resp = 0, param = 0;
+       u32 resp = 0, param = 0, cpu_state, cnt = 0;
        int rc;
 
        rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MCP_HALT, 0, &resp,
                         &param);
-       if (rc)
+       if (rc) {
                DP_ERR(p_hwfn, "MCP response failure, aborting\n");
+               return rc;
+       }
 
-       return rc;
+       do {
+               msleep(QED_MCP_HALT_SLEEP_MS);
+               cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
+               if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED)
+                       break;
+       } while (++cnt < QED_MCP_HALT_MAX_RETRIES);
+
+       if (cnt == QED_MCP_HALT_MAX_RETRIES) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to halt the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
+                         qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE), cpu_state);
+               return -EBUSY;
+       }
+
+       qed_mcp_cmd_set_blocking(p_hwfn, true);
+
+       return 0;
 }
 
+#define QED_MCP_RESUME_SLEEP_MS        10
+
 int qed_mcp_resume(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 value, cpu_mode;
+       u32 cpu_mode, cpu_state;
 
        qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_STATE, 0xffffffff);
 
-       value = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
-       value &= ~MCP_REG_CPU_MODE_SOFT_HALT;
-       qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, value);
        cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
+       cpu_mode &= ~MCP_REG_CPU_MODE_SOFT_HALT;
+       qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, cpu_mode);
+       msleep(QED_MCP_RESUME_SLEEP_MS);
+       cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
 
-       return (cpu_mode & MCP_REG_CPU_MODE_SOFT_HALT) ? -EAGAIN : 0;
+       if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to resume the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
+                         cpu_mode, cpu_state);
+               return -EBUSY;
+       }
+
+       qed_mcp_cmd_set_blocking(p_hwfn, false);
+
+       return 0;
 }
 
 int qed_mcp_ov_update_current_config(struct qed_hwfn *p_hwfn,
index 047976d5c6e962e19323bd5fb6ce99abbd92aa2e..85e6b3989e7a913c7157f27ff27469e6cbf1f3aa 100644 (file)
@@ -635,11 +635,14 @@ struct qed_mcp_info {
         */
        spinlock_t                              cmd_lock;
 
+       /* Flag to indicate whether sending a MFW mailbox command is blocked */
+       bool                                    b_block_cmd;
+
        /* Spinlock used for syncing SW link-changes and link-changes
         * originating from attention context.
         */
        spinlock_t                              link_lock;
-       bool                                    block_mb_sending;
+
        u32                                     public_base;
        u32                                     drv_mb_addr;
        u32                                     mfw_mb_addr;
@@ -660,14 +663,20 @@ struct qed_mcp_info {
 };
 
 struct qed_mcp_mb_params {
-       u32                     cmd;
-       u32                     param;
-       void                    *p_data_src;
-       u8                      data_src_size;
-       void                    *p_data_dst;
-       u8                      data_dst_size;
-       u32                     mcp_resp;
-       u32                     mcp_param;
+       u32 cmd;
+       u32 param;
+       void *p_data_src;
+       void *p_data_dst;
+       u8 data_src_size;
+       u8 data_dst_size;
+       u32 mcp_resp;
+       u32 mcp_param;
+       u32 flags;
+#define QED_MB_FLAG_CAN_SLEEP  (0x1 << 0)
+#define QED_MB_FLAG_AVOID_BLOCK        (0x1 << 1)
+#define QED_MB_FLAGS_IS_SET(params, flag) \
+       ({ typeof(params) __params = (params); \
+          (__params && (__params->flags & QED_MB_FLAG_ ## flag)); })
 };
 
 struct qed_drv_tlv_hdr {
index d8ad2dcad8d5ef589252eb797556359ebe89fbcb..f736f70956fd3763f3f94bffa0e009dec28b9516 100644 (file)
        0
 #define MCP_REG_CPU_STATE \
        0xe05004UL
+#define MCP_REG_CPU_STATE_SOFT_HALTED  (0x1UL << 10)
 #define MCP_REG_CPU_EVENT_MASK \
        0xe05008UL
+#define MCP_REG_CPU_PROGRAM_COUNTER    0xe0501cUL
 #define PGLUE_B_REG_PF_BAR0_SIZE \
        0x2aae60UL
 #define PGLUE_B_REG_PF_BAR1_SIZE \
index 9673d19308e65c37a7ad42e5752ac9f8238b7d4f..b16ce7d93caff5802e41b79ecb8e8b8e5fc78ed5 100644 (file)
@@ -2006,18 +2006,16 @@ unlock:
 static int qede_parse_actions(struct qede_dev *edev,
                              struct tcf_exts *exts)
 {
-       int rc = -EINVAL, num_act = 0;
+       int rc = -EINVAL, num_act = 0, i;
        const struct tc_action *a;
        bool is_drop = false;
-       LIST_HEAD(actions);
 
        if (!tcf_exts_has_actions(exts)) {
                DP_NOTICE(edev, "No tc actions received\n");
                return rc;
        }
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                num_act++;
 
                if (is_tcf_gact_shot(a))
index 353f1c129af1e247e1a8ddaa6d316edfc285682d..059ba9429e51a3193f3af73c16a20ce94ef42844 100644 (file)
@@ -2384,26 +2384,20 @@ static int qlge_update_hw_vlan_features(struct net_device *ndev,
        return status;
 }
 
-static netdev_features_t qlge_fix_features(struct net_device *ndev,
-       netdev_features_t features)
-{
-       int err;
-
-       /* Update the behavior of vlan accel in the adapter */
-       err = qlge_update_hw_vlan_features(ndev, features);
-       if (err)
-               return err;
-
-       return features;
-}
-
 static int qlge_set_features(struct net_device *ndev,
        netdev_features_t features)
 {
        netdev_features_t changed = ndev->features ^ features;
+       int err;
+
+       if (changed & NETIF_F_HW_VLAN_CTAG_RX) {
+               /* Update the behavior of vlan accel in the adapter */
+               err = qlge_update_hw_vlan_features(ndev, features);
+               if (err)
+                       return err;
 
-       if (changed & NETIF_F_HW_VLAN_CTAG_RX)
                qlge_vlan_mode(ndev, features);
+       }
 
        return 0;
 }
@@ -4719,7 +4713,6 @@ static const struct net_device_ops qlge_netdev_ops = {
        .ndo_set_mac_address    = qlge_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = qlge_tx_timeout,
-       .ndo_fix_features       = qlge_fix_features,
        .ndo_set_features       = qlge_set_features,
        .ndo_vlan_rx_add_vid    = qlge_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = qlge_vlan_rx_kill_vid,
index b81f4faf7b10114df1f17a0c0d80881e8ea9c5ea..1470fc12282b255181838457ff6a07a362e3e321 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /* Renesas Ethernet AVB device driver
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
@@ -5,10 +6,6 @@
  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  *
  * Based on the SuperH Ethernet driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
  */
 
 #ifndef __RAVB_H__
index c06f2df895c2c3e432fc8341f15cc77b0550db11..aff5516b781e27067efc9c1cca19f11bea19dd19 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /* Renesas Ethernet AVB device driver
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
@@ -5,10 +6,6 @@
  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  *
  * Based on the SuperH Ethernet driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
  */
 
 #include <linux/cache.h>
index 5573199c4536c283164351ca17d4377ad5a6c6a2..ad4433d592377a9ee2b65753cf61f02735f90518 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*  SuperH Ethernet device driver
  *
  *  Copyright (C) 2014 Renesas Electronics Corporation
@@ -5,18 +6,6 @@
  *  Copyright (C) 2008-2014 Renesas Solutions Corp.
  *  Copyright (C) 2013-2017 Cogent Embedded, Inc.
  *  Copyright (C) 2014 Codethink Limited
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
  */
 
 #include <linux/module.h>
index f94be99cf4002190347014d7643387883556981a..0c18650bbfe69f7c22a78a87b1c263bd4f2e15e5 100644 (file)
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*  SuperH Ethernet device driver
  *
  *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
  *  Copyright (C) 2008-2012 Renesas Solutions Corp.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
  */
 
 #ifndef __SH_ETH_H__
index edf20361ea5f15c7ddee617f899e31b92d7e261e..bf4acebb6bcddd8807041a75c000251bbc28f19d 100644 (file)
@@ -33,7 +33,7 @@ config DWMAC_DWC_QOS_ETH
        select PHYLIB
        select CRC32
        select MII
-       depends on OF && COMMON_CLK && HAS_DMA
+       depends on OF && HAS_DMA
        help
          Support for chips using the snps,dwc-qos-ethernet.txt DT binding.
 
@@ -57,7 +57,7 @@ config DWMAC_ANARION
 config DWMAC_IPQ806X
        tristate "QCA IPQ806x DWMAC support"
        default ARCH_QCOM
-       depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
+       depends on OF && (ARCH_QCOM || COMPILE_TEST)
        select MFD_SYSCON
        help
          Support for QCA IPQ806X DWMAC Ethernet.
@@ -100,7 +100,7 @@ config DWMAC_OXNAS
 config DWMAC_ROCKCHIP
        tristate "Rockchip dwmac support"
        default ARCH_ROCKCHIP
-       depends on OF && COMMON_CLK && (ARCH_ROCKCHIP || COMPILE_TEST)
+       depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
        select MFD_SYSCON
        help
          Support for Ethernet controller on Rockchip RK3288 SoC.
@@ -123,7 +123,7 @@ config DWMAC_SOCFPGA
 config DWMAC_STI
        tristate "STi GMAC support"
        default ARCH_STI
-       depends on OF && COMMON_CLK && (ARCH_STI || COMPILE_TEST)
+       depends on OF && (ARCH_STI || COMPILE_TEST)
        select MFD_SYSCON
        ---help---
          Support for ethernet controller on STi SOCs.
@@ -147,7 +147,7 @@ config DWMAC_STM32
 config DWMAC_SUNXI
        tristate "Allwinner GMAC support"
        default ARCH_SUNXI
-       depends on OF && COMMON_CLK && (ARCH_SUNXI || COMPILE_TEST)
+       depends on OF && (ARCH_SUNXI || COMPILE_TEST)
        ---help---
          Support for Allwinner A20/A31 GMAC ethernet controllers.
 
index 1a96dd9c1091e6c515753132c4a3fd0128f41bdf..531294f4978bc42bbb0e3cb0177b1312a33bef61 100644 (file)
@@ -61,7 +61,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry,
        struct stmmac_tc_entry *action_entry = entry;
        const struct tc_action *act;
        struct tcf_exts *exts;
-       LIST_HEAD(actions);
+       int i;
 
        exts = cls->knode.exts;
        if (!tcf_exts_has_actions(exts))
@@ -69,8 +69,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry,
        if (frag)
                action_entry = frag;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(act, &actions, list) {
+       tcf_exts_for_each_action(i, act, exts) {
                /* Accept */
                if (is_tcf_gact_ok(act)) {
                        action_entry->val.af = 1;
index 507f68190cb1b4cbf88b8a441a040f8aacafd1d4..1121a1ec407cd0951e938572fd27c4fa93ca3c85 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/pci.h>
 #include <linux/skbuff.h>
 #include <linux/if_vlan.h>
 #include <linux/in.h>
@@ -2039,12 +2040,16 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
 {
        struct net_device *ndev;
        struct net_device_context *net_device_ctx;
+       struct device *pdev = vf_netdev->dev.parent;
        struct netvsc_device *netvsc_dev;
        int ret;
 
        if (vf_netdev->addr_len != ETH_ALEN)
                return NOTIFY_DONE;
 
+       if (!pdev || !dev_is_pci(pdev) || dev_is_pf(pdev))
+               return NOTIFY_DONE;
+
        /*
         * We will use the MAC address to locate the synthetic interface to
         * associate with the VF interface. If we don't find a matching
index 97742708460bc8a415713537ff90060c07b07d27..2cd71bdb6484c774659598fff1e99cd49181337b 100644 (file)
@@ -5217,8 +5217,8 @@ static int rtl8152_probe(struct usb_interface *intf,
                netdev->hw_features &= ~NETIF_F_RXCSUM;
        }
 
-       if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 &&
-           udev->serial && !strcmp(udev->serial, "000001000000")) {
+       if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial &&
+           (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) {
                dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation");
                set_bit(DELL_TB_RX_AGG_BUG, &tp->flags);
        }
index 1b9951d2067e631de9115b1845dcc2e050069c0e..d668682f91dfdb3428e02a44df2c8ade9ccf0042 100644 (file)
@@ -316,6 +316,14 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
                old_value = *dbbuf_db;
                *dbbuf_db = value;
 
+               /*
+                * Ensure that the doorbell is updated before reading the event
+                * index from memory.  The controller needs to provide similar
+                * ordering to ensure the envent index is updated before reading
+                * the doorbell.
+                */
+               mb();
+
                if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
                        return false;
        }
index ebf3e7a6c49ee27003c1e667501eb9d5441791d0..b5ec96abd04870209ed7ea97452180cf6cb63038 100644 (file)
@@ -1210,7 +1210,7 @@ static int __init nvmet_init(void)
 
        error = nvmet_init_discovery();
        if (error)
-               goto out;
+               goto out_free_work_queue;
 
        error = nvmet_init_configfs();
        if (error)
@@ -1219,6 +1219,8 @@ static int __init nvmet_init(void)
 
 out_exit_discovery:
        nvmet_exit_discovery();
+out_free_work_queue:
+       destroy_workqueue(buffered_io_wq);
 out:
        return error;
 }
index 34712def81b15a566bb16a7e320ec7012796cf27..5251689a1d9ac2e5a5852c724f7f54d2ec80801c 100644 (file)
@@ -311,7 +311,7 @@ fcloop_tgt_lsrqst_done_work(struct work_struct *work)
        struct fcloop_tport *tport = tls_req->tport;
        struct nvmefc_ls_req *lsreq = tls_req->lsreq;
 
-       if (tport->remoteport)
+       if (!tport || tport->remoteport)
                lsreq->done(lsreq, tls_req->status);
 }
 
@@ -329,6 +329,7 @@ fcloop_ls_req(struct nvme_fc_local_port *localport,
 
        if (!rport->targetport) {
                tls_req->status = -ECONNREFUSED;
+               tls_req->tport = NULL;
                schedule_work(&tls_req->work);
                return ret;
        }
index 977a8307fbb1a4e0d66cb1c619834472bfe0d1ea..4f28165592056d5ec90309c5bff737f5ba66ea0b 100644 (file)
@@ -260,10 +260,13 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
 
        mutex_lock(&tz->lock);
 
-       if (mode == THERMAL_DEVICE_ENABLED)
+       if (mode == THERMAL_DEVICE_ENABLED) {
                tz->polling_delay = data->polling_delay;
-       else
+               tz->passive_delay = data->passive_delay;
+       } else {
                tz->polling_delay = 0;
+               tz->passive_delay = 0;
+       }
 
        mutex_unlock(&tz->lock);
 
index c866cc1659606726584e47b6e74ff59fe2d6aa51..450ed66edf582b4c6c77e3a376a17173cfdf57b9 100644 (file)
@@ -1,16 +1,6 @@
-/*
- * Copyright 2016 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2016 Freescale Semiconductor, Inc.
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -197,7 +187,7 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        int ret;
        struct qoriq_tmu_data *data;
        struct device_node *np = pdev->dev.of_node;
-       u32 site = 0;
+       u32 site;
 
        if (!np) {
                dev_err(&pdev->dev, "Device OF-Node is NULL");
@@ -233,8 +223,9 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_tmu;
 
-       data->tz = thermal_zone_of_sensor_register(&pdev->dev, data->sensor_id,
-                               data, &tmu_tz_ops);
+       data->tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
+                                                       data->sensor_id,
+                                                       data, &tmu_tz_ops);
        if (IS_ERR(data->tz)) {
                ret = PTR_ERR(data->tz);
                dev_err(&pdev->dev,
@@ -243,7 +234,7 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        }
 
        /* Enable monitoring */
-       site |= 0x1 << (15 - data->sensor_id);
+       site = 0x1 << (15 - data->sensor_id);
        tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
 
        return 0;
@@ -261,8 +252,6 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
 {
        struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
 
-       thermal_zone_of_sensor_unregister(&pdev->dev, data->tz);
-
        /* Disable monitoring */
        tmu_write(data, TMR_DISABLE, &data->regs->tmr);
 
index 766521eb70715a1ff6c9a6b93434ec47d8716c49..7aed5337bdd35b3b3214372e7d5f9a01cf26789c 100644 (file)
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  R-Car Gen3 THS thermal sensor driver
  *  Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
  *
  * Copyright (C) 2016 Renesas Electronics Corporation.
  * Copyright (C) 2016 Sang Engineering
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
  */
 #include <linux/delay.h>
 #include <linux/err.h>
index e77e63070e998e1d997537ca88da1e7dd4ea533c..78f932822d381c9dbc013aee618be56e533baaab 100644 (file)
@@ -1,21 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  R-Car THS/TSC thermal sensor driver
  *
  * Copyright (C) 2012 Renesas Solutions Corp.
  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -660,6 +648,6 @@ static struct platform_driver rcar_thermal_driver = {
 };
 module_platform_driver(rcar_thermal_driver);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
index 96c1d8400822a3d852553e5baddaaed9907d7f71..b13c6b4b2c665a332a40aeada1eaa1e421d9a4aa 100644 (file)
@@ -952,7 +952,7 @@ static void vhost_iotlb_notify_vq(struct vhost_dev *d,
        list_for_each_entry_safe(node, n, &d->pending_list, node) {
                struct vhost_iotlb_msg *vq_msg = &node->msg.iotlb;
                if (msg->iova <= vq_msg->iova &&
-                   msg->iova + msg->size - 1 > vq_msg->iova &&
+                   msg->iova + msg->size - 1 >= vq_msg->iova &&
                    vq_msg->type == VHOST_IOTLB_MISS) {
                        vhost_poll_queue(&node->vq->poll);
                        list_del(&node->node);
index ec3fba7d492f483e14accbfd98d5b63550f2591c..488a9e7f8f66020f4424b322db62eacdcbbdd057 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mpage.h>
 #include <linux/user_namespace.h>
 #include <linux/seq_file.h>
+#include <linux/blkdev.h>
 
 #include "isofs.h"
 #include "zisofs.h"
@@ -653,6 +654,12 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
        /*
         * What if bugger tells us to go beyond page size?
         */
+       if (bdev_logical_block_size(s->s_bdev) > 2048) {
+               printk(KERN_WARNING
+                      "ISOFS: unsupported/invalid hardware sector size %d\n",
+                       bdev_logical_block_size(s->s_bdev));
+               goto out_freesbi;
+       }
        opt.blocksize = sb_min_blocksize(s, opt.blocksize);
 
        sbi->s_high_sierra = 0; /* default is iso9660 */
index 05506d60131c69d546f574e9633f7d01039c70c6..59cdb27826defe2ddac7023438132c1b80a49c29 100644 (file)
@@ -132,13 +132,13 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
        struct fsnotify_mark *mark;
 
        assert_spin_locked(&conn->lock);
+       /* We can get detached connector here when inode is getting unlinked. */
+       if (!fsnotify_valid_obj_type(conn->type))
+               return;
        hlist_for_each_entry(mark, &conn->list, obj_list) {
                if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
                        new_mask |= mark->mask;
        }
-       if (WARN_ON(!fsnotify_valid_obj_type(conn->type)))
-               return;
-
        *fsnotify_conn_mask_p(conn) = new_mask;
 }
 
index 860bfbe7a07aa5b9a4491365b48655122fa5eb60..f0cbf58ad4dade2129c19d5dba42c8bb4eed276d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/quotaops.h>
 #include <linux/types.h>
 #include <linux/writeback.h>
+#include <linux/nospec.h>
 
 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
                                     qid_t id)
@@ -120,8 +121,6 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
        struct if_dqinfo uinfo;
        int ret;
 
-       /* This checks whether qc_state has enough entries... */
-       BUILD_BUG_ON(MAXQUOTAS > XQM_MAXQUOTAS);
        if (!sb->s_qcop->get_state)
                return -ENOSYS;
        ret = sb->s_qcop->get_state(sb, &state);
@@ -354,10 +353,10 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
         * GETXSTATE quotactl has space for just one set of time limits so
         * report them for the first enabled quota type
         */
-       for (type = 0; type < XQM_MAXQUOTAS; type++)
+       for (type = 0; type < MAXQUOTAS; type++)
                if (state.s_state[type].flags & QCI_ACCT_ENABLED)
                        break;
-       BUG_ON(type == XQM_MAXQUOTAS);
+       BUG_ON(type == MAXQUOTAS);
        fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
        fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
        fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
@@ -427,10 +426,10 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
         * GETXSTATV quotactl has space for just one set of time limits so
         * report them for the first enabled quota type
         */
-       for (type = 0; type < XQM_MAXQUOTAS; type++)
+       for (type = 0; type < MAXQUOTAS; type++)
                if (state.s_state[type].flags & QCI_ACCT_ENABLED)
                        break;
-       BUG_ON(type == XQM_MAXQUOTAS);
+       BUG_ON(type == MAXQUOTAS);
        fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
        fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
        fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
@@ -701,8 +700,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 {
        int ret;
 
-       if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
+       if (type >= MAXQUOTAS)
                return -EINVAL;
+       type = array_index_nospec(type, MAXQUOTAS);
        /*
         * Quota not supported on this fs? Check this before s_quota_types
         * since they needn't be set if quota is not supported at all.
index 3040dc2a32f6a17a4822343497577e871b03161c..6f515651a2c2fe3817c763e3d77d351509a862d9 100644 (file)
@@ -764,9 +764,7 @@ static int udf_find_fileset(struct super_block *sb,
                            struct kernel_lb_addr *root)
 {
        struct buffer_head *bh = NULL;
-       long lastblock;
        uint16_t ident;
-       struct udf_sb_info *sbi;
 
        if (fileset->logicalBlockNum != 0xFFFFFFFF ||
            fileset->partitionReferenceNum != 0xFFFF) {
@@ -779,69 +777,11 @@ static int udf_find_fileset(struct super_block *sb,
                        return 1;
                }
 
-       }
-
-       sbi = UDF_SB(sb);
-       if (!bh) {
-               /* Search backwards through the partitions */
-               struct kernel_lb_addr newfileset;
-
-/* --> cvg: FIXME - is it reasonable? */
-               return 1;
-
-               for (newfileset.partitionReferenceNum = sbi->s_partitions - 1;
-                    (newfileset.partitionReferenceNum != 0xFFFF &&
-                     fileset->logicalBlockNum == 0xFFFFFFFF &&
-                     fileset->partitionReferenceNum == 0xFFFF);
-                    newfileset.partitionReferenceNum--) {
-                       lastblock = sbi->s_partmaps
-                                       [newfileset.partitionReferenceNum]
-                                               .s_partition_len;
-                       newfileset.logicalBlockNum = 0;
-
-                       do {
-                               bh = udf_read_ptagged(sb, &newfileset, 0,
-                                                     &ident);
-                               if (!bh) {
-                                       newfileset.logicalBlockNum++;
-                                       continue;
-                               }
-
-                               switch (ident) {
-                               case TAG_IDENT_SBD:
-                               {
-                                       struct spaceBitmapDesc *sp;
-                                       sp = (struct spaceBitmapDesc *)
-                                                               bh->b_data;
-                                       newfileset.logicalBlockNum += 1 +
-                                               ((le32_to_cpu(sp->numOfBytes) +
-                                                 sizeof(struct spaceBitmapDesc)
-                                                 - 1) >> sb->s_blocksize_bits);
-                                       brelse(bh);
-                                       break;
-                               }
-                               case TAG_IDENT_FSD:
-                                       *fileset = newfileset;
-                                       break;
-                               default:
-                                       newfileset.logicalBlockNum++;
-                                       brelse(bh);
-                                       bh = NULL;
-                                       break;
-                               }
-                       } while (newfileset.logicalBlockNum < lastblock &&
-                                fileset->logicalBlockNum == 0xFFFFFFFF &&
-                                fileset->partitionReferenceNum == 0xFFFF);
-               }
-       }
-
-       if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
-            fileset->partitionReferenceNum != 0xFFFF) && bh) {
                udf_debug("Fileset at block=%u, partition=%u\n",
                          fileset->logicalBlockNum,
                          fileset->partitionReferenceNum);
 
-               sbi->s_partition = fileset->partitionReferenceNum;
+               UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
                udf_load_fileset(sb, bh, root);
                brelse(bh);
                return 0;
@@ -1570,10 +1510,16 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
  */
 #define PART_DESC_ALLOC_STEP 32
 
+struct part_desc_seq_scan_data {
+       struct udf_vds_record rec;
+       u32 partnum;
+};
+
 struct desc_seq_scan_data {
        struct udf_vds_record vds[VDS_POS_LENGTH];
        unsigned int size_part_descs;
-       struct udf_vds_record *part_descs_loc;
+       unsigned int num_part_descs;
+       struct part_desc_seq_scan_data *part_descs_loc;
 };
 
 static struct udf_vds_record *handle_partition_descriptor(
@@ -1582,10 +1528,14 @@ static struct udf_vds_record *handle_partition_descriptor(
 {
        struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
        int partnum;
+       int i;
 
        partnum = le16_to_cpu(desc->partitionNumber);
-       if (partnum >= data->size_part_descs) {
-               struct udf_vds_record *new_loc;
+       for (i = 0; i < data->num_part_descs; i++)
+               if (partnum == data->part_descs_loc[i].partnum)
+                       return &(data->part_descs_loc[i].rec);
+       if (data->num_part_descs >= data->size_part_descs) {
+               struct part_desc_seq_scan_data *new_loc;
                unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
 
                new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
@@ -1597,7 +1547,7 @@ static struct udf_vds_record *handle_partition_descriptor(
                data->part_descs_loc = new_loc;
                data->size_part_descs = new_size;
        }
-       return &(data->part_descs_loc[partnum]);
+       return &(data->part_descs_loc[data->num_part_descs++].rec);
 }
 
 
@@ -1647,6 +1597,7 @@ static noinline int udf_process_sequence(
 
        memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
        data.size_part_descs = PART_DESC_ALLOC_STEP;
+       data.num_part_descs = 0;
        data.part_descs_loc = kcalloc(data.size_part_descs,
                                      sizeof(*data.part_descs_loc),
                                      GFP_KERNEL);
@@ -1658,7 +1609,6 @@ static noinline int udf_process_sequence(
         * are in it.
         */
        for (; (!done && block <= lastblock); block++) {
-
                bh = udf_read_tagged(sb, block, block, &ident);
                if (!bh)
                        break;
@@ -1730,13 +1680,10 @@ static noinline int udf_process_sequence(
        }
 
        /* Now handle prevailing Partition Descriptors */
-       for (i = 0; i < data.size_part_descs; i++) {
-               if (data.part_descs_loc[i].block) {
-                       ret = udf_load_partdesc(sb,
-                                               data.part_descs_loc[i].block);
-                       if (ret < 0)
-                               return ret;
-               }
+       for (i = 0; i < data.num_part_descs; i++) {
+               ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
+               if (ret < 0)
+                       return ret;
        }
 
        return 0;
index b79387fd57da9c2673aee5db81fb4fa2e74ffea8..65b4eaed1d965ca193407f9209a62310a51aafb1 100644 (file)
@@ -855,7 +855,7 @@ static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
 }
 
 u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold);
-void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf);
+void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred);
 
 int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
 /**
index 9abc0ca7259b78d5400166dbafd81825ca05b915..9f0aa1b48c7849ae4fd7545bfbf5d8b5a3db102e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for Texas Instruments INA219, INA226 power monitor chips
  *
- * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
index ca9772c8e48b0652cf1cfa0929d037cff1e846f3..f32dd270b8e3f26a91cb6b10cdd7ac3dbb2cf6e8 100644 (file)
@@ -408,13 +408,7 @@ struct qc_type_state {
 
 struct qc_state {
        unsigned int s_incoredqs;       /* Number of dquots in core */
-       /*
-        * Per quota type information. The array should really have
-        * max(MAXQUOTAS, XQM_MAXQUOTAS) entries. BUILD_BUG_ON in
-        * quota_getinfo() makes sure XQM_MAXQUOTAS is large enough.  Once VFS
-        * supports project quotas, this can be changed to MAXQUOTAS
-        */
-       struct qc_type_state s_state[XQM_MAXQUOTAS];
+       struct qc_type_state s_state[MAXQUOTAS];  /* Per quota type information */
 };
 
 /* Structure for communicating via ->set_info */
index 1ad5b19e83a95d0a4ba17181f1f55134022791f1..970303448c9029e2aaab37e3735bc83e0490de04 100644 (file)
@@ -23,13 +23,11 @@ struct tc_action {
        const struct tc_action_ops      *ops;
        __u32                           type; /* for backward compat(TCA_OLD_COMPAT) */
        __u32                           order;
-       struct list_head                list;
        struct tcf_idrinfo              *idrinfo;
 
        u32                             tcfa_index;
        refcount_t                      tcfa_refcnt;
        atomic_t                        tcfa_bindcnt;
-       u32                             tcfa_capab;
        int                             tcfa_action;
        struct tcf_t                    tcfa_tm;
        struct gnet_stats_basic_packed  tcfa_bstats;
@@ -44,7 +42,6 @@ struct tc_action {
 #define tcf_index      common.tcfa_index
 #define tcf_refcnt     common.tcfa_refcnt
 #define tcf_bindcnt    common.tcfa_bindcnt
-#define tcf_capab      common.tcfa_capab
 #define tcf_action     common.tcfa_action
 #define tcf_tm         common.tcfa_tm
 #define tcf_bstats     common.tcfa_bstats
@@ -102,7 +99,6 @@ struct tc_action_ops {
        size_t  (*get_fill_size)(const struct tc_action *act);
        struct net_device *(*get_dev)(const struct tc_action *a);
        void    (*put_dev)(struct net_device *dev);
-       int     (*delete)(struct net *net, u32 index);
 };
 
 struct tc_action_net {
@@ -148,8 +144,6 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
                       const struct tc_action_ops *ops,
                       struct netlink_ext_ack *extack);
 int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
-bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
-                   int bind);
 int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
                   struct tc_action **a, const struct tc_action_ops *ops,
                   int bind, bool cpustats);
@@ -158,7 +152,6 @@ void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a);
 void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
 int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
                        struct tc_action **a, int bind);
-int tcf_idr_delete_index(struct tc_action_net *tn, u32 index);
 int __tcf_idr_release(struct tc_action *a, bool bind, bool strict);
 
 static inline int tcf_idr_release(struct tc_action *a, bool bind)
index ef727f71336e7e5f89d92000194bcfab4bacc5a8..75a3f3fdb3591720d266fd33d98c608fc673b6ca 100644 (file)
@@ -298,19 +298,13 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts)
 #endif
 }
 
-static inline void tcf_exts_to_list(const struct tcf_exts *exts,
-                                   struct list_head *actions)
-{
 #ifdef CONFIG_NET_CLS_ACT
-       int i;
-
-       for (i = 0; i < exts->nr_actions; i++) {
-               struct tc_action *a = exts->actions[i];
-
-               list_add_tail(&a->list, actions);
-       }
+#define tcf_exts_for_each_action(i, a, exts) \
+       for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = (exts)->actions[i]); i++)
+#else
+#define tcf_exts_for_each_action(i, a, exts) \
+       for (; 0; (void)(i), (void)(a), (void)(exts))
 #endif
-}
 
 static inline void
 tcf_exts_stats_update(const struct tcf_exts *exts,
@@ -361,6 +355,15 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
 #endif
 }
 
+static inline struct tc_action *tcf_exts_first_action(struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+       return exts->actions[0];
+#else
+       return NULL;
+#endif
+}
+
 /**
  * tcf_exts_exec - execute tc filter extensions
  * @skb: socket buffer
index 04b8eda94e7d5f3f6c5b89655d808653c7479bbd..03cc59ee9c9536b885d605027af093c3dd0634ee 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/jhash.h>
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
+#include <linux/random.h>
 #include <uapi/linux/btf.h>
 #include "percpu_freelist.h"
 #include "bpf_lru_list.h"
@@ -41,6 +42,7 @@ struct bpf_htab {
        atomic_t count; /* number of elements in this hashtable */
        u32 n_buckets;  /* number of hash buckets */
        u32 elem_size;  /* size of each element in bytes */
+       u32 hashrnd;
 };
 
 /* each htab element is struct htab_elem + key + value */
@@ -371,6 +373,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
        if (!htab->buckets)
                goto free_htab;
 
+       htab->hashrnd = get_random_int();
        for (i = 0; i < htab->n_buckets; i++) {
                INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
                raw_spin_lock_init(&htab->buckets[i].lock);
@@ -402,9 +405,9 @@ free_htab:
        return ERR_PTR(err);
 }
 
-static inline u32 htab_map_hash(const void *key, u32 key_len)
+static inline u32 htab_map_hash(const void *key, u32 key_len, u32 hashrnd)
 {
-       return jhash(key, key_len, 0);
+       return jhash(key, key_len, hashrnd);
 }
 
 static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash)
@@ -470,7 +473,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        head = select_bucket(htab, hash);
 
@@ -597,7 +600,7 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
        if (!key)
                goto find_first_elem;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        head = select_bucket(htab, hash);
 
@@ -824,7 +827,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -880,7 +883,7 @@ static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -945,7 +948,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -998,7 +1001,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -1071,7 +1074,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
        b = __select_bucket(htab, hash);
        head = &b->head;
 
@@ -1103,7 +1106,7 @@ static int htab_lru_map_delete_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
        b = __select_bucket(htab, hash);
        head = &b->head;
 
index 98e621a29e8e6953ec9dec5b4cb6f8559dd750d3..cf5195c7c33172879158f56323ff81c6d3bf7c4f 100644 (file)
@@ -1427,12 +1427,15 @@ out:
 static void smap_write_space(struct sock *sk)
 {
        struct smap_psock *psock;
+       void (*write_space)(struct sock *sk);
 
        rcu_read_lock();
        psock = smap_psock_sk(sk);
        if (likely(psock && test_bit(SMAP_TX_RUNNING, &psock->state)))
                schedule_work(&psock->tx_work);
+       write_space = psock->save_write_space;
        rcu_read_unlock();
+       write_space(sk);
 }
 
 static void smap_stop_sock(struct smap_psock *psock, struct sock *sk)
@@ -2140,7 +2143,9 @@ static struct bpf_map *sock_hash_alloc(union bpf_attr *attr)
                return ERR_PTR(-EPERM);
 
        /* check sanity of attributes */
-       if (attr->max_entries == 0 || attr->value_size != 4 ||
+       if (attr->max_entries == 0 ||
+           attr->key_size == 0 ||
+           attr->value_size != 4 ||
            attr->map_flags & ~SOCK_CREATE_FLAG_MASK)
                return ERR_PTR(-EINVAL);
 
@@ -2267,8 +2272,10 @@ static struct htab_elem *alloc_sock_hash_elem(struct bpf_htab *htab,
        }
        l_new = kmalloc_node(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN,
                             htab->map.numa_node);
-       if (!l_new)
+       if (!l_new) {
+               atomic_dec(&htab->count);
                return ERR_PTR(-ENOMEM);
+       }
 
        memcpy(l_new->key, key, key_size);
        l_new->sk = sk;
index 310e29b5150737eac76503b91baf551da3bc47da..30526afa8343124f06f0649592ee246dc4d88fbe 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/rhashtable.h>
 #include <linux/err.h>
 #include <linux/export.h>
-#include <linux/rhashtable.h>
 
 #define HASH_DEFAULT_SIZE      64UL
 #define HASH_MIN_SIZE          4U
index 962c4fd338ba57e4344eeb62a648de59a5460c36..1c45c1d6d241dbcca8542c51eb0f25b903131756 100644 (file)
@@ -767,7 +767,6 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
        const struct tc_action *a;
        struct dsa_port *to_dp;
        int err = -EOPNOTSUPP;
-       LIST_HEAD(actions);
 
        if (!ds->ops->port_mirror_add)
                return err;
@@ -775,8 +774,7 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
        if (!tcf_exts_has_one_action(cls->exts))
                return err;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       a = list_first_entry(&actions, struct tc_action, list);
+       a = tcf_exts_first_action(cls->exts);
 
        if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
                struct dsa_mall_mirror_tc_entry *mirror;
index 13d34427ca3dd5bee810395ba4a1ab9759863182..02ff2dde96094cf33b662a20994424a7adea509e 100644 (file)
@@ -95,11 +95,10 @@ struct bbr {
        u32     mode:3,              /* current bbr_mode in state machine */
                prev_ca_state:3,     /* CA state on previous ACK */
                packet_conservation:1,  /* use packet conservation? */
-               restore_cwnd:1,      /* decided to revert cwnd to old value */
                round_start:1,       /* start of packet-timed tx->ack round? */
                idle_restart:1,      /* restarting after idle? */
                probe_rtt_round_done:1,  /* a BBR_PROBE_RTT round at 4 pkts? */
-               unused:12,
+               unused:13,
                lt_is_sampling:1,    /* taking long-term ("LT") samples now? */
                lt_rtt_cnt:7,        /* round trips in long-term interval */
                lt_use_bw:1;         /* use lt_bw as our bw estimate? */
@@ -175,6 +174,8 @@ static const u32 bbr_lt_bw_diff = 4000 / 8;
 /* If we estimate we're policed, use lt_bw for this many round trips: */
 static const u32 bbr_lt_bw_max_rtts = 48;
 
+static void bbr_check_probe_rtt_done(struct sock *sk);
+
 /* Do we estimate that STARTUP filled the pipe? */
 static bool bbr_full_bw_reached(const struct sock *sk)
 {
@@ -309,6 +310,8 @@ static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
                 */
                if (bbr->mode == BBR_PROBE_BW)
                        bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT);
+               else if (bbr->mode == BBR_PROBE_RTT)
+                       bbr_check_probe_rtt_done(sk);
        }
 }
 
@@ -396,17 +399,11 @@ static bool bbr_set_cwnd_to_recover_or_restore(
                cwnd = tcp_packets_in_flight(tp) + acked;
        } else if (prev_state >= TCP_CA_Recovery && state < TCP_CA_Recovery) {
                /* Exiting loss recovery; restore cwnd saved before recovery. */
-               bbr->restore_cwnd = 1;
+               cwnd = max(cwnd, bbr->prior_cwnd);
                bbr->packet_conservation = 0;
        }
        bbr->prev_ca_state = state;
 
-       if (bbr->restore_cwnd) {
-               /* Restore cwnd after exiting loss recovery or PROBE_RTT. */
-               cwnd = max(cwnd, bbr->prior_cwnd);
-               bbr->restore_cwnd = 0;
-       }
-
        if (bbr->packet_conservation) {
                *new_cwnd = max(cwnd, tcp_packets_in_flight(tp) + acked);
                return true;    /* yes, using packet conservation */
@@ -423,10 +420,10 @@ static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs,
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bbr *bbr = inet_csk_ca(sk);
-       u32 cwnd = 0, target_cwnd = 0;
+       u32 cwnd = tp->snd_cwnd, target_cwnd = 0;
 
        if (!acked)
-               return;
+               goto done;  /* no packet fully ACKed; just apply caps */
 
        if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd))
                goto done;
@@ -748,6 +745,20 @@ static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs)
                bbr_reset_probe_bw_mode(sk);  /* we estimate queue is drained */
 }
 
+static void bbr_check_probe_rtt_done(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct bbr *bbr = inet_csk_ca(sk);
+
+       if (!(bbr->probe_rtt_done_stamp &&
+             after(tcp_jiffies32, bbr->probe_rtt_done_stamp)))
+               return;
+
+       bbr->min_rtt_stamp = tcp_jiffies32;  /* wait a while until PROBE_RTT */
+       tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd);
+       bbr_reset_mode(sk);
+}
+
 /* The goal of PROBE_RTT mode is to have BBR flows cooperatively and
  * periodically drain the bottleneck queue, to converge to measure the true
  * min_rtt (unloaded propagation delay). This allows the flows to keep queues
@@ -806,12 +817,8 @@ static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs)
                } else if (bbr->probe_rtt_done_stamp) {
                        if (bbr->round_start)
                                bbr->probe_rtt_round_done = 1;
-                       if (bbr->probe_rtt_round_done &&
-                           after(tcp_jiffies32, bbr->probe_rtt_done_stamp)) {
-                               bbr->min_rtt_stamp = tcp_jiffies32;
-                               bbr->restore_cwnd = 1;  /* snap to prior_cwnd */
-                               bbr_reset_mode(sk);
-                       }
+                       if (bbr->probe_rtt_round_done)
+                               bbr_check_probe_rtt_done(sk);
                }
        }
        /* Restart after idle ends only once we process a new S/ACK for data */
@@ -862,7 +869,6 @@ static void bbr_init(struct sock *sk)
        bbr->has_seen_rtt = 0;
        bbr_init_pacing_rate_from_rtt(sk);
 
-       bbr->restore_cwnd = 0;
        bbr->round_start = 0;
        bbr->idle_restart = 0;
        bbr->full_bw_reached = 0;
index 9e041fa5c545367961f03fa8a9124aebbc1b6c69..44c09eddbb781c03da2417aaa925e360de01a6e9 100644 (file)
@@ -2517,6 +2517,12 @@ static int __net_init tcp_sk_init(struct net *net)
                if (res)
                        goto fail;
                sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
+
+               /* Please enforce IP_DF and IPID==0 for RST and
+                * ACK sent in SYN-RECV and TIME-WAIT state.
+                */
+               inet_sk(sk)->pmtudisc = IP_PMTUDISC_DO;
+
                *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk;
        }
 
index 2fac4ad748672cd62de6653d3fdedebe743c6ad0..d51a8c0b3372d09ad1c78b76f94b4ebaf7ca3f61 100644 (file)
@@ -2398,7 +2398,7 @@ static void addrconf_add_mroute(struct net_device *dev)
 
        ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
 
-       ip6_route_add(&cfg, GFP_ATOMIC, NULL);
+       ip6_route_add(&cfg, GFP_KERNEL, NULL);
 }
 
 static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
@@ -3062,7 +3062,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
        if (addr.s6_addr32[3]) {
                add_addr(idev, &addr, plen, scope);
                addrconf_prefix_route(&addr, plen, 0, idev->dev, 0, pflags,
-                                     GFP_ATOMIC);
+                                     GFP_KERNEL);
                return;
        }
 
@@ -3087,7 +3087,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
 
                                add_addr(idev, &addr, plen, flag);
                                addrconf_prefix_route(&addr, plen, 0, idev->dev,
-                                                     0, pflags, GFP_ATOMIC);
+                                                     0, pflags, GFP_KERNEL);
                        }
                }
        }
index d212738e9d100d4e3270f9188466da6b8a3d186c..c861a6d4671d3f0f82f68752d16a8192ac649f8a 100644 (file)
@@ -198,6 +198,8 @@ void fib6_info_destroy_rcu(struct rcu_head *head)
                }
        }
 
+       lwtstate_put(f6i->fib6_nh.nh_lwtstate);
+
        if (f6i->fib6_nh.nh_dev)
                dev_put(f6i->fib6_nh.nh_dev);
 
index 38dec9da90d338b4704a8acd4586536b467f75b9..5095367c7204927f489c2833c736fbf5292c8d09 100644 (file)
@@ -1094,7 +1094,8 @@ static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n,
        }
 
        t = rtnl_dereference(ip6n->tnls_wc[0]);
-       unregister_netdevice_queue(t->dev, list);
+       if (t)
+               unregister_netdevice_queue(t->dev, list);
 }
 
 static int __net_init vti6_init_net(struct net *net)
index 7208c16302f61adc15636f6a332ff0c02325cfcf..c4ea13e8360b9a399c811563165383e720c1cbb4 100644 (file)
@@ -956,7 +956,7 @@ static void ip6_rt_init_dst(struct rt6_info *rt, struct fib6_info *ort)
        rt->dst.error = 0;
        rt->dst.output = ip6_output;
 
-       if (ort->fib6_type == RTN_LOCAL) {
+       if (ort->fib6_type == RTN_LOCAL || ort->fib6_type == RTN_ANYCAST) {
                rt->dst.input = ip6_input;
        } else if (ipv6_addr_type(&ort->fib6_dst.addr) & IPV6_ADDR_MULTICAST) {
                rt->dst.input = ip6_mc_input;
index 82e6edf9c5d9c8454d17c53a2e0c461ff399a881..45f33d6dedf771c7d9f4a21496201ad3198aba8b 100644 (file)
@@ -100,7 +100,7 @@ static int ncsi_write_package_info(struct sk_buff *skb,
        bool found;
        int rc;
 
-       if (id > ndp->package_num) {
+       if (id > ndp->package_num - 1) {
                netdev_info(ndp->ndev.dev, "NCSI: No package with id %u\n", id);
                return -ENODEV;
        }
@@ -240,7 +240,7 @@ static int ncsi_pkg_info_all_nl(struct sk_buff *skb,
                return 0; /* done */
 
        hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
-                         &ncsi_genl_family, 0,  NCSI_CMD_PKG_INFO);
+                         &ncsi_genl_family, NLM_F_MULTI,  NCSI_CMD_PKG_INFO);
        if (!hdr) {
                rc = -EMSGSIZE;
                goto err;
index 2c7b7c352d3e8cf77c7aed4d29b61d481249827f..b9bbcf3d6c63976912433109d5c450830fb779f4 100644 (file)
@@ -37,7 +37,6 @@
 #include <net/tcp.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
-#include <net/tcp.h>
 #include <net/addrconf.h>
 
 #include "rds.h"
index 229d63c99be23b2329caa84b6912c8f770ccca64..db83dac1e7f488cd2fd0d013bce374c5d4123f3c 100644 (file)
@@ -300,21 +300,17 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(tcf_generic_walker);
 
-static bool __tcf_idr_check(struct tc_action_net *tn, u32 index,
-                           struct tc_action **a, int bind)
+int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
 {
        struct tcf_idrinfo *idrinfo = tn->idrinfo;
        struct tc_action *p;
 
        spin_lock(&idrinfo->lock);
        p = idr_find(&idrinfo->action_idr, index);
-       if (IS_ERR(p)) {
+       if (IS_ERR(p))
                p = NULL;
-       } else if (p) {
+       else if (p)
                refcount_inc(&p->tcfa_refcnt);
-               if (bind)
-                       atomic_inc(&p->tcfa_bindcnt);
-       }
        spin_unlock(&idrinfo->lock);
 
        if (p) {
@@ -323,23 +319,10 @@ static bool __tcf_idr_check(struct tc_action_net *tn, u32 index,
        }
        return false;
 }
-
-int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
-{
-       return __tcf_idr_check(tn, index, a, 0);
-}
 EXPORT_SYMBOL(tcf_idr_search);
 
-bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
-                  int bind)
+static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
 {
-       return __tcf_idr_check(tn, index, a, bind);
-}
-EXPORT_SYMBOL(tcf_idr_check);
-
-int tcf_idr_delete_index(struct tc_action_net *tn, u32 index)
-{
-       struct tcf_idrinfo *idrinfo = tn->idrinfo;
        struct tc_action *p;
        int ret = 0;
 
@@ -370,7 +353,6 @@ int tcf_idr_delete_index(struct tc_action_net *tn, u32 index)
        spin_unlock(&idrinfo->lock);
        return ret;
 }
-EXPORT_SYMBOL(tcf_idr_delete_index);
 
 int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
                   struct tc_action **a, const struct tc_action_ops *ops,
@@ -409,7 +391,6 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
 
        p->idrinfo = idrinfo;
        p->ops = ops;
-       INIT_LIST_HEAD(&p->list);
        *a = p;
        return 0;
 err3:
@@ -686,14 +667,18 @@ static int tcf_action_put(struct tc_action *p)
        return __tcf_action_put(p, false);
 }
 
+/* Put all actions in this array, skip those NULL's. */
 static void tcf_action_put_many(struct tc_action *actions[])
 {
        int i;
 
-       for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
+       for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
                struct tc_action *a = actions[i];
-               const struct tc_action_ops *ops = a->ops;
+               const struct tc_action_ops *ops;
 
+               if (!a)
+                       continue;
+               ops = a->ops;
                if (tcf_action_put(a))
                        module_put(ops->owner);
        }
@@ -1175,41 +1160,38 @@ err_out:
        return err;
 }
 
-static int tcf_action_delete(struct net *net, struct tc_action *actions[],
-                            int *acts_deleted, struct netlink_ext_ack *extack)
+static int tcf_action_delete(struct net *net, struct tc_action *actions[])
 {
-       u32 act_index;
-       int ret, i;
+       int i;
 
        for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
                struct tc_action *a = actions[i];
                const struct tc_action_ops *ops = a->ops;
-
                /* Actions can be deleted concurrently so we must save their
                 * type and id to search again after reference is released.
                 */
-               act_index = a->tcfa_index;
+               struct tcf_idrinfo *idrinfo = a->idrinfo;
+               u32 act_index = a->tcfa_index;
 
                if (tcf_action_put(a)) {
                        /* last reference, action was deleted concurrently */
                        module_put(ops->owner);
                } else  {
+                       int ret;
+
                        /* now do the delete */
-                       ret = ops->delete(net, act_index);
-                       if (ret < 0) {
-                               *acts_deleted = i + 1;
+                       ret = tcf_idr_delete_index(idrinfo, act_index);
+                       if (ret < 0)
                                return ret;
-                       }
                }
+               actions[i] = NULL;
        }
-       *acts_deleted = i;
        return 0;
 }
 
 static int
 tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
-              int *acts_deleted, u32 portid, size_t attr_size,
-              struct netlink_ext_ack *extack)
+              u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
 {
        int ret;
        struct sk_buff *skb;
@@ -1227,7 +1209,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
        }
 
        /* now do the delete */
-       ret = tcf_action_delete(net, actions, acts_deleted, extack);
+       ret = tcf_action_delete(net, actions);
        if (ret < 0) {
                NL_SET_ERR_MSG(extack, "Failed to delete TC action");
                kfree_skb(skb);
@@ -1249,8 +1231,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
        struct tc_action *act;
        size_t attr_size = 0;
-       struct tc_action *actions[TCA_ACT_MAX_PRIO + 1] = {};
-       int acts_deleted = 0;
+       struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
 
        ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
        if (ret < 0)
@@ -1280,14 +1261,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        if (event == RTM_GETACTION)
                ret = tcf_get_notify(net, portid, n, actions, event, extack);
        else { /* delete */
-               ret = tcf_del_notify(net, n, actions, &acts_deleted, portid,
-                                    attr_size, extack);
+               ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
                if (ret)
                        goto err;
-               return ret;
+               return 0;
        }
 err:
-       tcf_action_put_many(&actions[acts_deleted]);
+       tcf_action_put_many(actions);
        return ret;
 }
 
index d30b23e424364300f5440da022abb2129b9cf5f8..0c68bc9cf0b4df540a223e14dfa8ff569f96a40c 100644 (file)
@@ -395,13 +395,6 @@ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_bpf_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, bpf_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_bpf_ops __read_mostly = {
        .kind           =       "bpf",
        .type           =       TCA_ACT_BPF,
@@ -412,7 +405,6 @@ static struct tc_action_ops act_bpf_ops __read_mostly = {
        .init           =       tcf_bpf_init,
        .walk           =       tcf_bpf_walker,
        .lookup         =       tcf_bpf_search,
-       .delete         =       tcf_bpf_delete,
        .size           =       sizeof(struct tcf_bpf),
 };
 
index 54c0bf54f2acf71cd63ff17ef0cb74898bc0d478..6f0f273f1139f83ef1a45f017c37d200c36fcae1 100644 (file)
@@ -198,13 +198,6 @@ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_connmark_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, connmark_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_connmark_ops = {
        .kind           =       "connmark",
        .type           =       TCA_ACT_CONNMARK,
@@ -214,7 +207,6 @@ static struct tc_action_ops act_connmark_ops = {
        .init           =       tcf_connmark_init,
        .walk           =       tcf_connmark_walker,
        .lookup         =       tcf_connmark_search,
-       .delete         =       tcf_connmark_delete,
        .size           =       sizeof(struct tcf_connmark_info),
 };
 
index e698d3fe2080d1051d70c6ab92ff111bcd42d36d..b8a67ae3105ad10f645bfcb65a503dafcbe5cbb2 100644 (file)
@@ -659,13 +659,6 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
        return nla_total_size(sizeof(struct tc_csum));
 }
 
-static int tcf_csum_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, csum_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_csum_ops = {
        .kind           = "csum",
        .type           = TCA_ACT_CSUM,
@@ -677,7 +670,6 @@ static struct tc_action_ops act_csum_ops = {
        .walk           = tcf_csum_walker,
        .lookup         = tcf_csum_search,
        .get_fill_size  = tcf_csum_get_fill_size,
-       .delete         = tcf_csum_delete,
        .size           = sizeof(struct tcf_csum),
 };
 
index 6a3f25a8ffb30b8998fc2a7c37aaccc2c29c466d..cd1d9bd32ef9af4c5789e0331b6d1c1b7e6820f3 100644 (file)
@@ -243,13 +243,6 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
        return sz;
 }
 
-static int tcf_gact_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, gact_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_gact_ops = {
        .kind           =       "gact",
        .type           =       TCA_ACT_GACT,
@@ -261,7 +254,6 @@ static struct tc_action_ops act_gact_ops = {
        .walk           =       tcf_gact_walker,
        .lookup         =       tcf_gact_search,
        .get_fill_size  =       tcf_gact_get_fill_size,
-       .delete         =       tcf_gact_delete,
        .size           =       sizeof(struct tcf_gact),
 };
 
index d1081bdf1bdb5565660e41130e541800392e3889..196430aefe87a355a9a237ef7184fa2a4830a3a3 100644 (file)
@@ -167,16 +167,16 @@ static struct tcf_meta_ops *find_ife_oplist(u16 metaid)
 {
        struct tcf_meta_ops *o;
 
-       read_lock_bh(&ife_mod_lock);
+       read_lock(&ife_mod_lock);
        list_for_each_entry(o, &ifeoplist, list) {
                if (o->metaid == metaid) {
                        if (!try_module_get(o->owner))
                                o = NULL;
-                       read_unlock_bh(&ife_mod_lock);
+                       read_unlock(&ife_mod_lock);
                        return o;
                }
        }
-       read_unlock_bh(&ife_mod_lock);
+       read_unlock(&ife_mod_lock);
 
        return NULL;
 }
@@ -190,12 +190,12 @@ int register_ife_op(struct tcf_meta_ops *mops)
            !mops->get || !mops->alloc)
                return -EINVAL;
 
-       write_lock_bh(&ife_mod_lock);
+       write_lock(&ife_mod_lock);
 
        list_for_each_entry(m, &ifeoplist, list) {
                if (m->metaid == mops->metaid ||
                    (strcmp(mops->name, m->name) == 0)) {
-                       write_unlock_bh(&ife_mod_lock);
+                       write_unlock(&ife_mod_lock);
                        return -EEXIST;
                }
        }
@@ -204,7 +204,7 @@ int register_ife_op(struct tcf_meta_ops *mops)
                mops->release = ife_release_meta_gen;
 
        list_add_tail(&mops->list, &ifeoplist);
-       write_unlock_bh(&ife_mod_lock);
+       write_unlock(&ife_mod_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(unregister_ife_op);
@@ -214,7 +214,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops)
        struct tcf_meta_ops *m;
        int err = -ENOENT;
 
-       write_lock_bh(&ife_mod_lock);
+       write_lock(&ife_mod_lock);
        list_for_each_entry(m, &ifeoplist, list) {
                if (m->metaid == mops->metaid) {
                        list_del(&mops->list);
@@ -222,7 +222,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops)
                        break;
                }
        }
-       write_unlock_bh(&ife_mod_lock);
+       write_unlock(&ife_mod_lock);
 
        return err;
 }
@@ -265,11 +265,8 @@ static const char *ife_meta_id2name(u32 metaid)
 #endif
 
 /* called when adding new meta information
- * under ife->tcf_lock for existing action
 */
-static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
-                               void *val, int len, bool exists,
-                               bool rtnl_held)
+static int load_metaops_and_vet(u32 metaid, void *val, int len, bool rtnl_held)
 {
        struct tcf_meta_ops *ops = find_ife_oplist(metaid);
        int ret = 0;
@@ -277,15 +274,11 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
        if (!ops) {
                ret = -ENOENT;
 #ifdef CONFIG_MODULES
-               if (exists)
-                       spin_unlock_bh(&ife->tcf_lock);
                if (rtnl_held)
                        rtnl_unlock();
                request_module("ife-meta-%s", ife_meta_id2name(metaid));
                if (rtnl_held)
                        rtnl_lock();
-               if (exists)
-                       spin_lock_bh(&ife->tcf_lock);
                ops = find_ife_oplist(metaid);
 #endif
        }
@@ -302,24 +295,17 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
 }
 
 /* called when adding new meta information
- * under ife->tcf_lock for existing action
 */
-static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
-                       int len, bool atomic)
+static int __add_metainfo(const struct tcf_meta_ops *ops,
+                         struct tcf_ife_info *ife, u32 metaid, void *metaval,
+                         int len, bool atomic, bool exists)
 {
        struct tcf_meta_info *mi = NULL;
-       struct tcf_meta_ops *ops = find_ife_oplist(metaid);
        int ret = 0;
 
-       if (!ops)
-               return -ENOENT;
-
        mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL);
-       if (!mi) {
-               /*put back what find_ife_oplist took */
-               module_put(ops->owner);
+       if (!mi)
                return -ENOMEM;
-       }
 
        mi->metaid = metaid;
        mi->ops = ops;
@@ -327,29 +313,47 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
                ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL);
                if (ret != 0) {
                        kfree(mi);
-                       module_put(ops->owner);
                        return ret;
                }
        }
 
+       if (exists)
+               spin_lock_bh(&ife->tcf_lock);
        list_add_tail(&mi->metalist, &ife->metalist);
+       if (exists)
+               spin_unlock_bh(&ife->tcf_lock);
+
+       return ret;
+}
+
+static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
+                       int len, bool exists)
+{
+       const struct tcf_meta_ops *ops = find_ife_oplist(metaid);
+       int ret;
 
+       if (!ops)
+               return -ENOENT;
+       ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists);
+       if (ret)
+               /*put back what find_ife_oplist took */
+               module_put(ops->owner);
        return ret;
 }
 
-static int use_all_metadata(struct tcf_ife_info *ife)
+static int use_all_metadata(struct tcf_ife_info *ife, bool exists)
 {
        struct tcf_meta_ops *o;
        int rc = 0;
        int installed = 0;
 
-       read_lock_bh(&ife_mod_lock);
+       read_lock(&ife_mod_lock);
        list_for_each_entry(o, &ifeoplist, list) {
-               rc = add_metainfo(ife, o->metaid, NULL, 0, true);
+               rc = __add_metainfo(o, ife, o->metaid, NULL, 0, true, exists);
                if (rc == 0)
                        installed += 1;
        }
-       read_unlock_bh(&ife_mod_lock);
+       read_unlock(&ife_mod_lock);
 
        if (installed)
                return 0;
@@ -422,7 +426,6 @@ static void tcf_ife_cleanup(struct tc_action *a)
                kfree_rcu(p, rcu);
 }
 
-/* under ife->tcf_lock for existing action */
 static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
                             bool exists, bool rtnl_held)
 {
@@ -436,8 +439,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
                        val = nla_data(tb[i]);
                        len = nla_len(tb[i]);
 
-                       rc = load_metaops_and_vet(ife, i, val, len, exists,
-                                                 rtnl_held);
+                       rc = load_metaops_and_vet(i, val, len, rtnl_held);
                        if (rc != 0)
                                return rc;
 
@@ -540,8 +542,6 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
                p->eth_type = ife_type;
        }
 
-       if (exists)
-               spin_lock_bh(&ife->tcf_lock);
 
        if (ret == ACT_P_CREATED)
                INIT_LIST_HEAD(&ife->metalist);
@@ -551,10 +551,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
                                       NULL, NULL);
                if (err) {
 metadata_parse_err:
-                       if (exists)
-                               spin_unlock_bh(&ife->tcf_lock);
                        tcf_idr_release(*a, bind);
-
                        kfree(p);
                        return err;
                }
@@ -569,17 +566,16 @@ metadata_parse_err:
                 * as we can. You better have at least one else we are
                 * going to bail out
                 */
-               err = use_all_metadata(ife);
+               err = use_all_metadata(ife, exists);
                if (err) {
-                       if (exists)
-                               spin_unlock_bh(&ife->tcf_lock);
                        tcf_idr_release(*a, bind);
-
                        kfree(p);
                        return err;
                }
        }
 
+       if (exists)
+               spin_lock_bh(&ife->tcf_lock);
        ife->tcf_action = parm->action;
        /* protected by tcf_lock when modifying existing action */
        rcu_swap_protected(ife->params, p, 1);
@@ -853,13 +849,6 @@ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_ife_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, ife_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_ife_ops = {
        .kind = "ife",
        .type = TCA_ACT_IFE,
@@ -870,7 +859,6 @@ static struct tc_action_ops act_ife_ops = {
        .init = tcf_ife_init,
        .walk = tcf_ife_walker,
        .lookup = tcf_ife_search,
-       .delete = tcf_ife_delete,
        .size = sizeof(struct tcf_ife_info),
 };
 
index 51f235bbeb5bccb4267fd70eeec8399494c9f246..23273b5303fd9dcc68cf09ee6f701defe50580b5 100644 (file)
@@ -337,13 +337,6 @@ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_ipt_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, ipt_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_ipt_ops = {
        .kind           =       "ipt",
        .type           =       TCA_ACT_IPT,
@@ -354,7 +347,6 @@ static struct tc_action_ops act_ipt_ops = {
        .init           =       tcf_ipt_init,
        .walk           =       tcf_ipt_walker,
        .lookup         =       tcf_ipt_search,
-       .delete         =       tcf_ipt_delete,
        .size           =       sizeof(struct tcf_ipt),
 };
 
@@ -395,13 +387,6 @@ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_xt_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, xt_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_xt_ops = {
        .kind           =       "xt",
        .type           =       TCA_ACT_XT,
@@ -412,7 +397,6 @@ static struct tc_action_ops act_xt_ops = {
        .init           =       tcf_xt_init,
        .walk           =       tcf_xt_walker,
        .lookup         =       tcf_xt_search,
-       .delete         =       tcf_xt_delete,
        .size           =       sizeof(struct tcf_ipt),
 };
 
index 38fd20f10f6796eaba1402ee572d7712837f1a2c..8bf66d0a6800006e070eacc77519257410696097 100644 (file)
@@ -395,13 +395,6 @@ static void tcf_mirred_put_dev(struct net_device *dev)
        dev_put(dev);
 }
 
-static int tcf_mirred_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, mirred_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_mirred_ops = {
        .kind           =       "mirred",
        .type           =       TCA_ACT_MIRRED,
@@ -416,7 +409,6 @@ static struct tc_action_ops act_mirred_ops = {
        .size           =       sizeof(struct tcf_mirred),
        .get_dev        =       tcf_mirred_get_dev,
        .put_dev        =       tcf_mirred_put_dev,
-       .delete         =       tcf_mirred_delete,
 };
 
 static __net_init int mirred_init_net(struct net *net)
index 822e903bfc25f008d9754d1340a5b4352f4fe59e..4313aa102440e9b55fb0ba200406801217d65284 100644 (file)
@@ -300,13 +300,6 @@ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_nat_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, nat_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_nat_ops = {
        .kind           =       "nat",
        .type           =       TCA_ACT_NAT,
@@ -316,7 +309,6 @@ static struct tc_action_ops act_nat_ops = {
        .init           =       tcf_nat_init,
        .walk           =       tcf_nat_walker,
        .lookup         =       tcf_nat_search,
-       .delete         =       tcf_nat_delete,
        .size           =       sizeof(struct tcf_nat),
 };
 
index 8a7a7cb94e8308e8b4d240f957b64080b269f485..10703407001972a8cccc297a8c0d85e72edfed1c 100644 (file)
@@ -460,13 +460,6 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_pedit_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, pedit_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_pedit_ops = {
        .kind           =       "pedit",
        .type           =       TCA_ACT_PEDIT,
@@ -477,7 +470,6 @@ static struct tc_action_ops act_pedit_ops = {
        .init           =       tcf_pedit_init,
        .walk           =       tcf_pedit_walker,
        .lookup         =       tcf_pedit_search,
-       .delete         =       tcf_pedit_delete,
        .size           =       sizeof(struct tcf_pedit),
 };
 
index 06f0742db593166370cfb69f1ef8a687e29007be..5d8bfa878477e8e738be55d2c9b818423c3c8ccc 100644 (file)
@@ -320,13 +320,6 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_police_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, police_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 MODULE_AUTHOR("Alexey Kuznetsov");
 MODULE_DESCRIPTION("Policing actions");
 MODULE_LICENSE("GPL");
@@ -340,7 +333,6 @@ static struct tc_action_ops act_police_ops = {
        .init           =       tcf_police_init,
        .walk           =       tcf_police_walker,
        .lookup         =       tcf_police_search,
-       .delete         =       tcf_police_delete,
        .size           =       sizeof(struct tcf_police),
 };
 
index 207b4132d1b066a394467ace6cf454dbce53a33f..44e9c00657bc1e8572d78e8a9ca1c6a142eb9c76 100644 (file)
@@ -232,13 +232,6 @@ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_sample_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, sample_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_sample_ops = {
        .kind     = "sample",
        .type     = TCA_ACT_SAMPLE,
@@ -249,7 +242,6 @@ static struct tc_action_ops act_sample_ops = {
        .cleanup  = tcf_sample_cleanup,
        .walk     = tcf_sample_walker,
        .lookup   = tcf_sample_search,
-       .delete   = tcf_sample_delete,
        .size     = sizeof(struct tcf_sample),
 };
 
index e616523ba3c15f9126146240d440d96849ac4ded..52400d49f81f233a572de8cdffff9c94099e614a 100644 (file)
@@ -196,13 +196,6 @@ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_simp_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, simp_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_simp_ops = {
        .kind           =       "simple",
        .type           =       TCA_ACT_SIMP,
@@ -213,7 +206,6 @@ static struct tc_action_ops act_simp_ops = {
        .init           =       tcf_simp_init,
        .walk           =       tcf_simp_walker,
        .lookup         =       tcf_simp_search,
-       .delete         =       tcf_simp_delete,
        .size           =       sizeof(struct tcf_defact),
 };
 
index 926d7bc4a89d9db85078677f1bdb9d6c57a767fc..73e44ce2a8837d9151b77de1e1bf619872af217c 100644 (file)
@@ -299,13 +299,6 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_skbedit_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, skbedit_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_skbedit_ops = {
        .kind           =       "skbedit",
        .type           =       TCA_ACT_SKBEDIT,
@@ -316,7 +309,6 @@ static struct tc_action_ops act_skbedit_ops = {
        .cleanup        =       tcf_skbedit_cleanup,
        .walk           =       tcf_skbedit_walker,
        .lookup         =       tcf_skbedit_search,
-       .delete         =       tcf_skbedit_delete,
        .size           =       sizeof(struct tcf_skbedit),
 };
 
index d6a1af0c41712cf6e61bcdaefc06959e616efa21..588077fafd6cc58473b1d0de85b1aa3103b3bf69 100644 (file)
@@ -259,13 +259,6 @@ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_skbmod_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, skbmod_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_skbmod_ops = {
        .kind           =       "skbmod",
        .type           =       TCA_ACT_SKBMOD,
@@ -276,7 +269,6 @@ static struct tc_action_ops act_skbmod_ops = {
        .cleanup        =       tcf_skbmod_cleanup,
        .walk           =       tcf_skbmod_walker,
        .lookup         =       tcf_skbmod_search,
-       .delete         =       tcf_skbmod_delete,
        .size           =       sizeof(struct tcf_skbmod),
 };
 
index 8f09cf08d8fe1242cdbbc1951124e0f19ace18ae..420759153d5f4442eebab5a375714f7f89df7ea9 100644 (file)
@@ -548,13 +548,6 @@ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tunnel_key_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_tunnel_key_ops = {
        .kind           =       "tunnel_key",
        .type           =       TCA_ACT_TUNNEL_KEY,
@@ -565,7 +558,6 @@ static struct tc_action_ops act_tunnel_key_ops = {
        .cleanup        =       tunnel_key_release,
        .walk           =       tunnel_key_walker,
        .lookup         =       tunnel_key_search,
-       .delete         =       tunnel_key_delete,
        .size           =       sizeof(struct tcf_tunnel_key),
 };
 
index 209e70ad2c09a0b0e9567f24b33108f7b5e1f1e4..033d273afe50236a090fd4caddd0a8328ce82157 100644 (file)
@@ -296,13 +296,6 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_vlan_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, vlan_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_vlan_ops = {
        .kind           =       "vlan",
        .type           =       TCA_ACT_VLAN,
@@ -313,7 +306,6 @@ static struct tc_action_ops act_vlan_ops = {
        .cleanup        =       tcf_vlan_cleanup,
        .walk           =       tcf_vlan_walker,
        .lookup         =       tcf_vlan_search,
-       .delete         =       tcf_vlan_delete,
        .size           =       sizeof(struct tcf_vlan),
 };
 
index d5d2a6dc39216b0ca28bd11094f0b64fda5c5964..f218ccf1e2d9a651ad07c2a6276742b97d3b2102 100644 (file)
@@ -914,6 +914,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        struct nlattr *opt = tca[TCA_OPTIONS];
        struct nlattr *tb[TCA_U32_MAX + 1];
        u32 htid, flags = 0;
+       size_t sel_size;
        int err;
 #ifdef CONFIG_CLS_U32_PERF
        size_t size;
@@ -1076,8 +1077,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        }
 
        s = nla_data(tb[TCA_U32_SEL]);
+       sel_size = struct_size(s, keys, s->nkeys);
+       if (nla_len(tb[TCA_U32_SEL]) < sel_size) {
+               err = -EINVAL;
+               goto erridr;
+       }
 
-       n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
+       n = kzalloc(offsetof(typeof(*n), sel) + sel_size, GFP_KERNEL);
        if (n == NULL) {
                err = -ENOBUFS;
                goto erridr;
@@ -1092,7 +1098,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        }
 #endif
 
-       memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
+       memcpy(&n->sel, s, sel_size);
        RCU_INIT_POINTER(n->ht_up, ht);
        n->handle = handle;
        n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
index 35fc7252187c1f54fbcbceb827d7270381b2da5b..c07c30b916d5e4d7b7fef5586f92df366194da85 100644 (file)
@@ -64,7 +64,6 @@
 #include <linux/vmalloc.h>
 #include <linux/reciprocal_div.h>
 #include <net/netlink.h>
-#include <linux/version.h>
 #include <linux/if_vlan.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
@@ -621,15 +620,20 @@ static bool cake_ddst(int flow_mode)
 }
 
 static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb,
-                    int flow_mode)
+                    int flow_mode, u16 flow_override, u16 host_override)
 {
-       u32 flow_hash = 0, srchost_hash, dsthost_hash;
+       u32 flow_hash = 0, srchost_hash = 0, dsthost_hash = 0;
        u16 reduced_hash, srchost_idx, dsthost_idx;
        struct flow_keys keys, host_keys;
 
        if (unlikely(flow_mode == CAKE_FLOW_NONE))
                return 0;
 
+       /* If both overrides are set we can skip packet dissection entirely */
+       if ((flow_override || !(flow_mode & CAKE_FLOW_FLOWS)) &&
+           (host_override || !(flow_mode & CAKE_FLOW_HOSTS)))
+               goto skip_hash;
+
        skb_flow_dissect_flow_keys(skb, &keys,
                                   FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
 
@@ -676,6 +680,14 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb,
        if (flow_mode & CAKE_FLOW_FLOWS)
                flow_hash = flow_hash_from_keys(&keys);
 
+skip_hash:
+       if (flow_override)
+               flow_hash = flow_override - 1;
+       if (host_override) {
+               dsthost_hash = host_override - 1;
+               srchost_hash = host_override - 1;
+       }
+
        if (!(flow_mode & CAKE_FLOW_FLOWS)) {
                if (flow_mode & CAKE_FLOW_SRC_IP)
                        flow_hash ^= srchost_hash;
@@ -1571,7 +1583,7 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t,
        struct cake_sched_data *q = qdisc_priv(sch);
        struct tcf_proto *filter;
        struct tcf_result res;
-       u32 flow = 0;
+       u16 flow = 0, host = 0;
        int result;
 
        filter = rcu_dereference_bh(q->filter_list);
@@ -1595,10 +1607,12 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t,
 #endif
                if (TC_H_MIN(res.classid) <= CAKE_QUEUES)
                        flow = TC_H_MIN(res.classid);
+               if (TC_H_MAJ(res.classid) <= (CAKE_QUEUES << 16))
+                       host = TC_H_MAJ(res.classid) >> 16;
        }
 hash:
        *t = cake_select_tin(sch, skb);
-       return flow ?: cake_hash(*t, skb, flow_mode) + 1;
+       return cake_hash(*t, skb, flow_mode, flow, host) + 1;
 }
 
 static void cake_reconfigure(struct Qdisc *sch);
index 93c0c225ab340ae0f0de3c5c2e6b2a149579c19e..180b6640e5316bb89b502414c2b51c4db0269997 100644 (file)
@@ -213,9 +213,14 @@ static void tls_write_space(struct sock *sk)
 {
        struct tls_context *ctx = tls_get_ctx(sk);
 
-       /* We are already sending pages, ignore notification */
-       if (ctx->in_tcp_sendpages)
+       /* If in_tcp_sendpages call lower protocol write space handler
+        * to ensure we wake up any waiting operations there. For example
+        * if do_tcp_sendpages where to call sk_wait_event.
+        */
+       if (ctx->in_tcp_sendpages) {
+               ctx->sk_write_space(sk);
                return;
+       }
 
        if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) {
                gfp_t sk_allocation = sk->sk_allocation;
index 911ca6d3cb5a6cd7d056a04cf3df57d5833bafeb..bfe2dbea480ba8ef54e0cc24659aa15d267aea2a 100644 (file)
@@ -74,14 +74,14 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
                return 0;
 
        if (!dev->netdev_ops->ndo_bpf || !dev->netdev_ops->ndo_xsk_async_xmit)
-               return force_zc ? -ENOTSUPP : 0; /* fail or fallback */
+               return force_zc ? -EOPNOTSUPP : 0; /* fail or fallback */
 
        bpf.command = XDP_QUERY_XSK_UMEM;
 
        rtnl_lock();
        err = xdp_umem_query(dev, queue_id);
        if (err) {
-               err = err < 0 ? -ENOTSUPP : -EBUSY;
+               err = err < 0 ? -EOPNOTSUPP : -EBUSY;
                goto err_rtnl_unlock;
        }
 
index 1832100d1b274db7b71045e4dfe9e7e00e534ae0..6d41323be291bbf7e18348375aa88006d36facda 100644 (file)
@@ -194,8 +194,10 @@ int do_event_pipe(int argc, char **argv)
        }
 
        while (argc) {
-               if (argc < 2)
+               if (argc < 2) {
                        BAD_ARG();
+                       goto err_close_map;
+               }
 
                if (is_prefix(*argv, "cpu")) {
                        char *endptr;
@@ -221,6 +223,7 @@ int do_event_pipe(int argc, char **argv)
                        NEXT_ARG();
                } else {
                        BAD_ARG();
+                       goto err_close_map;
                }
 
                do_all = false;