Merge tag 'mlx5-fixes-2018-11-19' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorDavid S. Miller <davem@davemloft.net>
Tue, 20 Nov 2018 03:04:33 +0000 (19:04 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Nov 2018 03:04:33 +0000 (19:04 -0800)
Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2018-11-19

The following fixes are for mlx5 core and netdev driver.

For -stable v4.16
bc7fda7d4637 ('net/mlx5e: IPoIB, Reset QP after channels are closed')

For -stable v4.17
36917a270395 ('net/mlx5: IPSec, Fix the SA context hash key')

For -stable v4.18
6492a432be3a ('net/mlx5e: Always use the match level enum when parsing TC rule match')
c3f81be236b1 ('net/mlx5e: Removed unnecessary warnings in FEC caps query')
c5ce2e736b64 ('net/mlx5e: Fix selftest for small MTUs')

For -stable v4.19
effcd896b25e ('net/mlx5e: Adjust to max number of channles when re-attaching')
394cbc5acd68 ('net/mlx5e: RX, verify received packet size in Linear Striding RQ')
447cbb3613c8 ('net/mlx5e: Don't match on vlan non-existence if ethertype is wildcarded')
c223c1574612 ('net/mlx5e: Claim TC hw offloads support only under a proper build config')

Please pull and let me know if there's any problem.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
540 files changed:
.mailmap
CREDITS
Documentation/ABI/testing/sysfs-class-led-trigger-pattern
Documentation/admin-guide/pm/cpufreq.rst
Documentation/cpu-freq/cpufreq-stats.txt
Documentation/devicetree/bindings/arm/shmobile.txt
Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt [deleted file]
Documentation/devicetree/bindings/i2c/i2c-omap.txt
Documentation/devicetree/bindings/net/can/holt_hi311x.txt
Documentation/devicetree/bindings/net/can/rcar_can.txt
Documentation/i2c/busses/i2c-nvidia-gpu [new file with mode: 0644]
Documentation/networking/rxrpc.txt
Documentation/x86/x86_64/mm.txt
Documentation/x86/zero-page.txt
MAINTAINERS
Makefile
arch/alpha/include/asm/termios.h
arch/alpha/include/uapi/asm/ioctls.h
arch/alpha/include/uapi/asm/termbits.h
arch/arm/boot/dts/imx53-ppd.dts
arch/arm/boot/dts/imx6sll.dtsi
arch/arm/boot/dts/imx6sx-sdb.dtsi
arch/arm/boot/dts/vf610m4-colibri.dts
arch/arm/configs/multi_v7_defconfig
arch/arm/include/asm/cputype.h
arch/arm/include/asm/pgtable-2level.h
arch/arm/include/asm/proc-fns.h
arch/arm/kernel/bugs.c
arch/arm/kernel/head-common.S
arch/arm/kernel/setup.c
arch/arm/kernel/smp.c
arch/arm/mach-omap2/display.c
arch/arm/mm/proc-v7-bugs.c
arch/arm/mm/proc-v7.S
arch/arm/vfp/vfpmodule.c
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/renesas/r8a7795.dtsi
arch/arm64/boot/dts/renesas/r8a77980-condor.dts
arch/arm64/include/asm/processor.h
arch/arm64/kernel/setup.c
arch/arm64/mm/init.c
arch/arm64/mm/mmu.c
arch/m68k/include/asm/pgtable_mm.h
arch/microblaze/include/asm/pgtable.h
arch/mips/cavium-octeon/executive/cvmx-helper.c
arch/mips/mm/dma-noncoherent.c
arch/nds32/include/asm/pgtable.h
arch/parisc/include/asm/pgtable.h
arch/parisc/include/asm/spinlock.h
arch/parisc/kernel/syscall.S
arch/powerpc/include/asm/io.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/kernel/setup_64.c
arch/powerpc/kvm/trace.h
arch/powerpc/kvm/trace_booke.h
arch/powerpc/kvm/trace_hv.h
arch/powerpc/kvm/trace_pr.h
arch/powerpc/mm/numa.c
arch/powerpc/mm/slb.c
arch/powerpc/platforms/powernv/npu-dma.c
arch/riscv/Makefile
arch/riscv/configs/defconfig
arch/riscv/include/asm/ptrace.h
arch/riscv/kernel/module.c
arch/riscv/lib/Makefile
arch/s390/Makefile
arch/s390/boot/compressed/Makefile
arch/s390/configs/debug_defconfig
arch/s390/configs/performance_defconfig
arch/s390/defconfig
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/pgalloc.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/processor.h
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/tlb.h
arch/s390/kernel/entry.S
arch/s390/kernel/perf_cpum_cf.c
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kernel/vdso32/Makefile
arch/s390/kernel/vdso64/Makefile
arch/s390/kernel/vmlinux.lds.S
arch/s390/mm/pgalloc.c
arch/s390/numa/numa.c
arch/um/drivers/ubd_kern.c
arch/x86/Kconfig
arch/x86/Makefile
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore_snb.c
arch/x86/include/asm/mce.h
arch/x86/include/asm/mshyperv.h
arch/x86/include/asm/page_64_types.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/asm/qspinlock.h
arch/x86/include/asm/xen/page.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/ldt.c
arch/x86/kernel/vsmp_64.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/p2m.c
arch/x86/xen/spinlock.c
arch/xtensa/include/asm/processor.h
arch/xtensa/kernel/head.S
block/bio.c
block/blk-core.c
block/blk-lib.c
block/blk-merge.c
block/blk.h
block/bounce.c
crypto/crypto_user_base.c
crypto/crypto_user_stat.c
crypto/simd.c
drivers/acpi/Kconfig
drivers/acpi/nfit/core.c
drivers/acpi/nfit/mce.c
drivers/ata/libata-core.c
drivers/ata/sata_rcar.c
drivers/block/floppy.c
drivers/block/xen-blkfront.c
drivers/clk/clk-fixed-factor.c
drivers/clk/meson/axg.c
drivers/clk/meson/gxbb.c
drivers/clk/qcom/gcc-qcs404.c
drivers/clocksource/i8253.c
drivers/cpufreq/imx6q-cpufreq.c
drivers/cpuidle/cpuidle-arm.c
drivers/crypto/hisilicon/sec/sec_algs.c
drivers/firmware/efi/arm-init.c
drivers/firmware/efi/arm-runtime.c
drivers/firmware/efi/efi.c
drivers/firmware/efi/libstub/arm-stub.c
drivers/firmware/efi/libstub/fdt.c
drivers/firmware/efi/memmap.c
drivers/firmware/efi/runtime-wrappers.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/vega10_ih.c
drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
drivers/gpu/drm/amd/include/amd_shared.h
drivers/gpu/drm/amd/include/atomfirmware.h
drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_fourcc.c
drivers/gpu/drm/etnaviv/etnaviv_sched.c
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/gtt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/mmio_context.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_gtt.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hotplug.c
drivers/gpu/drm/i915/intel_lpe_audio.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/selftests/huge_pages.c
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
drivers/gpu/drm/meson/meson_venc.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.c
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/venc.c
drivers/gpu/drm/omapdrm/omap_crtc.c
drivers/gpu/drm/sun4i/sun4i_lvds.c
drivers/gpu/drm/sun4i/sun4i_rgb.c
drivers/gpu/drm/sun4i/sun4i_tcon.c
drivers/gpu/vga/vga_switcheroo.c
drivers/hid/hid-alps.c
drivers/hid/hid-asus.c
drivers/hid/hid-ids.h
drivers/hid/hid-quirks.c
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
drivers/hid/usbhid/hiddev.c
drivers/hwmon/hwmon.c
drivers/hwmon/ibmpowernv.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-nvidia-gpu.c [new file with mode: 0644]
drivers/i2c/busses/i2c-qcom-geni.c
drivers/leds/trigger/ledtrig-pattern.c
drivers/mtd/devices/Kconfig
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/spi-nor/cadence-quadspi.c
drivers/mtd/spi-nor/spi-nor.c
drivers/net/bonding/bond_main.c
drivers/net/can/dev.c
drivers/net/can/flexcan.c
drivers/net/can/rcar/rcar_can.c
drivers/net/can/rx-offload.c
drivers/net/can/spi/hi311x.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
drivers/net/can/usb/ucan.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mv88e6xxx/global1.c
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/amazon/ena/ena_netdev.h
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
drivers/net/ethernet/aquantia/atlantic/aq_main.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
drivers/net/ethernet/atheros/alx/alx.h
drivers/net/ethernet/atheros/alx/main.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/chelsio/Kconfig
drivers/net/ethernet/chelsio/cxgb4/Makefile
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_switch.h
drivers/net/ethernet/intel/ice/ice_txrx.c
drivers/net/ethernet/intel/ice/ice_txrx.h
drivers/net/ethernet/intel/ice/ice_type.h
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
drivers/net/ethernet/intel/igb/igb_ptp.c
drivers/net/ethernet/lantiq_xrx200.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/alloc.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/qlogic/qed/qed_dcbx.c
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_fcoe.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/ethernet/qlogic/qed/qed_iscsi.c
drivers/net/ethernet/qlogic/qed/qed_l2.c
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_rdma.c
drivers/net/ethernet/qlogic/qed/qed_rdma.h
drivers/net/ethernet/qlogic/qed/qed_roce.c
drivers/net/ethernet/qlogic/qed/qed_sp.h
drivers/net/ethernet/qlogic/qed/qed_sp_commands.c
drivers/net/ethernet/qlogic/qed/qed_spq.c
drivers/net/ethernet/qlogic/qed/qed_sriov.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/descs_com.h
drivers/net/ethernet/stmicro/stmmac/enh_desc.c
drivers/net/ethernet/stmicro/stmmac/ring_mode.c
drivers/net/fddi/defza.c
drivers/net/fddi/defza.h
drivers/net/phy/broadcom.c
drivers/net/phy/mdio-gpio.c
drivers/net/phy/realtek.c
drivers/net/tun.c
drivers/net/usb/smsc95xx.c
drivers/nvme/host/core.c
drivers/nvme/host/multipath.c
drivers/nvme/target/core.c
drivers/nvme/target/rdma.c
drivers/of/device.c
drivers/of/of_numa.c
drivers/pci/pci-acpi.c
drivers/pinctrl/meson/pinctrl-meson-gxbb.c
drivers/pinctrl/meson/pinctrl-meson-gxl.c
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/meson/pinctrl-meson8.c
drivers/pinctrl/meson/pinctrl-meson8b.c
drivers/rtc/hctosys.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-pcf2127.c
drivers/s390/net/ism_drv.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_mpc.h
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/scsi/Kconfig
drivers/scsi/NCR5380.c
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/myrb.c
drivers/scsi/myrs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_lib.c
drivers/scsi/ufs/ufshcd.c
drivers/target/target_core_transport.c
drivers/tty/serial/sh-sci.c
drivers/tty/tty_baudrate.c
drivers/tty/vt/vt.c
drivers/usb/typec/ucsi/Kconfig
drivers/usb/typec/ucsi/Makefile
drivers/usb/typec/ucsi/ucsi_ccg.c [new file with mode: 0644]
drivers/xen/grant-table.c
drivers/xen/privcmd-buf.c
fs/afs/rxrpc.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/super.c
fs/btrfs/tree-checker.c
fs/btrfs/tree-log.c
fs/ceph/file.c
fs/ceph/mds_client.c
fs/ceph/quota.c
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/fuse/dev.c
fs/fuse/file.c
fs/gfs2/bmap.c
fs/gfs2/rgrp.c
fs/inode.c
fs/namespace.c
fs/nfs/callback_proc.c
fs/nfs/delegation.c
fs/nfs/nfs4state.c
fs/nfsd/nfs4proc.c
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
fs/ocfs2/aops.c
fs/ocfs2/cluster/masklog.h
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_message.c
include/asm-generic/4level-fixup.h
include/asm-generic/5level-fixup.h
include/asm-generic/pgtable-nop4d-hack.h
include/asm-generic/pgtable-nop4d.h
include/asm-generic/pgtable-nopmd.h
include/asm-generic/pgtable-nopud.h
include/asm-generic/pgtable.h
include/linux/can/dev.h
include/linux/can/rx-offload.h
include/linux/ceph/ceph_features.h
include/linux/compiler-gcc.h
include/linux/compiler.h
include/linux/compiler_attributes.h
include/linux/compiler_types.h
include/linux/efi.h
include/linux/hid.h
include/linux/i8253.h
include/linux/mm.h
include/linux/mtd/nand.h
include/linux/netdevice.h
include/linux/netfilter/ipset/ip_set.h
include/linux/netfilter/ipset/ip_set_comment.h
include/linux/nmi.h
include/net/addrconf.h
include/net/af_rxrpc.h
include/net/if_inet6.h
include/net/netfilter/nf_conntrack_l4proto.h
include/net/sctp/sctp.h
include/trace/events/kyber.h
include/trace/events/rxrpc.h
include/uapi/linux/kfd_ioctl.h
include/uapi/linux/netfilter/nf_tables.h
include/uapi/linux/netfilter_bridge.h
include/uapi/linux/sctp.h
include/xen/xen-ops.h
kernel/bpf/core.c
kernel/bpf/syscall.c
kernel/debug/kdb/kdb_bt.c
kernel/debug/kdb/kdb_io.c
kernel/debug/kdb/kdb_keyboard.c
kernel/debug/kdb/kdb_main.c
kernel/debug/kdb/kdb_private.h
kernel/debug/kdb/kdb_support.c
kernel/resource.c
kernel/sched/core.c
kernel/sched/fair.c
kernel/sched/psi.c
kernel/time/posix-cpu-timers.c
kernel/trace/trace_probe.c
kernel/user_namespace.c
lib/raid6/test/Makefile
lib/ubsan.c
mm/gup.c
mm/hugetlb.c
mm/memblock.c
mm/page_alloc.c
mm/shmem.c
mm/swapfile.c
mm/vmstat.c
mm/z3fold.c
net/batman-adv/bat_v_elp.c
net/batman-adv/fragmentation.c
net/bridge/br_private.h
net/bridge/br_vlan.c
net/can/raw.c
net/core/dev.c
net/core/flow_dissector.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/inet_fragment.c
net/ipv4/ip_fragment.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel_core.c
net/ipv6/af_inet6.c
net/ipv6/anycast.c
net/ipv6/ip6_fib.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/route.c
net/l2tp/l2tp_core.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/ipset/ip_set_hash_netportnet.c
net/netfilter/ipset/ip_set_list_set.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_icmp.c
net/netfilter/nf_conntrack_proto_icmpv6.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nft_compat.c
net/netfilter/nft_numgen.c
net/netfilter/nft_osf.c
net/netfilter/xt_IDLETIMER.c
net/openvswitch/conntrack.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-internal.h
net/rxrpc/call_event.c
net/rxrpc/output.c
net/sched/act_mirred.c
net/sched/act_pedit.c
net/sched/cls_flower.c
net/sched/sch_fq.c
net/sched/sch_netem.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/socket.c
net/sctp/stream.c
net/socket.c
net/sunrpc/auth_generic.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/xdr.c
net/tipc/discover.c
net/tipc/link.c
net/tipc/net.c
net/tipc/net.h
net/tipc/socket.c
scripts/faddr2line
scripts/kconfig/merge_config.sh
scripts/package/builddeb
scripts/package/mkdebian
scripts/package/mkspec
scripts/setlocalversion
scripts/spdxcheck.py
security/integrity/digsig_asymmetric.c
security/selinux/hooks.c
security/selinux/ss/mls.c
sound/pci/hda/thinkpad_helper.c
tools/arch/arm64/include/asm/barrier.h
tools/perf/Documentation/perf-list.txt
tools/perf/Makefile.perf
tools/perf/builtin-record.c
tools/perf/builtin-stat.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/examples/bpf/augmented_raw_syscalls.c [new file with mode: 0644]
tools/perf/jvmti/jvmti_agent.c
tools/perf/scripts/python/exported-sql-viewer.py
tools/perf/tests/attr/test-record-group-sampling
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
tools/perf/util/intel-pt-decoder/intel-pt-log.c
tools/perf/util/intel-pt-decoder/intel-pt-log.h
tools/perf/util/intel-pt.c
tools/perf/util/pmu.c
tools/testing/nvdimm/test/nfit.c
tools/testing/selftests/powerpc/mm/wild_bctr.c
tools/testing/selftests/tc-testing/tdc.py

index a76be45fef6ca5b2d23139304ff5ea338bdd1d07..28fecafa65069c1af077453a4159a6a290949982 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -159,6 +159,7 @@ Peter Oruba <peter@oruba.de>
 Peter Oruba <peter.oruba@amd.com>
 Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
 Praveen BP <praveenbp@ti.com>
+Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com>
 Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com>
 Oleksij Rempel <linux@rempel-privat.de> <bug-track@fisher-privat.net>
 Oleksij Rempel <linux@rempel-privat.de> <external.Oleksij.Rempel@de.bosch.com>
diff --git a/CREDITS b/CREDITS
index 5befd2d714d0037548bed049a979dc4fcee1d300..84cbec4c62115adc38b976504b04799bb6fb0469 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2138,6 +2138,10 @@ E: paul@laufernet.com
 D: Soundblaster driver fixes, ISAPnP quirk
 S: California, USA
 
+N: Jarkko Lavinen
+E: jarkko.lavinen@nokia.com
+D: OMAP MMC support
+
 N: Jonathan Layes
 D: ARPD support
 
index fb3d1e03b8819bb950e961172d27dac3a3191129..1e5d172e064624d96216eae51a4be60c02a29979 100644 (file)
@@ -37,8 +37,8 @@ Description:
                  0-|   /             \/             \/
                    +---0----1----2----3----4----5----6------------> time (s)
 
-               2. To make the LED go instantly from one brigntess value to another,
-               we should use use zero-time lengths (the brightness must be same as
+               2. To make the LED go instantly from one brightness value to another,
+               we should use zero-time lengths (the brightness must be same as
                the previous tuple's). So the format should be:
                "brightness_1 duration_1 brightness_1 0 brightness_2 duration_2
                brightness_2 0 ...". For example:
index 47153e64dfb530465ca01d28272e058293eb08b5..7eca9026a9ed2c3ed2a35b7e2184660e8caa9fdf 100644 (file)
@@ -150,7 +150,7 @@ data structures necessary to handle the given policy and, possibly, to add
 a governor ``sysfs`` interface to it.  Next, the governor is started by
 invoking its ``->start()`` callback.
 
-That callback it expected to register per-CPU utilization update callbacks for
+That callback is expected to register per-CPU utilization update callbacks for
 all of the online CPUs belonging to the given policy with the CPU scheduler.
 The utilization update callbacks will be invoked by the CPU scheduler on
 important events, like task enqueue and dequeue, on every iteration of the
index a873855c811d63f3a47cd2ec830404abb89d48c8..14378cecb1723f7d9b4b4f3b0b1ccd0ca3126c26 100644 (file)
@@ -86,9 +86,11 @@ transitions.
 This will give a fine grained information about all the CPU frequency
 transitions. The cat output here is a two dimensional matrix, where an entry
 <i,j> (row i, column j) represents the count of number of transitions from 
-Freq_i to Freq_j. Freq_i is in descending order with increasing rows and 
-Freq_j is in descending order with increasing columns. The output here also 
-contains the actual freq values for each row and column for better readability.
+Freq_i to Freq_j. Freq_i rows and Freq_j columns follow the sorting order in
+which the driver has provided the frequency table initially to the cpufreq core
+and so can be sorted (ascending or descending) or unsorted.  The output here
+also contains the actual freq values for each row and column for better
+readability.
 
 If the transition table is bigger than PAGE_SIZE, reading this will
 return an -EFBIG error.
index f5e0f82fd5031efb1570361eabf2d096769ef7f5..58c4256d37a39e5082cdb5f354548dbe0cf160d6 100644 (file)
@@ -27,7 +27,7 @@ SoCs:
     compatible = "renesas,r8a77470"
   - RZ/G2M (R8A774A1)
     compatible = "renesas,r8a774a1"
-  - RZ/G2E (RA8774C0)
+  - RZ/G2E (R8A774C0)
     compatible = "renesas,r8a774c0"
   - R-Car M1A (R8A77781)
     compatible = "renesas,r8a7778"
diff --git a/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt b/Documentation/devicetree/bindings/cpufreq/arm_big_little_dt.txt
deleted file mode 100644 (file)
index 2aa06ac..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-Generic ARM big LITTLE cpufreq driver's DT glue
------------------------------------------------
-
-This is DT specific glue layer for generic cpufreq driver for big LITTLE
-systems.
-
-Both required and optional properties listed below must be defined
-under node /cpus/cpu@x. Where x is the first cpu inside a cluster.
-
-FIXME: Cpus should boot in the order specified in DT and all cpus for a cluster
-must be present contiguously. Generic DT driver will check only node 'x' for
-cpu:x.
-
-Required properties:
-- operating-points: Refer to Documentation/devicetree/bindings/opp/opp.txt
-  for details
-
-Optional properties:
-- clock-latency: Specify the possible maximum transition latency for clock,
-  in unit of nanoseconds.
-
-Examples:
-
-cpus {
-       #address-cells = <1>;
-       #size-cells = <0>;
-
-       cpu@0 {
-               compatible = "arm,cortex-a15";
-               reg = <0>;
-               next-level-cache = <&L2>;
-               operating-points = <
-                       /* kHz    uV */
-                       792000  1100000
-                       396000  950000
-                       198000  850000
-               >;
-               clock-latency = <61036>; /* two CLK32 periods */
-       };
-
-       cpu@1 {
-               compatible = "arm,cortex-a15";
-               reg = <1>;
-               next-level-cache = <&L2>;
-       };
-
-       cpu@100 {
-               compatible = "arm,cortex-a7";
-               reg = <100>;
-               next-level-cache = <&L2>;
-               operating-points = <
-                       /* kHz    uV */
-                       792000  950000
-                       396000  750000
-                       198000  450000
-               >;
-               clock-latency = <61036>; /* two CLK32 periods */
-       };
-
-       cpu@101 {
-               compatible = "arm,cortex-a7";
-               reg = <101>;
-               next-level-cache = <&L2>;
-       };
-};
index 7e49839d41249ca5168b0de1ea02781a2798486d..4b90ba9f31b70b712c285af7ef7f7be180b39b14 100644 (file)
@@ -1,8 +1,12 @@
 I2C for OMAP platforms
 
 Required properties :
-- compatible : Must be "ti,omap2420-i2c", "ti,omap2430-i2c", "ti,omap3-i2c"
-  or "ti,omap4-i2c"
+- compatible : Must be
+       "ti,omap2420-i2c" for OMAP2420 SoCs
+       "ti,omap2430-i2c" for OMAP2430 SoCs
+       "ti,omap3-i2c" for OMAP3 SoCs
+       "ti,omap4-i2c" for OMAP4+ SoCs
+       "ti,am654-i2c", "ti,omap4-i2c" for AM654 SoCs
 - ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
 - #address-cells = <1>;
 - #size-cells = <0>;
index 903a78da65be288cf750af872584b60e9f42c06f..3a9926f99937039022d283817beac8e9bcbbc926 100644 (file)
@@ -17,7 +17,7 @@ Example:
                reg = <1>;
                clocks = <&clk32m>;
                interrupt-parent = <&gpio4>;
-               interrupts = <13 IRQ_TYPE_EDGE_RISING>;
+               interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
                vdd-supply = <&reg5v0>;
                xceiver-supply = <&reg5v0>;
        };
index cc4372842bf37670284d9b676699b5eb00882de9..9936b9ee67c36672afeb050a5641aa44cebbb728 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
 - compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC.
              "renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC.
              "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
+             "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
              "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
              "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
              "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC.
@@ -14,26 +15,32 @@ Required properties:
              "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
              "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
              "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
+             "renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC.
              "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
              "renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
              compatible device.
-             "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device.
+             "renesas,rcar-gen3-can" for a generic R-Car Gen3 or RZ/G2
+             compatible device.
              When compatible with the generic version, nodes must list the
              SoC-specific version corresponding to the platform first
              followed by the generic version.
 
 - reg: physical base address and size of the R-Car CAN register map.
 - interrupts: interrupt specifier for the sole interrupt.
-- clocks: phandles and clock specifiers for 3 CAN clock inputs.
-- clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk".
+- clocks: phandles and clock specifiers for 2 CAN clock inputs for RZ/G2
+         devices.
+         phandles and clock specifiers for 3 CAN clock inputs for every other
+         SoC.
+- clock-names: 2 clock input name strings for RZ/G2: "clkp1", "can_clk".
+              3 clock input name strings for every other SoC: "clkp1", "clkp2",
+              "can_clk".
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for "renesas,can-r8a7795" and "renesas,can-r8a7796"
-compatible:
-In R8A7795 and R8A7796 SoCs, "clkp2" can be CANFD clock. This is a div6 clock
-and can be used by both CAN and CAN FD controller at the same time. It needs to
-be scaled to maximum frequency if any of these controllers use it. This is done
+Required properties for R8A7795, R8A7796 and R8A77965:
+For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
+be used by both CAN and CAN FD controller at the same time. It needs to be
+scaled to maximum frequency if any of these controllers use it. This is done
 using the below properties:
 
 - assigned-clocks: phandle of clkp2(CANFD) clock.
@@ -42,8 +49,9 @@ using the below properties:
 Optional properties:
 - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are:
                            <0x0> (default) : Peripheral clock (clkp1)
-                           <0x1> : Peripheral clock (clkp2)
-                           <0x3> : Externally input clock
+                           <0x1> : Peripheral clock (clkp2) (not supported by
+                                   RZ/G2 devices)
+                           <0x3> : External input clock
 
 Example
 -------
diff --git a/Documentation/i2c/busses/i2c-nvidia-gpu b/Documentation/i2c/busses/i2c-nvidia-gpu
new file mode 100644 (file)
index 0000000..31884d2
--- /dev/null
@@ -0,0 +1,18 @@
+Kernel driver i2c-nvidia-gpu
+
+Datasheet: not publicly available.
+
+Authors:
+       Ajay Gupta <ajayg@nvidia.com>
+
+Description
+-----------
+
+i2c-nvidia-gpu is a driver for I2C controller included in NVIDIA Turing
+and later GPUs and it is used to communicate with Type-C controller on GPUs.
+
+If your 'lspci -v' listing shows something like the following,
+
+01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device 1ad9 (rev a1)
+
+then this driver should support the I2C controller of your GPU.
index 605e00cdd6beb1d024519ab8417464fc12064724..89f1302d593a5c0404ed8a434ba580e8440a9139 100644 (file)
@@ -1056,18 +1056,23 @@ The kernel interface functions are as follows:
 
        u32 rxrpc_kernel_check_life(struct socket *sock,
                                    struct rxrpc_call *call);
+       void rxrpc_kernel_probe_life(struct socket *sock,
+                                    struct rxrpc_call *call);
 
-     This returns a number that is updated when ACKs are received from the peer
-     (notably including PING RESPONSE ACKs which we can elicit by sending PING
-     ACKs to see if the call still exists on the server).  The caller should
-     compare the numbers of two calls to see if the call is still alive after
-     waiting for a suitable interval.
+     The first function returns a number that is updated when ACKs are received
+     from the peer (notably including PING RESPONSE ACKs which we can elicit by
+     sending PING ACKs to see if the call still exists on the server).  The
+     caller should compare the numbers of two calls to see if the call is still
+     alive after waiting for a suitable interval.
 
      This allows the caller to work out if the server is still contactable and
      if the call is still alive on the server whilst waiting for the server to
      process a client operation.
 
-     This function may transmit a PING ACK.
+     The second function causes a ping ACK to be transmitted to try to provoke
+     the peer into responding, which would then cause the value returned by the
+     first function to change.  Note that this must be called in TASK_RUNNING
+     state.
 
  (*) Get reply timestamp.
 
index 73aaaa3da4369e39b41bf360b24b820061a15df9..804f9426ed17bdcf0c8fb6dc682ae9254050beb9 100644 (file)
@@ -34,23 +34,24 @@ __________________|____________|__________________|_________|___________________
 ____________________________________________________________|___________________________________________________________
                   |            |                  |         |
  ffff800000000000 | -128    TB | ffff87ffffffffff |    8 TB | ... guard hole, also reserved for hypervisor
- ffff880000000000 | -120    TB | ffffc7ffffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)
- ffffc80000000000 |  -56    TB | ffffc8ffffffffff |    1 TB | ... unused hole
+ ffff880000000000 | -120    TB | ffff887fffffffff |  0.5 TB | LDT remap for PTI
+ ffff888000000000 | -119.5  TB | ffffc87fffffffff |   64 TB | direct mapping of all physical memory (page_offset_base)
+ ffffc88000000000 |  -55.5  TB | ffffc8ffffffffff |  0.5 TB | ... unused hole
  ffffc90000000000 |  -55    TB | ffffe8ffffffffff |   32 TB | vmalloc/ioremap space (vmalloc_base)
  ffffe90000000000 |  -23    TB | ffffe9ffffffffff |    1 TB | ... unused hole
  ffffea0000000000 |  -22    TB | ffffeaffffffffff |    1 TB | virtual memory map (vmemmap_base)
  ffffeb0000000000 |  -21    TB | ffffebffffffffff |    1 TB | ... unused hole
  ffffec0000000000 |  -20    TB | fffffbffffffffff |   16 TB | KASAN shadow memory
- fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
-                  |            |                  |         | vaddr_end for KASLR
- fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
- fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | LDT remap for PTI
- ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
 __________________|____________|__________________|_________|____________________________________________________________
                                                             |
-                                                            | Identical layout to the 47-bit one from here on:
+                                                            | Identical layout to the 56-bit one from here on:
 ____________________________________________________________|____________________________________________________________
                   |            |                  |         |
+ fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
+                  |            |                  |         | vaddr_end for KASLR
+ fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
+ fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
+ ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
  ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
  ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
  ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
@@ -83,7 +84,7 @@ Notes:
 __________________|____________|__________________|_________|___________________________________________________________
                   |            |                  |         |
  0000800000000000 |  +64    PB | ffff7fffffffffff | ~16K PB | ... huge, still almost 64 bits wide hole of non-canonical
-                  |            |                  |         |     virtual memory addresses up to the -128 TB
+                  |            |                  |         |     virtual memory addresses up to the -64 PB
                   |            |                  |         |     starting offset of kernel mappings.
 __________________|____________|__________________|_________|___________________________________________________________
                                                             |
@@ -91,23 +92,24 @@ __________________|____________|__________________|_________|___________________
 ____________________________________________________________|___________________________________________________________
                   |            |                  |         |
  ff00000000000000 |  -64    PB | ff0fffffffffffff |    4 PB | ... guard hole, also reserved for hypervisor
- ff10000000000000 |  -60    PB | ff8fffffffffffff |   32 PB | direct mapping of all physical memory (page_offset_base)
- ff90000000000000 |  -28    PB | ff9fffffffffffff |    4 PB | LDT remap for PTI
+ ff10000000000000 |  -60    PB | ff10ffffffffffff | 0.25 PB | LDT remap for PTI
+ ff11000000000000 |  -59.75 PB | ff90ffffffffffff |   32 PB | direct mapping of all physical memory (page_offset_base)
+ ff91000000000000 |  -27.75 PB | ff9fffffffffffff | 3.75 PB | ... unused hole
  ffa0000000000000 |  -24    PB | ffd1ffffffffffff | 12.5 PB | vmalloc/ioremap space (vmalloc_base)
  ffd2000000000000 |  -11.5  PB | ffd3ffffffffffff |  0.5 PB | ... unused hole
  ffd4000000000000 |  -11    PB | ffd5ffffffffffff |  0.5 PB | virtual memory map (vmemmap_base)
  ffd6000000000000 |  -10.5  PB | ffdeffffffffffff | 2.25 PB | ... unused hole
  ffdf000000000000 |   -8.25 PB | fffffdffffffffff |   ~8 PB | KASAN shadow memory
- fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
-                  |            |                  |         | vaddr_end for KASLR
- fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
- fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
- ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
 __________________|____________|__________________|_________|____________________________________________________________
                                                             |
                                                             | Identical layout to the 47-bit one from here on:
 ____________________________________________________________|____________________________________________________________
                   |            |                  |         |
+ fffffc0000000000 |   -4    TB | fffffdffffffffff |    2 TB | ... unused hole
+                  |            |                  |         | vaddr_end for KASLR
+ fffffe0000000000 |   -2    TB | fffffe7fffffffff |  0.5 TB | cpu_entry_area mapping
+ fffffe8000000000 |   -1.5  TB | fffffeffffffffff |  0.5 TB | ... unused hole
+ ffffff0000000000 |   -1    TB | ffffff7fffffffff |  0.5 TB | %esp fixup stacks
  ffffff8000000000 | -512    GB | ffffffeeffffffff |  444 GB | ... unused hole
  ffffffef00000000 |  -68    GB | fffffffeffffffff |   64 GB | EFI region mapping space
  ffffffff00000000 |   -4    GB | ffffffff7fffffff |    2 GB | ... unused hole
index 97b7adbceda4828ab217301a305a3b20892d0603..68aed077f7b62ed0e70315bde602bfbec50a78bf 100644 (file)
@@ -25,7 +25,7 @@ Offset        Proto   Name            Meaning
 0C8/004        ALL     ext_cmd_line_ptr  cmd_line_ptr high 32bits
 140/080        ALL     edid_info       Video mode setup (struct edid_info)
 1C0/020        ALL     efi_info        EFI 32 information (struct efi_info)
-1E0/004        ALL     alk_mem_k       Alternative mem check, in KB
+1E0/004        ALL     alt_mem_k       Alternative mem check, in KB
 1E4/004        ALL     scratch         Scratch field for the kernel setup code
 1E8/001        ALL     e820_entries    Number of entries in e820_table (below)
 1E9/001        ALL     eddbuf_entries  Number of entries in eddbuf (below)
index f4855974f325063c1e5fea88d9d755ce75ee3b66..d258515ac1171e1353d26c0acbd30c772ea4b358 100644 (file)
@@ -717,7 +717,7 @@ F:  include/linux/mfd/altera-a10sr.h
 F:     include/dt-bindings/reset/altr,rst-mgr-a10sr.h
 
 ALTERA TRIPLE SPEED ETHERNET DRIVER
-M:     Vince Bridgers <vbridger@opensource.altera.com>
+M:     Thor Thayer <thor.thayer@linux.intel.com>
 L:     netdev@vger.kernel.org
 L:     nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 S:     Maintained
@@ -3276,6 +3276,12 @@ F:       include/uapi/linux/caif/
 F:     include/net/caif/
 F:     net/caif/
 
+CAKE QDISC
+M:     Toke Høiland-Jørgensen <toke@toke.dk>
+L:     cake@lists.bufferbloat.net (moderated for non-subscribers)
+S:     Maintained
+F:     net/sched/sch_cake.c
+
 CALGARY x86-64 IOMMU
 M:     Muli Ben-Yehuda <mulix@mulix.org>
 M:     Jon Mason <jdmason@kudzu.us>
@@ -5528,6 +5534,7 @@ F:        net/bridge/
 ETHERNET PHY LIBRARY
 M:     Andrew Lunn <andrew@lunn.ch>
 M:     Florian Fainelli <f.fainelli@gmail.com>
+M:     Heiner Kallweit <hkallweit1@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/ABI/testing/sysfs-bus-mdio
@@ -6607,9 +6614,9 @@ F:        arch/*/include/asm/suspend*.h
 
 HID CORE LAYER
 M:     Jiri Kosina <jikos@kernel.org>
-R:     Benjamin Tissoires <benjamin.tissoires@redhat.com>
+M:     Benjamin Tissoires <benjamin.tissoires@redhat.com>
 L:     linux-input@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
 S:     Maintained
 F:     drivers/hid/
 F:     include/linux/hid*
@@ -6861,6 +6868,13 @@ L:       linux-acpi@vger.kernel.org
 S:     Maintained
 F:     drivers/i2c/i2c-core-acpi.c
 
+I2C CONTROLLER DRIVER FOR NVIDIA GPU
+M:     Ajay Gupta <ajayg@nvidia.com>
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+F:     Documentation/i2c/busses/i2c-nvidia-gpu
+F:     drivers/i2c/busses/i2c-nvidia-gpu.c
+
 I2C MUXES
 M:     Peter Rosin <peda@axentia.se>
 L:     linux-i2c@vger.kernel.org
@@ -8367,7 +8381,7 @@ F:        drivers/media/dvb-frontends/lgdt3305.*
 LIBATA PATA ARASAN COMPACT FLASH CONTROLLER
 M:     Viresh Kumar <vireshk@kernel.org>
 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:     include/linux/pata_arasan_cf_data.h
 F:     drivers/ata/pata_arasan_cf.c
@@ -8384,7 +8398,7 @@ F:        drivers/ata/ata_generic.c
 LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS
 M:     Linus Walleij <linus.walleij@linaro.org>
 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_ftide010.c
 F:     drivers/ata/sata_gemini.c
@@ -8403,7 +8417,7 @@ F:        include/linux/ahci_platform.h
 LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER
 M:     Mikael Pettersson <mikpelinux@gmail.com>
 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/sata_promise.*
 
@@ -10784,6 +10798,14 @@ L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     arch/arm/mach-omap2/omap_hwmod.*
 
+OMAP I2C DRIVER
+M:     Vignesh R <vigneshr@ti.com>
+L:     linux-omap@vger.kernel.org
+L:     linux-i2c@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/i2c/i2c-omap.txt
+F:     drivers/i2c/busses/i2c-omap.c
+
 OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:     linux-media@vger.kernel.org
@@ -10793,9 +10815,9 @@ F:      drivers/media/platform/omap3isp/
 F:     drivers/staging/media/omap4iss/
 
 OMAP MMC SUPPORT
-M:     Jarkko Lavinen <jarkko.lavinen@nokia.com>
+M:     Aaro Koskinen <aaro.koskinen@iki.fi>
 L:     linux-omap@vger.kernel.org
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/mmc/host/omap.c
 
 OMAP POWER MANAGEMENT SUPPORT
@@ -11730,6 +11752,7 @@ F:      Documentation/devicetree/bindings/pinctrl/fsl,*
 PIN CONTROLLER - INTEL
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
 M:     Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git
 S:     Maintained
 F:     drivers/pinctrl/intel/
 
@@ -15436,9 +15459,9 @@ F:      include/linux/usb/gadget*
 
 USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
 M:     Jiri Kosina <jikos@kernel.org>
-R:     Benjamin Tissoires <benjamin.tissoires@redhat.com>
+M:     Benjamin Tissoires <benjamin.tissoires@redhat.com>
 L:     linux-usb@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
 S:     Maintained
 F:     Documentation/hid/hiddev.txt
 F:     drivers/hid/usbhid/
index 9fce8b91c15f6055f534eb18432e706a5ac3b09c..ddbf627cad8f5fd8a2d0d06a913294d88a0ff878 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 20
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = "People's Front"
 
 # *DOCUMENTATION*
index 6a8c53dec57e6e3aa22a5be371b922ebb1bd154d..b7c77bb1bfd20368a8ff95a93d5493353e58023a 100644 (file)
 })
 
 #define user_termios_to_kernel_termios(k, u) \
-       copy_from_user(k, u, sizeof(struct termios))
+       copy_from_user(k, u, sizeof(struct termios2))
 
 #define kernel_termios_to_user_termios(u, k) \
+       copy_to_user(u, k, sizeof(struct termios2))
+
+#define user_termios_to_kernel_termios_1(k, u) \
+       copy_from_user(k, u, sizeof(struct termios))
+
+#define kernel_termios_to_user_termios_1(u, k) \
        copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* _ALPHA_TERMIOS_H */
index 1e9121c9b3c74c16d129ce6fac97f614080dca94..971311605288faea94b19d23d0b346361a11a6a9 100644 (file)
 #define TCXONC         _IO('t', 30)
 #define TCFLSH         _IO('t', 31)
 
+#define TCGETS2                _IOR('T', 42, struct termios2)
+#define TCSETS2                _IOW('T', 43, struct termios2)
+#define TCSETSW2       _IOW('T', 44, struct termios2)
+#define TCSETSF2       _IOW('T', 45, struct termios2)
+
 #define TIOCSWINSZ     _IOW('t', 103, struct winsize)
 #define TIOCGWINSZ     _IOR('t', 104, struct winsize)
 #define        TIOCSTART       _IO('t', 110)           /* start output, like ^Q */
index de6c8360fbe3657e3ddf7cd6bb648a3d8b0fdb71..4575ba34a0eaeecb9b17cb9f3b6b18a698bafdfb 100644 (file)
@@ -26,6 +26,19 @@ struct termios {
        speed_t c_ospeed;               /* output speed */
 };
 
+/* Alpha has identical termios and termios2 */
+
+struct termios2 {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_cc[NCCS];                /* control characters */
+       cc_t c_line;                    /* line discipline (== c_cc[19]) */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
 /* Alpha has matching termios and ktermios */
 
 struct ktermios {
@@ -152,6 +165,7 @@ struct ktermios {
 #define B3000000  00034
 #define B3500000  00035
 #define B4000000  00036
+#define BOTHER    00037
 
 #define CSIZE  00001400
 #define   CS5  00000000
@@ -169,6 +183,9 @@ struct ktermios {
 #define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
 
+#define CIBAUD 07600000
+#define IBSHIFT        16
+
 /* c_lflag bits */
 #define ISIG   0x00000080
 #define ICANON 0x00000100
index b560ff88459bf1b74a0c093f3bdc15d2118c0182..5ff9a179c83c3326ab2dec5fdceee155021bf716 100644 (file)
@@ -55,7 +55,7 @@
        };
 
        chosen {
-               stdout-path = "&uart1:115200n8";
+               stdout-path = "serial0:115200n8";
        };
 
        memory@70000000 {
index ed9a980bce8501fcca0c3d357a8440cb8debd59d..beefa1b2049d7b56476a62429c2b4e4abf65ad33 100644 (file)
                        i2c1: i2c@21a0000 {
                                #address-cells = <1>;
                                #size-cells = <0>;
-                               compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+                               compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
                                reg = <0x021a0000 0x4000>;
                                interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SLL_CLK_I2C1>;
index 53b3408b5fab1845248b2b7ff078eba462f730ab..7d7d679945d28efe4f827e1b6197001088826b7f 100644 (file)
                regulator-name = "enet_3v3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
-               gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+               gpio = <&gpio2 6 GPIO_ACTIVE_LOW>;
+               regulator-boot-on;
+               regulator-always-on;
        };
 
        reg_pcie_gpio: regulator-pcie-gpio {
        phy-supply = <&reg_enet_3v3>;
        phy-mode = "rgmii";
        phy-handle = <&ethphy1>;
+       phy-reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
        status = "okay";
 
        mdio {
                                MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3   0x3081
                                MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN    0x3081
                                MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M       0x91
+                               /* phy reset */
+                               MX6SX_PAD_ENET2_CRS__GPIO2_IO_7         0x10b0
                        >;
                };
 
index 41ec66a969907d492dabec284e6a101f592e0216..ca62495587602f44d3e514fb2df910edfc584ea1 100644 (file)
@@ -50,8 +50,8 @@
        compatible = "fsl,vf610m4";
 
        chosen {
-               bootargs = "console=ttyLP2,115200 clk_ignore_unused init=/linuxrc rw";
-               stdout-path = "&uart2";
+               bootargs = "clk_ignore_unused init=/linuxrc rw";
+               stdout-path = "serial2:115200";
        };
 
        memory@8c000000 {
index 1c7616815a86ab80fa81ffacbb509a2408554cfa..63af6234c1b69a20b763470a8a73a989e1d7f747 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EMBEDDED=y
index 0d289240b6ca110ab961a280ddd20fc1c567f2a4..775cac3c02bb0a31facb970e16feef83f86c6632 100644 (file)
 #include <linux/kernel.h>
 
 extern unsigned int processor_id;
+struct proc_info_list *lookup_processor(u32 midr);
 
 #ifdef CONFIG_CPU_CP15
 #define read_cpuid(reg)                                                        \
index 92fd2c8a9af0638834d6c2b5814b9a88911f33fe..12659ce5c1f38e2f166937b18957c4fbf5732c3d 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef _ASM_PGTABLE_2LEVEL_H
 #define _ASM_PGTABLE_2LEVEL_H
 
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 
 /*
  * Hardware-wise, we have a two level page table structure, where the first
index e25f4392e1b2868446de858701d408aaaee26eab..e1b6f280ab088fb0b8ac59b6ceb3543606c97e01 100644 (file)
@@ -23,7 +23,7 @@ struct mm_struct;
 /*
  * Don't change this structure - ASM code relies on it.
  */
-extern struct processor {
+struct processor {
        /* MISC
         * get data abort address/flags
         */
@@ -79,9 +79,13 @@ extern struct processor {
        unsigned int suspend_size;
        void (*do_suspend)(void *);
        void (*do_resume)(void *);
-} processor;
+};
 
 #ifndef MULTI_CPU
+static inline void init_proc_vtable(const struct processor *p)
+{
+}
+
 extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
@@ -98,17 +102,50 @@ extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn));
 extern void cpu_do_suspend(void *);
 extern void cpu_do_resume(void *);
 #else
-#define cpu_proc_init                  processor._proc_init
-#define cpu_proc_fin                   processor._proc_fin
-#define cpu_reset                      processor.reset
-#define cpu_do_idle                    processor._do_idle
-#define cpu_dcache_clean_area          processor.dcache_clean_area
-#define cpu_set_pte_ext                        processor.set_pte_ext
-#define cpu_do_switch_mm               processor.switch_mm
 
-/* These three are private to arch/arm/kernel/suspend.c */
-#define cpu_do_suspend                 processor.do_suspend
-#define cpu_do_resume                  processor.do_resume
+extern struct processor processor;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+#include <linux/smp.h>
+/*
+ * This can't be a per-cpu variable because we need to access it before
+ * per-cpu has been initialised.  We have a couple of functions that are
+ * called in a pre-emptible context, and so can't use smp_processor_id()
+ * there, hence PROC_TABLE().  We insist in init_proc_vtable() that the
+ * function pointers for these are identical across all CPUs.
+ */
+extern struct processor *cpu_vtable[];
+#define PROC_VTABLE(f)                 cpu_vtable[smp_processor_id()]->f
+#define PROC_TABLE(f)                  cpu_vtable[0]->f
+static inline void init_proc_vtable(const struct processor *p)
+{
+       unsigned int cpu = smp_processor_id();
+       *cpu_vtable[cpu] = *p;
+       WARN_ON_ONCE(cpu_vtable[cpu]->dcache_clean_area !=
+                    cpu_vtable[0]->dcache_clean_area);
+       WARN_ON_ONCE(cpu_vtable[cpu]->set_pte_ext !=
+                    cpu_vtable[0]->set_pte_ext);
+}
+#else
+#define PROC_VTABLE(f)                 processor.f
+#define PROC_TABLE(f)                  processor.f
+static inline void init_proc_vtable(const struct processor *p)
+{
+       processor = *p;
+}
+#endif
+
+#define cpu_proc_init                  PROC_VTABLE(_proc_init)
+#define cpu_check_bugs                 PROC_VTABLE(check_bugs)
+#define cpu_proc_fin                   PROC_VTABLE(_proc_fin)
+#define cpu_reset                      PROC_VTABLE(reset)
+#define cpu_do_idle                    PROC_VTABLE(_do_idle)
+#define cpu_dcache_clean_area          PROC_TABLE(dcache_clean_area)
+#define cpu_set_pte_ext                        PROC_TABLE(set_pte_ext)
+#define cpu_do_switch_mm               PROC_VTABLE(switch_mm)
+
+/* These two are private to arch/arm/kernel/suspend.c */
+#define cpu_do_suspend                 PROC_VTABLE(do_suspend)
+#define cpu_do_resume                  PROC_VTABLE(do_resume)
 #endif
 
 extern void cpu_resume(void);
index 7be5113101915cd81a5558f45238041138fb5a58..d41d3598e5e541115c08f9b81b26fd187a7fe7af 100644 (file)
@@ -6,8 +6,8 @@
 void check_other_bugs(void)
 {
 #ifdef MULTI_CPU
-       if (processor.check_bugs)
-               processor.check_bugs();
+       if (cpu_check_bugs)
+               cpu_check_bugs();
 #endif
 }
 
index 6e0375e7db055bc82cf0674b37b74646e2d64ff0..997b02302c3145f5ac380ae18823eba50d916ac7 100644 (file)
@@ -145,6 +145,9 @@ __mmap_switched_data:
 #endif
        .size   __mmap_switched_data, . - __mmap_switched_data
 
+       __FINIT
+       .text
+
 /*
  * This provides a C-API version of __lookup_processor_type
  */
@@ -156,9 +159,6 @@ ENTRY(lookup_processor_type)
        ldmfd   sp!, {r4 - r6, r9, pc}
 ENDPROC(lookup_processor_type)
 
-       __FINIT
-       .text
-
 /*
  * Read processor ID register (CP#15, CR0), and look up in the linker-built
  * supported processor list.  Note that we can't use the absolute addresses
index ac7e08886863cfa74855e5b91c4f436e85da1e0a..375b13f7e780663eddb3f04e632751064a6b5bfd 100644 (file)
@@ -114,6 +114,11 @@ EXPORT_SYMBOL(elf_hwcap2);
 
 #ifdef MULTI_CPU
 struct processor processor __ro_after_init;
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+struct processor *cpu_vtable[NR_CPUS] = {
+       [0] = &processor,
+};
+#endif
 #endif
 #ifdef MULTI_TLB
 struct cpu_tlb_fns cpu_tlb __ro_after_init;
@@ -666,28 +671,33 @@ static void __init smp_build_mpidr_hash(void)
 }
 #endif
 
-static void __init setup_processor(void)
+/*
+ * locate processor in the list of supported processor types.  The linker
+ * builds this table for us from the entries in arch/arm/mm/proc-*.S
+ */
+struct proc_info_list *lookup_processor(u32 midr)
 {
-       struct proc_info_list *list;
+       struct proc_info_list *list = lookup_processor_type(midr);
 
-       /*
-        * locate processor in the list of supported processor
-        * types.  The linker builds this table for us from the
-        * entries in arch/arm/mm/proc-*.S
-        */
-       list = lookup_processor_type(read_cpuid_id());
        if (!list) {
-               pr_err("CPU configuration botched (ID %08x), unable to continue.\n",
-                      read_cpuid_id());
-               while (1);
+               pr_err("CPU%u: configuration botched (ID %08x), CPU halted\n",
+                      smp_processor_id(), midr);
+               while (1)
+               /* can't use cpu_relax() here as it may require MMU setup */;
        }
 
+       return list;
+}
+
+static void __init setup_processor(void)
+{
+       unsigned int midr = read_cpuid_id();
+       struct proc_info_list *list = lookup_processor(midr);
+
        cpu_name = list->cpu_name;
        __cpu_architecture = __get_cpu_architecture();
 
-#ifdef MULTI_CPU
-       processor = *list->proc;
-#endif
+       init_proc_vtable(list->proc);
 #ifdef MULTI_TLB
        cpu_tlb = *list->tlb;
 #endif
@@ -699,7 +709,7 @@ static void __init setup_processor(void)
 #endif
 
        pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
-               cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+               list->cpu_name, midr, midr & 15,
                proc_arch[cpu_architecture()], get_cr());
 
        snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c",
index 0978282d5fc27a7c4a5e6b0e274da8bfc4c14c8d..12a6172263c0b057a94f2041accf581088374fb0 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/procinfo.h>
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
@@ -102,6 +103,30 @@ static unsigned long get_arch_pgd(pgd_t *pgd)
 #endif
 }
 
+#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+       if (!cpu_vtable[cpu])
+               cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL);
+
+       return cpu_vtable[cpu] ? 0 : -ENOMEM;
+}
+
+static void secondary_biglittle_init(void)
+{
+       init_proc_vtable(lookup_processor(read_cpuid_id())->proc);
+}
+#else
+static int secondary_biglittle_prepare(unsigned int cpu)
+{
+       return 0;
+}
+
+static void secondary_biglittle_init(void)
+{
+}
+#endif
+
 int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
        int ret;
@@ -109,6 +134,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
        if (!smp_ops.smp_boot_secondary)
                return -ENOSYS;
 
+       ret = secondary_biglittle_prepare(cpu);
+       if (ret)
+               return ret;
+
        /*
         * We need to tell the secondary core where to find
         * its stack and the page tables.
@@ -359,6 +388,8 @@ asmlinkage void secondary_start_kernel(void)
        struct mm_struct *mm = &init_mm;
        unsigned int cpu;
 
+       secondary_biglittle_init();
+
        /*
         * The identity mapping is uncached (strongly ordered), so
         * switch away from it before attempting any exclusive accesses.
index 9500b6e2738019a4fb53e50c8150a2972ca8c391..f86b72d1d59e51f4af15319df87ee61141b4fd02 100644 (file)
@@ -209,11 +209,61 @@ static int __init omapdss_init_fbdev(void)
 
        return 0;
 }
-#else
-static inline int omapdss_init_fbdev(void)
+
+static const char * const omapdss_compat_names[] __initconst = {
+       "ti,omap2-dss",
+       "ti,omap3-dss",
+       "ti,omap4-dss",
+       "ti,omap5-dss",
+       "ti,dra7-dss",
+};
+
+static struct device_node * __init omapdss_find_dss_of_node(void)
 {
-       return 0;
+       struct device_node *node;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
+               node = of_find_compatible_node(NULL, NULL,
+                       omapdss_compat_names[i]);
+               if (node)
+                       return node;
+       }
+
+       return NULL;
 }
+
+static int __init omapdss_init_of(void)
+{
+       int r;
+       struct device_node *node;
+       struct platform_device *pdev;
+
+       /* only create dss helper devices if dss is enabled in the .dts */
+
+       node = omapdss_find_dss_of_node();
+       if (!node)
+               return 0;
+
+       if (!of_device_is_available(node))
+               return 0;
+
+       pdev = of_find_device_by_node(node);
+
+       if (!pdev) {
+               pr_err("Unable to find DSS platform device\n");
+               return -ENODEV;
+       }
+
+       r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+       if (r) {
+               pr_err("Unable to populate DSS submodule devices\n");
+               return r;
+       }
+
+       return omapdss_init_fbdev();
+}
+omap_device_initcall(omapdss_init_of);
 #endif /* CONFIG_FB_OMAP2 */
 
 static void dispc_disable_outputs(void)
@@ -361,58 +411,3 @@ int omap_dss_reset(struct omap_hwmod *oh)
 
        return r;
 }
-
-static const char * const omapdss_compat_names[] __initconst = {
-       "ti,omap2-dss",
-       "ti,omap3-dss",
-       "ti,omap4-dss",
-       "ti,omap5-dss",
-       "ti,dra7-dss",
-};
-
-static struct device_node * __init omapdss_find_dss_of_node(void)
-{
-       struct device_node *node;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(omapdss_compat_names); ++i) {
-               node = of_find_compatible_node(NULL, NULL,
-                       omapdss_compat_names[i]);
-               if (node)
-                       return node;
-       }
-
-       return NULL;
-}
-
-static int __init omapdss_init_of(void)
-{
-       int r;
-       struct device_node *node;
-       struct platform_device *pdev;
-
-       /* only create dss helper devices if dss is enabled in the .dts */
-
-       node = omapdss_find_dss_of_node();
-       if (!node)
-               return 0;
-
-       if (!of_device_is_available(node))
-               return 0;
-
-       pdev = of_find_device_by_node(node);
-
-       if (!pdev) {
-               pr_err("Unable to find DSS platform device\n");
-               return -ENODEV;
-       }
-
-       r = of_platform_populate(node, NULL, NULL, &pdev->dev);
-       if (r) {
-               pr_err("Unable to populate DSS submodule devices\n");
-               return r;
-       }
-
-       return omapdss_init_fbdev();
-}
-omap_device_initcall(omapdss_init_of);
index 5544b82a2e7a553d015e23d77a9017682dd91f11..9a07916af8dd27dd021781c06451340ce6d03032 100644 (file)
@@ -52,8 +52,6 @@ static void cpu_v7_spectre_init(void)
        case ARM_CPU_PART_CORTEX_A17:
        case ARM_CPU_PART_CORTEX_A73:
        case ARM_CPU_PART_CORTEX_A75:
-               if (processor.switch_mm != cpu_v7_bpiall_switch_mm)
-                       goto bl_error;
                per_cpu(harden_branch_predictor_fn, cpu) =
                        harden_branch_predictor_bpiall;
                spectre_v2_method = "BPIALL";
@@ -61,8 +59,6 @@ static void cpu_v7_spectre_init(void)
 
        case ARM_CPU_PART_CORTEX_A15:
        case ARM_CPU_PART_BRAHMA_B15:
-               if (processor.switch_mm != cpu_v7_iciallu_switch_mm)
-                       goto bl_error;
                per_cpu(harden_branch_predictor_fn, cpu) =
                        harden_branch_predictor_iciallu;
                spectre_v2_method = "ICIALLU";
@@ -88,11 +84,9 @@ static void cpu_v7_spectre_init(void)
                                          ARM_SMCCC_ARCH_WORKAROUND_1, &res);
                        if ((int)res.a0 != 0)
                                break;
-                       if (processor.switch_mm != cpu_v7_hvc_switch_mm && cpu)
-                               goto bl_error;
                        per_cpu(harden_branch_predictor_fn, cpu) =
                                call_hvc_arch_workaround_1;
-                       processor.switch_mm = cpu_v7_hvc_switch_mm;
+                       cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
                        spectre_v2_method = "hypervisor";
                        break;
 
@@ -101,11 +95,9 @@ static void cpu_v7_spectre_init(void)
                                          ARM_SMCCC_ARCH_WORKAROUND_1, &res);
                        if ((int)res.a0 != 0)
                                break;
-                       if (processor.switch_mm != cpu_v7_smc_switch_mm && cpu)
-                               goto bl_error;
                        per_cpu(harden_branch_predictor_fn, cpu) =
                                call_smc_arch_workaround_1;
-                       processor.switch_mm = cpu_v7_smc_switch_mm;
+                       cpu_do_switch_mm = cpu_v7_smc_switch_mm;
                        spectre_v2_method = "firmware";
                        break;
 
@@ -119,11 +111,6 @@ static void cpu_v7_spectre_init(void)
        if (spectre_v2_method)
                pr_info("CPU%u: Spectre v2: using %s workaround\n",
                        smp_processor_id(), spectre_v2_method);
-       return;
-
-bl_error:
-       pr_err("CPU%u: Spectre v2: incorrect context switching function, system vulnerable\n",
-               cpu);
 }
 #else
 static void cpu_v7_spectre_init(void)
index 6fe52819e0148c6f3f04b11c75e278cd0b04a1f9..339eb17c9808e2c04a043485e42e5d29a49de347 100644 (file)
@@ -112,7 +112,7 @@ ENTRY(cpu_v7_hvc_switch_mm)
        hvc     #0
        ldmfd   sp!, {r0 - r3}
        b       cpu_v7_switch_mm
-ENDPROC(cpu_v7_smc_switch_mm)
+ENDPROC(cpu_v7_hvc_switch_mm)
 #endif
 ENTRY(cpu_v7_iciallu_switch_mm)
        mov     r3, #0
index aff6e6eadc700f08241668e66c1235ea825217ce..ee7b07938dd59311f47fe5b385bcc27bfa4878f8 100644 (file)
@@ -573,7 +573,7 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp *ufp,
         */
        ufp_exc->fpexc = hwstate->fpexc;
        ufp_exc->fpinst = hwstate->fpinst;
-       ufp_exc->fpinst2 = ufp_exc->fpinst2;
+       ufp_exc->fpinst2 = hwstate->fpinst2;
 
        /* Ensure that VFP is disabled. */
        vfp_flush_hwstate(thread);
index 8253a1a9e9857112f43c24d85c5c411e653376dd..fef7351e9f677da62cd0c50e8c424a3590dd7b51 100644 (file)
                        clock-names = "stmmaceth";
                        tx-fifo-depth = <16384>;
                        rx-fifo-depth = <16384>;
+                       snps,multicast-filter-bins = <256>;
                        status = "disabled";
                };
 
                        clock-names = "stmmaceth";
                        tx-fifo-depth = <16384>;
                        rx-fifo-depth = <16384>;
+                       snps,multicast-filter-bins = <256>;
                        status = "disabled";
                };
 
                        clock-names = "stmmaceth";
                        tx-fifo-depth = <16384>;
                        rx-fifo-depth = <16384>;
+                       snps,multicast-filter-bins = <256>;
                        status = "disabled";
                };
 
index b5f2273caca4ded1e6bc0cfe3a5e52b97a3fd854..a79c8d369e0b48c4ddb3448bf4d2498acb676504 100644 (file)
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac1 0x35>, <&dmac1 0x34>,
                               <&dmac2 0x35>, <&dmac2 0x34>;
-                       dma-names = "tx", "rx";
+                       dma-names = "tx", "rx", "tx", "rx";
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 518>;
                        status = "disabled";
index fe2e2c051cc93fc0668a3d3e59a3b13432ef4766..5a7012be0d6ad953198c035df5626f2ff8ce0fe9 100644 (file)
@@ -15,7 +15,7 @@
 
        aliases {
                serial0 = &scif0;
-               ethernet0 = &avb;
+               ethernet0 = &gether;
        };
 
        chosen {
        };
 };
 
-&avb {
-       pinctrl-0 = <&avb_pins>;
-       pinctrl-names = "default";
-
-       phy-mode = "rgmii-id";
-       phy-handle = <&phy0>;
-       renesas,no-ether-link;
-       status = "okay";
-
-       phy0: ethernet-phy@0 {
-               rxc-skew-ps = <1500>;
-               reg = <0>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
-       };
-};
-
 &canfd {
        pinctrl-0 = <&canfd0_pins>;
        pinctrl-names = "default";
        clock-frequency = <32768>;
 };
 
+&gether {
+       pinctrl-0 = <&gether_pins>;
+       pinctrl-names = "default";
+
+       phy-mode = "rgmii-id";
+       phy-handle = <&phy0>;
+       renesas,no-ether-link;
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               rxc-skew-ps = <1500>;
+               reg = <0>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
 &i2c0 {
        pinctrl-0 = <&i2c0_pins>;
        pinctrl-names = "default";
 };
 
 &pfc {
-       avb_pins: avb {
-               groups = "avb_mdio", "avb_rgmii";
-               function = "avb";
-       };
-
        canfd0_pins: canfd0 {
                groups = "canfd0_data_a";
                function = "canfd0";
        };
 
+       gether_pins: gether {
+               groups = "gether_mdio_a", "gether_rgmii",
+                        "gether_txcrefclk", "gether_txcrefclk_mega";
+               function = "gether";
+       };
+
        i2c0_pins: i2c0 {
                groups = "i2c0";
                function = "i2c0";
index 3e2091708b8e51f04b90e8d6b14c586dd54afeab..6b0d4dff50125e49522212cb7e6db1a778da539d 100644 (file)
 #define KERNEL_DS      UL(-1)
 #define USER_DS                (TASK_SIZE_64 - 1)
 
+/*
+ * On arm64 systems, unaligned accesses by the CPU are cheap, and so there is
+ * no point in shifting all network buffers by 2 bytes just to make some IP
+ * header fields appear aligned in memory, potentially sacrificing some DMA
+ * performance on some platforms.
+ */
+#define NET_IP_ALIGN   0
+
 #ifndef __ASSEMBLY__
 #ifdef __KERNEL__
 
index 953e316521fcaa34fcbe26a9ca8ca7de6b9f51e9..f4fc1e0544b73c5c3785ee35a027ec6cb60623dd 100644 (file)
@@ -313,6 +313,7 @@ void __init setup_arch(char **cmdline_p)
        arm64_memblock_init();
 
        paging_init();
+       efi_apply_persistent_mem_reservations();
 
        acpi_table_upgrade();
 
index 9d9582cac6c40cad483d431682a178c67c445b45..9b432d9fcada8dac8e7b1041437387f29785b2af 100644 (file)
@@ -483,8 +483,6 @@ void __init arm64_memblock_init(void)
        high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
 
        dma_contiguous_reserve(arm64_dma_phys_limit);
-
-       memblock_allow_resize();
 }
 
 void __init bootmem_init(void)
index 394b8d554def4c3372425ed5088ee1116ef9898e..d1d6601b385d9214ceadd17ba51057ff4e023177 100644 (file)
@@ -659,6 +659,8 @@ void __init paging_init(void)
 
        memblock_free(__pa_symbol(init_pg_dir),
                      __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir));
+
+       memblock_allow_resize();
 }
 
 /*
index 6181e4134483c26aa1a34d55e4b316ddad98f5f5..fe3ddd73a0ccb9e4fec24425164cc8c6c7f477bc 100644 (file)
  */
 #ifdef CONFIG_SUN3
 #define PTRS_PER_PTE   16
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 #define PTRS_PER_PMD   1
 #define PTRS_PER_PGD   2048
 #elif defined(CONFIG_COLDFIRE)
 #define PTRS_PER_PTE   512
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 #define PTRS_PER_PMD   1
 #define PTRS_PER_PGD   1024
 #else
index f64ebb9c9a413535c105e3235eb50469d51b5697..e14b6621c933e47e1f87db0114f895b39f5450ef 100644 (file)
@@ -63,7 +63,7 @@ extern int mem_init_done;
 
 #include <asm-generic/4level-fixup.h>
 
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
index 75108ec669ebc881c6949962ef61f6368c4a814a..6c79e8a16a2681f01cf4ffb0a702a8414499bf7b 100644 (file)
@@ -67,7 +67,7 @@ void (*cvmx_override_pko_queue_priority) (int pko_port,
 void (*cvmx_override_ipd_port_setup) (int ipd_port);
 
 /* Port count per interface */
-static int interface_port_count[5];
+static int interface_port_count[9];
 
 /**
  * Return the number of interfaces the chip has. Each interface
index e6c9485cadcffc7e0ecba01326ca3b777363edb4..cb38461391cb78c714535d2536b5cb4eed1bddad 100644 (file)
@@ -50,7 +50,7 @@ void *arch_dma_alloc(struct device *dev, size_t size,
        void *ret;
 
        ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs);
-       if (!ret && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
+       if (ret && !(attrs & DMA_ATTR_NON_CONSISTENT)) {
                dma_cache_wback_inv((unsigned long) ret, size);
                ret = (void *)UNCAC_ADDR(ret);
        }
index d3e19a55cf530046795f7c2836fbc13dc3b823fb..9f52db930c004ecc5c6de013721e06d7b4bf52a3 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef _ASMNDS32_PGTABLE_H
 #define _ASMNDS32_PGTABLE_H
 
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 #include <asm-generic/4level-fixup.h>
 #include <asm-generic/sizes.h>
 
index b941ac7d4e70b35181351565136a9c25e7ee66f0..c7bb74e22436079de3d9f6153e98fe47cf8a9df4 100644 (file)
@@ -111,7 +111,7 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
 #if CONFIG_PGTABLE_LEVELS == 3
 #define BITS_PER_PMD   (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY)
 #else
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 #define BITS_PER_PMD   0
 #endif
 #define PTRS_PER_PMD    (1UL << BITS_PER_PMD)
index 16aec9ba2580a6dd3b3b9bfe03d29099815d2412..8a63515f03bfe3931930d094a479060815832fe6 100644 (file)
@@ -37,8 +37,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *x)
        volatile unsigned int *a;
 
        a = __ldcw_align(x);
-       /* Release with ordered store. */
-       __asm__ __volatile__("stw,ma %0,0(%1)" : : "r"(1), "r"(a) : "memory");
+       mb();
+       *a = 1;
 }
 
 static inline int arch_spin_trylock(arch_spinlock_t *x)
index 9505c317818df77cb1e67ea39fa3b43110d32d16..a9bc90dc4ae75e4e0489a297ef64c645a9cc7557 100644 (file)
@@ -640,7 +640,8 @@ cas_action:
        sub,<>  %r28, %r25, %r0
 2:     stw     %r24, 0(%r26)
        /* Free lock */
-       stw,ma  %r20, 0(%sr2,%r20)
+       sync
+       stw     %r20, 0(%sr2,%r20)
 #if ENABLE_LWS_DEBUG
        /* Clear thread register indicator */
        stw     %r0, 4(%sr2,%r20)
@@ -654,7 +655,8 @@ cas_action:
 3:             
        /* Error occurred on load or store */
        /* Free lock */
-       stw,ma  %r20, 0(%sr2,%r20)
+       sync
+       stw     %r20, 0(%sr2,%r20)
 #if ENABLE_LWS_DEBUG
        stw     %r0, 4(%sr2,%r20)
 #endif
@@ -855,7 +857,8 @@ cas2_action:
 
 cas2_end:
        /* Free lock */
-       stw,ma  %r20, 0(%sr2,%r20)
+       sync
+       stw     %r20, 0(%sr2,%r20)
        /* Enable interrupts */
        ssm     PSW_SM_I, %r0
        /* Return to userspace, set no error */
@@ -865,7 +868,8 @@ cas2_end:
 22:
        /* Error occurred on load or store */
        /* Free lock */
-       stw,ma  %r20, 0(%sr2,%r20)
+       sync
+       stw     %r20, 0(%sr2,%r20)
        ssm     PSW_SM_I, %r0
        ldo     1(%r0),%r28
        b       lws_exit
index 3ef40b703c4ab86e7daf3982ae4781de8988b32f..e746becd9d6ff29c65ab0109fb82dd945a046f6d 100644 (file)
@@ -268,19 +268,13 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
  * their hooks, a bitfield is reserved for use by the platform near the
  * top of MMIO addresses (not PIO, those have to cope the hard way).
  *
- * This bit field is 12 bits and is at the top of the IO virtual
- * addresses PCI_IO_INDIRECT_TOKEN_MASK.
+ * The highest address in the kernel virtual space are:
  *
- * The kernel virtual space is thus:
+ *  d0003fffffffffff   # with Hash MMU
+ *  c00fffffffffffff   # with Radix MMU
  *
- *  0xD000000000000000         : vmalloc
- *  0xD000080000000000         : PCI PHB IO space
- *  0xD000080080000000         : ioremap
- *  0xD0000fffffffffff         : end of ioremap region
- *
- * Since the top 4 bits are reserved as the region ID, we use thus
- * the next 12 bits and keep 4 bits available for the future if the
- * virtual address space is ever to be extended.
+ * The top 4 bits are reserved as the region ID on hash, leaving us 8 bits
+ * that can be used for the field.
  *
  * The direct IO mapping operations will then mask off those bits
  * before doing the actual access, though that only happen when
@@ -292,8 +286,8 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
  */
 
 #ifdef CONFIG_PPC_INDIRECT_MMIO
-#define PCI_IO_IND_TOKEN_MASK  0x0fff000000000000ul
-#define PCI_IO_IND_TOKEN_SHIFT 48
+#define PCI_IO_IND_TOKEN_SHIFT 52
+#define PCI_IO_IND_TOKEN_MASK  (0xfful << PCI_IO_IND_TOKEN_SHIFT)
 #define PCI_FIX_ADDR(addr)                                             \
        ((PCI_IO_ADDR)(((unsigned long)(addr)) & ~PCI_IO_IND_TOKEN_MASK))
 #define PCI_GET_ADDR_TOKEN(addr)                                       \
index 6093bc8f74e518bf225c014c25521c8a515ba013..a6e9e314c7077044c0bb58590c95dddce4be8ed1 100644 (file)
                                        __PPC_RS(t) | __PPC_RA0(a) | __PPC_RB(b))
 #define PPC_SLBFEE_DOT(t, b)   stringify_in_c(.long PPC_INST_SLBFEE | \
                                        __PPC_RT(t) | __PPC_RB(b))
+#define __PPC_SLBFEE_DOT(t, b) stringify_in_c(.long PPC_INST_SLBFEE |  \
+                                              ___PPC_RT(t) | ___PPC_RB(b))
 #define PPC_ICBT(c,a,b)                stringify_in_c(.long PPC_INST_ICBT | \
                                       __PPC_CT(c) | __PPC_RA0(a) | __PPC_RB(b))
 /* PASemi instructions */
index f73886a1a7f51714da637c0f9c81a8dfd1107b7f..0b8a735b6d85f08512143b539c5ee5329598c48c 100644 (file)
@@ -54,6 +54,7 @@ struct pt_regs
 
 #ifdef CONFIG_PPC64
        unsigned long ppr;
+       unsigned long __pad;    /* Maintain 16 byte interrupt stack alignment */
 #endif
 };
 #endif
index 2a51e4cc8246d35d18d8ddd54b258af02dda47c4..236c1151a3a77057013313ed5da588673f5f3419 100644 (file)
@@ -636,6 +636,8 @@ static void *__init alloc_stack(unsigned long limit, int cpu)
 {
        unsigned long pa;
 
+       BUILD_BUG_ON(STACK_INT_FRAME_SIZE % 16);
+
        pa = memblock_alloc_base_nid(THREAD_SIZE, THREAD_SIZE, limit,
                                        early_cpu_to_node(cpu), MEMBLOCK_NONE);
        if (!pa) {
index 491b0f715d6bc2c345850645f2dbcd4700f6f182..ea1d7c80831900c4403443b8d836cd462998bf22 100644 (file)
@@ -6,8 +6,6 @@
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvm
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace
 
 /*
  * Tracepoint for guest mode entry.
@@ -120,4 +118,10 @@ TRACE_EVENT(kvm_check_requests,
 #endif /* _TRACE_KVM_H */
 
 /* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+
 #include <trace/define_trace.h>
index ac640e81fdc5f43709858ad8b3dd5ec2eee58a8f..3837842986aa46ee4ac80f4759d1051d9221c87c 100644 (file)
@@ -6,8 +6,6 @@
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvm_booke
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_booke
 
 #define kvm_trace_symbol_exit \
        {0, "CRITICAL"}, \
@@ -218,4 +216,11 @@ TRACE_EVENT(kvm_booke_queue_irqprio,
 #endif
 
 /* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_booke
+
 #include <trace/define_trace.h>
index bcfe8a987f6a977e65f2e9c7a02962a7099c2a66..8a1e3b0047f190e53a64dfe57c9c88f9ac11d617 100644 (file)
@@ -9,8 +9,6 @@
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvm_hv
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_hv
 
 #define kvm_trace_symbol_hcall \
        {H_REMOVE,                      "H_REMOVE"}, \
@@ -497,4 +495,11 @@ TRACE_EVENT(kvmppc_run_vcpu_exit,
 #endif /* _TRACE_KVM_HV_H */
 
 /* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_hv
+
 #include <trace/define_trace.h>
index 2f9a8829552b946ee8a308a2e069ab6a5c9bb1ba..46a46d328fbf2237dd203d3c33d54dbe0db129b1 100644 (file)
@@ -8,8 +8,6 @@
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvm_pr
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_pr
 
 TRACE_EVENT(kvm_book3s_reenter,
        TP_PROTO(int r, struct kvm_vcpu *vcpu),
@@ -257,4 +255,11 @@ TRACE_EVENT(kvm_exit,
 #endif /* _TRACE_KVM_H */
 
 /* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_pr
+
 #include <trace/define_trace.h>
index 3a048e98a13231b6ce8ec239d91e98fe1ed2d3a9..ce28ae5ca08033ff36ee157e9b83be3a61d44f52 100644 (file)
@@ -1178,7 +1178,7 @@ static long vphn_get_associativity(unsigned long cpu,
 
        switch (rc) {
        case H_FUNCTION:
-               printk(KERN_INFO
+               printk_once(KERN_INFO
                        "VPHN is not supported. Disabling polling...\n");
                stop_topology_update();
                break;
index c3fdf2969d9faec5cacac62dfd9416011f9b17eb..bc3914d54e26ef8c400c65c92b8c359c171f8207 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/paca.h>
+#include <asm/ppc-opcode.h>
 #include <asm/cputable.h>
 #include <asm/cacheflush.h>
 #include <asm/smp.h>
@@ -58,27 +59,19 @@ static inline unsigned long mk_vsid_data(unsigned long ea, int ssize,
        return __mk_vsid_data(get_kernel_vsid(ea, ssize), ssize, flags);
 }
 
-static void assert_slb_exists(unsigned long ea)
+static void assert_slb_presence(bool present, unsigned long ea)
 {
 #ifdef CONFIG_DEBUG_VM
        unsigned long tmp;
 
        WARN_ON_ONCE(mfmsr() & MSR_EE);
 
-       asm volatile("slbfee. %0, %1" : "=r"(tmp) : "r"(ea) : "cr0");
-       WARN_ON(tmp == 0);
-#endif
-}
-
-static void assert_slb_notexists(unsigned long ea)
-{
-#ifdef CONFIG_DEBUG_VM
-       unsigned long tmp;
+       if (!cpu_has_feature(CPU_FTR_ARCH_206))
+               return;
 
-       WARN_ON_ONCE(mfmsr() & MSR_EE);
+       asm volatile(__PPC_SLBFEE_DOT(%0, %1) : "=r"(tmp) : "r"(ea) : "cr0");
 
-       asm volatile("slbfee. %0, %1" : "=r"(tmp) : "r"(ea) : "cr0");
-       WARN_ON(tmp != 0);
+       WARN_ON(present == (tmp == 0));
 #endif
 }
 
@@ -114,7 +107,7 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize,
         */
        slb_shadow_update(ea, ssize, flags, index);
 
-       assert_slb_notexists(ea);
+       assert_slb_presence(false, ea);
        asm volatile("slbmte  %0,%1" :
                     : "r" (mk_vsid_data(ea, ssize, flags)),
                       "r" (mk_esid_data(ea, ssize, index))
@@ -137,7 +130,7 @@ void __slb_restore_bolted_realmode(void)
                       "r" (be64_to_cpu(p->save_area[index].esid)));
        }
 
-       assert_slb_exists(local_paca->kstack);
+       assert_slb_presence(true, local_paca->kstack);
 }
 
 /*
@@ -185,7 +178,7 @@ void slb_flush_and_restore_bolted(void)
                     :: "r" (be64_to_cpu(p->save_area[KSTACK_INDEX].vsid)),
                        "r" (be64_to_cpu(p->save_area[KSTACK_INDEX].esid))
                     : "memory");
-       assert_slb_exists(get_paca()->kstack);
+       assert_slb_presence(true, get_paca()->kstack);
 
        get_paca()->slb_cache_ptr = 0;
 
@@ -443,9 +436,9 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
                                ea = (unsigned long)
                                        get_paca()->slb_cache[i] << SID_SHIFT;
                                /*
-                                * Could assert_slb_exists here, but hypervisor
-                                * or machine check could have come in and
-                                * removed the entry at this point.
+                                * Could assert_slb_presence(true) here, but
+                                * hypervisor or machine check could have come
+                                * in and removed the entry at this point.
                                 */
 
                                slbie_data = ea;
@@ -676,7 +669,7 @@ static long slb_insert_entry(unsigned long ea, unsigned long context,
         * User preloads should add isync afterwards in case the kernel
         * accesses user memory before it returns to userspace with rfid.
         */
-       assert_slb_notexists(ea);
+       assert_slb_presence(false, ea);
        asm volatile("slbmte %0, %1" : : "r" (vsid_data), "r" (esid_data));
 
        barrier();
@@ -715,7 +708,7 @@ static long slb_allocate_kernel(unsigned long ea, unsigned long id)
                        return -EFAULT;
 
                if (ea < H_VMALLOC_END)
-                       flags = get_paca()->vmalloc_sllp;
+                       flags = local_paca->vmalloc_sllp;
                else
                        flags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_io_psize].sllp;
        } else {
index 6f60e09319223015f5ebd36e3aa1fd9f66078520..75b9352529818899e99a978a4d85beeae535db90 100644 (file)
@@ -102,63 +102,6 @@ struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
 }
 EXPORT_SYMBOL(pnv_pci_get_npu_dev);
 
-#define NPU_DMA_OP_UNSUPPORTED()                                       \
-       dev_err_once(dev, "%s operation unsupported for NVLink devices\n", \
-               __func__)
-
-static void *dma_npu_alloc(struct device *dev, size_t size,
-                          dma_addr_t *dma_handle, gfp_t flag,
-                          unsigned long attrs)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-       return NULL;
-}
-
-static void dma_npu_free(struct device *dev, size_t size,
-                        void *vaddr, dma_addr_t dma_handle,
-                        unsigned long attrs)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-}
-
-static dma_addr_t dma_npu_map_page(struct device *dev, struct page *page,
-                                  unsigned long offset, size_t size,
-                                  enum dma_data_direction direction,
-                                  unsigned long attrs)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-       return 0;
-}
-
-static int dma_npu_map_sg(struct device *dev, struct scatterlist *sglist,
-                         int nelems, enum dma_data_direction direction,
-                         unsigned long attrs)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-       return 0;
-}
-
-static int dma_npu_dma_supported(struct device *dev, u64 mask)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-       return 0;
-}
-
-static u64 dma_npu_get_required_mask(struct device *dev)
-{
-       NPU_DMA_OP_UNSUPPORTED();
-       return 0;
-}
-
-static const struct dma_map_ops dma_npu_ops = {
-       .map_page               = dma_npu_map_page,
-       .map_sg                 = dma_npu_map_sg,
-       .alloc                  = dma_npu_alloc,
-       .free                   = dma_npu_free,
-       .dma_supported          = dma_npu_dma_supported,
-       .get_required_mask      = dma_npu_get_required_mask,
-};
-
 /*
  * Returns the PE assoicated with the PCI device of the given
  * NPU. Returns the linked pci device if pci_dev != NULL.
@@ -270,10 +213,11 @@ static void pnv_npu_dma_set_32(struct pnv_ioda_pe *npe)
        rc = pnv_npu_set_window(npe, 0, gpe->table_group.tables[0]);
 
        /*
-        * We don't initialise npu_pe->tce32_table as we always use
-        * dma_npu_ops which are nops.
+        * NVLink devices use the same TCE table configuration as
+        * their parent device so drivers shouldn't be doing DMA
+        * operations directly on these devices.
         */
-       set_dma_ops(&npe->pdev->dev, &dma_npu_ops);
+       set_dma_ops(&npe->pdev->dev, NULL);
 }
 
 /*
index d10146197533affd63c3e7392ccd73a4d7ba2e27..4af153a182b071fcd4853a8853fb94fb1333312b 100644 (file)
@@ -77,4 +77,8 @@ core-y += arch/riscv/kernel/ arch/riscv/mm/
 
 libs-y += arch/riscv/lib/
 
+PHONY += vdso_install
+vdso_install:
+       $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+
 all: vmlinux
index 07fa9ea75fea1f1c72caaa6f246c28df86b6a532..ef4f15df9adf03c091bf621f900413680a2829f2 100644 (file)
@@ -76,4 +76,5 @@ CONFIG_NFS_V4_1=y
 CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
 CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_PRINTK_TIME=y
 # CONFIG_RCU_TRACE is not set
index 2c5df945d43c9abfdfd197a61d8c92ce20e48133..bbe1862e8f80cd404164f03a485a89f253f9fa45 100644 (file)
@@ -56,8 +56,8 @@ struct pt_regs {
        unsigned long sstatus;
        unsigned long sbadaddr;
        unsigned long scause;
-        /* a0 value before the syscall */
-        unsigned long orig_a0;
+       /* a0 value before the syscall */
+       unsigned long orig_a0;
 };
 
 #ifdef CONFIG_64BIT
index 3303ed2cd4193f82c51730a992d6c875b361ff80..7dd308129b40f1862ab04dc1e12c790bf7c111fe 100644 (file)
@@ -21,7 +21,7 @@ static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
 {
        if (v != (u32)v) {
                pr_err("%s: value %016llx out of range for 32-bit field\n",
-                      me->name, v);
+                      me->name, (long long)v);
                return -EINVAL;
        }
        *location = v;
@@ -102,7 +102,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
        if (offset != (s32)offset) {
                pr_err(
                  "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
-                 me->name, v, location);
+                 me->name, (long long)v, location);
                return -EINVAL;
        }
 
@@ -144,7 +144,7 @@ static int apply_r_riscv_hi20_rela(struct module *me, u32 *location,
        if (IS_ENABLED(CMODEL_MEDLOW)) {
                pr_err(
                  "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
-                 me->name, v, location);
+                 me->name, (long long)v, location);
                return -EINVAL;
        }
 
@@ -188,7 +188,7 @@ static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
        } else {
                pr_err(
                  "%s: can not generate the GOT entry for symbol = %016llx from PC = %p\n",
-                 me->name, v, location);
+                 me->name, (long long)v, location);
                return -EINVAL;
        }
 
@@ -212,7 +212,7 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
                } else {
                        pr_err(
                          "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
-                         me->name, v, location);
+                         me->name, (long long)v, location);
                        return -EINVAL;
                }
        }
@@ -234,7 +234,7 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
        if (offset != fill_v) {
                pr_err(
                  "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
-                 me->name, v, location);
+                 me->name, (long long)v, location);
                return -EINVAL;
        }
 
index 5739bd05d289e5034b5d9faee2baebb1be1251ed..4e2e600f7d5384074fff062628cbb04f9113f7ab 100644 (file)
@@ -3,6 +3,6 @@ lib-y   += memcpy.o
 lib-y  += memset.o
 lib-y  += uaccess.o
 
-lib-(CONFIG_64BIT) += tishift.o
+lib-$(CONFIG_64BIT) += tishift.o
 
 lib-$(CONFIG_32BIT) += udivdi3.o
index 0b33577932c3bd9c552c62cfe473979987c97313..e21053e5e0da2a06c3ba78e9967e55837ecaddc0 100644 (file)
@@ -27,7 +27,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-option,-ffreestanding)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g)
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,))
 UTS_MACHINE    := s390x
-STACK_SIZE     := $(if $(CONFIG_KASAN),32768,16384)
+STACK_SIZE     := $(if $(CONFIG_KASAN),65536,16384)
 CHECKFLAGS     += -D__s390__ -D__s390x__
 
 export LD_BFD
index 593039620487a6cdad8e076272b8e97cacff0153..b1bdd15e3429f39d50b0c8e73896c5539a4cfc5e 100644 (file)
@@ -22,10 +22,10 @@ OBJCOPYFLAGS :=
 OBJECTS := $(addprefix $(obj)/,$(obj-y))
 
 LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
-$(obj)/vmlinux: $(obj)/vmlinux.lds $(objtree)/arch/s390/boot/startup.a $(OBJECTS)
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(objtree)/arch/s390/boot/startup.a $(OBJECTS) FORCE
        $(call if_changed,ld)
 
-OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info
+OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=load
 $(obj)/info.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
@@ -46,17 +46,17 @@ suffix-$(CONFIG_KERNEL_LZMA)  := .lzma
 suffix-$(CONFIG_KERNEL_LZO)  := .lzo
 suffix-$(CONFIG_KERNEL_XZ)  := .xz
 
-$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,gzip)
-$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,bzip2)
-$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,lz4)
-$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,lzma)
-$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,lzo)
-$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
+$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,xzkern)
 
 OBJCOPYFLAGS_piggy.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.bin.compressed
index 259d1698ac50a468021e17a6a2fbe93526f520f2..c69cb04b7a5948e56535a145cb788de06fa4bed8 100644 (file)
@@ -64,6 +64,8 @@ CONFIG_NUMA=y
 CONFIG_PREEMPT=y
 CONFIG_HZ_100=y
 CONFIG_KEXEC_FILE=y
+CONFIG_EXPOLINE=y
+CONFIG_EXPOLINE_AUTO=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -84,9 +86,11 @@ CONFIG_PCI_DEBUG=y
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_S390=y
 CONFIG_CHSC_SCH=y
+CONFIG_VFIO_AP=m
 CONFIG_CRASH_DUMP=y
 CONFIG_BINFMT_MISC=m
 CONFIG_HIBERNATION=y
+CONFIG_PM_DEBUG=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_DIAG=m
@@ -161,8 +165,6 @@ CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NF_CT_NETLINK_TIMEOUT=m
 CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
@@ -365,6 +367,8 @@ CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
 CONFIG_OPENVSWITCH=m
+CONFIG_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS=m
 CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
@@ -461,6 +465,7 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
+CONFIG_ISM=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -486,9 +491,12 @@ CONFIG_MLX4_INFINIBAND=m
 CONFIG_MLX5_INFINIBAND=m
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
+CONFIG_VFIO_MDEV=m
+CONFIG_VFIO_MDEV_DEVICE=m
 CONFIG_VIRTIO_PCI=m
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_INPUT=y
+CONFIG_S390_AP_IOMMU=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
@@ -615,7 +623,6 @@ CONFIG_DEBUG_CREDENTIALS=y
 CONFIG_RCU_TORTURE_TEST=m
 CONFIG_RCU_CPU_STALL_TIMEOUT=300
 CONFIG_NOTIFIER_ERROR_INJECTION=m
-CONFIG_PM_NOTIFIER_ERROR_INJECT=m
 CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
 CONFIG_FAULT_INJECTION=y
 CONFIG_FAILSLAB=y
@@ -727,3 +734,4 @@ CONFIG_APPLDATA_BASE=y
 CONFIG_KVM=m
 CONFIG_KVM_S390_UCONTROL=y
 CONFIG_VHOST_NET=m
+CONFIG_VHOST_VSOCK=m
index 37fd60c20e22dec8cd8452baaf89135debccf735..32f539dc9c19240d589a5cb62fb51e0a30d9baf5 100644 (file)
@@ -65,6 +65,8 @@ CONFIG_NR_CPUS=512
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
 CONFIG_KEXEC_FILE=y
+CONFIG_EXPOLINE=y
+CONFIG_EXPOLINE_AUTO=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -82,9 +84,11 @@ CONFIG_PCI=y
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_S390=y
 CONFIG_CHSC_SCH=y
+CONFIG_VFIO_AP=m
 CONFIG_CRASH_DUMP=y
 CONFIG_BINFMT_MISC=m
 CONFIG_HIBERNATION=y
+CONFIG_PM_DEBUG=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_DIAG=m
@@ -159,8 +163,6 @@ CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NF_CT_NETLINK_TIMEOUT=m
 CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
 CONFIG_NFT_CT=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
@@ -362,6 +364,8 @@ CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
 CONFIG_OPENVSWITCH=m
+CONFIG_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS=m
 CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
@@ -458,6 +462,7 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
+CONFIG_ISM=m
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -483,9 +488,12 @@ CONFIG_MLX4_INFINIBAND=m
 CONFIG_MLX5_INFINIBAND=m
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
+CONFIG_VFIO_MDEV=m
+CONFIG_VFIO_MDEV_DEVICE=m
 CONFIG_VIRTIO_PCI=m
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_INPUT=y
+CONFIG_S390_AP_IOMMU=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
@@ -666,3 +674,4 @@ CONFIG_APPLDATA_BASE=y
 CONFIG_KVM=m
 CONFIG_KVM_S390_UCONTROL=y
 CONFIG_VHOST_NET=m
+CONFIG_VHOST_VSOCK=m
index 7cb6a52f727dafc6c994423b0db21ccafec4993a..4d58a92b5d979f15e3469240c47a8e6f5fc4c189 100644 (file)
@@ -26,14 +26,23 @@ CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_PROFILING=y
+CONFIG_LIVEPATCH=y
+CONFIG_NR_CPUS=256
+CONFIG_NUMA=y
+CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
+CONFIG_CRASH_DUMP=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_DEBUG=y
+CONFIG_CMM=m
 CONFIG_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_JUMP_LABEL=y
@@ -44,11 +53,7 @@ CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_IBM_PARTITION=y
 CONFIG_DEFAULT_DEADLINE=y
-CONFIG_LIVEPATCH=y
-CONFIG_NR_CPUS=256
-CONFIG_NUMA=y
-CONFIG_HZ_100=y
-CONFIG_KEXEC_FILE=y
+CONFIG_BINFMT_MISC=m
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -60,9 +65,6 @@ CONFIG_ZBUD=m
 CONFIG_ZSMALLOC=m
 CONFIG_ZSMALLOC_STAT=y
 CONFIG_IDLE_PAGE_TRACKING=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HIBERNATION=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -98,6 +100,7 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_VIRTIO_BLK=y
 CONFIG_SCSI=y
+# CONFIG_SCSI_MQ_DEFAULT is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
@@ -131,6 +134,7 @@ CONFIG_EQUALIZER=m
 CONFIG_TUN=m
 CONFIG_VIRTIO_NET=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_CORTINA is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SOCIONEXT is not set
@@ -157,33 +161,6 @@ CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_LOCK_STAT=y
-CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_SG=y
-CONFIG_DEBUG_NOTIFIERS=y
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-CONFIG_LATENCYTOP=y
-CONFIG_SCHED_TRACER=y
-CONFIG_FTRACE_SYSCALLS=y
-CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_FUNCTION_PROFILER=y
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_S390_PTDUMP=y
 CONFIG_CRYPTO_CRYPTD=m
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
@@ -193,6 +170,7 @@ CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_CFB=m
 CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_OFB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_XTS=m
 CONFIG_CRYPTO_CMAC=m
@@ -231,7 +209,6 @@ CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 CONFIG_CRYPTO_USER_API_RNG=m
 CONFIG_ZCRYPT=m
-CONFIG_ZCRYPT_MULTIDEVNODES=y
 CONFIG_PKEY=m
 CONFIG_CRYPTO_PAES_S390=m
 CONFIG_CRYPTO_SHA1_S390=m
@@ -247,4 +224,30 @@ CONFIG_CRC7=m
 # CONFIG_XZ_DEC_ARM is not set
 # CONFIG_XZ_DEC_ARMTHUMB is not set
 # CONFIG_XZ_DEC_SPARC is not set
-CONFIG_CMM=m
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_LATENCYTOP=y
+CONFIG_SCHED_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
+CONFIG_STACK_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_FUNCTION_PROFILER=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_S390_PTDUMP=y
index dbd689d556ce5dd9368392a1e0676c18163acc3c..ccbb53e2202404b85aae86e883d3e64405d2d305 100644 (file)
@@ -46,8 +46,6 @@ static inline int init_new_context(struct task_struct *tsk,
                mm->context.asce_limit = STACK_TOP_MAX;
                mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
                                   _ASCE_USER_BITS | _ASCE_TYPE_REGION3;
-               /* pgd_alloc() did not account this pud */
-               mm_inc_nr_puds(mm);
                break;
        case -PAGE_SIZE:
                /* forked 5-level task, set new asce with new_mm->pgd */
@@ -63,9 +61,6 @@ static inline int init_new_context(struct task_struct *tsk,
                /* forked 2-level compat task, set new asce with new mm->pgd */
                mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
                                   _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
-               /* pgd_alloc() did not account this pmd */
-               mm_inc_nr_pmds(mm);
-               mm_inc_nr_puds(mm);
        }
        crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
        return 0;
index f0f9bcf94c03749b0f0030d9de5765cff1597d37..5ee733720a5716b2308210d497f9c8ab73485cfa 100644 (file)
@@ -36,11 +36,11 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry)
 
 static inline unsigned long pgd_entry_type(struct mm_struct *mm)
 {
-       if (mm->context.asce_limit <= _REGION3_SIZE)
+       if (mm_pmd_folded(mm))
                return _SEGMENT_ENTRY_EMPTY;
-       if (mm->context.asce_limit <= _REGION2_SIZE)
+       if (mm_pud_folded(mm))
                return _REGION3_ENTRY_EMPTY;
-       if (mm->context.asce_limit <= _REGION1_SIZE)
+       if (mm_p4d_folded(mm))
                return _REGION2_ENTRY_EMPTY;
        return _REGION1_ENTRY_EMPTY;
 }
index 411d435e7a7d2a5a8c650c812017d66f9738710a..063732414dfbb5076c431d13e694e239e878ebef 100644 (file)
@@ -493,6 +493,24 @@ static inline int is_module_addr(void *addr)
                                   _REGION_ENTRY_PROTECT | \
                                   _REGION_ENTRY_NOEXEC)
 
+static inline bool mm_p4d_folded(struct mm_struct *mm)
+{
+       return mm->context.asce_limit <= _REGION1_SIZE;
+}
+#define mm_p4d_folded(mm) mm_p4d_folded(mm)
+
+static inline bool mm_pud_folded(struct mm_struct *mm)
+{
+       return mm->context.asce_limit <= _REGION2_SIZE;
+}
+#define mm_pud_folded(mm) mm_pud_folded(mm)
+
+static inline bool mm_pmd_folded(struct mm_struct *mm)
+{
+       return mm->context.asce_limit <= _REGION3_SIZE;
+}
+#define mm_pmd_folded(mm) mm_pmd_folded(mm)
+
 static inline int mm_has_pgste(struct mm_struct *mm)
 {
 #ifdef CONFIG_PGSTE
index 302795c47c06c299b732ed73de7b057a71b3805c..81038ab357ce955682b713f0c4241611ba5f931f 100644 (file)
@@ -236,7 +236,7 @@ static inline unsigned long current_stack_pointer(void)
        return sp;
 }
 
-static __no_sanitize_address_or_inline unsigned short stap(void)
+static __no_kasan_or_inline unsigned short stap(void)
 {
        unsigned short cpu_address;
 
@@ -330,7 +330,7 @@ static inline void __load_psw(psw_t psw)
  * Set PSW mask to specified value, while leaving the
  * PSW addr pointing to the next instruction.
  */
-static __no_sanitize_address_or_inline void __load_psw_mask(unsigned long mask)
+static __no_kasan_or_inline void __load_psw_mask(unsigned long mask)
 {
        unsigned long addr;
        psw_t psw;
index 27248f42a03c4561a9e1481fbea205b3b866f928..ce4e17c9aad6fa266d306676df4e7cdc69eb7df0 100644 (file)
@@ -14,7 +14,7 @@
  * General size of kernel stacks
  */
 #ifdef CONFIG_KASAN
-#define THREAD_SIZE_ORDER 3
+#define THREAD_SIZE_ORDER 4
 #else
 #define THREAD_SIZE_ORDER 2
 #endif
index 457b7ba0fbb66de24fd82219e18a51ad2663221f..b31c779cf58176ad3bf91ee816053cbcf40b3476 100644 (file)
@@ -136,7 +136,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
                                unsigned long address)
 {
-       if (tlb->mm->context.asce_limit <= _REGION3_SIZE)
+       if (mm_pmd_folded(tlb->mm))
                return;
        pgtable_pmd_page_dtor(virt_to_page(pmd));
        tlb_remove_table(tlb, pmd);
@@ -152,7 +152,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
 static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
                                unsigned long address)
 {
-       if (tlb->mm->context.asce_limit <= _REGION1_SIZE)
+       if (mm_p4d_folded(tlb->mm))
                return;
        tlb_remove_table(tlb, p4d);
 }
@@ -167,7 +167,7 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
 static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
                                unsigned long address)
 {
-       if (tlb->mm->context.asce_limit <= _REGION2_SIZE)
+       if (mm_pud_folded(tlb->mm))
                return;
        tlb_remove_table(tlb, pud);
 }
index 724fba4d09d2df3a35c372224ddc944c9def3ace..39191a0feed1cdedd692e68826b3b19db581cbbb 100644 (file)
@@ -236,10 +236,10 @@ ENTRY(__switch_to)
        stmg    %r6,%r15,__SF_GPRS(%r15)        # store gprs of prev task
        lghi    %r4,__TASK_stack
        lghi    %r1,__TASK_thread
-       lg      %r5,0(%r4,%r3)                  # start of kernel stack of next
+       llill   %r5,STACK_INIT
        stg     %r15,__THREAD_ksp(%r1,%r2)      # store kernel stack of prev
-       lgr     %r15,%r5
-       aghi    %r15,STACK_INIT                 # end of kernel stack of next
+       lg      %r15,0(%r4,%r3)                 # start of kernel stack of next
+       agr     %r15,%r5                        # end of kernel stack of next
        stg     %r3,__LC_CURRENT                # store task struct of next
        stg     %r15,__LC_KERNEL_STACK          # store end of kernel stack
        lg      %r15,__THREAD_ksp(%r1,%r3)      # load kernel stack of next
index cc085e2d2ce9907690fbe0912dd301ab44e8171d..74091fd3101e9122943b9155572a1c46d2bf9858 100644 (file)
@@ -373,7 +373,7 @@ static int __hw_perf_event_init(struct perf_event *event)
                return -ENOENT;
 
        if (ev > PERF_CPUM_CF_MAX_CTR)
-               return -EINVAL;
+               return -ENOENT;
 
        /* Obtain the counter set to which the specified counter belongs */
        set = get_counter_set(ev);
index 7bf604ff50a1bd082024c85fb5d32e06cca9c4f8..bfabeb1889cc0cca5c6859cb36bbbeb15b662049 100644 (file)
@@ -1842,10 +1842,30 @@ static void cpumsf_pmu_del(struct perf_event *event, int flags)
 CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC, PERF_EVENT_CPUM_SF);
 CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG);
 
-static struct attribute *cpumsf_pmu_events_attr[] = {
-       CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC),
-       NULL,
-       NULL,
+/* Attribute list for CPU_SF.
+ *
+ * The availablitiy depends on the CPU_MF sampling facility authorization
+ * for basic + diagnositic samples. This is determined at initialization
+ * time by the sampling facility device driver.
+ * If the authorization for basic samples is turned off, it should be
+ * also turned off for diagnostic sampling.
+ *
+ * During initialization of the device driver, check the authorization
+ * level for diagnostic sampling and installs the attribute
+ * file for diagnostic sampling if necessary.
+ *
+ * For now install a placeholder to reference all possible attributes:
+ * SF_CYCLES_BASIC and SF_CYCLES_BASIC_DIAG.
+ * Add another entry for the final NULL pointer.
+ */
+enum {
+       SF_CYCLES_BASIC_ATTR_IDX = 0,
+       SF_CYCLES_BASIC_DIAG_ATTR_IDX,
+       SF_CYCLES_ATTR_MAX
+};
+
+static struct attribute *cpumsf_pmu_events_attr[SF_CYCLES_ATTR_MAX + 1] = {
+       [SF_CYCLES_BASIC_ATTR_IDX] = CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC)
 };
 
 PMU_FORMAT_ATTR(event, "config:0-63");
@@ -2040,7 +2060,10 @@ static int __init init_cpum_sampling_pmu(void)
 
        if (si.ad) {
                sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB);
-               cpumsf_pmu_events_attr[1] =
+               /* Sampling of diagnostic data authorized,
+                * install event into attribute list of PMU device.
+                */
+               cpumsf_pmu_events_attr[SF_CYCLES_BASIC_DIAG_ATTR_IDX] =
                        CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG);
        }
 
index eb8aebea3ea7bd7a6967136b6cb9aee3e25473aa..e76309fbbcb3b6e23af21350f98f2b555502b978 100644 (file)
@@ -37,7 +37,7 @@ KASAN_SANITIZE := n
 $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32)
+$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) FORCE
        $(call if_changed,vdso32ld)
 
 # strip rule for the .so file
@@ -46,12 +46,12 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
        $(call if_changed,objcopy)
 
 # assembly rules for the .S files
-$(obj-vdso32): %.o: %.S
+$(obj-vdso32): %.o: %.S FORCE
        $(call if_changed_dep,vdso32as)
 
 # actual build commands
 quiet_cmd_vdso32ld = VDSO32L $@
-      cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+      cmd_vdso32ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
 quiet_cmd_vdso32as = VDSO32A $@
       cmd_vdso32as = $(CC) $(a_flags) -c -o $@ $<
 
index a22b2cf86eec985d7f3bf32da11f5f0c220c28e7..f849ac61c5da02ee8b764bc3c01fc44c16137e04 100644 (file)
@@ -37,7 +37,7 @@ KASAN_SANITIZE := n
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64)
+$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE
        $(call if_changed,vdso64ld)
 
 # strip rule for the .so file
@@ -46,12 +46,12 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
        $(call if_changed,objcopy)
 
 # assembly rules for the .S files
-$(obj-vdso64): %.o: %.S
+$(obj-vdso64): %.o: %.S FORCE
        $(call if_changed_dep,vdso64as)
 
 # actual build commands
 quiet_cmd_vdso64ld = VDSO64L $@
-      cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
+      cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
 quiet_cmd_vdso64as = VDSO64A $@
       cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
 
index 21eb7407d51bac8e71f3743defba1f7de5291e3d..8429ab07971575394622444ea6be40eb85b37f62 100644 (file)
@@ -154,14 +154,14 @@ SECTIONS
         * uncompressed image info used by the decompressor
         * it should match struct vmlinux_info
         */
-       .vmlinux.info 0 : {
+       .vmlinux.info 0 (INFO) : {
                QUAD(_stext)                                    /* default_lma */
                QUAD(startup_continue)                          /* entry */
                QUAD(__bss_start - _stext)                      /* image_size */
                QUAD(__bss_stop - __bss_start)                  /* bss_size */
                QUAD(__boot_data_start)                         /* bootdata_off */
                QUAD(__boot_data_end - __boot_data_start)       /* bootdata_size */
-       }
+       } :NONE
 
        /* Debugging sections.  */
        STABS_DEBUG
index 76d89ee8b428837fc6c32f962d0104787caa29a3..814f26520aa2c2439de4e10ce52bf0476c8f2661 100644 (file)
@@ -101,6 +101,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end)
                        mm->context.asce_limit = _REGION1_SIZE;
                        mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
                                _ASCE_USER_BITS | _ASCE_TYPE_REGION2;
+                       mm_inc_nr_puds(mm);
                } else {
                        crst_table_init(table, _REGION1_ENTRY_EMPTY);
                        pgd_populate(mm, (pgd_t *) table, (p4d_t *) pgd);
index ae0d9e889534cd880f750845fb58d919080e9325..d31bde0870d894bdc2cd3a3006d966924d1d5c1c 100644 (file)
@@ -53,6 +53,7 @@ int __node_distance(int a, int b)
 {
        return mode->distance ? mode->distance(a, b) : 0;
 }
+EXPORT_SYMBOL(__node_distance);
 
 int numa_debug_enabled;
 
index 74c002ddc0ce74868286b77f43dfa6885e6c3e70..28c40624bcb6f0e9b15030037d6f199b46c5fa0f 100644 (file)
@@ -1305,6 +1305,7 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,
                io_req->fds[0] = dev->cow.fd;
        else
                io_req->fds[0] = dev->fd;
+       io_req->error = 0;
 
        if (req_op(req) == REQ_OP_FLUSH) {
                io_req->op = UBD_FLUSH;
@@ -1313,9 +1314,7 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,
                io_req->cow_offset = -1;
                io_req->offset = off;
                io_req->length = bvec->bv_len;
-               io_req->error = 0;
                io_req->sector_mask = 0;
-
                io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
                io_req->offsets[0] = 0;
                io_req->offsets[1] = dev->cow.data_offset;
@@ -1341,11 +1340,14 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,
 static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
                                 const struct blk_mq_queue_data *bd)
 {
+       struct ubd *ubd_dev = hctx->queue->queuedata;
        struct request *req = bd->rq;
        int ret = 0;
 
        blk_mq_start_request(req);
 
+       spin_lock_irq(&ubd_dev->lock);
+
        if (req_op(req) == REQ_OP_FLUSH) {
                ret = ubd_queue_one_vec(hctx, req, 0, NULL);
        } else {
@@ -1361,9 +1363,11 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
                }
        }
 out:
-       if (ret < 0) {
+       spin_unlock_irq(&ubd_dev->lock);
+
+       if (ret < 0)
                blk_mq_requeue_request(req, true);
-       }
+
        return BLK_STS_OK;
 }
 
index ba7e3464ee9235fe43f0edd66034d670b2fc4ffd..9d734f3c8234d4bbdd44bb06518a768a6b9b7d02 100644 (file)
@@ -525,7 +525,6 @@ config X86_VSMP
        bool "ScaleMP vSMP"
        select HYPERVISOR_GUEST
        select PARAVIRT
-       select PARAVIRT_XXL
        depends on X86_64 && PCI
        depends on X86_EXTENDED_PLATFORM
        depends on SMP
index 5b562e4640099086493bc0fa6d46da88a0780f09..88398fdf81291ff7c58aef6f705ddf0910ecb59d 100644 (file)
@@ -213,8 +213,6 @@ ifdef CONFIG_X86_64
 KBUILD_LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
 endif
 
-# Speed up the build
-KBUILD_CFLAGS += -pipe
 # Workaround for a gcc prelease that unfortunately was shipped in a suse release
 KBUILD_CFLAGS += -Wno-sign-compare
 #
@@ -239,7 +237,7 @@ archheaders:
 archmacros:
        $(Q)$(MAKE) $(build)=arch/x86/kernel arch/x86/kernel/macros.s
 
-ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s -Wa,-
+ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s
 export ASM_MACRO_FLAGS
 KBUILD_CFLAGS += $(ASM_MACRO_FLAGS)
 
index e17ab885b1e928d17a671eb96f12cf21905bdb93..cb46d602a6b8bd17eb458f84778019b56b15a93c 100644 (file)
@@ -129,8 +129,15 @@ struct intel_uncore_box {
        struct intel_uncore_extra_reg shared_regs[0];
 };
 
-#define UNCORE_BOX_FLAG_INITIATED      0
-#define UNCORE_BOX_FLAG_CTL_OFFS8      1 /* event config registers are 8-byte apart */
+/* CFL uncore 8th cbox MSRs */
+#define CFL_UNC_CBO_7_PERFEVTSEL0              0xf70
+#define CFL_UNC_CBO_7_PER_CTR0                 0xf76
+
+#define UNCORE_BOX_FLAG_INITIATED              0
+/* event config registers are 8-byte apart */
+#define UNCORE_BOX_FLAG_CTL_OFFS8              1
+/* CFL 8th CBOX has different MSR space */
+#define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS     2
 
 struct uncore_event_desc {
        struct kobj_attribute attr;
@@ -297,17 +304,27 @@ unsigned int uncore_freerunning_counter(struct intel_uncore_box *box,
 static inline
 unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
 {
-       return box->pmu->type->event_ctl +
-               (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-               uncore_msr_box_offset(box);
+       if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) {
+               return CFL_UNC_CBO_7_PERFEVTSEL0 +
+                      (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx);
+       } else {
+               return box->pmu->type->event_ctl +
+                      (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+                      uncore_msr_box_offset(box);
+       }
 }
 
 static inline
 unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
 {
-       return box->pmu->type->perf_ctr +
-               (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
-               uncore_msr_box_offset(box);
+       if (test_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags)) {
+               return CFL_UNC_CBO_7_PER_CTR0 +
+                      (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx);
+       } else {
+               return box->pmu->type->perf_ctr +
+                      (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
+                      uncore_msr_box_offset(box);
+       }
 }
 
 static inline
index 8527c3e1038b78d868743274c35368ab318649ca..2593b0d7aeee6089413d980618ce07c35d84c101 100644 (file)
 #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC 0x1910
 #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC 0x190f
 #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC 0x191f
+#define PCI_DEVICE_ID_INTEL_KBL_Y_IMC  0x590c
+#define PCI_DEVICE_ID_INTEL_KBL_U_IMC  0x5904
+#define PCI_DEVICE_ID_INTEL_KBL_UQ_IMC 0x5914
+#define PCI_DEVICE_ID_INTEL_KBL_SD_IMC 0x590f
+#define PCI_DEVICE_ID_INTEL_KBL_SQ_IMC 0x591f
+#define PCI_DEVICE_ID_INTEL_CFL_2U_IMC 0x3ecc
+#define PCI_DEVICE_ID_INTEL_CFL_4U_IMC 0x3ed0
+#define PCI_DEVICE_ID_INTEL_CFL_4H_IMC 0x3e10
+#define PCI_DEVICE_ID_INTEL_CFL_6H_IMC 0x3ec4
+#define PCI_DEVICE_ID_INTEL_CFL_2S_D_IMC       0x3e0f
+#define PCI_DEVICE_ID_INTEL_CFL_4S_D_IMC       0x3e1f
+#define PCI_DEVICE_ID_INTEL_CFL_6S_D_IMC       0x3ec2
+#define PCI_DEVICE_ID_INTEL_CFL_8S_D_IMC       0x3e30
+#define PCI_DEVICE_ID_INTEL_CFL_4S_W_IMC       0x3e18
+#define PCI_DEVICE_ID_INTEL_CFL_6S_W_IMC       0x3ec6
+#define PCI_DEVICE_ID_INTEL_CFL_8S_W_IMC       0x3e31
+#define PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC       0x3e33
+#define PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC       0x3eca
+#define PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC       0x3e32
 
 /* SNB event control */
 #define SNB_UNC_CTL_EV_SEL_MASK                        0x000000ff
@@ -202,6 +221,10 @@ static void skl_uncore_msr_init_box(struct intel_uncore_box *box)
                wrmsrl(SKL_UNC_PERF_GLOBAL_CTL,
                        SNB_UNC_GLOBAL_CTL_EN | SKL_UNC_GLOBAL_CTL_CORE_ALL);
        }
+
+       /* The 8th CBOX has different MSR space */
+       if (box->pmu->pmu_idx == 7)
+               __set_bit(UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS, &box->flags);
 }
 
 static void skl_uncore_msr_enable_box(struct intel_uncore_box *box)
@@ -228,7 +251,7 @@ static struct intel_uncore_ops skl_uncore_msr_ops = {
 static struct intel_uncore_type skl_uncore_cbox = {
        .name           = "cbox",
        .num_counters   = 4,
-       .num_boxes      = 5,
+       .num_boxes      = 8,
        .perf_ctr_bits  = 44,
        .fixed_ctr_bits = 48,
        .perf_ctr       = SNB_UNC_CBO_0_PER_CTR0,
@@ -569,7 +592,82 @@ static const struct pci_device_id skl_uncore_pci_ids[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SQ_IMC),
                .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
        },
-
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_Y_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_U_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_UQ_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_SD_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_SQ_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_2U_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4U_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4H_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6H_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_2S_D_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_D_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_D_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_D_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_W_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_W_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_W_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
        { /* end: all zeroes */ },
 };
 
@@ -618,6 +716,25 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
        IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core H Quad Core */
        IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Dual Core */
        IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Quad Core */
+       IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core Y */
+       IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U */
+       IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U Quad Core */
+       IMC_DEV(KBL_SD_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core S Dual Core */
+       IMC_DEV(KBL_SQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core S Quad Core */
+       IMC_DEV(CFL_2U_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core U 2 Cores */
+       IMC_DEV(CFL_4U_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core U 4 Cores */
+       IMC_DEV(CFL_4H_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core H 4 Cores */
+       IMC_DEV(CFL_6H_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core H 6 Cores */
+       IMC_DEV(CFL_2S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 2 Cores Desktop */
+       IMC_DEV(CFL_4S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Desktop */
+       IMC_DEV(CFL_6S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Desktop */
+       IMC_DEV(CFL_8S_D_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Desktop */
+       IMC_DEV(CFL_4S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Work Station */
+       IMC_DEV(CFL_6S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Work Station */
+       IMC_DEV(CFL_8S_W_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Work Station */
+       IMC_DEV(CFL_4S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Server */
+       IMC_DEV(CFL_6S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Server */
+       IMC_DEV(CFL_8S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Server */
        {  /* end marker */ }
 };
 
index 4da9b1c58d287bbdda427e31dd67a1653b519043..c1a812bd5a27d770da1076c5b22ca9dc7dd66762 100644 (file)
@@ -221,6 +221,8 @@ static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c) { return mce_am
 
 int mce_available(struct cpuinfo_x86 *c);
 bool mce_is_memory_error(struct mce *m);
+bool mce_is_correctable(struct mce *m);
+int mce_usable_address(struct mce *m);
 
 DECLARE_PER_CPU(unsigned, mce_exception_count);
 DECLARE_PER_CPU(unsigned, mce_poll_count);
index 0d6271cce198dcd1ac0108ac9a4ea803a6e8b2dc..1d0a7778e16317cab0087c46a1c30a8754e3ec8e 100644 (file)
@@ -232,7 +232,7 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
                                      : "cc");
        }
 #endif
-               return hv_status;
+       return hv_status;
 }
 
 /*
index cd0cf1c568b4cef2fcc5b16c4ebcf374ee9add0d..8f657286d599a9577dca86b46b8199c9c547a661 100644 (file)
 
 /*
  * Set __PAGE_OFFSET to the most negative possible address +
- * PGDIR_SIZE*16 (pgd slot 272).  The gap is to allow a space for a
- * hypervisor to fit.  Choosing 16 slots here is arbitrary, but it's
- * what Xen requires.
+ * PGDIR_SIZE*17 (pgd slot 273).
+ *
+ * The gap is to allow a space for LDT remap for PTI (1 pgd slot) and space for
+ * a hypervisor (16 slots). Choosing 16 slots for a hypervisor is arbitrary,
+ * but it's what Xen requires.
  */
-#define __PAGE_OFFSET_BASE_L5  _AC(0xff10000000000000, UL)
-#define __PAGE_OFFSET_BASE_L4  _AC(0xffff880000000000, UL)
+#define __PAGE_OFFSET_BASE_L5  _AC(0xff11000000000000, UL)
+#define __PAGE_OFFSET_BASE_L4  _AC(0xffff888000000000, UL)
 
 #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT
 #define __PAGE_OFFSET           page_offset_base
index 04edd2d58211a78e3261993bd8d0e088e3b4c4ef..84bd9bdc1987faa634cd1daad7dbfe94d586a82b 100644 (file)
@@ -111,9 +111,7 @@ extern unsigned int ptrs_per_p4d;
  */
 #define MAXMEM                 (1UL << MAX_PHYSMEM_BITS)
 
-#define LDT_PGD_ENTRY_L4       -3UL
-#define LDT_PGD_ENTRY_L5       -112UL
-#define LDT_PGD_ENTRY          (pgtable_l5_enabled() ? LDT_PGD_ENTRY_L5 : LDT_PGD_ENTRY_L4)
+#define LDT_PGD_ENTRY          -240UL
 #define LDT_BASE_ADDR          (LDT_PGD_ENTRY << PGDIR_SHIFT)
 #define LDT_END_ADDR           (LDT_BASE_ADDR + PGDIR_SIZE)
 
index 87623c6b13db5c735bfe80d377f678f1a5f1b893..bd5ac6cc37db5f87c92cc3013138dffa8b2a0302 100644 (file)
 #define queued_fetch_set_pending_acquire queued_fetch_set_pending_acquire
 static __always_inline u32 queued_fetch_set_pending_acquire(struct qspinlock *lock)
 {
-       u32 val = 0;
-
-       if (GEN_BINARY_RMWcc(LOCK_PREFIX "btsl", lock->val.counter, c,
-                            "I", _Q_PENDING_OFFSET))
-               val |= _Q_PENDING_VAL;
+       u32 val;
 
+       /*
+        * We can't use GEN_BINARY_RMWcc() inside an if() stmt because asm goto
+        * and CONFIG_PROFILE_ALL_BRANCHES=y results in a label inside a
+        * statement expression, which GCC doesn't like.
+        */
+       val = GEN_BINARY_RMWcc(LOCK_PREFIX "btsl", lock->val.counter, c,
+                              "I", _Q_PENDING_OFFSET) * _Q_PENDING_VAL;
        val |= atomic_read(&lock->val) & ~_Q_PENDING_MASK;
 
        return val;
index 123e669bf363d375820ba3ab2ce981f01aa4329e..790ce08e41f20f4b16a9c085204ea877d6db5e5e 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/mm.h>
 #include <linux/device.h>
 
-#include <linux/uaccess.h>
+#include <asm/extable.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -93,12 +93,39 @@ clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
  */
 static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
 {
-       return __put_user(val, (unsigned long __user *)addr);
+       int ret = 0;
+
+       asm volatile("1: mov %[val], %[ptr]\n"
+                    "2:\n"
+                    ".section .fixup, \"ax\"\n"
+                    "3: sub $1, %[ret]\n"
+                    "   jmp 2b\n"
+                    ".previous\n"
+                    _ASM_EXTABLE(1b, 3b)
+                    : [ret] "+r" (ret), [ptr] "=m" (*addr)
+                    : [val] "r" (val));
+
+       return ret;
 }
 
-static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val)
+static inline int xen_safe_read_ulong(const unsigned long *addr,
+                                     unsigned long *val)
 {
-       return __get_user(*val, (unsigned long __user *)addr);
+       int ret = 0;
+       unsigned long rval = ~0ul;
+
+       asm volatile("1: mov %[ptr], %[rval]\n"
+                    "2:\n"
+                    ".section .fixup, \"ax\"\n"
+                    "3: sub $1, %[ret]\n"
+                    "   jmp 2b\n"
+                    ".previous\n"
+                    _ASM_EXTABLE(1b, 3b)
+                    : [ret] "+r" (ret), [rval] "+r" (rval)
+                    : [ptr] "m" (*addr));
+       *val = rval;
+
+       return ret;
 }
 
 #ifdef CONFIG_XEN_PV
index 8c66d2fc8f81dd1d2404f22e5a06ac696ee8fad9..36d2696c9563e88a8e354068d7e8a43d636371d3 100644 (file)
@@ -485,7 +485,7 @@ static void mce_report_event(struct pt_regs *regs)
  * be somewhat complicated (e.g. segment offset would require an instruction
  * parser). So only support physical addresses up to page granuality for now.
  */
-static int mce_usable_address(struct mce *m)
+int mce_usable_address(struct mce *m)
 {
        if (!(m->status & MCI_STATUS_ADDRV))
                return 0;
@@ -505,6 +505,7 @@ static int mce_usable_address(struct mce *m)
 
        return 1;
 }
+EXPORT_SYMBOL_GPL(mce_usable_address);
 
 bool mce_is_memory_error(struct mce *m)
 {
@@ -534,7 +535,7 @@ bool mce_is_memory_error(struct mce *m)
 }
 EXPORT_SYMBOL_GPL(mce_is_memory_error);
 
-static bool mce_is_correctable(struct mce *m)
+bool mce_is_correctable(struct mce *m)
 {
        if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED)
                return false;
@@ -547,6 +548,7 @@ static bool mce_is_correctable(struct mce *m)
 
        return true;
 }
+EXPORT_SYMBOL_GPL(mce_is_correctable);
 
 static bool cec_add_mce(struct mce *m)
 {
index 1c72f3819eb123d8fb7271a0c49cf94aceae5ee3..e81a2db42df7ba0d6fb28d9b0b2fcf0340bbd585 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kexec.h>
+#include <linux/i8253.h>
 #include <asm/processor.h>
 #include <asm/hypervisor.h>
 #include <asm/hyperv-tlfs.h>
@@ -295,6 +296,16 @@ static void __init ms_hyperv_init_platform(void)
        if (efi_enabled(EFI_BOOT))
                x86_platform.get_nmi_reason = hv_get_nmi_reason;
 
+       /*
+        * Hyper-V VMs have a PIT emulation quirk such that zeroing the
+        * counter register during PIT shutdown restarts the PIT. So it
+        * continues to interrupt @18.2 HZ. Setting i8253_clear_counter
+        * to false tells pit_shutdown() not to zero the counter so that
+        * the PIT really is shutdown. Generation 2 VMs don't have a PIT,
+        * and setting this value has no effect.
+        */
+       i8253_clear_counter_on_shutdown = false;
+
 #if IS_ENABLED(CONFIG_HYPERV)
        /*
         * Setup the hook to get control post apic initialization.
index d9ab49bed8afce9fb2eef06d457709debcf073ba..0eda91f8eeacee4d2511e60383728d22789a948f 100644 (file)
@@ -77,7 +77,7 @@ static __init int setup_vmw_sched_clock(char *s)
 }
 early_param("no-vmw-sched-clock", setup_vmw_sched_clock);
 
-static unsigned long long vmware_sched_clock(void)
+static unsigned long long notrace vmware_sched_clock(void)
 {
        unsigned long long ns;
 
index ab18e0884dc6fdfb6e403760921b3dc87d7ff592..6135ae8ce0364772f5cc72f73b4bb8f2ad3a8d9e 100644 (file)
@@ -199,14 +199,6 @@ static void sanity_check_ldt_mapping(struct mm_struct *mm)
 /*
  * If PTI is enabled, this maps the LDT into the kernelmode and
  * usermode tables for the given mm.
- *
- * There is no corresponding unmap function.  Even if the LDT is freed, we
- * leave the PTEs around until the slot is reused or the mm is destroyed.
- * This is harmless: the LDT is always in ordinary memory, and no one will
- * access the freed slot.
- *
- * If we wanted to unmap freed LDTs, we'd also need to do a flush to make
- * it useful, and the flush would slow down modify_ldt().
  */
 static int
 map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
@@ -214,8 +206,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
        unsigned long va;
        bool is_vmalloc;
        spinlock_t *ptl;
-       pgd_t *pgd;
-       int i;
+       int i, nr_pages;
 
        if (!static_cpu_has(X86_FEATURE_PTI))
                return 0;
@@ -229,16 +220,11 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
        /* Check if the current mappings are sane */
        sanity_check_ldt_mapping(mm);
 
-       /*
-        * Did we already have the top level entry allocated?  We can't
-        * use pgd_none() for this because it doens't do anything on
-        * 4-level page table kernels.
-        */
-       pgd = pgd_offset(mm, LDT_BASE_ADDR);
-
        is_vmalloc = is_vmalloc_addr(ldt->entries);
 
-       for (i = 0; i * PAGE_SIZE < ldt->nr_entries * LDT_ENTRY_SIZE; i++) {
+       nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
+
+       for (i = 0; i < nr_pages; i++) {
                unsigned long offset = i << PAGE_SHIFT;
                const void *src = (char *)ldt->entries + offset;
                unsigned long pfn;
@@ -272,13 +258,39 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
        /* Propagate LDT mapping to the user page-table */
        map_ldt_struct_to_user(mm);
 
-       va = (unsigned long)ldt_slot_va(slot);
-       flush_tlb_mm_range(mm, va, va + LDT_SLOT_STRIDE, PAGE_SHIFT, false);
-
        ldt->slot = slot;
        return 0;
 }
 
+static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
+{
+       unsigned long va;
+       int i, nr_pages;
+
+       if (!ldt)
+               return;
+
+       /* LDT map/unmap is only required for PTI */
+       if (!static_cpu_has(X86_FEATURE_PTI))
+               return;
+
+       nr_pages = DIV_ROUND_UP(ldt->nr_entries * LDT_ENTRY_SIZE, PAGE_SIZE);
+
+       for (i = 0; i < nr_pages; i++) {
+               unsigned long offset = i << PAGE_SHIFT;
+               spinlock_t *ptl;
+               pte_t *ptep;
+
+               va = (unsigned long)ldt_slot_va(ldt->slot) + offset;
+               ptep = get_locked_pte(mm, va, &ptl);
+               pte_clear(mm, va, ptep);
+               pte_unmap_unlock(ptep, ptl);
+       }
+
+       va = (unsigned long)ldt_slot_va(ldt->slot);
+       flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, PAGE_SHIFT, false);
+}
+
 #else /* !CONFIG_PAGE_TABLE_ISOLATION */
 
 static int
@@ -286,6 +298,10 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
 {
        return 0;
 }
+
+static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
+{
+}
 #endif /* CONFIG_PAGE_TABLE_ISOLATION */
 
 static void free_ldt_pgtables(struct mm_struct *mm)
@@ -524,6 +540,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
        }
 
        install_ldt(mm, new_ldt);
+       unmap_ldt_struct(mm, old_ldt);
        free_ldt_struct(old_ldt);
        error = 0;
 
index 1eae5af491c278367630f805c48d78cc32f29cbb..891a75dbc131323b70e9776998cc0b437b4fe033 100644 (file)
 
 #define TOPOLOGY_REGISTER_OFFSET 0x10
 
-#if defined CONFIG_PCI && defined CONFIG_PARAVIRT_XXL
-/*
- * Interrupt control on vSMPowered systems:
- * ~AC is a shadow of IF.  If IF is 'on' AC should be 'off'
- * and vice versa.
- */
-
-asmlinkage __visible unsigned long vsmp_save_fl(void)
-{
-       unsigned long flags = native_save_fl();
-
-       if (!(flags & X86_EFLAGS_IF) || (flags & X86_EFLAGS_AC))
-               flags &= ~X86_EFLAGS_IF;
-       return flags;
-}
-PV_CALLEE_SAVE_REGS_THUNK(vsmp_save_fl);
-
-__visible void vsmp_restore_fl(unsigned long flags)
-{
-       if (flags & X86_EFLAGS_IF)
-               flags &= ~X86_EFLAGS_AC;
-       else
-               flags |= X86_EFLAGS_AC;
-       native_restore_fl(flags);
-}
-PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl);
-
-asmlinkage __visible void vsmp_irq_disable(void)
-{
-       unsigned long flags = native_save_fl();
-
-       native_restore_fl((flags & ~X86_EFLAGS_IF) | X86_EFLAGS_AC);
-}
-PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable);
-
-asmlinkage __visible void vsmp_irq_enable(void)
-{
-       unsigned long flags = native_save_fl();
-
-       native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
-}
-PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_enable);
-
-static unsigned __init vsmp_patch(u8 type, void *ibuf,
-                                 unsigned long addr, unsigned len)
-{
-       switch (type) {
-       case PARAVIRT_PATCH(irq.irq_enable):
-       case PARAVIRT_PATCH(irq.irq_disable):
-       case PARAVIRT_PATCH(irq.save_fl):
-       case PARAVIRT_PATCH(irq.restore_fl):
-               return paravirt_patch_default(type, ibuf, addr, len);
-       default:
-               return native_patch(type, ibuf, addr, len);
-       }
-
-}
-
-static void __init set_vsmp_pv_ops(void)
+#ifdef CONFIG_PCI
+static void __init set_vsmp_ctl(void)
 {
        void __iomem *address;
        unsigned int cap, ctl, cfg;
@@ -109,28 +52,12 @@ static void __init set_vsmp_pv_ops(void)
        }
 #endif
 
-       if (cap & ctl & (1 << 4)) {
-               /* Setup irq ops and turn on vSMP  IRQ fastpath handling */
-               pv_ops.irq.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable);
-               pv_ops.irq.irq_enable = PV_CALLEE_SAVE(vsmp_irq_enable);
-               pv_ops.irq.save_fl = PV_CALLEE_SAVE(vsmp_save_fl);
-               pv_ops.irq.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl);
-               pv_ops.init.patch = vsmp_patch;
-               ctl &= ~(1 << 4);
-       }
        writel(ctl, address + 4);
        ctl = readl(address + 4);
        pr_info("vSMP CTL: control set to:0x%08x\n", ctl);
 
        early_iounmap(address, 8);
 }
-#else
-static void __init set_vsmp_pv_ops(void)
-{
-}
-#endif
-
-#ifdef CONFIG_PCI
 static int is_vsmp = -1;
 
 static void __init detect_vsmp_box(void)
@@ -164,11 +91,14 @@ static int is_vsmp_box(void)
 {
        return 0;
 }
+static void __init set_vsmp_ctl(void)
+{
+}
 #endif
 
 static void __init vsmp_cap_cpus(void)
 {
-#if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP)
+#if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP) && defined(CONFIG_PCI)
        void __iomem *address;
        unsigned int cfg, topology, node_shift, maxcpus;
 
@@ -221,6 +151,6 @@ void __init vsmp_init(void)
 
        vsmp_cap_cpus();
 
-       set_vsmp_pv_ops();
+       set_vsmp_ctl();
        return;
 }
index 0d7b3ae4960bb0cc424cdc853cdf2f35a73835ae..a5d7ed12533707f8714e066cd4be4c30f880988d 100644 (file)
@@ -1905,7 +1905,7 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        init_top_pgt[0] = __pgd(0);
 
        /* Pre-constructed entries are in pfn, so convert to mfn */
-       /* L4[272] -> level3_ident_pgt  */
+       /* L4[273] -> level3_ident_pgt  */
        /* L4[511] -> level3_kernel_pgt */
        convert_pfn_mfn(init_top_pgt);
 
@@ -1925,8 +1925,8 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        addr[0] = (unsigned long)pgd;
        addr[1] = (unsigned long)l3;
        addr[2] = (unsigned long)l2;
-       /* Graft it onto L4[272][0]. Note that we creating an aliasing problem:
-        * Both L4[272][0] and L4[511][510] have entries that point to the same
+       /* Graft it onto L4[273][0]. Note that we creating an aliasing problem:
+        * Both L4[273][0] and L4[511][510] have entries that point to the same
         * L2 (PMD) tables. Meaning that if you modify it in __va space
         * it will be also modified in the __ka space! (But if you just
         * modify the PMD table to point to other PTE's or none, then you
index b06731705529b1e4c339bc21db8de0a565acf6d8..055e37e43541ed17d11cf4a194085b7fc3a3192c 100644 (file)
@@ -656,8 +656,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 
        /*
         * The interface requires atomic updates on p2m elements.
-        * xen_safe_write_ulong() is using __put_user which does an atomic
-        * store via asm().
+        * xen_safe_write_ulong() is using an atomic store via asm().
         */
        if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
                return true;
index 441c8826216982a4fb9532b68d68a37cbb0d3e05..1c8a8816a402abd09bf199f57314daf61d9819d9 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/log2.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
+#include <linux/atomic.h>
 
 #include <asm/paravirt.h>
 #include <asm/qspinlock.h>
@@ -21,6 +22,7 @@
 
 static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
 static DEFINE_PER_CPU(char *, irq_name);
+static DEFINE_PER_CPU(atomic_t, xen_qlock_wait_nest);
 static bool xen_pvspin = true;
 
 static void xen_qlock_kick(int cpu)
@@ -39,25 +41,25 @@ static void xen_qlock_kick(int cpu)
  */
 static void xen_qlock_wait(u8 *byte, u8 val)
 {
-       unsigned long flags;
        int irq = __this_cpu_read(lock_kicker_irq);
+       atomic_t *nest_cnt = this_cpu_ptr(&xen_qlock_wait_nest);
 
        /* If kicker interrupts not initialized yet, just spin */
        if (irq == -1 || in_nmi())
                return;
 
-       /* Guard against reentry. */
-       local_irq_save(flags);
+       /* Detect reentry. */
+       atomic_inc(nest_cnt);
 
-       /* If irq pending already clear it. */
-       if (xen_test_irq_pending(irq)) {
+       /* If irq pending already and no nested call clear it. */
+       if (atomic_read(nest_cnt) == 1 && xen_test_irq_pending(irq)) {
                xen_clear_irq_pending(irq);
        } else if (READ_ONCE(*byte) == val) {
                /* Block until irq becomes pending (or a spurious wakeup) */
                xen_poll_irq(irq);
        }
 
-       local_irq_restore(flags);
+       atomic_dec(nest_cnt);
 }
 
 static irqreturn_t dummy_handler(int irq, void *dev_id)
index be9bfd9aa865beb554b2b6e7ce92010cf276b927..34a23016dd1442f5c95d445f13276d97c772072d 100644 (file)
 # error Linux requires the Xtensa Windowed Registers Option.
 #endif
 
-#define ARCH_SLAB_MINALIGN     XCHAL_DATA_WIDTH
+/* Xtensa ABI requires stack alignment to be at least 16 */
+
+#define STACK_ALIGN (XCHAL_DATA_WIDTH > 16 ? XCHAL_DATA_WIDTH : 16)
+
+#define ARCH_SLAB_MINALIGN STACK_ALIGN
 
 /*
  * User space process size: 1 GB.
index 2f76118ecf6230ff01fe0e43221269da7b208f46..9053a5622d2c3435faefe4950f953b7923e8332f 100644 (file)
@@ -88,9 +88,12 @@ _SetupMMU:
        initialize_mmu
 #if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
        rsr     a2, excsave1
-       movi    a3, 0x08000000
+       movi    a3, XCHAL_KSEG_PADDR
+       bltu    a2, a3, 1f
+       sub     a2, a2, a3
+       movi    a3, XCHAL_KSEG_SIZE
        bgeu    a2, a3, 1f
-       movi    a3, 0xd0000000
+       movi    a3, XCHAL_KSEG_CACHED_VADDR
        add     a2, a2, a3
        wsr     a2, excsave1
 1:
index d5368a4455613452972e0b8b06ea3e1ceacb335e..4f4d9884443b63a8f002ddd754ea467f9a0e4c16 100644 (file)
@@ -605,6 +605,7 @@ void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
        if (bio_flagged(bio_src, BIO_THROTTLED))
                bio_set_flag(bio, BIO_THROTTLED);
        bio->bi_opf = bio_src->bi_opf;
+       bio->bi_ioprio = bio_src->bi_ioprio;
        bio->bi_write_hint = bio_src->bi_write_hint;
        bio->bi_iter = bio_src->bi_iter;
        bio->bi_io_vec = bio_src->bi_io_vec;
@@ -1260,6 +1261,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
                if (ret)
                        goto cleanup;
        } else {
+               zero_fill_bio(bio);
                iov_iter_advance(iter, bio->bi_iter.bi_size);
        }
 
index ce12515f9b9b9930da4515ed8f70a4cf5f5b946f..deb56932f8c46e9cb0fe0950000b8da1922addfc 100644 (file)
@@ -798,9 +798,8 @@ void blk_cleanup_queue(struct request_queue *q)
         * dispatch may still be in-progress since we dispatch requests
         * from more than one contexts.
         *
-        * No need to quiesce queue if it isn't initialized yet since
-        * blk_freeze_queue() should be enough for cases of passthrough
-        * request.
+        * We rely on driver to deal with the race in case that queue
+        * initialization isn't done.
         */
        if (q->mq_ops && blk_queue_init_done(q))
                blk_mq_quiesce_queue(q);
index 76f867ea9a9b92fdfa921843a6a0ffe2c4297087..5f2c429d437847447bc329a00c11a91f58a28edf 100644 (file)
@@ -51,16 +51,14 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
        if ((sector | nr_sects) & bs_mask)
                return -EINVAL;
 
-       while (nr_sects) {
-               unsigned int req_sects = nr_sects;
-               sector_t end_sect;
+       if (!nr_sects)
+               return -EINVAL;
 
-               if (!req_sects)
-                       goto fail;
-               if (req_sects > UINT_MAX >> 9)
-                       req_sects = UINT_MAX >> 9;
+       while (nr_sects) {
+               sector_t req_sects = min_t(sector_t, nr_sects,
+                               bio_allowed_max_sectors(q));
 
-               end_sect = sector + req_sects;
+               WARN_ON_ONCE((req_sects << 9) > UINT_MAX);
 
                bio = blk_next_bio(bio, 0, gfp_mask);
                bio->bi_iter.bi_sector = sector;
@@ -68,8 +66,8 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                bio_set_op_attrs(bio, op, 0);
 
                bio->bi_iter.bi_size = req_sects << 9;
+               sector += req_sects;
                nr_sects -= req_sects;
-               sector = end_sect;
 
                /*
                 * We can loop for a long time in here, if someone does
@@ -82,14 +80,6 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 
        *biop = bio;
        return 0;
-
-fail:
-       if (bio) {
-               submit_bio_wait(bio);
-               bio_put(bio);
-       }
-       *biop = NULL;
-       return -EOPNOTSUPP;
 }
 EXPORT_SYMBOL(__blkdev_issue_discard);
 
@@ -161,7 +151,7 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
                return -EOPNOTSUPP;
 
        /* Ensure that max_write_same_sectors doesn't overflow bi_size */
-       max_write_same_sectors = UINT_MAX >> 9;
+       max_write_same_sectors = bio_allowed_max_sectors(q);
 
        while (nr_sects) {
                bio = blk_next_bio(bio, 1, gfp_mask);
index 6b5ad275ed565de274746b1ef473f46a3a20a621..e7696c47489ad1f8caa11a64ff8fdb2b6d0f41a2 100644 (file)
@@ -46,7 +46,7 @@ static inline bool bio_will_gap(struct request_queue *q,
                bio_get_first_bvec(prev_rq->bio, &pb);
        else
                bio_get_first_bvec(prev, &pb);
-       if (pb.bv_offset)
+       if (pb.bv_offset & queue_virt_boundary(q))
                return true;
 
        /*
@@ -90,7 +90,8 @@ static struct bio *blk_bio_discard_split(struct request_queue *q,
        /* Zero-sector (unknown) and one-sector granularities are the same.  */
        granularity = max(q->limits.discard_granularity >> 9, 1U);
 
-       max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
+       max_discard_sectors = min(q->limits.max_discard_sectors,
+                       bio_allowed_max_sectors(q));
        max_discard_sectors -= max_discard_sectors % granularity;
 
        if (unlikely(!max_discard_sectors)) {
index a1841b8ff12963a883047780762229f923989f01..0089fefdf771d7082ee05ca97504005090a26025 100644 (file)
@@ -169,7 +169,7 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
 static inline bool __bvec_gap_to_prev(struct request_queue *q,
                struct bio_vec *bprv, unsigned int offset)
 {
-       return offset ||
+       return (offset & queue_virt_boundary(q)) ||
                ((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
 }
 
@@ -395,6 +395,16 @@ static inline unsigned long blk_rq_deadline(struct request *rq)
        return rq->__deadline & ~0x1UL;
 }
 
+/*
+ * The max size one bio can handle is UINT_MAX becasue bvec_iter.bi_size
+ * is defined as 'unsigned int', meantime it has to aligned to with logical
+ * block size which is the minimum accepted unit by hardware.
+ */
+static inline unsigned int bio_allowed_max_sectors(struct request_queue *q)
+{
+       return round_down(UINT_MAX, queue_logical_block_size(q)) >> 9;
+}
+
 /*
  * Internal io_context interface
  */
index 36869afc258ccf6ea609e0e74db6cea56e6d2c34..559c55bda040e2da3d2ec1bc66dacb6e7f02b829 100644 (file)
@@ -248,6 +248,7 @@ static struct bio *bounce_clone_bio(struct bio *bio_src, gfp_t gfp_mask,
                return NULL;
        bio->bi_disk            = bio_src->bi_disk;
        bio->bi_opf             = bio_src->bi_opf;
+       bio->bi_ioprio          = bio_src->bi_ioprio;
        bio->bi_write_hint      = bio_src->bi_write_hint;
        bio->bi_iter.bi_sector  = bio_src->bi_iter.bi_sector;
        bio->bi_iter.bi_size    = bio_src->bi_iter.bi_size;
index e41f6cc33fff49f2b35ad52504742ba79c70c3b8..784748dbb19f0c58482ad18c761c7de121d41928 100644 (file)
@@ -84,7 +84,7 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_cipher rcipher;
 
-       strlcpy(rcipher.type, "cipher", sizeof(rcipher.type));
+       strncpy(rcipher.type, "cipher", sizeof(rcipher.type));
 
        rcipher.blocksize = alg->cra_blocksize;
        rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
@@ -103,7 +103,7 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_comp rcomp;
 
-       strlcpy(rcomp.type, "compression", sizeof(rcomp.type));
+       strncpy(rcomp.type, "compression", sizeof(rcomp.type));
        if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
                    sizeof(struct crypto_report_comp), &rcomp))
                goto nla_put_failure;
@@ -117,7 +117,7 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_acomp racomp;
 
-       strlcpy(racomp.type, "acomp", sizeof(racomp.type));
+       strncpy(racomp.type, "acomp", sizeof(racomp.type));
 
        if (nla_put(skb, CRYPTOCFGA_REPORT_ACOMP,
                    sizeof(struct crypto_report_acomp), &racomp))
@@ -132,7 +132,7 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_akcipher rakcipher;
 
-       strlcpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
+       strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
 
        if (nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER,
                    sizeof(struct crypto_report_akcipher), &rakcipher))
@@ -147,7 +147,7 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
 {
        struct crypto_report_kpp rkpp;
 
-       strlcpy(rkpp.type, "kpp", sizeof(rkpp.type));
+       strncpy(rkpp.type, "kpp", sizeof(rkpp.type));
 
        if (nla_put(skb, CRYPTOCFGA_REPORT_KPP,
                    sizeof(struct crypto_report_kpp), &rkpp))
@@ -161,10 +161,10 @@ nla_put_failure:
 static int crypto_report_one(struct crypto_alg *alg,
                             struct crypto_user_alg *ualg, struct sk_buff *skb)
 {
-       strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
-       strlcpy(ualg->cru_driver_name, alg->cra_driver_name,
+       strncpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
+       strncpy(ualg->cru_driver_name, alg->cra_driver_name,
                sizeof(ualg->cru_driver_name));
-       strlcpy(ualg->cru_module_name, module_name(alg->cra_module),
+       strncpy(ualg->cru_module_name, module_name(alg->cra_module),
                sizeof(ualg->cru_module_name));
 
        ualg->cru_type = 0;
@@ -177,7 +177,7 @@ static int crypto_report_one(struct crypto_alg *alg,
        if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
                struct crypto_report_larval rl;
 
-               strlcpy(rl.type, "larval", sizeof(rl.type));
+               strncpy(rl.type, "larval", sizeof(rl.type));
                if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
                            sizeof(struct crypto_report_larval), &rl))
                        goto nla_put_failure;
index 021ad06bbb628b5bc199ccded03c44429bae061c..1dfaa0ccd555b5bd3246822365114fa69c7e5ae1 100644 (file)
@@ -37,6 +37,8 @@ static int crypto_report_aead(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&raead, 0, sizeof(raead));
+
        strncpy(raead.type, "aead", sizeof(raead.type));
 
        v32 = atomic_read(&alg->encrypt_cnt);
@@ -65,6 +67,8 @@ static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rcipher, 0, sizeof(rcipher));
+
        strlcpy(rcipher.type, "cipher", sizeof(rcipher.type));
 
        v32 = atomic_read(&alg->encrypt_cnt);
@@ -93,6 +97,8 @@ static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rcomp, 0, sizeof(rcomp));
+
        strlcpy(rcomp.type, "compression", sizeof(rcomp.type));
        v32 = atomic_read(&alg->compress_cnt);
        rcomp.stat_compress_cnt = v32;
@@ -120,6 +126,8 @@ static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&racomp, 0, sizeof(racomp));
+
        strlcpy(racomp.type, "acomp", sizeof(racomp.type));
        v32 = atomic_read(&alg->compress_cnt);
        racomp.stat_compress_cnt = v32;
@@ -147,6 +155,8 @@ static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rakcipher, 0, sizeof(rakcipher));
+
        strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type));
        v32 = atomic_read(&alg->encrypt_cnt);
        rakcipher.stat_encrypt_cnt = v32;
@@ -177,6 +187,8 @@ static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg)
        struct crypto_stat rkpp;
        u32 v;
 
+       memset(&rkpp, 0, sizeof(rkpp));
+
        strlcpy(rkpp.type, "kpp", sizeof(rkpp.type));
 
        v = atomic_read(&alg->setsecret_cnt);
@@ -203,6 +215,8 @@ static int crypto_report_ahash(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rhash, 0, sizeof(rhash));
+
        strncpy(rhash.type, "ahash", sizeof(rhash.type));
 
        v32 = atomic_read(&alg->hash_cnt);
@@ -227,6 +241,8 @@ static int crypto_report_shash(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rhash, 0, sizeof(rhash));
+
        strncpy(rhash.type, "shash", sizeof(rhash.type));
 
        v32 = atomic_read(&alg->hash_cnt);
@@ -251,6 +267,8 @@ static int crypto_report_rng(struct sk_buff *skb, struct crypto_alg *alg)
        u64 v64;
        u32 v32;
 
+       memset(&rrng, 0, sizeof(rrng));
+
        strncpy(rrng.type, "rng", sizeof(rrng.type));
 
        v32 = atomic_read(&alg->generate_cnt);
@@ -275,6 +293,8 @@ static int crypto_reportstat_one(struct crypto_alg *alg,
                                 struct crypto_user_alg *ualg,
                                 struct sk_buff *skb)
 {
+       memset(ualg, 0, sizeof(*ualg));
+
        strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name));
        strlcpy(ualg->cru_driver_name, alg->cra_driver_name,
                sizeof(ualg->cru_driver_name));
@@ -291,6 +311,7 @@ static int crypto_reportstat_one(struct crypto_alg *alg,
        if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
                struct crypto_stat rl;
 
+               memset(&rl, 0, sizeof(rl));
                strlcpy(rl.type, "larval", sizeof(rl.type));
                if (nla_put(skb, CRYPTOCFGA_STAT_LARVAL,
                            sizeof(struct crypto_stat), &rl))
index ea7240be3001ba245c12d3214c11a7c7e6a8a1fd..78e8d037ae2b342d94ff837d6c9de82b6a4a1090 100644 (file)
@@ -124,8 +124,9 @@ static int simd_skcipher_init(struct crypto_skcipher *tfm)
 
        ctx->cryptd_tfm = cryptd_tfm;
 
-       reqsize = sizeof(struct skcipher_request);
-       reqsize += crypto_skcipher_reqsize(&cryptd_tfm->base);
+       reqsize = crypto_skcipher_reqsize(cryptd_skcipher_child(cryptd_tfm));
+       reqsize = max(reqsize, crypto_skcipher_reqsize(&cryptd_tfm->base));
+       reqsize += sizeof(struct skcipher_request);
 
        crypto_skcipher_set_reqsize(tfm, reqsize);
 
index 8f3a444c6ea9233a2c0cd116e387a71c65d2360f..7cea769c37df55b50c55a7e8751a05057b5348cd 100644 (file)
@@ -512,7 +512,7 @@ config CRC_PMIC_OPREGION
 
 config XPOWER_PMIC_OPREGION
        bool "ACPI operation region support for XPower AXP288 PMIC"
-       depends on MFD_AXP20X_I2C && IOSF_MBI
+       depends on MFD_AXP20X_I2C && IOSF_MBI=y
        help
          This config adds ACPI operation region support for XPower AXP288 PMIC.
 
index f8c638f3c946d904fd0d9ea0aa3301bca2bafd14..14d9f5bea0151c39e706ebfb4ecddb1962fdcc33 100644 (file)
@@ -2928,9 +2928,9 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc)
                return rc;
 
        if (ars_status_process_records(acpi_desc))
-               return -ENOMEM;
+               dev_err(acpi_desc->dev, "Failed to process ARS records\n");
 
-       return 0;
+       return rc;
 }
 
 static int ars_register(struct acpi_nfit_desc *acpi_desc,
@@ -3341,8 +3341,6 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
                struct nvdimm *nvdimm, unsigned int cmd)
 {
        struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
-       struct nfit_spa *nfit_spa;
-       int rc = 0;
 
        if (nvdimm)
                return 0;
@@ -3355,17 +3353,10 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
         * just needs guarantees that any ARS it initiates are not
         * interrupted by any intervening start requests from userspace.
         */
-       mutex_lock(&acpi_desc->init_mutex);
-       list_for_each_entry(nfit_spa, &acpi_desc->spas, list)
-               if (acpi_desc->scrub_spa
-                               || test_bit(ARS_REQ_SHORT, &nfit_spa->ars_state)
-                               || test_bit(ARS_REQ_LONG, &nfit_spa->ars_state)) {
-                       rc = -EBUSY;
-                       break;
-               }
-       mutex_unlock(&acpi_desc->init_mutex);
+       if (work_busy(&acpi_desc->dwork.work))
+               return -EBUSY;
 
-       return rc;
+       return 0;
 }
 
 int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc,
index e9626bf6ca2960a2398aeeefc0f4c9e814e60c1b..d6c1b10f6c2542a8cfbbac6dae31246cd35134f7 100644 (file)
@@ -25,8 +25,12 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
        struct acpi_nfit_desc *acpi_desc;
        struct nfit_spa *nfit_spa;
 
-       /* We only care about memory errors */
-       if (!mce_is_memory_error(mce))
+       /* We only care about uncorrectable memory errors */
+       if (!mce_is_memory_error(mce) || mce_is_correctable(mce))
+               return NOTIFY_DONE;
+
+       /* Verify the address reported in the MCE is valid. */
+       if (!mce_usable_address(mce))
                return NOTIFY_DONE;
 
        /*
index 6e594644cb1d360dabbdf3a4b68851a45c5bfb0f..a7f5202a48152a42e6b2b7ab5835289d8cb6fcca 100644 (file)
@@ -4553,7 +4553,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* These specific Samsung models/firmware-revs do not handle LPM well */
        { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM, },
        { "SAMSUNG SSD PM830 mSATA *",  "CXM13D1Q", ATA_HORKAGE_NOLPM, },
-       { "SAMSUNG MZ7TD256HAFV-000L9", "DXT02L5Q", ATA_HORKAGE_NOLPM, },
+       { "SAMSUNG MZ7TD256HAFV-000L9", NULL,       ATA_HORKAGE_NOLPM, },
 
        /* devices that don't properly handle queued TRIM commands */
        { "Micron_M500IT_*",            "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
index 10ecb232245db8c617ee808966db432ece834358..4b1ff5bc256a3032191f090226ffb4c5d0286ae9 100644 (file)
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Renesas R-Car SATA driver
  *
  * Author: Vladimir Barinov <source@cogentembedded.com>
  * Copyright (C) 2013-2015 Cogent Embedded, Inc.
  * Copyright (C) 2013-2015 Renesas Solutions Corp.
- *
- * 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;  either version 2 of the  License, or (at your
- * option) any later version.
  */
 
 #include <linux/kernel.h>
index a8cfa011c28483ef389ee161b5ca86af71eac13e..fb23578e9a416703648154b7371f05bbe3f5ceb8 100644 (file)
@@ -4148,10 +4148,11 @@ static int __floppy_read_block_0(struct block_device *bdev, int drive)
        bio.bi_end_io = floppy_rb0_cb;
        bio_set_op_attrs(&bio, REQ_OP_READ, 0);
 
+       init_completion(&cbdata.complete);
+
        submit_bio(&bio);
        process_fd_request();
 
-       init_completion(&cbdata.complete);
        wait_for_completion(&cbdata.complete);
 
        __free_page(page);
index 56452cabce5b587cb7309f9ba24640bbf0ba05da..0ed4b200fa5855e10a142b6f6ce237901cf749ec 100644 (file)
@@ -1919,6 +1919,7 @@ static int negotiate_mq(struct blkfront_info *info)
                              GFP_KERNEL);
        if (!info->rinfo) {
                xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
+               info->nr_rings = 0;
                return -ENOMEM;
        }
 
index ef0ca9414f371bc3275b7afce529029e10b49f68..ff83e899df71fca602aadba443fdce73308eb9c5 100644 (file)
@@ -210,6 +210,7 @@ static int of_fixed_factor_clk_remove(struct platform_device *pdev)
 {
        struct clk *clk = platform_get_drvdata(pdev);
 
+       of_clk_del_provider(pdev->dev.of_node);
        clk_unregister_fixed_factor(clk);
 
        return 0;
index c981159b02c0f09c604a78005f26103c75962e9c..792735d7e46ea0faf3299f710813df3f98cd3834 100644 (file)
@@ -325,6 +325,7 @@ static struct clk_regmap axg_fclk_div2 = {
                .ops = &clk_regmap_gate_ops,
                .parent_names = (const char *[]){ "fclk_div2_div" },
                .num_parents = 1,
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
@@ -349,6 +350,18 @@ static struct clk_regmap axg_fclk_div3 = {
                .ops = &clk_regmap_gate_ops,
                .parent_names = (const char *[]){ "fclk_div3_div" },
                .num_parents = 1,
+               /*
+                * FIXME:
+                * This clock, as fdiv2, is used by the SCPI FW and is required
+                * by the platform to operate correctly.
+                * Until the following condition are met, we need this clock to
+                * be marked as critical:
+                * a) The SCPI generic driver claims and enable all the clocks
+                *    it needs
+                * b) CCF has a clock hand-off mechanism to make the sure the
+                *    clock stays on until the proper driver comes along
+                */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
index 9309cfaaa464ebd5f3e7d26e174c3c8449e16208..4ada9668fd49c2596de2667aebccd841ee673bb5 100644 (file)
@@ -506,6 +506,18 @@ static struct clk_regmap gxbb_fclk_div3 = {
                .ops = &clk_regmap_gate_ops,
                .parent_names = (const char *[]){ "fclk_div3_div" },
                .num_parents = 1,
+               /*
+                * FIXME:
+                * This clock, as fdiv2, is used by the SCPI FW and is required
+                * by the platform to operate correctly.
+                * Until the following condition are met, we need this clock to
+                * be marked as critical:
+                * a) The SCPI generic driver claims and enable all the clocks
+                *    it needs
+                * b) CCF has a clock hand-off mechanism to make the sure the
+                *    clock stays on until the proper driver comes along
+                */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
index e4ca6a45f31397324d4f79378b59036a38218641..ef1b267cb058a4a03f0ead86218ee165653fd737 100644 (file)
@@ -265,7 +265,7 @@ static struct clk_fixed_factor cxo = {
        .div = 1,
        .hw.init = &(struct clk_init_data){
                .name = "cxo",
-               .parent_names = (const char *[]){ "xo_board" },
+               .parent_names = (const char *[]){ "xo-board" },
                .num_parents = 1,
                .ops = &clk_fixed_factor_ops,
        },
index 9c38895542f4abb5bff8c487ff22701e008443a2..d4350bb10b83a26aa1c9a56555ff8a20e949148a 100644 (file)
 DEFINE_RAW_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
+/*
+ * Handle PIT quirk in pit_shutdown() where zeroing the counter register
+ * restarts the PIT, negating the shutdown. On platforms with the quirk,
+ * platform specific code can set this to false.
+ */
+bool i8253_clear_counter_on_shutdown __ro_after_init = true;
+
 #ifdef CONFIG_CLKSRC_I8253
 /*
  * Since the PIT overflows every tick, its not very useful
@@ -109,8 +116,11 @@ static int pit_shutdown(struct clock_event_device *evt)
        raw_spin_lock(&i8253_lock);
 
        outb_p(0x30, PIT_MODE);
-       outb_p(0, PIT_CH0);
-       outb_p(0, PIT_CH0);
+
+       if (i8253_clear_counter_on_shutdown) {
+               outb_p(0, PIT_CH0);
+               outb_p(0, PIT_CH0);
+       }
 
        raw_spin_unlock(&i8253_lock);
        return 0;
index 8cfee0ab804b43e2dc90e9f55b241a7aa17de363..d8c3595e90236e5f9d87ca9b5f55a7cbdb76ccdc 100644 (file)
@@ -160,8 +160,13 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
        /* Ensure the arm clock divider is what we expect */
        ret = clk_set_rate(clks[ARM].clk, new_freq * 1000);
        if (ret) {
+               int ret1;
+
                dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
-               regulator_set_voltage_tol(arm_reg, volt_old, 0);
+               ret1 = regulator_set_voltage_tol(arm_reg, volt_old, 0);
+               if (ret1)
+                       dev_warn(cpu_dev,
+                                "failed to restore vddarm voltage: %d\n", ret1);
                return ret;
        }
 
index 073557f433eb1be630a7f64b8cfc9930771eff2a..3a407a3ef22b4c5a53046452c75c3784e0b77d9d 100644 (file)
@@ -82,7 +82,6 @@ static int __init arm_idle_init_cpu(int cpu)
 {
        int ret;
        struct cpuidle_driver *drv;
-       struct cpuidle_device *dev;
 
        drv = kmemdup(&arm_idle_driver, sizeof(*drv), GFP_KERNEL);
        if (!drv)
@@ -103,13 +102,6 @@ static int __init arm_idle_init_cpu(int cpu)
                goto out_kfree_drv;
        }
 
-       ret = cpuidle_register_driver(drv);
-       if (ret) {
-               if (ret != -EBUSY)
-                       pr_err("Failed to register cpuidle driver\n");
-               goto out_kfree_drv;
-       }
-
        /*
         * Call arch CPU operations in order to initialize
         * idle states suspend back-end specific data
@@ -117,37 +109,21 @@ static int __init arm_idle_init_cpu(int cpu)
        ret = arm_cpuidle_init(cpu);
 
        /*
-        * Skip the cpuidle device initialization if the reported
+        * Allow the initialization to continue for other CPUs, if the reported
         * failure is a HW misconfiguration/breakage (-ENXIO).
         */
-       if (ret == -ENXIO)
-               return 0;
-
        if (ret) {
                pr_err("CPU %d failed to init idle CPU ops\n", cpu);
-               goto out_unregister_drv;
-       }
-
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev) {
-               ret = -ENOMEM;
-               goto out_unregister_drv;
+               ret = ret == -ENXIO ? 0 : ret;
+               goto out_kfree_drv;
        }
-       dev->cpu = cpu;
 
-       ret = cpuidle_register_device(dev);
-       if (ret) {
-               pr_err("Failed to register cpuidle device for CPU %d\n",
-                      cpu);
-               goto out_kfree_dev;
-       }
+       ret = cpuidle_register(drv, NULL);
+       if (ret)
+               goto out_kfree_drv;
 
        return 0;
 
-out_kfree_dev:
-       kfree(dev);
-out_unregister_drv:
-       cpuidle_unregister_driver(drv);
 out_kfree_drv:
        kfree(drv);
        return ret;
@@ -178,9 +154,7 @@ out_fail:
        while (--cpu >= 0) {
                dev = per_cpu(cpuidle_devices, cpu);
                drv = cpuidle_get_cpu_driver(dev);
-               cpuidle_unregister_device(dev);
-               cpuidle_unregister_driver(drv);
-               kfree(dev);
+               cpuidle_unregister(drv);
                kfree(drv);
        }
 
index f7d6d690116ee8f32bada36c6b25520976c219c5..cdc4f9a171d986625352319d76ccf243e417410a 100644 (file)
@@ -732,6 +732,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
        int *splits_in_nents;
        int *splits_out_nents = NULL;
        struct sec_request_el *el, *temp;
+       bool split = skreq->src != skreq->dst;
 
        mutex_init(&sec_req->lock);
        sec_req->req_base = &skreq->base;
@@ -750,7 +751,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
        if (ret)
                goto err_free_split_sizes;
 
-       if (skreq->src != skreq->dst) {
+       if (split) {
                sec_req->len_out = sg_nents(skreq->dst);
                ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps,
                                           &splits_out, &splits_out_nents,
@@ -785,8 +786,9 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
                                               split_sizes[i],
                                               skreq->src != skreq->dst,
                                               splits_in[i], splits_in_nents[i],
-                                              splits_out[i],
-                                              splits_out_nents[i], info);
+                                              split ? splits_out[i] : NULL,
+                                              split ? splits_out_nents[i] : 0,
+                                              info);
                if (IS_ERR(el)) {
                        ret = PTR_ERR(el);
                        goto err_free_elements;
@@ -806,13 +808,6 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
         * more refined but this is unlikely to happen so no need.
         */
 
-       /* Cleanup - all elements in pointer arrays have been coppied */
-       kfree(splits_in_nents);
-       kfree(splits_in);
-       kfree(splits_out_nents);
-       kfree(splits_out);
-       kfree(split_sizes);
-
        /* Grab a big lock for a long time to avoid concurrency issues */
        mutex_lock(&queue->queuelock);
 
@@ -827,13 +822,13 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
             (!queue->havesoftqueue ||
              kfifo_avail(&queue->softqueue) > steps)) ||
            !list_empty(&ctx->backlog)) {
+               ret = -EBUSY;
                if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
                        list_add_tail(&sec_req->backlog_head, &ctx->backlog);
                        mutex_unlock(&queue->queuelock);
-                       return -EBUSY;
+                       goto out;
                }
 
-               ret = -EBUSY;
                mutex_unlock(&queue->queuelock);
                goto err_free_elements;
        }
@@ -842,7 +837,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
        if (ret)
                goto err_free_elements;
 
-       return -EINPROGRESS;
+       ret = -EINPROGRESS;
+out:
+       /* Cleanup - all elements in pointer arrays have been copied */
+       kfree(splits_in_nents);
+       kfree(splits_in);
+       kfree(splits_out_nents);
+       kfree(splits_out);
+       kfree(split_sizes);
+       return ret;
 
 err_free_elements:
        list_for_each_entry_safe(el, temp, &sec_req->elements, head) {
@@ -854,7 +857,7 @@ err_free_elements:
                                 crypto_skcipher_ivsize(atfm),
                                 DMA_BIDIRECTIONAL);
 err_unmap_out_sg:
-       if (skreq->src != skreq->dst)
+       if (split)
                sec_unmap_sg_on_err(skreq->dst, steps, splits_out,
                                    splits_out_nents, sec_req->len_out,
                                    info->dev);
index 388a929baf95d1e1107ab4b0ab20516dea3cfdf7..1a6a77df8a5e8aea45f3cbc2bac9c5d0883b0edb 100644 (file)
@@ -265,6 +265,10 @@ void __init efi_init(void)
                                    (params.mmap & ~PAGE_MASK)));
 
        init_screen_info();
+
+       /* ARM does not permit early mappings to persist across paging_init() */
+       if (IS_ENABLED(CONFIG_ARM))
+               efi_memmap_unmap();
 }
 
 static int __init register_gop_device(void)
index 922cfb813109a3c14a88a0bb054a09534e813ec9..a00934d263c519a9d476a57a5bb2388c6041b810 100644 (file)
@@ -110,7 +110,7 @@ static int __init arm_enable_runtime_services(void)
 {
        u64 mapsize;
 
-       if (!efi_enabled(EFI_BOOT) || !efi_enabled(EFI_MEMMAP)) {
+       if (!efi_enabled(EFI_BOOT)) {
                pr_info("EFI services will not be available.\n");
                return 0;
        }
index 249eb70691b0f5e7567cf4fc3bbb8dda9df571cf..fad7c62cfc0e422f3b8459653a561f4dee770a6e 100644 (file)
@@ -592,7 +592,11 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 
                early_memunmap(tbl, sizeof(*tbl));
        }
+       return 0;
+}
 
+int __init efi_apply_persistent_mem_reservations(void)
+{
        if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
                unsigned long prsv = efi.mem_reserve;
 
@@ -963,36 +967,43 @@ bool efi_is_table_address(unsigned long phys_addr)
 }
 
 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
+static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
 
 int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 {
-       struct linux_efi_memreserve *rsv, *parent;
+       struct linux_efi_memreserve *rsv;
 
-       if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+       if (!efi_memreserve_root)
                return -ENODEV;
 
-       rsv = kmalloc(sizeof(*rsv), GFP_KERNEL);
+       rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
        if (!rsv)
                return -ENOMEM;
 
-       parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
-       if (!parent) {
-               kfree(rsv);
-               return -ENOMEM;
-       }
-
        rsv->base = addr;
        rsv->size = size;
 
        spin_lock(&efi_mem_reserve_persistent_lock);
-       rsv->next = parent->next;
-       parent->next = __pa(rsv);
+       rsv->next = efi_memreserve_root->next;
+       efi_memreserve_root->next = __pa(rsv);
        spin_unlock(&efi_mem_reserve_persistent_lock);
 
-       memunmap(parent);
+       return 0;
+}
 
+static int __init efi_memreserve_root_init(void)
+{
+       if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+               return -ENODEV;
+
+       efi_memreserve_root = memremap(efi.mem_reserve,
+                                      sizeof(*efi_memreserve_root),
+                                      MEMREMAP_WB);
+       if (!efi_memreserve_root)
+               return -ENOMEM;
        return 0;
 }
+early_initcall(efi_memreserve_root_init);
 
 #ifdef CONFIG_KEXEC
 static int update_efi_random_seed(struct notifier_block *nb,
index 30ac0c975f8a1cc6bd544ba90991a4330ea05cd9..3d36142cf81208d408cab75e28edf957fa865c9e 100644 (file)
@@ -75,6 +75,9 @@ void install_memreserve_table(efi_system_table_t *sys_table_arg)
        efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
        efi_status_t status;
 
+       if (IS_ENABLED(CONFIG_ARM))
+               return;
+
        status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
                                (void **)&rsv);
        if (status != EFI_SUCCESS) {
index 8830fa601e45d9a1b1094419cd1ec66f41a25e49..0c0d2312f4a8ad27f6e852bc82d5f2b6c0124e64 100644 (file)
@@ -158,6 +158,10 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
                        return efi_status;
                }
        }
+
+       /* shrink the FDT back to its minimum size */
+       fdt_pack(fdt);
+
        return EFI_SUCCESS;
 
 fdt_set_fail:
index fa2904fb841fe459a6562b9fea237c5213fa97be..38b686c67b177da4875b9174c0f50ca165c6b2d4 100644 (file)
@@ -118,6 +118,9 @@ int __init efi_memmap_init_early(struct efi_memory_map_data *data)
 
 void __init efi_memmap_unmap(void)
 {
+       if (!efi_enabled(EFI_MEMMAP))
+               return;
+
        if (!efi.memmap.late) {
                unsigned long size;
 
index a19d845bdb06748907972b652415594e18a095f9..8903b9ccfc2b8da6cdc5341fef8619744d904c88 100644 (file)
@@ -67,7 +67,7 @@ struct efi_runtime_work efi_rts_work;
        }                                                               \
                                                                        \
        init_completion(&efi_rts_work.efi_rts_comp);                    \
-       INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts);            \
+       INIT_WORK(&efi_rts_work.work, efi_call_rts);                    \
        efi_rts_work.arg1 = _arg1;                                      \
        efi_rts_work.arg2 = _arg2;                                      \
        efi_rts_work.arg3 = _arg3;                                      \
index d0102cfc8efbd1825df74c84ed26a0d0042a7e25..104b2e0d893bdad124d8f00405d3287b7bc24992 100644 (file)
@@ -151,6 +151,7 @@ extern int amdgpu_compute_multipipe;
 extern int amdgpu_gpu_recovery;
 extern int amdgpu_emu_mode;
 extern uint amdgpu_smu_memory_pool_size;
+extern uint amdgpu_dc_feature_mask;
 extern struct amdgpu_mgpu_info mgpu_info;
 
 #ifdef CONFIG_DRM_AMDGPU_SI
index 943dbf3c5da12ddb03439e3cc1ea002771e5ab14..8de55f7f1a3a3922b4a1ac2d17cf12cdd35d1fd6 100644 (file)
@@ -127,6 +127,9 @@ int amdgpu_compute_multipipe = -1;
 int amdgpu_gpu_recovery = -1; /* auto */
 int amdgpu_emu_mode = 0;
 uint amdgpu_smu_memory_pool_size = 0;
+/* FBC (bit 0) disabled by default*/
+uint amdgpu_dc_feature_mask = 0;
+
 struct amdgpu_mgpu_info mgpu_info = {
        .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
 };
@@ -631,6 +634,14 @@ module_param(halt_if_hws_hang, int, 0644);
 MODULE_PARM_DESC(halt_if_hws_hang, "Halt if HWS hang is detected (0 = off (default), 1 = on)");
 #endif
 
+/**
+ * DOC: dcfeaturemask (uint)
+ * Override display features enabled. See enum DC_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h.
+ * The default is the current set of stable display features.
+ */
+MODULE_PARM_DESC(dcfeaturemask, "all stable DC features enabled (default))");
+module_param_named(dcfeaturemask, amdgpu_dc_feature_mask, uint, 0444);
+
 static const struct pci_device_id pciidlist[] = {
 #ifdef  CONFIG_DRM_AMDGPU_SI
        {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
index 352b304090602e342ef6f584acab90edf126f51a..dad0e2342df9db7641f77f1473a87f6d78d99050 100644 (file)
@@ -1632,13 +1632,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
                        continue;
                }
 
-               /* First check if the entry is already handled */
-               if (cursor.pfn < frag_start) {
-                       cursor.entry->huge = true;
-                       amdgpu_vm_pt_next(adev, &cursor);
-                       continue;
-               }
-
                /* If it isn't already handled it can't be a huge page */
                if (cursor.entry->huge) {
                        /* Add the entry to the relocated list to update it. */
@@ -1701,8 +1694,17 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
                        }
                } while (frag_start < entry_end);
 
-               if (frag >= shift)
+               if (amdgpu_vm_pt_descendant(adev, &cursor)) {
+                       /* Mark all child entries as huge */
+                       while (cursor.pfn < frag_start) {
+                               cursor.entry->huge = true;
+                               amdgpu_vm_pt_next(adev, &cursor);
+                       }
+
+               } else if (frag >= shift) {
+                       /* or just move on to the next on the same level. */
                        amdgpu_vm_pt_next(adev, &cursor);
+               }
        }
 
        return 0;
index ceb7847b504f70fe73435e5b81b4ee4da5588421..bfa317ad20a956017273a7c1fe7ca2decd6491e1 100644 (file)
@@ -72,7 +72,7 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
 
        /* Program the system aperture low logical page number. */
        WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
-                    min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18);
+                    min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
 
        if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
                /*
@@ -82,11 +82,11 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
                 * to get rid of the VM fault and hardware hang.
                 */
                WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
-                            max((adev->gmc.vram_end >> 18) + 0x1,
+                            max((adev->gmc.fb_end >> 18) + 0x1,
                                 adev->gmc.agp_end >> 18));
        else
                WREG32_SOC15(GC, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
-                            max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
+                            max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
 
        /* Set default page address. */
        value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start
index fd23ba1226a57d9d3f1189db15f07daaab7e199d..a0db67adc34cee3d1ee13ca97d8b333ff36dfdc6 100644 (file)
@@ -90,7 +90,7 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
 
        /* Program the system aperture low logical page number. */
        WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
-                    min(adev->gmc.vram_start, adev->gmc.agp_start) >> 18);
+                    min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
 
        if (adev->asic_type == CHIP_RAVEN && adev->rev_id >= 0x8)
                /*
@@ -100,11 +100,11 @@ static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
                 * to get rid of the VM fault and hardware hang.
                 */
                WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
-                            max((adev->gmc.vram_end >> 18) + 0x1,
+                            max((adev->gmc.fb_end >> 18) + 0x1,
                                 adev->gmc.agp_end >> 18));
        else
                WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
-                            max(adev->gmc.vram_end, adev->gmc.agp_end) >> 18);
+                            max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
 
        /* Set default page address. */
        value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
index a99f71797aa359f83217887dd4dcf531d639d45e..a0fda6f9252a52979b5c90569d48b4212f4ea27a 100644 (file)
@@ -129,7 +129,7 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
        else
                wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
        WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
-       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
+       WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF);
 
        /* set rptr, wptr to 0 */
        WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
index 2d4473557b0d23210782ff72397b47bd7f9c94ef..d13fc4fcb51790859f03aefb14f4bd90067c8fd8 100644 (file)
@@ -49,6 +49,7 @@ int vega20_reg_base_init(struct amdgpu_device *adev)
                adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
                adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
                adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
+               adev->reg_offset[CLK_HWIP][i] = (uint32_t *)(&(CLK_BASE.instance[i]));
        }
        return 0;
 }
index b0df6dc9a775f061120fbad6837e92f483317aea..c1262f62cd9f21400c68a6040000d31e4a9a9716 100644 (file)
@@ -429,6 +429,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
            adev->asic_type < CHIP_RAVEN)
                init_data.flags.gpu_vm_support = true;
 
+       if (amdgpu_dc_feature_mask & DC_FBC_MASK)
+               init_data.flags.fbc_support = true;
+
        /* Display Core create. */
        adev->dm.dc = dc_create(&init_data);
 
@@ -1524,13 +1527,6 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
 {
        struct amdgpu_display_manager *dm = bl_get_data(bd);
 
-       /*
-        * PWM interperts 0 as 100% rather than 0% because of HW
-        * limitation for level 0.So limiting minimum brightness level
-        * to 1.
-        */
-       if (bd->props.brightness < 1)
-               return 1;
        if (dc_link_set_backlight_level(dm->backlight_link,
                        bd->props.brightness, 0, 0))
                return 0;
@@ -2707,18 +2703,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
        drm_connector = &aconnector->base;
 
        if (!aconnector->dc_sink) {
-               /*
-                * Create dc_sink when necessary to MST
-                * Don't apply fake_sink to MST
-                */
-               if (aconnector->mst_port) {
-                       dm_dp_mst_dc_sink_create(drm_connector);
-                       return stream;
+               if (!aconnector->mst_port) {
+                       sink = create_fake_sink(aconnector);
+                       if (!sink)
+                               return stream;
                }
-
-               sink = create_fake_sink(aconnector);
-               if (!sink)
-                       return stream;
        } else {
                sink = aconnector->dc_sink;
        }
@@ -3308,7 +3297,7 @@ void dm_drm_plane_destroy_state(struct drm_plane *plane,
 static const struct drm_plane_funcs dm_plane_funcs = {
        .update_plane   = drm_atomic_helper_update_plane,
        .disable_plane  = drm_atomic_helper_disable_plane,
-       .destroy        = drm_plane_cleanup,
+       .destroy        = drm_primary_helper_destroy,
        .reset = dm_drm_plane_reset,
        .atomic_duplicate_state = dm_drm_plane_duplicate_state,
        .atomic_destroy_state = dm_drm_plane_destroy_state,
index 978b34a5011ce508055064658b556ef5082097e7..924a38a1fc446019a0aac035b018b952e3be9923 100644 (file)
@@ -160,8 +160,6 @@ struct amdgpu_dm_connector {
        struct mutex hpd_lock;
 
        bool fake_enable;
-
-       bool mst_connected;
 };
 
 #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
index 03601d717fed90708463fca143a6de50d6b750b1..d02c32a1039c02b97f02d721030ae82e546799df 100644 (file)
@@ -205,40 +205,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
        .atomic_get_property = amdgpu_dm_connector_atomic_get_property
 };
 
-void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
-{
-       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-       struct dc_sink *dc_sink;
-       struct dc_sink_init_data init_params = {
-                       .link = aconnector->dc_link,
-                       .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
-
-       /* FIXME none of this is safe. we shouldn't touch aconnector here in
-        * atomic_check
-        */
-
-       /*
-        * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
-        */
-       if (!aconnector->port || !aconnector->port->aux.ddc.algo)
-               return;
-
-       ASSERT(aconnector->edid);
-
-       dc_sink = dc_link_add_remote_sink(
-               aconnector->dc_link,
-               (uint8_t *)aconnector->edid,
-               (aconnector->edid->extensions + 1) * EDID_LENGTH,
-               &init_params);
-
-       dc_sink->priv = aconnector;
-       aconnector->dc_sink = dc_sink;
-
-       if (aconnector->dc_sink)
-               amdgpu_dm_update_freesync_caps(
-                               connector, aconnector->edid);
-}
-
 static int dm_dp_mst_get_modes(struct drm_connector *connector)
 {
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
@@ -319,12 +285,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)
        struct amdgpu_device *adev = dev->dev_private;
        struct amdgpu_encoder *amdgpu_encoder;
        struct drm_encoder *encoder;
-       const struct drm_connector_helper_funcs *connector_funcs =
-               connector->base.helper_private;
-       struct drm_encoder *enc_master =
-               connector_funcs->best_encoder(&connector->base);
 
-       DRM_DEBUG_KMS("enc master is %p\n", enc_master);
        amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL);
        if (!amdgpu_encoder)
                return NULL;
@@ -354,25 +315,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        struct amdgpu_device *adev = dev->dev_private;
        struct amdgpu_dm_connector *aconnector;
        struct drm_connector *connector;
-       struct drm_connector_list_iter conn_iter;
-
-       drm_connector_list_iter_begin(dev, &conn_iter);
-       drm_for_each_connector_iter(connector, &conn_iter) {
-               aconnector = to_amdgpu_dm_connector(connector);
-               if (aconnector->mst_port == master
-                               && !aconnector->port) {
-                       DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n",
-                                               aconnector, connector->base.id, aconnector->mst_port);
-
-                       aconnector->port = port;
-                       drm_connector_set_path_property(connector, pathprop);
-
-                       drm_connector_list_iter_end(&conn_iter);
-                       aconnector->mst_connected = true;
-                       return &aconnector->base;
-               }
-       }
-       drm_connector_list_iter_end(&conn_iter);
 
        aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
        if (!aconnector)
@@ -421,8 +363,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
         */
        amdgpu_dm_connector_funcs_reset(connector);
 
-       aconnector->mst_connected = true;
-
        DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
                        aconnector, connector->base.id, aconnector->mst_port);
 
@@ -434,6 +374,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                                        struct drm_connector *connector)
 {
+       struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
+       struct drm_device *dev = master->base.dev;
+       struct amdgpu_device *adev = dev->dev_private;
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 
        DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
@@ -447,7 +390,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                aconnector->dc_sink = NULL;
        }
 
-       aconnector->mst_connected = false;
+       drm_connector_unregister(connector);
+       if (adev->mode_info.rfbdev)
+               drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector);
+       drm_connector_put(connector);
 }
 
 static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
@@ -458,18 +404,10 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
        drm_kms_helper_hotplug_event(dev);
 }
 
-static void dm_dp_mst_link_status_reset(struct drm_connector *connector)
-{
-       mutex_lock(&connector->dev->mode_config.mutex);
-       drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD);
-       mutex_unlock(&connector->dev->mode_config.mutex);
-}
-
 static void dm_dp_mst_register_connector(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct amdgpu_device *adev = dev->dev_private;
-       struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 
        if (adev->mode_info.rfbdev)
                drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector);
@@ -477,9 +415,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)
                DRM_ERROR("adev->mode_info.rfbdev is NULL\n");
 
        drm_connector_register(connector);
-
-       if (aconnector->mst_connected)
-               dm_dp_mst_link_status_reset(connector);
 }
 
 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
index 8cf51da26657e29e72062b34aeed7e5d827f9e21..2da851b40042aee9b79eb2c666d45c0f5061fee0 100644 (file)
@@ -31,6 +31,5 @@ struct amdgpu_dm_connector;
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
                                       struct amdgpu_dm_connector *aconnector);
-void dm_dp_mst_dc_sink_create(struct drm_connector *connector);
 
 #endif
index fb04a4ad141fdb68f68a747f6c4474a15e7da8a2..5da2186b3615ff97b3bc54a68b3849ad6c85856f 100644 (file)
@@ -1722,7 +1722,7 @@ static void write_i2c_retimer_setting(
                i2c_success = i2c_write(pipe_ctx, slave_address,
                                buffer, sizeof(buffer));
                RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
-                       offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n",
+                       offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
                        slave_address, buffer[0], buffer[1], i2c_success?1:0);
                if (!i2c_success)
                        /* Write failure */
@@ -1734,7 +1734,7 @@ static void write_i2c_retimer_setting(
                i2c_success = i2c_write(pipe_ctx, slave_address,
                                buffer, sizeof(buffer));
                RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\
-                       offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n",
+                       offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",
                        slave_address, buffer[0], buffer[1], i2c_success?1:0);
                if (!i2c_success)
                        /* Write failure */
index 199527171100b0ed7cbd34aae7468e0989efc9a6..b57fa61b3034a14869a2cee91423b7f7e0fa11e0 100644 (file)
@@ -169,6 +169,7 @@ struct link_training_settings;
 struct dc_config {
        bool gpu_vm_support;
        bool disable_disp_pll_sharing;
+       bool fbc_support;
 };
 
 enum visual_confirm {
index b75ede5f84f76837960463387a90ca35aa7ac62a..b459867a05b202e84a1a59c5ea656fc4b4395b2a 100644 (file)
@@ -1736,7 +1736,12 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,
        if (events->force_trigger)
                value |= 0x1;
 
-       value |= 0x84;
+       if (num_pipes) {
+               struct dc *dc = pipe_ctx[0]->stream->ctx->dc;
+
+               if (dc->fbc_compressor)
+                       value |= 0x84;
+       }
 
        for (i = 0; i < num_pipes; i++)
                pipe_ctx[i]->stream_res.tg->funcs->
index e3624ca24574827a684a3c96dc257b2a4c19f215..7c9fd9052ee233f2c91d5a2c5cd4c91765603335 100644 (file)
@@ -1362,7 +1362,8 @@ static bool construct(
                pool->base.sw_i2cs[i] = NULL;
        }
 
-       dc->fbc_compressor = dce110_compressor_create(ctx);
+       if (dc->config.fbc_support)
+               dc->fbc_compressor = dce110_compressor_create(ctx);
 
        if (!underlay_create(ctx, &pool->base))
                goto res_create_fail;
index 2083c308007cde72412f7ad7291dc85fe882e532..470d7b89071a40163dc039af84a4bc345852cfcf 100644 (file)
@@ -133,6 +133,10 @@ enum PP_FEATURE_MASK {
        PP_AVFS_MASK = 0x40000,
 };
 
+enum DC_FEATURE_MASK {
+       DC_FBC_MASK = 0x1,
+};
+
 /**
  * struct amd_ip_funcs - general hooks for managing amdgpu IP Blocks
  */
index d2e7c0fa96c2f7263f367cf67597993aa9ebcbf5..8eb0bb241210bdffe3ff4f3e280bed4856a1c810 100644 (file)
@@ -1325,7 +1325,7 @@ struct atom_smu_info_v3_3 {
   struct   atom_common_table_header  table_header;
   uint8_t  smuip_min_ver;
   uint8_t  smuip_max_ver;
-  uint8_t  smu_rsd1;
+  uint8_t  waflclk_ss_mode;
   uint8_t  gpuclk_ss_mode;
   uint16_t sclk_ss_percentage;
   uint16_t sclk_ss_rate_10hz;
@@ -1355,7 +1355,10 @@ struct atom_smu_info_v3_3 {
   uint32_t syspll3_1_vco_freq_10khz;
   uint32_t bootup_fclk_10khz;
   uint32_t bootup_waflclk_10khz;
-  uint32_t reserved[3];
+  uint32_t smu_info_caps;
+  uint16_t waflclk_ss_percentage;    // in unit of 0.001%
+  uint16_t smuinitoffset;
+  uint32_t reserved;
 };
 
 /*
index 99a33c33a32c9e47fb8bbaf455d8f44efe69c18f..101c09b212ade5690299c823f27aea1ae65cae4a 100644 (file)
@@ -713,20 +713,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
        for (i = 0; i < wm_with_clock_ranges->num_wm_dmif_sets; i++) {
                table->WatermarkRow[1][i].MinClock =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
+                       1000));
                table->WatermarkRow[1][i].MaxClock =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
+                       1000));
                table->WatermarkRow[1][i].MinUclk =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
+                       1000));
                table->WatermarkRow[1][i].MaxUclk =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
+                       1000));
                table->WatermarkRow[1][i].WmSetting = (uint8_t)
                                wm_with_clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
        }
@@ -734,20 +734,20 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table,
        for (i = 0; i < wm_with_clock_ranges->num_wm_mcif_sets; i++) {
                table->WatermarkRow[0][i].MinClock =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
+                       1000));
                table->WatermarkRow[0][i].MaxClock =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
+                       1000));
                table->WatermarkRow[0][i].MinUclk =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
+                       1000));
                table->WatermarkRow[0][i].MaxUclk =
                        cpu_to_le16((uint16_t)
-                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz) /
-                       1000);
+                       (wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
+                       1000));
                table->WatermarkRow[0][i].WmSetting = (uint8_t)
                                wm_with_clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
        }
index 57143d51e3eed6b1dce0011748345cfece4c7165..99861f32b1f95aedfb5c64d39814baca329662c2 100644 (file)
@@ -120,6 +120,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
        data->registry_data.disable_auto_wattman = 1;
        data->registry_data.auto_wattman_debug = 0;
        data->registry_data.auto_wattman_sample_period = 100;
+       data->registry_data.fclk_gfxclk_ratio = 0x3F6CCCCD;
        data->registry_data.auto_wattman_threshold = 50;
        data->registry_data.gfxoff_controlled_by_driver = 1;
        data->gfxoff_allowed = false;
@@ -829,6 +830,28 @@ static int vega20_enable_all_smu_features(struct pp_hwmgr *hwmgr)
        return 0;
 }
 
+static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr)
+{
+       struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
+
+       if (data->smu_features[GNLD_DPM_UCLK].enabled)
+               return smum_send_msg_to_smc_with_parameter(hwmgr,
+                       PPSMC_MSG_SetUclkFastSwitch,
+                       1);
+
+       return 0;
+}
+
+static int vega20_send_clock_ratio(struct pp_hwmgr *hwmgr)
+{
+       struct vega20_hwmgr *data =
+                       (struct vega20_hwmgr *)(hwmgr->backend);
+
+       return smum_send_msg_to_smc_with_parameter(hwmgr,
+                       PPSMC_MSG_SetFclkGfxClkRatio,
+                       data->registry_data.fclk_gfxclk_ratio);
+}
+
 static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
 {
        struct vega20_hwmgr *data =
@@ -1532,6 +1555,16 @@ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
                        "[EnableDPMTasks] Failed to enable all smu features!",
                        return result);
 
+       result = vega20_notify_smc_display_change(hwmgr);
+       PP_ASSERT_WITH_CODE(!result,
+                       "[EnableDPMTasks] Failed to notify smc display change!",
+                       return result);
+
+       result = vega20_send_clock_ratio(hwmgr);
+       PP_ASSERT_WITH_CODE(!result,
+                       "[EnableDPMTasks] Failed to send clock ratio!",
+                       return result);
+
        /* Initialize UVD/VCE powergating state */
        vega20_init_powergate_state(hwmgr);
 
@@ -1972,19 +2005,6 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx,
        return ret;
 }
 
-static int vega20_notify_smc_display_change(struct pp_hwmgr *hwmgr,
-               bool has_disp)
-{
-       struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
-
-       if (data->smu_features[GNLD_DPM_UCLK].enabled)
-               return smum_send_msg_to_smc_with_parameter(hwmgr,
-                       PPSMC_MSG_SetUclkFastSwitch,
-                       has_disp ? 1 : 0);
-
-       return 0;
-}
-
 int vega20_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
                struct pp_display_clock_request *clock_req)
 {
@@ -2044,13 +2064,6 @@ static int vega20_notify_smc_display_config_after_ps_adjustment(
        struct pp_display_clock_request clock_req;
        int ret = 0;
 
-       if ((hwmgr->display_config->num_display > 1) &&
-            !hwmgr->display_config->multi_monitor_in_sync &&
-            !hwmgr->display_config->nb_pstate_switch_disable)
-               vega20_notify_smc_display_change(hwmgr, false);
-       else
-               vega20_notify_smc_display_change(hwmgr, true);
-
        min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
        min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk;
        min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
index 56fe6a0d42e804f956846faad473071335b3b887..25faaa5c5b10cbc5fcd720d7b15546a826641682 100644 (file)
@@ -328,6 +328,7 @@ struct vega20_registry_data {
        uint8_t   disable_auto_wattman;
        uint32_t  auto_wattman_debug;
        uint32_t  auto_wattman_sample_period;
+       uint32_t  fclk_gfxclk_ratio;
        uint8_t   auto_wattman_threshold;
        uint8_t   log_avfs_param;
        uint8_t   enable_enginess;
index 45d64a81e94539fe403087cd2827b2992e59edca..4f63a736ea0e7371b6f09b26ea8cc55ec6b9bdd0 100644 (file)
 #define PPSMC_MSG_SetSystemVirtualDramAddrHigh   0x4B
 #define PPSMC_MSG_SetSystemVirtualDramAddrLow    0x4C
 #define PPSMC_MSG_WaflTest                       0x4D
-// Unused ID 0x4E to 0x50
+#define PPSMC_MSG_SetFclkGfxClkRatio             0x4E
+// Unused ID 0x4F to 0x50
 #define PPSMC_MSG_AllowGfxOff                    0x51
 #define PPSMC_MSG_DisallowGfxOff                 0x52
 #define PPSMC_MSG_GetPptLimit                    0x53
index 5ff1d79b86c4a532917e819cfed3c4c702a3ea07..0e0df398222d1e0220b4388d0513bf73f66164ae 100644 (file)
@@ -1275,6 +1275,9 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_
        mutex_lock(&mgr->lock);
        mstb = mgr->mst_primary;
 
+       if (!mstb)
+               goto out;
+
        for (i = 0; i < lct - 1; i++) {
                int shift = (i % 2) ? 0 : 4;
                int port_num = (rad[i / 2] >> shift) & 0xf;
index 90a1c846fc25aada95b51178060a17d20aa5ed47..8aaa5e86a979ce0985c822201643768200e4a2e3 100644 (file)
@@ -97,9 +97,9 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format);
 
 /**
  * drm_driver_legacy_fb_format - compute drm fourcc code from legacy description
+ * @dev: DRM device
  * @bpp: bits per pixels
  * @depth: bit depth per pixel
- * @native: use host native byte order
  *
  * Computes a drm fourcc pixel format code for the given @bpp/@depth values.
  * Unlike drm_mode_legacy_fb_format() this looks at the drivers mode_config,
index e7c3ed6c9a2e10ddcd7665e851a1bffb9ff0247f..9b476368aa313efd7c33945aeadd2b4c481c70d2 100644 (file)
@@ -93,7 +93,7 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
         * If the GPU managed to complete this jobs fence, the timout is
         * spurious. Bail out.
         */
-       if (fence_completed(gpu, submit->out_fence->seqno))
+       if (dma_fence_is_signaled(submit->out_fence))
                return;
 
        /*
index 94529aa8233922b71cc36011fff305280651be53..aef487dd873153d77fd602726ab6bd92256ab593 100644 (file)
@@ -164,13 +164,6 @@ static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
        return frm;
 }
 
-static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
-{
-       struct decon_context *ctx = crtc->ctx;
-
-       return decon_get_frame_count(ctx, false);
-}
-
 static void decon_setup_trigger(struct decon_context *ctx)
 {
        if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG))
@@ -536,7 +529,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
        .disable                = decon_disable,
        .enable_vblank          = decon_enable_vblank,
        .disable_vblank         = decon_disable_vblank,
-       .get_vblank_counter     = decon_get_vblank_counter,
        .atomic_begin           = decon_atomic_begin,
        .update_plane           = decon_update_plane,
        .disable_plane          = decon_disable_plane,
@@ -554,7 +546,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
        int ret;
 
        ctx->drm_dev = drm_dev;
-       drm_dev->max_vblank_count = 0xffffffff;
 
        for (win = ctx->first_win; win < WINDOWS_NR; win++) {
                ctx->configs[win].pixel_formats = decon_formats;
index eea90251808fa2e58398fdcb1cac01d160307320..2696289ecc78f204fb504f24c4f897694acb41df 100644 (file)
@@ -162,16 +162,6 @@ static void exynos_drm_crtc_disable_vblank(struct drm_crtc *crtc)
                exynos_crtc->ops->disable_vblank(exynos_crtc);
 }
 
-static u32 exynos_drm_crtc_get_vblank_counter(struct drm_crtc *crtc)
-{
-       struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
-
-       if (exynos_crtc->ops->get_vblank_counter)
-               return exynos_crtc->ops->get_vblank_counter(exynos_crtc);
-
-       return 0;
-}
-
 static const struct drm_crtc_funcs exynos_crtc_funcs = {
        .set_config     = drm_atomic_helper_set_config,
        .page_flip      = drm_atomic_helper_page_flip,
@@ -181,7 +171,6 @@ static const struct drm_crtc_funcs exynos_crtc_funcs = {
        .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
        .enable_vblank = exynos_drm_crtc_enable_vblank,
        .disable_vblank = exynos_drm_crtc_disable_vblank,
-       .get_vblank_counter = exynos_drm_crtc_get_vblank_counter,
 };
 
 struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
index ec9604f1272b50d12b44a9f759693dc4a8eaebf6..5e61e707f95555da181969aa71254fc71ffa4098 100644 (file)
@@ -135,7 +135,6 @@ struct exynos_drm_crtc_ops {
        void (*disable)(struct exynos_drm_crtc *crtc);
        int (*enable_vblank)(struct exynos_drm_crtc *crtc);
        void (*disable_vblank)(struct exynos_drm_crtc *crtc);
-       u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
        enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc,
                const struct drm_display_mode *mode);
        bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
index 07af7758066db47c866a86a2be8fdfe5386421a5..d81e62ae286aea79d39757ecb2233608b905d75f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_atomic_helper.h>
@@ -1474,12 +1475,12 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
 {
        struct exynos_dsi *dsi = encoder_to_dsi(encoder);
        struct drm_connector *connector = &dsi->connector;
+       struct drm_device *drm = encoder->dev;
        int ret;
 
        connector->polled = DRM_CONNECTOR_POLL_HPD;
 
-       ret = drm_connector_init(encoder->dev, connector,
-                                &exynos_dsi_connector_funcs,
+       ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs,
                                 DRM_MODE_CONNECTOR_DSI);
        if (ret) {
                DRM_ERROR("Failed to initialize connector with drm\n");
@@ -1489,7 +1490,12 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder)
        connector->status = connector_status_disconnected;
        drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
        drm_connector_attach_encoder(connector, encoder);
+       if (!drm->registered)
+               return 0;
 
+       connector->funcs->reset(connector);
+       drm_fb_helper_add_one_connector(drm->fb_helper, connector);
+       drm_connector_register(connector);
        return 0;
 }
 
@@ -1527,7 +1533,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
                }
 
                dsi->panel = of_drm_find_panel(device->dev.of_node);
-               if (dsi->panel) {
+               if (IS_ERR(dsi->panel)) {
+                       dsi->panel = NULL;
+               } else {
                        drm_panel_attach(dsi->panel, &dsi->connector);
                        dsi->connector.status = connector_status_connected;
                }
index 918dd2c822098444c6708761baded3ef95420025..01d182289efa38fd75a83cd399b02bbfd1e590c0 100644 (file)
@@ -192,7 +192,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
        struct drm_fb_helper *helper;
        int ret;
 
-       if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
+       if (!dev->mode_config.num_crtc)
                return 0;
 
        fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
index 2402395a068da2fc5e83ba988aa76afccfe09f03..58e166effa456426d7fe2ee4f059a0533b4bfe0c 100644 (file)
@@ -1905,7 +1905,6 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu)
                vgpu_free_mm(mm);
                return ERR_PTR(-ENOMEM);
        }
-       mm->ggtt_mm.last_partial_off = -1UL;
 
        return mm;
 }
@@ -1930,7 +1929,6 @@ void _intel_vgpu_mm_release(struct kref *mm_ref)
                invalidate_ppgtt_mm(mm);
        } else {
                vfree(mm->ggtt_mm.virtual_ggtt);
-               mm->ggtt_mm.last_partial_off = -1UL;
        }
 
        vgpu_free_mm(mm);
@@ -2168,6 +2166,8 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
        struct intel_gvt_gtt_entry e, m;
        dma_addr_t dma_addr;
        int ret;
+       struct intel_gvt_partial_pte *partial_pte, *pos, *n;
+       bool partial_update = false;
 
        if (bytes != 4 && bytes != 8)
                return -EINVAL;
@@ -2178,68 +2178,57 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
        if (!vgpu_gmadr_is_valid(vgpu, gma))
                return 0;
 
-       ggtt_get_guest_entry(ggtt_mm, &e, g_gtt_index);
-
+       e.type = GTT_TYPE_GGTT_PTE;
        memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
                        bytes);
 
        /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes
-        * write, we assume the two 4 bytes writes are consecutive.
-        * Otherwise, we abort and report error
+        * write, save the first 4 bytes in a list and update virtual
+        * PTE. Only update shadow PTE when the second 4 bytes comes.
         */
        if (bytes < info->gtt_entry_size) {
-               if (ggtt_mm->ggtt_mm.last_partial_off == -1UL) {
-                       /* the first partial part*/
-                       ggtt_mm->ggtt_mm.last_partial_off = off;
-                       ggtt_mm->ggtt_mm.last_partial_data = e.val64;
-                       return 0;
-               } else if ((g_gtt_index ==
-                               (ggtt_mm->ggtt_mm.last_partial_off >>
-                               info->gtt_entry_size_shift)) &&
-                       (off != ggtt_mm->ggtt_mm.last_partial_off)) {
-                       /* the second partial part */
-
-                       int last_off = ggtt_mm->ggtt_mm.last_partial_off &
-                               (info->gtt_entry_size - 1);
-
-                       memcpy((void *)&e.val64 + last_off,
-                               (void *)&ggtt_mm->ggtt_mm.last_partial_data +
-                               last_off, bytes);
-
-                       ggtt_mm->ggtt_mm.last_partial_off = -1UL;
-               } else {
-                       int last_offset;
-
-                       gvt_vgpu_err("failed to populate guest ggtt entry: abnormal ggtt entry write sequence, last_partial_off=%lx, offset=%x, bytes=%d, ggtt entry size=%d\n",
-                                       ggtt_mm->ggtt_mm.last_partial_off, off,
-                                       bytes, info->gtt_entry_size);
-
-                       /* set host ggtt entry to scratch page and clear
-                        * virtual ggtt entry as not present for last
-                        * partially write offset
-                        */
-                       last_offset = ggtt_mm->ggtt_mm.last_partial_off &
-                                       (~(info->gtt_entry_size - 1));
-
-                       ggtt_get_host_entry(ggtt_mm, &m, last_offset);
-                       ggtt_invalidate_pte(vgpu, &m);
-                       ops->set_pfn(&m, gvt->gtt.scratch_mfn);
-                       ops->clear_present(&m);
-                       ggtt_set_host_entry(ggtt_mm, &m, last_offset);
-                       ggtt_invalidate(gvt->dev_priv);
-
-                       ggtt_get_guest_entry(ggtt_mm, &e, last_offset);
-                       ops->clear_present(&e);
-                       ggtt_set_guest_entry(ggtt_mm, &e, last_offset);
-
-                       ggtt_mm->ggtt_mm.last_partial_off = off;
-                       ggtt_mm->ggtt_mm.last_partial_data = e.val64;
+               bool found = false;
+
+               list_for_each_entry_safe(pos, n,
+                               &ggtt_mm->ggtt_mm.partial_pte_list, list) {
+                       if (g_gtt_index == pos->offset >>
+                                       info->gtt_entry_size_shift) {
+                               if (off != pos->offset) {
+                                       /* the second partial part*/
+                                       int last_off = pos->offset &
+                                               (info->gtt_entry_size - 1);
+
+                                       memcpy((void *)&e.val64 + last_off,
+                                               (void *)&pos->data + last_off,
+                                               bytes);
+
+                                       list_del(&pos->list);
+                                       kfree(pos);
+                                       found = true;
+                                       break;
+                               }
+
+                               /* update of the first partial part */
+                               pos->data = e.val64;
+                               ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
+                               return 0;
+                       }
+               }
 
-                       return 0;
+               if (!found) {
+                       /* the first partial part */
+                       partial_pte = kzalloc(sizeof(*partial_pte), GFP_KERNEL);
+                       if (!partial_pte)
+                               return -ENOMEM;
+                       partial_pte->offset = off;
+                       partial_pte->data = e.val64;
+                       list_add_tail(&partial_pte->list,
+                               &ggtt_mm->ggtt_mm.partial_pte_list);
+                       partial_update = true;
                }
        }
 
-       if (ops->test_present(&e)) {
+       if (!partial_update && (ops->test_present(&e))) {
                gfn = ops->get_pfn(&e);
                m = e;
 
@@ -2263,16 +2252,18 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
                } else
                        ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
        } else {
-               ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
-               ggtt_invalidate_pte(vgpu, &m);
                ops->set_pfn(&m, gvt->gtt.scratch_mfn);
                ops->clear_present(&m);
        }
 
 out:
+       ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
+
+       ggtt_get_host_entry(ggtt_mm, &e, g_gtt_index);
+       ggtt_invalidate_pte(vgpu, &e);
+
        ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
        ggtt_invalidate(gvt->dev_priv);
-       ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
        return 0;
 }
 
@@ -2430,6 +2421,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
 
        intel_vgpu_reset_ggtt(vgpu, false);
 
+       INIT_LIST_HEAD(&gtt->ggtt_mm->ggtt_mm.partial_pte_list);
+
        return create_scratch_page_tree(vgpu);
 }
 
@@ -2454,6 +2447,14 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
 
 static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu)
 {
+       struct intel_gvt_partial_pte *pos;
+
+       list_for_each_entry(pos,
+                       &vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list, list) {
+               gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n",
+                       pos->offset, pos->data);
+               kfree(pos);
+       }
        intel_vgpu_destroy_mm(vgpu->gtt.ggtt_mm);
        vgpu->gtt.ggtt_mm = NULL;
 }
index 7a9b36176efb7fca7198527512f8873ad21248cb..d8cb04cc946dff3e19466ff387089db96c226d53 100644 (file)
@@ -35,7 +35,6 @@
 #define _GVT_GTT_H_
 
 #define I915_GTT_PAGE_SHIFT         12
-#define I915_GTT_PAGE_MASK             (~(I915_GTT_PAGE_SIZE - 1))
 
 struct intel_vgpu_mm;
 
@@ -133,6 +132,12 @@ enum intel_gvt_mm_type {
 
 #define GVT_RING_CTX_NR_PDPS   GEN8_3LVL_PDPES
 
+struct intel_gvt_partial_pte {
+       unsigned long offset;
+       u64 data;
+       struct list_head list;
+};
+
 struct intel_vgpu_mm {
        enum intel_gvt_mm_type type;
        struct intel_vgpu *vgpu;
@@ -157,8 +162,7 @@ struct intel_vgpu_mm {
                } ppgtt_mm;
                struct {
                        void *virtual_ggtt;
-                       unsigned long last_partial_off;
-                       u64 last_partial_data;
+                       struct list_head partial_pte_list;
                } ggtt_mm;
        };
 };
index 90f50f67909a090d72b4cee84077d0b530a4969b..aa280bb071254547fd3d810494bd488d4edbcd44 100644 (file)
@@ -1609,7 +1609,7 @@ static int bxt_gt_disp_pwron_write(struct intel_vgpu *vgpu,
        return 0;
 }
 
-static int bxt_edp_psr_imr_iir_write(struct intel_vgpu *vgpu,
+static int edp_psr_imr_iir_write(struct intel_vgpu *vgpu,
                unsigned int offset, void *p_data, unsigned int bytes)
 {
        vgpu_vreg(vgpu, offset) = 0;
@@ -2607,6 +2607,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_DFH(_MMIO(0x1a178), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
        MMIO_DFH(_MMIO(0x1a17c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
        MMIO_DFH(_MMIO(0x2217c), D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
+
+       MMIO_DH(EDP_PSR_IMR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write);
+       MMIO_DH(EDP_PSR_IIR, D_BDW_PLUS, NULL, edp_psr_imr_iir_write);
        return 0;
 }
 
@@ -3205,9 +3208,6 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt)
        MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B), D_BXT);
        MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C), D_BXT);
 
-       MMIO_DH(EDP_PSR_IMR, D_BXT, NULL, bxt_edp_psr_imr_iir_write);
-       MMIO_DH(EDP_PSR_IIR, D_BXT, NULL, bxt_edp_psr_imr_iir_write);
-
        MMIO_D(RC6_CTX_BASE, D_BXT);
 
        MMIO_D(GEN8_PUSHBUS_CONTROL, D_BXT);
index 10e63eea5492916f676011c98ab1751e9d02dac1..36a5147cd01e5224b2c6563c29128d05688e7fba 100644 (file)
@@ -131,7 +131,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
        {RCS, GAMT_CHKN_BIT_REG, 0x0, false}, /* 0x4ab8 */
 
        {RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */
-       {RCS, GEN9_CSFE_CHICKEN1_RCS, 0x0, false}, /* 0x20d4 */
+       {RCS, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */
 
        {RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */
        {RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */
index 44e2c0f5ec502bc1a6c27007c77d56df89019ce3..ffdbbac4400eaf7d86390a3ff105a18ef36645ea 100644 (file)
@@ -1175,8 +1175,6 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
                return -EINVAL;
        }
 
-       dram_info->valid_dimm = true;
-
        /*
         * If any of the channel is single rank channel, worst case output
         * will be same as if single rank memory, so consider single rank
@@ -1193,8 +1191,7 @@ skl_dram_get_channels_info(struct drm_i915_private *dev_priv)
                return -EINVAL;
        }
 
-       if (ch0.is_16gb_dimm || ch1.is_16gb_dimm)
-               dram_info->is_16gb_dimm = true;
+       dram_info->is_16gb_dimm = ch0.is_16gb_dimm || ch1.is_16gb_dimm;
 
        dev_priv->dram_info.symmetric_memory = intel_is_dram_symmetric(val_ch0,
                                                                       val_ch1,
@@ -1314,7 +1311,6 @@ bxt_get_dram_info(struct drm_i915_private *dev_priv)
                return -EINVAL;
        }
 
-       dram_info->valid_dimm = true;
        dram_info->valid = true;
        return 0;
 }
@@ -1327,12 +1323,17 @@ intel_get_dram_info(struct drm_i915_private *dev_priv)
        int ret;
 
        dram_info->valid = false;
-       dram_info->valid_dimm = false;
-       dram_info->is_16gb_dimm = false;
        dram_info->rank = I915_DRAM_RANK_INVALID;
        dram_info->bandwidth_kbps = 0;
        dram_info->num_channels = 0;
 
+       /*
+        * Assume 16Gb DIMMs are present until proven otherwise.
+        * This is only used for the level 0 watermark latency
+        * w/a which does not apply to bxt/glk.
+        */
+       dram_info->is_16gb_dimm = !IS_GEN9_LP(dev_priv);
+
        if (INTEL_GEN(dev_priv) < 9 || IS_GEMINILAKE(dev_priv))
                return;
 
index 8624b4bdc242dd7cbd77d527eb3b84fe59a0777f..9102571e9692d1540ad987ed31c4ec735dd80cf5 100644 (file)
@@ -1948,7 +1948,6 @@ struct drm_i915_private {
 
        struct dram_info {
                bool valid;
-               bool valid_dimm;
                bool is_16gb_dimm;
                u8 num_channels;
                enum dram_rank {
index 09187286d34627df882e4ede753db7e40da41934..1aaccbe7e1debd0c11440ac9acae9c15b07880d5 100644 (file)
@@ -460,7 +460,7 @@ eb_validate_vma(struct i915_execbuffer *eb,
         * any non-page-aligned or non-canonical addresses.
         */
        if (unlikely(entry->flags & EXEC_OBJECT_PINNED &&
-                    entry->offset != gen8_canonical_addr(entry->offset & PAGE_MASK)))
+                    entry->offset != gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK)))
                return -EINVAL;
 
        /* pad_to_size was once a reserved field, so sanitize it */
index 56c7f86373112b96212fc7952a5968854f9bdbb1..47c302543799007bee421d85039be8b016aed6e7 100644 (file)
@@ -1757,7 +1757,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *base, struct seq_file *m)
                        if (i == 4)
                                continue;
 
-                       seq_printf(m, "\t\t(%03d, %04d) %08lx: ",
+                       seq_printf(m, "\t\t(%03d, %04d) %08llx: ",
                                   pde, pte,
                                   (pde * GEN6_PTES + pte) * I915_GTT_PAGE_SIZE);
                        for (i = 0; i < 4; i++) {
index 7e2af5f4f39bcbb5ec355257d41decea7b45d019..28039290655cb7d5cf11f2c94260ba88c669e169 100644 (file)
 #include "i915_selftest.h"
 #include "i915_timeline.h"
 
-#define I915_GTT_PAGE_SIZE_4K BIT(12)
-#define I915_GTT_PAGE_SIZE_64K BIT(16)
-#define I915_GTT_PAGE_SIZE_2M BIT(21)
+#define I915_GTT_PAGE_SIZE_4K  BIT_ULL(12)
+#define I915_GTT_PAGE_SIZE_64K BIT_ULL(16)
+#define I915_GTT_PAGE_SIZE_2M  BIT_ULL(21)
 
 #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K
 #define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M
 
+#define I915_GTT_PAGE_MASK -I915_GTT_PAGE_SIZE
+
 #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE
 
 #define I915_FENCE_REG_NONE -1
@@ -659,20 +661,20 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
                        u64 start, u64 end, unsigned int flags);
 
 /* Flags used by pin/bind&friends. */
-#define PIN_NONBLOCK           BIT(0)
-#define PIN_MAPPABLE           BIT(1)
-#define PIN_ZONE_4G            BIT(2)
-#define PIN_NONFAULT           BIT(3)
-#define PIN_NOEVICT            BIT(4)
-
-#define PIN_MBZ                        BIT(5) /* I915_VMA_PIN_OVERFLOW */
-#define PIN_GLOBAL             BIT(6) /* I915_VMA_GLOBAL_BIND */
-#define PIN_USER               BIT(7) /* I915_VMA_LOCAL_BIND */
-#define PIN_UPDATE             BIT(8)
-
-#define PIN_HIGH               BIT(9)
-#define PIN_OFFSET_BIAS                BIT(10)
-#define PIN_OFFSET_FIXED       BIT(11)
+#define PIN_NONBLOCK           BIT_ULL(0)
+#define PIN_MAPPABLE           BIT_ULL(1)
+#define PIN_ZONE_4G            BIT_ULL(2)
+#define PIN_NONFAULT           BIT_ULL(3)
+#define PIN_NOEVICT            BIT_ULL(4)
+
+#define PIN_MBZ                        BIT_ULL(5) /* I915_VMA_PIN_OVERFLOW */
+#define PIN_GLOBAL             BIT_ULL(6) /* I915_VMA_GLOBAL_BIND */
+#define PIN_USER               BIT_ULL(7) /* I915_VMA_LOCAL_BIND */
+#define PIN_UPDATE             BIT_ULL(8)
+
+#define PIN_HIGH               BIT_ULL(9)
+#define PIN_OFFSET_BIAS                BIT_ULL(10)
+#define PIN_OFFSET_FIXED       BIT_ULL(11)
 #define PIN_OFFSET_MASK                (-I915_GTT_PAGE_SIZE)
 
 #endif
index 7c491ea3d052aaccfc5eab69e2ea8f6b31f6813e..e31c27e45734ef19ae3764b5894da3320f4b2991 100644 (file)
@@ -2095,8 +2095,12 @@ enum i915_power_well_id {
 
 /* ICL PHY DFLEX registers */
 #define PORT_TX_DFLEXDPMLE1            _MMIO(0x1638C0)
-#define   DFLEXDPMLE1_DPMLETC_MASK(n)  (0xf << (4 * (n)))
-#define   DFLEXDPMLE1_DPMLETC(n, x)    ((x) << (4 * (n)))
+#define   DFLEXDPMLE1_DPMLETC_MASK(tc_port)    (0xf << (4 * (tc_port)))
+#define   DFLEXDPMLE1_DPMLETC_ML0(tc_port)     (1 << (4 * (tc_port)))
+#define   DFLEXDPMLE1_DPMLETC_ML1_0(tc_port)   (3 << (4 * (tc_port)))
+#define   DFLEXDPMLE1_DPMLETC_ML3(tc_port)     (8 << (4 * (tc_port)))
+#define   DFLEXDPMLE1_DPMLETC_ML3_2(tc_port)   (12 << (4 * (tc_port)))
+#define   DFLEXDPMLE1_DPMLETC_ML3_0(tc_port)   (15 << (4 * (tc_port)))
 
 /* BXT PHY Ref registers */
 #define _PORT_REF_DW3_A                        0x16218C
@@ -4593,12 +4597,12 @@ enum {
 
 #define  DRM_DIP_ENABLE                        (1 << 28)
 #define  PSR_VSC_BIT_7_SET             (1 << 27)
-#define  VSC_SELECT_MASK               (0x3 << 26)
-#define  VSC_SELECT_SHIFT              26
-#define  VSC_DIP_HW_HEA_DATA           (0 << 26)
-#define  VSC_DIP_HW_HEA_SW_DATA                (1 << 26)
-#define  VSC_DIP_HW_DATA_SW_HEA                (2 << 26)
-#define  VSC_DIP_SW_HEA_DATA           (3 << 26)
+#define  VSC_SELECT_MASK               (0x3 << 25)
+#define  VSC_SELECT_SHIFT              25
+#define  VSC_DIP_HW_HEA_DATA           (0 << 25)
+#define  VSC_DIP_HW_HEA_SW_DATA                (1 << 25)
+#define  VSC_DIP_HW_DATA_SW_HEA                (2 << 25)
+#define  VSC_DIP_SW_HEA_DATA           (3 << 25)
 #define  VDIP_ENABLE_PPS               (1 << 24)
 
 /* Panel power sequencing */
index 769f3f5866611174cbabeca5e4d1fbb0711b9b86..ee3ca2de983b96ea52ffda2c794963f2b23d705d 100644 (file)
@@ -144,6 +144,9 @@ static const struct {
 /* HDMI N/CTS table */
 #define TMDS_297M 297000
 #define TMDS_296M 296703
+#define TMDS_594M 594000
+#define TMDS_593M 593407
+
 static const struct {
        int sample_rate;
        int clock;
@@ -164,6 +167,20 @@ static const struct {
        { 176400, TMDS_297M, 18816, 247500 },
        { 192000, TMDS_296M, 23296, 281250 },
        { 192000, TMDS_297M, 20480, 247500 },
+       { 44100, TMDS_593M, 8918, 937500 },
+       { 44100, TMDS_594M, 9408, 990000 },
+       { 48000, TMDS_593M, 5824, 562500 },
+       { 48000, TMDS_594M, 6144, 594000 },
+       { 32000, TMDS_593M, 5824, 843750 },
+       { 32000, TMDS_594M, 3072, 445500 },
+       { 88200, TMDS_593M, 17836, 937500 },
+       { 88200, TMDS_594M, 18816, 990000 },
+       { 96000, TMDS_593M, 11648, 562500 },
+       { 96000, TMDS_594M, 12288, 594000 },
+       { 176400, TMDS_593M, 35672, 937500 },
+       { 176400, TMDS_594M, 37632, 990000 },
+       { 192000, TMDS_593M, 23296, 562500 },
+       { 192000, TMDS_594M, 24576, 594000 },
 };
 
 /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
index 29075c763428055ddb3625a80b59643e694f3d76..8d74276029e621f9ae7e6db54c815be5d2d0c9d1 100644 (file)
@@ -2138,16 +2138,8 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv,
 static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv,
                                     int pixel_rate)
 {
-       if (INTEL_GEN(dev_priv) >= 10)
+       if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
                return DIV_ROUND_UP(pixel_rate, 2);
-       else if (IS_GEMINILAKE(dev_priv))
-               /*
-                * FIXME: Avoid using a pixel clock that is more than 99% of the cdclk
-                * as a temporary workaround. Use a higher cdclk instead. (Note that
-                * intel_compute_max_dotclk() limits the max pixel clock to 99% of max
-                * cdclk.)
-                */
-               return DIV_ROUND_UP(pixel_rate * 100, 2 * 99);
        else if (IS_GEN9(dev_priv) ||
                 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
                return pixel_rate;
@@ -2543,14 +2535,8 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
 {
        int max_cdclk_freq = dev_priv->max_cdclk_freq;
 
-       if (INTEL_GEN(dev_priv) >= 10)
+       if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
                return 2 * max_cdclk_freq;
-       else if (IS_GEMINILAKE(dev_priv))
-               /*
-                * FIXME: Limiting to 99% as a temporary workaround. See
-                * intel_min_cdclk() for details.
-                */
-               return 2 * max_cdclk_freq * 99 / 100;
        else if (IS_GEN9(dev_priv) ||
                 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
                return max_cdclk_freq;
index 0ef0c6448d53a835fbdf5319a8010c64d613bd0f..01fa98299bae65a125862e57c307cdbce07c3d32 100644 (file)
@@ -474,7 +474,7 @@ static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv)
                        u8 eu_disabled_mask;
                        u32 n_disabled;
 
-                       if (!(sseu->subslice_mask[ss] & BIT(ss)))
+                       if (!(sseu->subslice_mask[s] & BIT(ss)))
                                /* skip disabled subslice */
                                continue;
 
index 9741cc419e1b2bc1f5eb4771ae75468f0099289d..a54843fdeb2f04a353c30af6e86e131c203b2868 100644 (file)
@@ -4850,8 +4850,31 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
  * chroma samples for both of the luma samples, and thus we don't
  * actually get the expected MPEG2 chroma siting convention :(
  * The same behaviour is observed on pre-SKL platforms as well.
+ *
+ * Theory behind the formula (note that we ignore sub-pixel
+ * source coordinates):
+ * s = source sample position
+ * d = destination sample position
+ *
+ * Downscaling 4:1:
+ * -0.5
+ * | 0.0
+ * | |     1.5 (initial phase)
+ * | |     |
+ * v v     v
+ * | s | s | s | s |
+ * |       d       |
+ *
+ * Upscaling 1:4:
+ * -0.5
+ * | -0.375 (initial phase)
+ * | |     0.0
+ * | |     |
+ * v v     v
+ * |       s       |
+ * | d | d | d | d |
  */
-u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
+u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited)
 {
        int phase = -0x8000;
        u16 trip = 0;
@@ -4859,6 +4882,15 @@ u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
        if (chroma_cosited)
                phase += (sub - 1) * 0x8000 / sub;
 
+       phase += scale / (2 * sub);
+
+       /*
+        * Hardware initial phase limited to [-0.5:1.5].
+        * Since the max hardware scale factor is 3.0, we
+        * should never actually excdeed 1.0 here.
+        */
+       WARN_ON(phase < -0x8000 || phase > 0x18000);
+
        if (phase < 0)
                phase = 0x10000 + phase;
        else
@@ -5067,13 +5099,20 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
 
        if (crtc->config->pch_pfit.enabled) {
                u16 uv_rgb_hphase, uv_rgb_vphase;
+               int pfit_w, pfit_h, hscale, vscale;
                int id;
 
                if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
                        return;
 
-               uv_rgb_hphase = skl_scaler_calc_phase(1, false);
-               uv_rgb_vphase = skl_scaler_calc_phase(1, false);
+               pfit_w = (crtc->config->pch_pfit.size >> 16) & 0xFFFF;
+               pfit_h = crtc->config->pch_pfit.size & 0xFFFF;
+
+               hscale = (crtc->config->pipe_src_w << 16) / pfit_w;
+               vscale = (crtc->config->pipe_src_h << 16) / pfit_h;
+
+               uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
+               uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
 
                id = scaler_state->scaler_id;
                I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
@@ -12768,17 +12807,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
                        intel_check_cpu_fifo_underruns(dev_priv);
                        intel_check_pch_fifo_underruns(dev_priv);
 
-                       if (!new_crtc_state->active) {
-                               /*
-                                * Make sure we don't call initial_watermarks
-                                * for ILK-style watermark updates.
-                                *
-                                * No clue what this is supposed to achieve.
-                                */
-                               if (INTEL_GEN(dev_priv) >= 9)
-                                       dev_priv->display.initial_watermarks(intel_state,
-                                                                            to_intel_crtc_state(new_crtc_state));
-                       }
+                       /* FIXME unify this for all platforms */
+                       if (!new_crtc_state->active &&
+                           !HAS_GMCH_DISPLAY(dev_priv) &&
+                           dev_priv->display.initial_watermarks)
+                               dev_priv->display.initial_watermarks(intel_state,
+                                                                    to_intel_crtc_state(new_crtc_state));
                }
        }
 
@@ -14646,7 +14680,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
             fb->height < SKL_MIN_YUV_420_SRC_H ||
             (fb->width % 4) != 0 || (fb->height % 4) != 0)) {
                DRM_DEBUG_KMS("src dimensions not correct for NV12\n");
-               return -EINVAL;
+               goto err;
        }
 
        for (i = 0; i < fb->format->num_planes; i++) {
index 1b00f8ea145ba3990d17f6e7142755bae8ca6a77..a911691dbd0fdd1837c8cfadec09f8d39eb7ac7d 100644 (file)
@@ -452,6 +452,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
        if (!intel_connector)
                return NULL;
 
+       intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
+       intel_connector->mst_port = intel_dp;
+       intel_connector->port = port;
+
        connector = &intel_connector->base;
        ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
                                 DRM_MODE_CONNECTOR_DisplayPort);
@@ -462,10 +466,6 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
 
        drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
 
-       intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
-       intel_connector->mst_port = intel_dp;
-       intel_connector->port = port;
-
        for_each_pipe(dev_priv, pipe) {
                struct drm_encoder *enc =
                        &intel_dp->mst_encoders[pipe]->base.base;
index f8dc84b2d2d3443dcd47232f013bddb4ae9731f8..8b298e5f012dac121385df61fa72d6a653a21354 100644 (file)
@@ -1646,7 +1646,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
                                  struct intel_crtc_state *crtc_state);
 
-u16 skl_scaler_calc_phase(int sub, bool chroma_center);
+u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_center);
 int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
 int skl_max_scale(const struct intel_crtc_state *crtc_state,
                  u32 pixel_format);
index 648a13c6043c0071ddd495424691d795b39b96a1..9a801813023728e2e0a05bb5feba1f8415eb3269 100644 (file)
@@ -228,7 +228,9 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
                drm_for_each_connector_iter(connector, &conn_iter) {
                        struct intel_connector *intel_connector = to_intel_connector(connector);
 
-                       if (intel_connector->encoder->hpd_pin == pin) {
+                       /* Don't check MST ports, they don't have pins */
+                       if (!intel_connector->mst_port &&
+                           intel_connector->encoder->hpd_pin == pin) {
                                if (connector->polled != intel_connector->polled)
                                        DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
                                                         connector->name);
@@ -395,37 +397,54 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
        struct intel_encoder *encoder;
        bool storm_detected = false;
        bool queue_dig = false, queue_hp = false;
+       u32 long_hpd_pulse_mask = 0;
+       u32 short_hpd_pulse_mask = 0;
+       enum hpd_pin pin;
 
        if (!pin_mask)
                return;
 
        spin_lock(&dev_priv->irq_lock);
+
+       /*
+        * Determine whether ->hpd_pulse() exists for each pin, and
+        * whether we have a short or a long pulse. This is needed
+        * as each pin may have up to two encoders (HDMI and DP) and
+        * only the one of them (DP) will have ->hpd_pulse().
+        */
        for_each_intel_encoder(&dev_priv->drm, encoder) {
-               enum hpd_pin pin = encoder->hpd_pin;
                bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
+               enum port port = encoder->port;
+               bool long_hpd;
 
+               pin = encoder->hpd_pin;
                if (!(BIT(pin) & pin_mask))
                        continue;
 
-               if (has_hpd_pulse) {
-                       bool long_hpd = long_mask & BIT(pin);
-                       enum port port = encoder->port;
+               if (!has_hpd_pulse)
+                       continue;
 
-                       DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
-                                        long_hpd ? "long" : "short");
-                       /*
-                        * For long HPD pulses we want to have the digital queue happen,
-                        * but we still want HPD storm detection to function.
-                        */
-                       queue_dig = true;
-                       if (long_hpd) {
-                               dev_priv->hotplug.long_port_mask |= (1 << port);
-                       } else {
-                               /* for short HPD just trigger the digital queue */
-                               dev_priv->hotplug.short_port_mask |= (1 << port);
-                               continue;
-                       }
+               long_hpd = long_mask & BIT(pin);
+
+               DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
+                                long_hpd ? "long" : "short");
+               queue_dig = true;
+
+               if (long_hpd) {
+                       long_hpd_pulse_mask |= BIT(pin);
+                       dev_priv->hotplug.long_port_mask |= BIT(port);
+               } else {
+                       short_hpd_pulse_mask |= BIT(pin);
+                       dev_priv->hotplug.short_port_mask |= BIT(port);
                }
+       }
+
+       /* Now process each pin just once */
+       for_each_hpd_pin(pin) {
+               bool long_hpd;
+
+               if (!(BIT(pin) & pin_mask))
+                       continue;
 
                if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
                        /*
@@ -442,11 +461,22 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
                if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
                        continue;
 
-               if (!has_hpd_pulse) {
+               /*
+                * Delegate to ->hpd_pulse() if one of the encoders for this
+                * pin has it, otherwise let the hotplug_work deal with this
+                * pin directly.
+                */
+               if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) {
+                       long_hpd = long_hpd_pulse_mask & BIT(pin);
+               } else {
                        dev_priv->hotplug.event_bits |= BIT(pin);
+                       long_hpd = true;
                        queue_hp = true;
                }
 
+               if (!long_hpd)
+                       continue;
+
                if (intel_hpd_irq_storm_detect(dev_priv, pin)) {
                        dev_priv->hotplug.event_bits &= ~BIT(pin);
                        storm_detected = true;
index cdf19553ffacd28f1097bb2096b8cc35d4654b84..5d5336fbe7b05836b7bedc28bffbfef9e6b08b4f 100644 (file)
@@ -297,8 +297,10 @@ void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv)
        lpe_audio_platdev_destroy(dev_priv);
 
        irq_free_desc(dev_priv->lpe_audio.irq);
-}
 
+       dev_priv->lpe_audio.irq = -1;
+       dev_priv->lpe_audio.platdev = NULL;
+}
 
 /**
  * intel_lpe_audio_notify() - notify lpe audio event
index 43957bb37a42249cfb75793fd688f191eaef2c98..37c94a54efcbb2501509b5a838e61d983985d8b2 100644 (file)
@@ -424,7 +424,8 @@ static u64 execlists_update_context(struct i915_request *rq)
 
        reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail);
 
-       /* True 32b PPGTT with dynamic page allocation: update PDP
+       /*
+        * True 32b PPGTT with dynamic page allocation: update PDP
         * registers and point the unallocated PDPs to scratch page.
         * PML4 is allocated during ppgtt init, so this is not needed
         * in 48-bit mode.
@@ -432,6 +433,17 @@ static u64 execlists_update_context(struct i915_request *rq)
        if (ppgtt && !i915_vm_is_48bit(&ppgtt->vm))
                execlists_update_context_pdps(ppgtt, reg_state);
 
+       /*
+        * Make sure the context image is complete before we submit it to HW.
+        *
+        * Ostensibly, writes (including the WCB) should be flushed prior to
+        * an uncached write such as our mmio register access, the empirical
+        * evidence (esp. on Braswell) suggests that the WC write into memory
+        * may not be visible to the HW prior to the completion of the UC
+        * register write and that we may begin execution from the context
+        * before its image is complete leading to invalid PD chasing.
+        */
+       wmb();
        return ce->lrc_desc;
 }
 
index 1db9b8328275038f93661c0e743bc0598303d25b..245f0022bcfd00c730f020b24326bfba90de4ea2 100644 (file)
@@ -2881,8 +2881,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
                 * any underrun. If not able to get Dimm info assume 16GB dimm
                 * to avoid any underrun.
                 */
-               if (!dev_priv->dram_info.valid_dimm ||
-                   dev_priv->dram_info.is_16gb_dimm)
+               if (dev_priv->dram_info.is_16gb_dimm)
                        wm[0] += 1;
 
        } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
index d0ef50bf930ad747abe7b4510521f8ad79923ba5..187bb0ceb4ac4324b3c12ab72635d4a776b2129c 100644 (file)
@@ -91,6 +91,7 @@ static int
 gen4_render_ring_flush(struct i915_request *rq, u32 mode)
 {
        u32 cmd, *cs;
+       int i;
 
        /*
         * read/write caches:
@@ -127,12 +128,45 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
                        cmd |= MI_INVALIDATE_ISP;
        }
 
-       cs = intel_ring_begin(rq, 2);
+       i = 2;
+       if (mode & EMIT_INVALIDATE)
+               i += 20;
+
+       cs = intel_ring_begin(rq, i);
        if (IS_ERR(cs))
                return PTR_ERR(cs);
 
        *cs++ = cmd;
-       *cs++ = MI_NOOP;
+
+       /*
+        * A random delay to let the CS invalidate take effect? Without this
+        * delay, the GPU relocation path fails as the CS does not see
+        * the updated contents. Just as important, if we apply the flushes
+        * to the EMIT_FLUSH branch (i.e. immediately after the relocation
+        * write and before the invalidate on the next batch), the relocations
+        * still fail. This implies that is a delay following invalidation
+        * that is required to reset the caches as opposed to a delay to
+        * ensure the memory is written.
+        */
+       if (mode & EMIT_INVALIDATE) {
+               *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
+               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
+                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = 0;
+               *cs++ = 0;
+
+               for (i = 0; i < 12; i++)
+                       *cs++ = MI_FLUSH;
+
+               *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
+               *cs++ = i915_ggtt_offset(rq->engine->scratch) |
+                       PIPE_CONTROL_GLOBAL_GTT;
+               *cs++ = 0;
+               *cs++ = 0;
+       }
+
+       *cs++ = cmd;
+
        intel_ring_advance(rq, cs);
 
        return 0;
index 0fdabce647ab64be1751da09ed705de3889ad969..44e4491a4918994b80ddde101042368263abf8d1 100644 (file)
@@ -2748,6 +2748,12 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                        .hsw.has_fuses = true,
                },
        },
+       {
+               .name = "DC off",
+               .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
+               .ops = &gen9_dc_off_power_well_ops,
+               .id = DISP_PW_ID_NONE,
+       },
        {
                .name = "power well 2",
                .domains = ICL_PW_2_POWER_DOMAINS,
@@ -2759,12 +2765,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                        .hsw.has_fuses = true,
                },
        },
-       {
-               .name = "DC off",
-               .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
-               .ops = &gen9_dc_off_power_well_ops,
-               .id = DISP_PW_ID_NONE,
-       },
        {
                .name = "power well 3",
                .domains = ICL_PW_3_POWER_DOMAINS,
@@ -3176,8 +3176,7 @@ static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv)
 void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
                            u8 req_slices)
 {
-       u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
-       u32 val;
+       const u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
        bool ret;
 
        if (req_slices > intel_dbuf_max_slices(dev_priv)) {
@@ -3188,7 +3187,6 @@ void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
        if (req_slices == hw_enabled_slices || req_slices == 0)
                return;
 
-       val = I915_READ(DBUF_CTL_S2);
        if (req_slices > hw_enabled_slices)
                ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true);
        else
index 5fd2f7bf3927191a22cdeba959c5fd7c4f6f512a..d3090a7537bb9576c89f69d17541eadbf9353d8c 100644 (file)
@@ -302,13 +302,65 @@ skl_plane_max_stride(struct intel_plane *plane,
                return min(8192 * cpp, 32768);
 }
 
+static void
+skl_program_scaler(struct intel_plane *plane,
+                  const struct intel_crtc_state *crtc_state,
+                  const struct intel_plane_state *plane_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+       enum pipe pipe = plane->pipe;
+       int scaler_id = plane_state->scaler_id;
+       const struct intel_scaler *scaler =
+               &crtc_state->scaler_state.scalers[scaler_id];
+       int crtc_x = plane_state->base.dst.x1;
+       int crtc_y = plane_state->base.dst.y1;
+       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
+       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
+       u16 y_hphase, uv_rgb_hphase;
+       u16 y_vphase, uv_rgb_vphase;
+       int hscale, vscale;
+
+       hscale = drm_rect_calc_hscale(&plane_state->base.src,
+                                     &plane_state->base.dst,
+                                     0, INT_MAX);
+       vscale = drm_rect_calc_vscale(&plane_state->base.src,
+                                     &plane_state->base.dst,
+                                     0, INT_MAX);
+
+       /* TODO: handle sub-pixel coordinates */
+       if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
+               y_hphase = skl_scaler_calc_phase(1, hscale, false);
+               y_vphase = skl_scaler_calc_phase(1, vscale, false);
+
+               /* MPEG2 chroma siting convention */
+               uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
+               uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
+       } else {
+               /* not used */
+               y_hphase = 0;
+               y_vphase = 0;
+
+               uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
+               uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
+       }
+
+       I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
+                     PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
+       I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
+       I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
+                     PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
+       I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
+                     PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
+       I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
+       I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
+}
+
 void
 skl_update_plane(struct intel_plane *plane,
                 const struct intel_crtc_state *crtc_state,
                 const struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-       const struct drm_framebuffer *fb = plane_state->base.fb;
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
        u32 plane_ctl = plane_state->ctl;
@@ -318,8 +370,6 @@ skl_update_plane(struct intel_plane *plane,
        u32 aux_stride = skl_plane_stride(plane_state, 1);
        int crtc_x = plane_state->base.dst.x1;
        int crtc_y = plane_state->base.dst.y1;
-       uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
-       uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
        uint32_t x = plane_state->color_plane[0].x;
        uint32_t y = plane_state->color_plane[0].y;
        uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
@@ -329,8 +379,6 @@ skl_update_plane(struct intel_plane *plane,
        /* Sizes are 0 based */
        src_w--;
        src_h--;
-       crtc_w--;
-       crtc_h--;
 
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
@@ -353,41 +401,8 @@ skl_update_plane(struct intel_plane *plane,
                      (plane_state->color_plane[1].y << 16) |
                      plane_state->color_plane[1].x);
 
-       /* program plane scaler */
        if (plane_state->scaler_id >= 0) {
-               int scaler_id = plane_state->scaler_id;
-               const struct intel_scaler *scaler =
-                       &crtc_state->scaler_state.scalers[scaler_id];
-               u16 y_hphase, uv_rgb_hphase;
-               u16 y_vphase, uv_rgb_vphase;
-
-               /* TODO: handle sub-pixel coordinates */
-               if (fb->format->format == DRM_FORMAT_NV12) {
-                       y_hphase = skl_scaler_calc_phase(1, false);
-                       y_vphase = skl_scaler_calc_phase(1, false);
-
-                       /* MPEG2 chroma siting convention */
-                       uv_rgb_hphase = skl_scaler_calc_phase(2, true);
-                       uv_rgb_vphase = skl_scaler_calc_phase(2, false);
-               } else {
-                       /* not used */
-                       y_hphase = 0;
-                       y_vphase = 0;
-
-                       uv_rgb_hphase = skl_scaler_calc_phase(1, false);
-                       uv_rgb_vphase = skl_scaler_calc_phase(1, false);
-               }
-
-               I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
-                             PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
-               I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
-               I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
-                             PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
-               I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
-                             PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
-               I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
-               I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
-                             ((crtc_w + 1) << 16)|(crtc_h + 1));
+               skl_program_scaler(plane, crtc_state, plane_state);
 
                I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
        } else {
index 8d03f64eabd71d449ebedca890135d69dabb1a74..5c22f2c8d4cfee20337d484a9eb227c3c6adcb34 100644 (file)
@@ -551,7 +551,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
                        err = igt_check_page_sizes(vma);
 
                        if (vma->page_sizes.gtt != I915_GTT_PAGE_SIZE_4K) {
-                               pr_err("page_sizes.gtt=%u, expected %lu\n",
+                               pr_err("page_sizes.gtt=%u, expected %llu\n",
                                       vma->page_sizes.gtt, I915_GTT_PAGE_SIZE_4K);
                                err = -EINVAL;
                        }
index 8e2e269db97e82917b299afbe680fc008b8c90a1..127d8151367177dea04bf5c121b2331e46d1accc 100644 (file)
@@ -1337,7 +1337,7 @@ static int igt_gtt_reserve(void *arg)
                GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
                if (vma->node.start != total ||
                    vma->node.size != 2*I915_GTT_PAGE_SIZE) {
-                       pr_err("i915_gem_gtt_reserve (pass 1) placement failed, found (%llx + %llx), expected (%llx + %lx)\n",
+                       pr_err("i915_gem_gtt_reserve (pass 1) placement failed, found (%llx + %llx), expected (%llx + %llx)\n",
                               vma->node.start, vma->node.size,
                               total, 2*I915_GTT_PAGE_SIZE);
                        err = -EINVAL;
@@ -1386,7 +1386,7 @@ static int igt_gtt_reserve(void *arg)
                GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
                if (vma->node.start != total ||
                    vma->node.size != 2*I915_GTT_PAGE_SIZE) {
-                       pr_err("i915_gem_gtt_reserve (pass 2) placement failed, found (%llx + %llx), expected (%llx + %lx)\n",
+                       pr_err("i915_gem_gtt_reserve (pass 2) placement failed, found (%llx + %llx), expected (%llx + %llx)\n",
                               vma->node.start, vma->node.size,
                               total, 2*I915_GTT_PAGE_SIZE);
                        err = -EINVAL;
@@ -1430,7 +1430,7 @@ static int igt_gtt_reserve(void *arg)
                GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
                if (vma->node.start != offset ||
                    vma->node.size != 2*I915_GTT_PAGE_SIZE) {
-                       pr_err("i915_gem_gtt_reserve (pass 3) placement failed, found (%llx + %llx), expected (%llx + %lx)\n",
+                       pr_err("i915_gem_gtt_reserve (pass 3) placement failed, found (%llx + %llx), expected (%llx + %llx)\n",
                               vma->node.start, vma->node.size,
                               offset, 2*I915_GTT_PAGE_SIZE);
                        err = -EINVAL;
index 514245e69b3847d1dc1d5f96249d5e49f849a4ca..acbbad3e322ca56957ff3b34228b694d12de30b3 100644 (file)
@@ -854,6 +854,13 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
        unsigned int sof_lines;
        unsigned int vsync_lines;
 
+       /* Use VENCI for 480i and 576i and double HDMI pixels */
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
+               hdmi_repeat = true;
+               use_enci = true;
+               venc_hdmi_latency = 1;
+       }
+
        if (meson_venc_hdmi_supported_vic(vic)) {
                vmode = meson_venc_hdmi_get_vic_vmode(vic);
                if (!vmode) {
@@ -865,13 +872,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
        } else {
                meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
                vmode = &vmode_dmt;
-       }
-
-       /* Use VENCI for 480i and 576i and double HDMI pixels */
-       if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
-               hdmi_repeat = true;
-               use_enci = true;
-               venc_hdmi_latency = 1;
+               use_enci = false;
        }
 
        /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
index 394c129cfb3bb8e03b8970fc839656e3d25becd5..0a485c5b982eb84addaf013dd8241509ca403d04 100644 (file)
@@ -5409,11 +5409,14 @@ static int dsi_probe(struct platform_device *pdev)
 
        /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
         * of data to 3 by default */
-       if (dsi->data->quirks & DSI_QUIRK_GNQ)
+       if (dsi->data->quirks & DSI_QUIRK_GNQ) {
+               dsi_runtime_get(dsi);
                /* NB_DATA_LANES */
                dsi->num_lanes_supported = 1 + REG_GET(dsi, DSI_GNQ, 11, 9);
-       else
+               dsi_runtime_put(dsi);
+       } else {
                dsi->num_lanes_supported = 3;
+       }
 
        r = dsi_init_output(dsi);
        if (r)
@@ -5426,15 +5429,19 @@ static int dsi_probe(struct platform_device *pdev)
        }
 
        r = of_platform_populate(dev->of_node, NULL, NULL, dev);
-       if (r)
+       if (r) {
                DSSERR("Failed to populate DSI child devices: %d\n", r);
+               goto err_uninit_output;
+       }
 
        r = component_add(&pdev->dev, &dsi_component_ops);
        if (r)
-               goto err_uninit_output;
+               goto err_of_depopulate;
 
        return 0;
 
+err_of_depopulate:
+       of_platform_depopulate(dev);
 err_uninit_output:
        dsi_uninit_output(dsi);
 err_pm_disable:
@@ -5470,19 +5477,12 @@ static int dsi_runtime_suspend(struct device *dev)
        /* wait for current handler to finish before turning the DSI off */
        synchronize_irq(dsi->irq);
 
-       dispc_runtime_put(dsi->dss->dispc);
-
        return 0;
 }
 
 static int dsi_runtime_resume(struct device *dev)
 {
        struct dsi_data *dsi = dev_get_drvdata(dev);
-       int r;
-
-       r = dispc_runtime_get(dsi->dss->dispc);
-       if (r)
-               return r;
 
        dsi->is_enabled = true;
        /* ensure the irq handler sees the is_enabled value */
index 1aaf260aa9b8638d2e7fac7aaa36ed3fe14a0880..7553c7fc1c457f23bb456046c17408ba89fc9d24 100644 (file)
@@ -1484,16 +1484,23 @@ static int dss_probe(struct platform_device *pdev)
                                                   dss);
 
        /* Add all the child devices as components. */
+       r = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+       if (r)
+               goto err_uninit_debugfs;
+
        omapdss_gather_components(&pdev->dev);
 
        device_for_each_child(&pdev->dev, &match, dss_add_child_component);
 
        r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
        if (r)
-               goto err_uninit_debugfs;
+               goto err_of_depopulate;
 
        return 0;
 
+err_of_depopulate:
+       of_platform_depopulate(&pdev->dev);
+
 err_uninit_debugfs:
        dss_debugfs_remove_file(dss->debugfs.clk);
        dss_debugfs_remove_file(dss->debugfs.dss);
@@ -1522,6 +1529,8 @@ static int dss_remove(struct platform_device *pdev)
 {
        struct dss_device *dss = platform_get_drvdata(pdev);
 
+       of_platform_depopulate(&pdev->dev);
+
        component_master_del(&pdev->dev, &dss_component_ops);
 
        dss_debugfs_remove_file(dss->debugfs.clk);
index cf6230eac31a3cffb37f62cb3e7b79ec9a6bb552..aabdda394c9c6f4cf7f93eb0f8e0f9a6126262d1 100644 (file)
@@ -635,10 +635,14 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
 
        hdmi->dss = dss;
 
-       r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
+       r = hdmi_runtime_get(hdmi);
        if (r)
                return r;
 
+       r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
+       if (r)
+               goto err_runtime_put;
+
        r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp);
        if (r)
                goto err_pll_uninit;
@@ -652,12 +656,16 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
        hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
                                               hdmi);
 
+       hdmi_runtime_put(hdmi);
+
        return 0;
 
 err_cec_uninit:
        hdmi4_cec_uninit(&hdmi->core);
 err_pll_uninit:
        hdmi_pll_uninit(&hdmi->pll);
+err_runtime_put:
+       hdmi_runtime_put(hdmi);
        return r;
 }
 
@@ -833,32 +841,6 @@ static int hdmi4_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int hdmi_runtime_suspend(struct device *dev)
-{
-       struct omap_hdmi *hdmi = dev_get_drvdata(dev);
-
-       dispc_runtime_put(hdmi->dss->dispc);
-
-       return 0;
-}
-
-static int hdmi_runtime_resume(struct device *dev)
-{
-       struct omap_hdmi *hdmi = dev_get_drvdata(dev);
-       int r;
-
-       r = dispc_runtime_get(hdmi->dss->dispc);
-       if (r < 0)
-               return r;
-
-       return 0;
-}
-
-static const struct dev_pm_ops hdmi_pm_ops = {
-       .runtime_suspend = hdmi_runtime_suspend,
-       .runtime_resume = hdmi_runtime_resume,
-};
-
 static const struct of_device_id hdmi_of_match[] = {
        { .compatible = "ti,omap4-hdmi", },
        {},
@@ -869,7 +851,6 @@ struct platform_driver omapdss_hdmi4hw_driver = {
        .remove         = hdmi4_remove,
        .driver         = {
                .name   = "omapdss_hdmi",
-               .pm     = &hdmi_pm_ops,
                .of_match_table = hdmi_of_match,
                .suppress_bind_attrs = true,
        },
index b0e4a7463f8c88517fcb398a049a8f5355df6dc9..9e8556f67a2914aed8ed1b71409956c2bcc07057 100644 (file)
@@ -825,32 +825,6 @@ static int hdmi5_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int hdmi_runtime_suspend(struct device *dev)
-{
-       struct omap_hdmi *hdmi = dev_get_drvdata(dev);
-
-       dispc_runtime_put(hdmi->dss->dispc);
-
-       return 0;
-}
-
-static int hdmi_runtime_resume(struct device *dev)
-{
-       struct omap_hdmi *hdmi = dev_get_drvdata(dev);
-       int r;
-
-       r = dispc_runtime_get(hdmi->dss->dispc);
-       if (r < 0)
-               return r;
-
-       return 0;
-}
-
-static const struct dev_pm_ops hdmi_pm_ops = {
-       .runtime_suspend = hdmi_runtime_suspend,
-       .runtime_resume = hdmi_runtime_resume,
-};
-
 static const struct of_device_id hdmi_of_match[] = {
        { .compatible = "ti,omap5-hdmi", },
        { .compatible = "ti,dra7-hdmi", },
@@ -862,7 +836,6 @@ struct platform_driver omapdss_hdmi5hw_driver = {
        .remove         = hdmi5_remove,
        .driver         = {
                .name   = "omapdss_hdmi5",
-               .pm     = &hdmi_pm_ops,
                .of_match_table = hdmi_of_match,
                .suppress_bind_attrs = true,
        },
index ff0b18c8e4acedc4d2e310d5377a789fecaaf9a2..b5f52727f8b17237f52bbad92e170a488e27b396 100644 (file)
@@ -946,19 +946,12 @@ static int venc_runtime_suspend(struct device *dev)
        if (venc->tv_dac_clk)
                clk_disable_unprepare(venc->tv_dac_clk);
 
-       dispc_runtime_put(venc->dss->dispc);
-
        return 0;
 }
 
 static int venc_runtime_resume(struct device *dev)
 {
        struct venc_device *venc = dev_get_drvdata(dev);
-       int r;
-
-       r = dispc_runtime_get(venc->dss->dispc);
-       if (r < 0)
-               return r;
 
        if (venc->tv_dac_clk)
                clk_prepare_enable(venc->tv_dac_clk);
index 62928ec0e7db7a6fd6c53d1801c62a19dae80758..caffc547ef97e385cb913f77fd3ebe55a082d486 100644 (file)
@@ -350,11 +350,14 @@ static void omap_crtc_arm_event(struct drm_crtc *crtc)
 static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
                                    struct drm_crtc_state *old_state)
 {
+       struct omap_drm_private *priv = crtc->dev->dev_private;
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
        int ret;
 
        DBG("%s", omap_crtc->name);
 
+       priv->dispc_ops->runtime_get(priv->dispc);
+
        spin_lock_irq(&crtc->dev->event_lock);
        drm_crtc_vblank_on(crtc);
        ret = drm_crtc_vblank_get(crtc);
@@ -367,6 +370,7 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
 static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
                                     struct drm_crtc_state *old_state)
 {
+       struct omap_drm_private *priv = crtc->dev->dev_private;
        struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 
        DBG("%s", omap_crtc->name);
@@ -379,6 +383,8 @@ static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
        spin_unlock_irq(&crtc->dev->event_lock);
 
        drm_crtc_vblank_off(crtc);
+
+       priv->dispc_ops->runtime_put(priv->dispc);
 }
 
 static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
index af7dcb6da351408391892dff43c9fc574291ae50..e7eb0d1e17be5e6575550f9e6c12d9b96f92a0d5 100644 (file)
@@ -75,7 +75,7 @@ static void sun4i_lvds_encoder_enable(struct drm_encoder *encoder)
 
        DRM_DEBUG_DRIVER("Enabling LVDS output\n");
 
-       if (!IS_ERR(tcon->panel)) {
+       if (tcon->panel) {
                drm_panel_prepare(tcon->panel);
                drm_panel_enable(tcon->panel);
        }
@@ -88,7 +88,7 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
 
        DRM_DEBUG_DRIVER("Disabling LVDS output\n");
 
-       if (!IS_ERR(tcon->panel)) {
+       if (tcon->panel) {
                drm_panel_disable(tcon->panel);
                drm_panel_unprepare(tcon->panel);
        }
index bf068da6b12e11b7a9440fdca6ff03ca84ff2479..f4a22689eb54c238f96626c03d8271d70ce645b8 100644 (file)
@@ -135,7 +135,7 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder)
 
        DRM_DEBUG_DRIVER("Enabling RGB output\n");
 
-       if (!IS_ERR(tcon->panel)) {
+       if (tcon->panel) {
                drm_panel_prepare(tcon->panel);
                drm_panel_enable(tcon->panel);
        }
@@ -148,7 +148,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder)
 
        DRM_DEBUG_DRIVER("Disabling RGB output\n");
 
-       if (!IS_ERR(tcon->panel)) {
+       if (tcon->panel) {
                drm_panel_disable(tcon->panel);
                drm_panel_unprepare(tcon->panel);
        }
index c78cd35a1294b215f84b33031ac7d826760b885a..f949287d926cd07f6859331c769ef02621ef130f 100644 (file)
@@ -491,7 +491,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
        sun4i_tcon0_mode_set_common(tcon, mode);
 
        /* Set dithering if needed */
-       sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector);
+       if (tcon->panel)
+               sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector);
 
        /* Adjust clock delay */
        clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
@@ -555,7 +556,7 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
         * Following code is a way to avoid quirks all around TCON
         * and DOTCLOCK drivers.
         */
-       if (!IS_ERR(tcon->panel)) {
+       if (tcon->panel) {
                struct drm_panel *panel = tcon->panel;
                struct drm_connector *connector = panel->connector;
                struct drm_display_info display_info = connector->display_info;
index cf2a18571d484d078dc1eabc59a3d6ff0f11ab07..a132c37d733490fa70af2674237162d73459a31d 100644 (file)
@@ -380,6 +380,9 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
                        mutex_unlock(&vgasr_mutex);
                        return -EINVAL;
                }
+               /* notify if GPU has been already bound */
+               if (ops->gpu_bound)
+                       ops->gpu_bound(pdev, id);
        }
        mutex_unlock(&vgasr_mutex);
 
index aec253b44156891bf71c192c1cd1e41b2e5801a3..3cd7229b6e5465b88759d42a9a12084cd948eeab 100644 (file)
@@ -660,6 +660,20 @@ exit:
        return ret;
 }
 
+static int alps_sp_open(struct input_dev *dev)
+{
+       struct hid_device *hid = input_get_drvdata(dev);
+
+       return hid_hw_open(hid);
+}
+
+static void alps_sp_close(struct input_dev *dev)
+{
+       struct hid_device *hid = input_get_drvdata(dev);
+
+       hid_hw_close(hid);
+}
+
 static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
 {
        struct alps_dev *data = hid_get_drvdata(hdev);
@@ -733,6 +747,10 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
                input2->id.version = input->id.version;
                input2->dev.parent = input->dev.parent;
 
+               input_set_drvdata(input2, hdev);
+               input2->open = alps_sp_open;
+               input2->close = alps_sp_close;
+
                __set_bit(EV_KEY, input2->evbit);
                data->sp_btn_cnt = (data->sp_btn_info & 0x0F);
                for (i = 0; i < data->sp_btn_cnt; i++)
index dc6d6477e9611eb2ba93a8d687bfaf9d4e634ef8..a1fa2fc8c9b57fd8e3de462d35b6247bd0d3e6e3 100644 (file)
@@ -359,6 +359,9 @@ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
        u32 value;
        int ret;
 
+       if (!IS_ENABLED(CONFIG_ASUS_WMI))
+               return false;
+
        ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2,
                                       ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
        hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
index f63489c882bb64f98f4c5bf9c84cbeb9df192c71..c0d668944dbe876260a926c0125f4ec1ab4afc52 100644 (file)
 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003                0x3003
 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008                0x3008
 
+#define I2C_VENDOR_ID_RAYDIUM          0x2386
+#define I2C_PRODUCT_ID_RAYDIUM_4B33    0x4b33
+
 #define USB_VENDOR_ID_RAZER            0x1532
 #define USB_DEVICE_ID_RAZER_BLADE_14   0x011D
 
index 52c3b01917e7236821b804a35711b1e034da4788..8237dd86fb17fa9157fd4c97b6da734e34af9733 100644 (file)
@@ -107,7 +107,6 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
-       { HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
index 4aab96cf081861f863a008cda0a080425fdf31fa..3cde7c1b9c33cd673858d5089ed097e724fb12b0 100644 (file)
@@ -49,6 +49,7 @@
 #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV       BIT(0)
 #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET       BIT(1)
 #define I2C_HID_QUIRK_NO_RUNTIME_PM            BIT(2)
+#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP                BIT(3)
 
 /* flags */
 #define I2C_HID_STARTED                0
@@ -158,6 +159,8 @@ struct i2c_hid {
 
        bool                    irq_wake_enabled;
        struct mutex            reset_lock;
+
+       unsigned long           sleep_delay;
 };
 
 static const struct i2c_hid_quirks {
@@ -172,6 +175,8 @@ static const struct i2c_hid_quirks {
        { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
                I2C_HID_QUIRK_NO_IRQ_AFTER_RESET |
                I2C_HID_QUIRK_NO_RUNTIME_PM },
+       { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33,
+               I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
        { 0, 0 }
 };
 
@@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
 {
        struct i2c_hid *ihid = i2c_get_clientdata(client);
        int ret;
+       unsigned long now, delay;
 
        i2c_hid_dbg(ihid, "%s\n", __func__);
 
@@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
                        goto set_pwr_exit;
        }
 
+       if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
+           power_state == I2C_HID_PWR_ON) {
+               now = jiffies;
+               if (time_after(ihid->sleep_delay, now)) {
+                       delay = jiffies_to_usecs(ihid->sleep_delay - now);
+                       usleep_range(delay, delay + 1);
+               }
+       }
+
        ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state,
                0, NULL, 0, NULL, 0);
 
+       if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
+           power_state == I2C_HID_PWR_SLEEP)
+               ihid->sleep_delay = jiffies + msecs_to_jiffies(20);
+
        if (ret)
                dev_err(&client->dev, "failed to change power setting.\n");
 
index cac262a912c1248747d2814fa9e3b3d3512f8c76..89f2976f9c534c475da40c3933d2775e46787ae9 100644 (file)
@@ -330,6 +330,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
                },
                .driver_data = (void *)&sipodev_desc
        },
+       {
+               .ident = "Direkt-Tek DTLAPY133-1",
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"),
+               },
+               .driver_data = (void *)&sipodev_desc
+       },
        {
                .ident = "Mediacom Flexbook Edge 11",
                .matches = {
index 23872d08308cdb5857d53b5bcdf907e20d74c345..a746017fac170ca15895435fd4df4fbe3a04d51f 100644 (file)
@@ -512,14 +512,24 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
                        if (cmd == HIDIOCGCOLLECTIONINDEX) {
                                if (uref->usage_index >= field->maxusage)
                                        goto inval;
+                               uref->usage_index =
+                                       array_index_nospec(uref->usage_index,
+                                                          field->maxusage);
                        } else if (uref->usage_index >= field->report_count)
                                goto inval;
                }
 
-               if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
-                   (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
-                    uref->usage_index + uref_multi->num_values > field->report_count))
-                       goto inval;
+               if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
+                       if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+                           uref->usage_index + uref_multi->num_values >
+                           field->report_count)
+                               goto inval;
+
+                       uref->usage_index =
+                               array_index_nospec(uref->usage_index,
+                                                  field->report_count -
+                                                  uref_multi->num_values);
+               }
 
                switch (cmd) {
                case HIDIOCGUSAGE:
index 975c951698846bffb8ae98ec4a70759e60a1f11b..84f61cec6319c8eb65ccc80553cbbdfde0542cc9 100644 (file)
@@ -649,8 +649,10 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
                                if (info[i]->config[j] & HWMON_T_INPUT) {
                                        err = hwmon_thermal_add_sensor(dev,
                                                                hwdev, j);
-                                       if (err)
-                                               goto free_device;
+                                       if (err) {
+                                               device_unregister(hdev);
+                                               goto ida_remove;
+                                       }
                                }
                        }
                }
@@ -658,8 +660,6 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata,
 
        return hdev;
 
-free_device:
-       device_unregister(hdev);
 free_hwmon:
        kfree(hwdev);
 ida_remove:
index 0ccca87f527191dc000649d1a0b1eaf44c87d35b..293dd1c6c7b36ef2b0770cf76e465aaea22b4673 100644 (file)
@@ -181,7 +181,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
        return sprintf(buf, "%s\n", sdata->label);
 }
 
-static int __init get_logical_cpu(int hwcpu)
+static int get_logical_cpu(int hwcpu)
 {
        int cpu;
 
@@ -192,9 +192,8 @@ static int __init get_logical_cpu(int hwcpu)
        return -ENOENT;
 }
 
-static void __init make_sensor_label(struct device_node *np,
-                                    struct sensor_data *sdata,
-                                    const char *label)
+static void make_sensor_label(struct device_node *np,
+                             struct sensor_data *sdata, const char *label)
 {
        u32 id;
        size_t n;
index 56ccb1ea7da5b405e904d90ac38b17303a3d2faa..f2c6819712013046246002346af928bd1ab16bc0 100644 (file)
@@ -224,6 +224,15 @@ config I2C_NFORCE2_S4985
          This driver can also be built as a module.  If so, the module
          will be called i2c-nforce2-s4985.
 
+config I2C_NVIDIA_GPU
+       tristate "NVIDIA GPU I2C controller"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the
+         NVIDIA GPU I2C controller which is used to communicate with the GPU's
+         Type-C controller. This driver can also be built as a module called
+         i2c-nvidia-gpu.
+
 config I2C_SIS5595
        tristate "SiS 5595"
        depends on PCI
@@ -752,7 +761,7 @@ config I2C_OCORES
 
 config I2C_OMAP
        tristate "OMAP I2C adapter"
-       depends on ARCH_OMAP
+       depends on ARCH_OMAP || ARCH_K3
        default y if MACH_OMAP_H3 || MACH_OMAP_OSK
        help
          If you say yes to this option, support will be included for the
index 18b26af82b1c5425a9dcec9c61cca3cdff694d60..5f0cb6915969aa98d5722b02e0fe9cb9a1ae25a7 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_I2C_ISCH)                += i2c-isch.o
 obj-$(CONFIG_I2C_ISMT)         += i2c-ismt.o
 obj-$(CONFIG_I2C_NFORCE2)      += i2c-nforce2.o
 obj-$(CONFIG_I2C_NFORCE2_S4985)        += i2c-nforce2-s4985.o
+obj-$(CONFIG_I2C_NVIDIA_GPU)   += i2c-nvidia-gpu.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
 obj-$(CONFIG_I2C_SIS5595)      += i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c
new file mode 100644 (file)
index 0000000..8822357
--- /dev/null
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nvidia GPU I2C controller Driver
+ *
+ * Copyright (C) 2018 NVIDIA Corporation. All rights reserved.
+ * Author: Ajay Gupta <ajayg@nvidia.com>
+ */
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+#include <asm/unaligned.h>
+
+/* I2C definitions */
+#define I2C_MST_CNTL                           0x00
+#define I2C_MST_CNTL_GEN_START                 BIT(0)
+#define I2C_MST_CNTL_GEN_STOP                  BIT(1)
+#define I2C_MST_CNTL_CMD_READ                  (1 << 2)
+#define I2C_MST_CNTL_CMD_WRITE                 (2 << 2)
+#define I2C_MST_CNTL_BURST_SIZE_SHIFT          6
+#define I2C_MST_CNTL_GEN_NACK                  BIT(28)
+#define I2C_MST_CNTL_STATUS                    GENMASK(30, 29)
+#define I2C_MST_CNTL_STATUS_OKAY               (0 << 29)
+#define I2C_MST_CNTL_STATUS_NO_ACK             (1 << 29)
+#define I2C_MST_CNTL_STATUS_TIMEOUT            (2 << 29)
+#define I2C_MST_CNTL_STATUS_BUS_BUSY           (3 << 29)
+#define I2C_MST_CNTL_CYCLE_TRIGGER             BIT(31)
+
+#define I2C_MST_ADDR                           0x04
+
+#define I2C_MST_I2C0_TIMING                            0x08
+#define I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ          0x10e
+#define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT            16
+#define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX                255
+#define I2C_MST_I2C0_TIMING_TIMEOUT_CHECK              BIT(24)
+
+#define I2C_MST_DATA                                   0x0c
+
+#define I2C_MST_HYBRID_PADCTL                          0x20
+#define I2C_MST_HYBRID_PADCTL_MODE_I2C                 BIT(0)
+#define I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV                BIT(14)
+#define I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV                BIT(15)
+
+struct gpu_i2c_dev {
+       struct device *dev;
+       void __iomem *regs;
+       struct i2c_adapter adapter;
+       struct i2c_board_info *gpu_ccgx_ucsi;
+};
+
+static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd)
+{
+       u32 val;
+
+       /* enable I2C */
+       val = readl(i2cd->regs + I2C_MST_HYBRID_PADCTL);
+       val |= I2C_MST_HYBRID_PADCTL_MODE_I2C |
+               I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
+               I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV;
+       writel(val, i2cd->regs + I2C_MST_HYBRID_PADCTL);
+
+       /* enable 100KHZ mode */
+       val = I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ;
+       val |= (I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX
+           << I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT);
+       val |= I2C_MST_I2C0_TIMING_TIMEOUT_CHECK;
+       writel(val, i2cd->regs + I2C_MST_I2C0_TIMING);
+}
+
+static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd)
+{
+       unsigned long target = jiffies + msecs_to_jiffies(1000);
+       u32 val;
+
+       do {
+               val = readl(i2cd->regs + I2C_MST_CNTL);
+               if (!(val & I2C_MST_CNTL_CYCLE_TRIGGER))
+                       break;
+               if ((val & I2C_MST_CNTL_STATUS) !=
+                               I2C_MST_CNTL_STATUS_BUS_BUSY)
+                       break;
+               usleep_range(500, 600);
+       } while (time_is_after_jiffies(target));
+
+       if (time_is_before_jiffies(target)) {
+               dev_err(i2cd->dev, "i2c timeout error %x\n", val);
+               return -ETIME;
+       }
+
+       val = readl(i2cd->regs + I2C_MST_CNTL);
+       switch (val & I2C_MST_CNTL_STATUS) {
+       case I2C_MST_CNTL_STATUS_OKAY:
+               return 0;
+       case I2C_MST_CNTL_STATUS_NO_ACK:
+               return -EIO;
+       case I2C_MST_CNTL_STATUS_TIMEOUT:
+               return -ETIME;
+       default:
+               return 0;
+       }
+}
+
+static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len)
+{
+       int status;
+       u32 val;
+
+       val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ |
+               (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) |
+               I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK;
+       writel(val, i2cd->regs + I2C_MST_CNTL);
+
+       status = gpu_i2c_check_status(i2cd);
+       if (status < 0)
+               return status;
+
+       val = readl(i2cd->regs + I2C_MST_DATA);
+       switch (len) {
+       case 1:
+               data[0] = val;
+               break;
+       case 2:
+               put_unaligned_be16(val, data);
+               break;
+       case 3:
+               put_unaligned_be16(val >> 8, data);
+               data[2] = val;
+               break;
+       case 4:
+               put_unaligned_be32(val, data);
+               break;
+       default:
+               break;
+       }
+       return status;
+}
+
+static int gpu_i2c_start(struct gpu_i2c_dev *i2cd)
+{
+       writel(I2C_MST_CNTL_GEN_START, i2cd->regs + I2C_MST_CNTL);
+       return gpu_i2c_check_status(i2cd);
+}
+
+static int gpu_i2c_stop(struct gpu_i2c_dev *i2cd)
+{
+       writel(I2C_MST_CNTL_GEN_STOP, i2cd->regs + I2C_MST_CNTL);
+       return gpu_i2c_check_status(i2cd);
+}
+
+static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data)
+{
+       u32 val;
+
+       writel(data, i2cd->regs + I2C_MST_DATA);
+
+       val = I2C_MST_CNTL_CMD_WRITE | (1 << I2C_MST_CNTL_BURST_SIZE_SHIFT);
+       writel(val, i2cd->regs + I2C_MST_CNTL);
+
+       return gpu_i2c_check_status(i2cd);
+}
+
+static int gpu_i2c_master_xfer(struct i2c_adapter *adap,
+                              struct i2c_msg *msgs, int num)
+{
+       struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap);
+       int status, status2;
+       int i, j;
+
+       /*
+        * The controller supports maximum 4 byte read due to known
+        * limitation of sending STOP after every read.
+        */
+       for (i = 0; i < num; i++) {
+               if (msgs[i].flags & I2C_M_RD) {
+                       /* program client address before starting read */
+                       writel(msgs[i].addr, i2cd->regs + I2C_MST_ADDR);
+                       /* gpu_i2c_read has implicit start */
+                       status = gpu_i2c_read(i2cd, msgs[i].buf, msgs[i].len);
+                       if (status < 0)
+                               goto stop;
+               } else {
+                       u8 addr = i2c_8bit_addr_from_msg(msgs + i);
+
+                       status = gpu_i2c_start(i2cd);
+                       if (status < 0) {
+                               if (i == 0)
+                                       return status;
+                               goto stop;
+                       }
+
+                       status = gpu_i2c_write(i2cd, addr);
+                       if (status < 0)
+                               goto stop;
+
+                       for (j = 0; j < msgs[i].len; j++) {
+                               status = gpu_i2c_write(i2cd, msgs[i].buf[j]);
+                               if (status < 0)
+                                       goto stop;
+                       }
+               }
+       }
+       status = gpu_i2c_stop(i2cd);
+       if (status < 0)
+               return status;
+
+       return i;
+stop:
+       status2 = gpu_i2c_stop(i2cd);
+       if (status2 < 0)
+               dev_err(i2cd->dev, "i2c stop failed %d\n", status2);
+       return status;
+}
+
+static const struct i2c_adapter_quirks gpu_i2c_quirks = {
+       .max_read_len = 4,
+       .flags = I2C_AQ_COMB_WRITE_THEN_READ,
+};
+
+static u32 gpu_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm gpu_i2c_algorithm = {
+       .master_xfer    = gpu_i2c_master_xfer,
+       .functionality  = gpu_i2c_functionality,
+};
+
+/*
+ * This driver is for Nvidia GPU cards with USB Type-C interface.
+ * We want to identify the cards using vendor ID and class code only
+ * to avoid dependency of adding product id for any new card which
+ * requires this driver.
+ * Currently there is no class code defined for UCSI device over PCI
+ * so using UNKNOWN class for now and it will be updated when UCSI
+ * over PCI gets a class code.
+ * There is no other NVIDIA cards with UNKNOWN class code. Even if the
+ * driver gets loaded for an undesired card then eventually i2c_read()
+ * (initiated from UCSI i2c_client) will timeout or UCSI commands will
+ * timeout.
+ */
+#define PCI_CLASS_SERIAL_UNKNOWN       0x0c80
+static const struct pci_device_id gpu_i2c_ids[] = {
+       { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+               PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00},
+       { }
+};
+MODULE_DEVICE_TABLE(pci, gpu_i2c_ids);
+
+static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq)
+{
+       struct i2c_client *ccgx_client;
+
+       i2cd->gpu_ccgx_ucsi = devm_kzalloc(i2cd->dev,
+                                          sizeof(*i2cd->gpu_ccgx_ucsi),
+                                          GFP_KERNEL);
+       if (!i2cd->gpu_ccgx_ucsi)
+               return -ENOMEM;
+
+       strlcpy(i2cd->gpu_ccgx_ucsi->type, "ccgx-ucsi",
+               sizeof(i2cd->gpu_ccgx_ucsi->type));
+       i2cd->gpu_ccgx_ucsi->addr = 0x8;
+       i2cd->gpu_ccgx_ucsi->irq = irq;
+       ccgx_client = i2c_new_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi);
+       if (!ccgx_client)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       struct gpu_i2c_dev *i2cd;
+       int status;
+
+       i2cd = devm_kzalloc(&pdev->dev, sizeof(*i2cd), GFP_KERNEL);
+       if (!i2cd)
+               return -ENOMEM;
+
+       i2cd->dev = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, i2cd);
+
+       status = pcim_enable_device(pdev);
+       if (status < 0) {
+               dev_err(&pdev->dev, "pcim_enable_device failed %d\n", status);
+               return status;
+       }
+
+       pci_set_master(pdev);
+
+       i2cd->regs = pcim_iomap(pdev, 0, 0);
+       if (!i2cd->regs) {
+               dev_err(&pdev->dev, "pcim_iomap failed\n");
+               return -ENOMEM;
+       }
+
+       status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+       if (status < 0) {
+               dev_err(&pdev->dev, "pci_alloc_irq_vectors err %d\n", status);
+               return status;
+       }
+
+       gpu_enable_i2c_bus(i2cd);
+
+       i2c_set_adapdata(&i2cd->adapter, i2cd);
+       i2cd->adapter.owner = THIS_MODULE;
+       strlcpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter",
+               sizeof(i2cd->adapter.name));
+       i2cd->adapter.algo = &gpu_i2c_algorithm;
+       i2cd->adapter.quirks = &gpu_i2c_quirks;
+       i2cd->adapter.dev.parent = &pdev->dev;
+       status = i2c_add_adapter(&i2cd->adapter);
+       if (status < 0)
+               goto free_irq_vectors;
+
+       status = gpu_populate_client(i2cd, pdev->irq);
+       if (status < 0) {
+               dev_err(&pdev->dev, "gpu_populate_client failed %d\n", status);
+               goto del_adapter;
+       }
+
+       return 0;
+
+del_adapter:
+       i2c_del_adapter(&i2cd->adapter);
+free_irq_vectors:
+       pci_free_irq_vectors(pdev);
+       return status;
+}
+
+static void gpu_i2c_remove(struct pci_dev *pdev)
+{
+       struct gpu_i2c_dev *i2cd = dev_get_drvdata(&pdev->dev);
+
+       i2c_del_adapter(&i2cd->adapter);
+       pci_free_irq_vectors(pdev);
+}
+
+static int gpu_i2c_resume(struct device *dev)
+{
+       struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev);
+
+       gpu_enable_i2c_bus(i2cd);
+       return 0;
+}
+
+static UNIVERSAL_DEV_PM_OPS(gpu_i2c_driver_pm, NULL, gpu_i2c_resume, NULL);
+
+static struct pci_driver gpu_i2c_driver = {
+       .name           = "nvidia-gpu",
+       .id_table       = gpu_i2c_ids,
+       .probe          = gpu_i2c_probe,
+       .remove         = gpu_i2c_remove,
+       .driver         = {
+               .pm     = &gpu_i2c_driver_pm,
+       },
+};
+
+module_pci_driver(gpu_i2c_driver);
+
+MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
+MODULE_DESCRIPTION("Nvidia GPU I2C controller Driver");
+MODULE_LICENSE("GPL v2");
index 527f55c8c4c70e560a9787a610c68017fbb10235..db075bc0d9525d62a7b366abd7c6eb1edeaaa76c 100644 (file)
@@ -571,18 +571,19 @@ static int geni_i2c_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
 
-       ret = i2c_add_adapter(&gi2c->adap);
-       if (ret) {
-               dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret);
-               return ret;
-       }
-
        gi2c->suspended = 1;
        pm_runtime_set_suspended(gi2c->se.dev);
        pm_runtime_set_autosuspend_delay(gi2c->se.dev, I2C_AUTO_SUSPEND_DELAY);
        pm_runtime_use_autosuspend(gi2c->se.dev);
        pm_runtime_enable(gi2c->se.dev);
 
+       ret = i2c_add_adapter(&gi2c->adap);
+       if (ret) {
+               dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret);
+               pm_runtime_disable(gi2c->se.dev);
+               return ret;
+       }
+
        return 0;
 }
 
@@ -590,8 +591,8 @@ static int geni_i2c_remove(struct platform_device *pdev)
 {
        struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
 
-       pm_runtime_disable(gi2c->se.dev);
        i2c_del_adapter(&gi2c->adap);
+       pm_runtime_disable(gi2c->se.dev);
        return 0;
 }
 
index ce7acd115dd8da7578b4fc8d3fc3733692d90743..1870cf87afe1ef7993b6e2cda9a28aeede31f268 100644 (file)
@@ -75,8 +75,6 @@ static void pattern_trig_timer_function(struct timer_list *t)
 {
        struct pattern_trig_data *data = from_timer(data, t, timer);
 
-       mutex_lock(&data->lock);
-
        for (;;) {
                if (!data->is_indefinite && !data->repeat)
                        break;
@@ -87,9 +85,10 @@ static void pattern_trig_timer_function(struct timer_list *t)
                                           data->curr->brightness);
                        mod_timer(&data->timer,
                                  jiffies + msecs_to_jiffies(data->curr->delta_t));
-
-                       /* Skip the tuple with zero duration */
-                       pattern_trig_update_patterns(data);
+                       if (!data->next->delta_t) {
+                               /* Skip the tuple with zero duration */
+                               pattern_trig_update_patterns(data);
+                       }
                        /* Select next tuple */
                        pattern_trig_update_patterns(data);
                } else {
@@ -116,8 +115,6 @@ static void pattern_trig_timer_function(struct timer_list *t)
 
                break;
        }
-
-       mutex_unlock(&data->lock);
 }
 
 static int pattern_trig_start_pattern(struct led_classdev *led_cdev)
@@ -176,14 +173,10 @@ static ssize_t repeat_store(struct device *dev, struct device_attribute *attr,
        if (res < -1 || res == 0)
                return -EINVAL;
 
-       /*
-        * Clear previous patterns' performence firstly, and remove the timer
-        * without mutex lock to avoid dead lock.
-        */
-       del_timer_sync(&data->timer);
-
        mutex_lock(&data->lock);
 
+       del_timer_sync(&data->timer);
+
        if (data->is_hw_pattern)
                led_cdev->pattern_clear(led_cdev);
 
@@ -234,14 +227,10 @@ static ssize_t pattern_trig_store_patterns(struct led_classdev *led_cdev,
        struct pattern_trig_data *data = led_cdev->trigger_data;
        int ccount, cr, offset = 0, err = 0;
 
-       /*
-        * Clear previous patterns' performence firstly, and remove the timer
-        * without mutex lock to avoid dead lock.
-        */
-       del_timer_sync(&data->timer);
-
        mutex_lock(&data->lock);
 
+       del_timer_sync(&data->timer);
+
        if (data->is_hw_pattern)
                led_cdev->pattern_clear(led_cdev);
 
index e514d57a0419defecb8dcbbc8be4604aea1321da..aa983422aa970f1035201a1a4841b7a09d9acc3f 100644 (file)
@@ -207,7 +207,7 @@ comment "Disk-On-Chip Device Drivers"
 config MTD_DOCG3
        tristate "M-Systems Disk-On-Chip G3"
        select BCH
-       select BCH_CONST_PARAMS
+       select BCH_CONST_PARAMS if !MTD_NAND_BCH
        select BITREVERSE
        help
          This provides an MTD device driver for the M-Systems DiskOnChip
index 784c6e1a0391e92c90723e698d8bc148fe3e4916..fd5fe12d74613ecebddb88699dcae5e1862d3829 100644 (file)
@@ -221,7 +221,14 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev,
                info->mtd = info->subdev[0].mtd;
                ret = 0;
        } else if (info->num_subdev > 1) {
-               struct mtd_info *cdev[nr];
+               struct mtd_info **cdev;
+
+               cdev = kmalloc_array(nr, sizeof(*cdev), GFP_KERNEL);
+               if (!cdev) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
                /*
                 * We detected multiple devices.  Concatenate them together.
                 */
@@ -230,6 +237,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev,
 
                info->mtd = mtd_concat_create(cdev, info->num_subdev,
                                              plat->name);
+               kfree(cdev);
                if (info->mtd == NULL) {
                        ret = -ENXIO;
                        goto err;
index 05bd0779fe9bf7eae08acca31b7ba30f7592b9b1..71050a0b31dfe3b6bf273ff4c240e7cfe307080f 100644 (file)
@@ -590,7 +590,6 @@ retry:
 
 /**
  * panic_nand_wait - [GENERIC] wait until the command is done
- * @mtd: MTD device structure
  * @chip: NAND chip structure
  * @timeo: timeout
  *
index e24db817154ee73ad1fc0fd9586f4e294fc2886a..d846428ef038e6b76f84591f73d40e9a4d30db33 100644 (file)
@@ -996,7 +996,7 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 err_unmap:
        dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
 
-       return 0;
+       return ret;
 }
 
 static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
index 9407ca5f9443338d56a355fe0eadfa6641a429dc..3e54e31889c7b53bbba362a5bd497279dc91b128 100644 (file)
@@ -3250,12 +3250,14 @@ static int spi_nor_init_params(struct spi_nor *nor,
                memcpy(&sfdp_params, params, sizeof(sfdp_params));
                memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));
 
-               if (spi_nor_parse_sfdp(nor, &sfdp_params))
+               if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
+                       nor->addr_width = 0;
                        /* restore previous erase map */
                        memcpy(&nor->erase_map, &prev_map,
                               sizeof(nor->erase_map));
-               else
+               } else {
                        memcpy(params, &sfdp_params, sizeof(*params));
+               }
        }
 
        return 0;
index ffa37adb76817f454505b32d010056dfc4d20dc8..333387f1f1fe66490cda8904a7d6c7aeb2d15287 100644 (file)
@@ -3112,13 +3112,13 @@ static int bond_slave_netdev_event(unsigned long event,
        case NETDEV_CHANGE:
                /* For 802.3ad mode only:
                 * Getting invalid Speed/Duplex values here will put slave
-                * in weird state. So mark it as link-down for the time
+                * in weird state. So mark it as link-fail for the time
                 * being and let link-monitoring (miimon) set it right when
                 * correct speeds/duplex are available.
                 */
                if (bond_update_speed_duplex(slave) &&
                    BOND_MODE(bond) == BOND_MODE_8023AD)
-                       slave->link = BOND_LINK_DOWN;
+                       slave->link = BOND_LINK_FAIL;
 
                if (BOND_MODE(bond) == BOND_MODE_8023AD)
                        bond_3ad_adapter_speed_duplex_changed(slave);
index 49163570a63afad2e36777993a57319370d6c8b0..3b3f88ffab53cded04a2c1586727bf82472f43ad 100644 (file)
@@ -477,6 +477,34 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(can_put_echo_skb);
 
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       struct sk_buff *skb = priv->echo_skb[idx];
+       struct canfd_frame *cf;
+
+       if (idx >= priv->echo_skb_max) {
+               netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+                          __func__, idx, priv->echo_skb_max);
+               return NULL;
+       }
+
+       if (!skb) {
+               netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
+                          __func__, idx);
+               return NULL;
+       }
+
+       /* Using "struct canfd_frame::len" for the frame
+        * length is supported on both CAN and CANFD frames.
+        */
+       cf = (struct canfd_frame *)skb->data;
+       *len_ptr = cf->len;
+       priv->echo_skb[idx] = NULL;
+
+       return skb;
+}
+
 /*
  * Get the skb from the stack and loop it back locally
  *
@@ -486,22 +514,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
  */
 unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
 {
-       struct can_priv *priv = netdev_priv(dev);
-
-       BUG_ON(idx >= priv->echo_skb_max);
-
-       if (priv->echo_skb[idx]) {
-               struct sk_buff *skb = priv->echo_skb[idx];
-               struct can_frame *cf = (struct can_frame *)skb->data;
-               u8 dlc = cf->can_dlc;
+       struct sk_buff *skb;
+       u8 len;
 
-               netif_rx(priv->echo_skb[idx]);
-               priv->echo_skb[idx] = NULL;
+       skb = __can_get_echo_skb(dev, idx, &len);
+       if (!skb)
+               return 0;
 
-               return dlc;
-       }
+       netif_rx(skb);
 
-       return 0;
+       return len;
 }
 EXPORT_SYMBOL_GPL(can_get_echo_skb);
 
index 8e972ef0863769e88a2c9d6cec37408d66566292..75ce11395ee8196f0dc3ed8b1368e591047d5edd 100644 (file)
 
 /* FLEXCAN interrupt flag register (IFLAG) bits */
 /* Errata ERR005829 step7: Reserve first valid MB */
-#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO        8
-#define FLEXCAN_TX_MB_OFF_FIFO         9
+#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO                8
 #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP   0
-#define FLEXCAN_TX_MB_OFF_TIMESTAMP            1
-#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST      (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1)
-#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST       63
-#define FLEXCAN_IFLAG_MB(x)            BIT(x)
+#define FLEXCAN_TX_MB                          63
+#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST      (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
+#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST       (FLEXCAN_TX_MB - 1)
+#define FLEXCAN_IFLAG_MB(x)            BIT(x & 0x1f)
 #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
 #define FLEXCAN_IFLAG_RX_FIFO_WARN     BIT(6)
 #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE        BIT(5)
@@ -259,9 +258,7 @@ struct flexcan_priv {
        struct can_rx_offload offload;
 
        struct flexcan_regs __iomem *regs;
-       struct flexcan_mb __iomem *tx_mb;
        struct flexcan_mb __iomem *tx_mb_reserved;
-       u8 tx_mb_idx;
        u32 reg_ctrl_default;
        u32 reg_imask1_default;
        u32 reg_imask2_default;
@@ -515,6 +512,7 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
 static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        const struct flexcan_priv *priv = netdev_priv(dev);
+       struct flexcan_regs __iomem *regs = priv->regs;
        struct can_frame *cf = (struct can_frame *)skb->data;
        u32 can_id;
        u32 data;
@@ -537,17 +535,17 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
 
        if (cf->can_dlc > 0) {
                data = be32_to_cpup((__be32 *)&cf->data[0]);
-               priv->write(data, &priv->tx_mb->data[0]);
+               priv->write(data, &regs->mb[FLEXCAN_TX_MB].data[0]);
        }
        if (cf->can_dlc > 4) {
                data = be32_to_cpup((__be32 *)&cf->data[4]);
-               priv->write(data, &priv->tx_mb->data[1]);
+               priv->write(data, &regs->mb[FLEXCAN_TX_MB].data[1]);
        }
 
        can_put_echo_skb(skb, dev, 0);
 
-       priv->write(can_id, &priv->tx_mb->can_id);
-       priv->write(ctrl, &priv->tx_mb->can_ctrl);
+       priv->write(can_id, &regs->mb[FLEXCAN_TX_MB].can_id);
+       priv->write(ctrl, &regs->mb[FLEXCAN_TX_MB].can_ctrl);
 
        /* Errata ERR005829 step8:
         * Write twice INACTIVE(0x8) code to first MB.
@@ -563,9 +561,13 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
 static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
 {
        struct flexcan_priv *priv = netdev_priv(dev);
+       struct flexcan_regs __iomem *regs = priv->regs;
        struct sk_buff *skb;
        struct can_frame *cf;
        bool rx_errors = false, tx_errors = false;
+       u32 timestamp;
+
+       timestamp = priv->read(&regs->timer) << 16;
 
        skb = alloc_can_err_skb(dev, &cf);
        if (unlikely(!skb))
@@ -612,17 +614,21 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
        if (tx_errors)
                dev->stats.tx_errors++;
 
-       can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
+       can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
 }
 
 static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
 {
        struct flexcan_priv *priv = netdev_priv(dev);
+       struct flexcan_regs __iomem *regs = priv->regs;
        struct sk_buff *skb;
        struct can_frame *cf;
        enum can_state new_state, rx_state, tx_state;
        int flt;
        struct can_berr_counter bec;
+       u32 timestamp;
+
+       timestamp = priv->read(&regs->timer) << 16;
 
        flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
        if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
@@ -652,7 +658,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
        if (unlikely(new_state == CAN_STATE_BUS_OFF))
                can_bus_off(dev);
 
-       can_rx_offload_irq_queue_err_skb(&priv->offload, skb);
+       can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
 }
 
 static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
@@ -720,9 +726,14 @@ static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload,
                        priv->write(BIT(n - 32), &regs->iflag2);
        } else {
                priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
-               priv->read(&regs->timer);
        }
 
+       /* Read the Free Running Timer. It is optional but recommended
+        * to unlock Mailbox as soon as possible and make it available
+        * for reception.
+        */
+       priv->read(&regs->timer);
+
        return 1;
 }
 
@@ -732,9 +743,9 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
        struct flexcan_regs __iomem *regs = priv->regs;
        u32 iflag1, iflag2;
 
-       iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default;
-       iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default &
-               ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+       iflag2 = priv->read(&regs->iflag2) & priv->reg_imask2_default &
+               ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
+       iflag1 = priv->read(&regs->iflag1) & priv->reg_imask1_default;
 
        return (u64)iflag2 << 32 | iflag1;
 }
@@ -746,11 +757,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
        struct flexcan_priv *priv = netdev_priv(dev);
        struct flexcan_regs __iomem *regs = priv->regs;
        irqreturn_t handled = IRQ_NONE;
-       u32 reg_iflag1, reg_esr;
+       u32 reg_iflag2, reg_esr;
        enum can_state last_state = priv->can.state;
 
-       reg_iflag1 = priv->read(&regs->iflag1);
-
        /* reception interrupt */
        if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
                u64 reg_iflag;
@@ -764,6 +773,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
                                break;
                }
        } else {
+               u32 reg_iflag1;
+
+               reg_iflag1 = priv->read(&regs->iflag1);
                if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) {
                        handled = IRQ_HANDLED;
                        can_rx_offload_irq_offload_fifo(&priv->offload);
@@ -779,17 +791,22 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
                }
        }
 
+       reg_iflag2 = priv->read(&regs->iflag2);
+
        /* transmission complete interrupt */
-       if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
+       if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) {
+               u32 reg_ctrl = priv->read(&regs->mb[FLEXCAN_TX_MB].can_ctrl);
+
                handled = IRQ_HANDLED;
-               stats->tx_bytes += can_get_echo_skb(dev, 0);
+               stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload,
+                                                              0, reg_ctrl << 16);
                stats->tx_packets++;
                can_led_event(dev, CAN_LED_EVENT_TX);
 
                /* after sending a RTR frame MB is in RX mode */
                priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
-                           &priv->tx_mb->can_ctrl);
-               priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), &regs->iflag1);
+                           &regs->mb[FLEXCAN_TX_MB].can_ctrl);
+               priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), &regs->iflag2);
                netif_wake_queue(dev);
        }
 
@@ -931,15 +948,13 @@ static int flexcan_chip_start(struct net_device *dev)
        reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
        reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
                FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
-               FLEXCAN_MCR_IDAM_C;
+               FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB);
 
-       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
+       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
                reg_mcr &= ~FLEXCAN_MCR_FEN;
-               reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last);
-       } else {
-               reg_mcr |= FLEXCAN_MCR_FEN |
-                       FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
-       }
+       else
+               reg_mcr |= FLEXCAN_MCR_FEN;
+
        netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
        priv->write(reg_mcr, &regs->mcr);
 
@@ -982,16 +997,17 @@ static int flexcan_chip_start(struct net_device *dev)
                priv->write(reg_ctrl2, &regs->ctrl2);
        }
 
-       /* clear and invalidate all mailboxes first */
-       for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
-               priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
-                           &regs->mb[i].can_ctrl);
-       }
-
        if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
-               for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++)
+               for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) {
                        priv->write(FLEXCAN_MB_CODE_RX_EMPTY,
                                    &regs->mb[i].can_ctrl);
+               }
+       } else {
+               /* clear and invalidate unused mailboxes first */
+               for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) {
+                       priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
+                                   &regs->mb[i].can_ctrl);
+               }
        }
 
        /* Errata ERR005829: mark first TX mailbox as INACTIVE */
@@ -1000,7 +1016,7 @@ static int flexcan_chip_start(struct net_device *dev)
 
        /* mark TX mailbox as INACTIVE */
        priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
-                   &priv->tx_mb->can_ctrl);
+                   &regs->mb[FLEXCAN_TX_MB].can_ctrl);
 
        /* acceptance mask/acceptance code (accept everything) */
        priv->write(0x0, &regs->rxgmask);
@@ -1355,17 +1371,13 @@ static int flexcan_probe(struct platform_device *pdev)
        priv->devtype_data = devtype_data;
        priv->reg_xceiver = reg_xceiver;
 
-       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
-               priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP;
+       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)
                priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP];
-       } else {
-               priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO;
+       else
                priv->tx_mb_reserved = &regs->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO];
-       }
-       priv->tx_mb = &regs->mb[priv->tx_mb_idx];
 
-       priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
-       priv->reg_imask2_default = 0;
+       priv->reg_imask1_default = 0;
+       priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB);
 
        priv->offload.mailbox_read = flexcan_mailbox_read;
 
index 11662f479e760ba77f613c90bfc8026b005da3ea..771a4608373978c31b7011a45cf5659f543820c1 100644 (file)
@@ -24,6 +24,9 @@
 
 #define RCAR_CAN_DRV_NAME      "rcar_can"
 
+#define RCAR_SUPPORTED_CLOCKS  (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
+                                BIT(CLKR_CLKEXT))
+
 /* Mailbox configuration:
  * mailbox 60 - 63 - Rx FIFO mailboxes
  * mailbox 56 - 59 - Tx FIFO mailboxes
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev)
                goto fail_clk;
        }
 
-       if (clock_select >= ARRAY_SIZE(clock_names)) {
+       if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) {
                err = -EINVAL;
                dev_err(&pdev->dev, "invalid CAN clock selected\n");
                goto fail_clk;
index c7d05027a7a07ea34f862aa3595ebf6026a93897..2ce4fa8698c73b437051de20e29eaad70b263f64 100644 (file)
@@ -211,7 +211,54 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload)
 }
 EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo);
 
-int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb)
+int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
+                               struct sk_buff *skb, u32 timestamp)
+{
+       struct can_rx_offload_cb *cb;
+       unsigned long flags;
+
+       if (skb_queue_len(&offload->skb_queue) >
+           offload->skb_queue_len_max)
+               return -ENOMEM;
+
+       cb = can_rx_offload_get_cb(skb);
+       cb->timestamp = timestamp;
+
+       spin_lock_irqsave(&offload->skb_queue.lock, flags);
+       __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare);
+       spin_unlock_irqrestore(&offload->skb_queue.lock, flags);
+
+       can_rx_offload_schedule(offload);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted);
+
+unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
+                                        unsigned int idx, u32 timestamp)
+{
+       struct net_device *dev = offload->dev;
+       struct net_device_stats *stats = &dev->stats;
+       struct sk_buff *skb;
+       u8 len;
+       int err;
+
+       skb = __can_get_echo_skb(dev, idx, &len);
+       if (!skb)
+               return 0;
+
+       err = can_rx_offload_queue_sorted(offload, skb, timestamp);
+       if (err) {
+               stats->rx_errors++;
+               stats->tx_fifo_errors++;
+       }
+
+       return len;
+}
+EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb);
+
+int can_rx_offload_queue_tail(struct can_rx_offload *offload,
+                             struct sk_buff *skb)
 {
        if (skb_queue_len(&offload->skb_queue) >
            offload->skb_queue_len_max)
@@ -222,7 +269,7 @@ int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_b
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(can_rx_offload_irq_queue_err_skb);
+EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail);
 
 static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight)
 {
index 53e320c92a8be21e286ab4f7ada738fd223a08fa..ddaf46239e39e92337a4ed54ecb3feb1ab94cc59 100644 (file)
@@ -760,7 +760,7 @@ static int hi3110_open(struct net_device *net)
 {
        struct hi3110_priv *priv = netdev_priv(net);
        struct spi_device *spi = priv->spi;
-       unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_RISING;
+       unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH;
        int ret;
 
        ret = open_candev(net);
index b939a4c10b8409f5fe58e700204fe4e5183b23c0..c89c7d4900d75068badc7a7234c36b5b7345f675 100644 (file)
@@ -528,7 +528,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
                        context = &priv->tx_contexts[i];
 
                        context->echo_index = i;
-                       can_put_echo_skb(skb, netdev, context->echo_index);
                        ++priv->active_tx_contexts;
                        if (priv->active_tx_contexts >= (int)dev->max_tx_urbs)
                                netif_stop_queue(netdev);
@@ -553,7 +552,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
                dev_kfree_skb(skb);
                spin_lock_irqsave(&priv->tx_contexts_lock, flags);
 
-               can_free_echo_skb(netdev, context->echo_index);
                context->echo_index = dev->max_tx_urbs;
                --priv->active_tx_contexts;
                netif_wake_queue(netdev);
@@ -564,6 +562,8 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
 
        context->priv = priv;
 
+       can_put_echo_skb(skb, netdev, context->echo_index);
+
        usb_fill_bulk_urb(urb, dev->udev,
                          usb_sndbulkpipe(dev->udev,
                                          dev->bulk_out->bEndpointAddress),
index c084bae5ec0a4d936f6a7f121272d972903a8023..5fc0be564274375f3d5c579521a2d3b89ecd4a88 100644 (file)
@@ -1019,6 +1019,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
                                        new_state : CAN_STATE_ERROR_ACTIVE;
 
                        can_change_state(netdev, cf, tx_state, rx_state);
+
+                       if (priv->can.restart_ms &&
+                           old_state >= CAN_STATE_BUS_OFF &&
+                           new_state < CAN_STATE_BUS_OFF)
+                               cf->can_id |= CAN_ERR_RESTARTED;
                }
 
                if (new_state == CAN_STATE_BUS_OFF) {
@@ -1028,11 +1033,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
 
                        can_bus_off(netdev);
                }
-
-               if (priv->can.restart_ms &&
-                   old_state >= CAN_STATE_BUS_OFF &&
-                   new_state < CAN_STATE_BUS_OFF)
-                       cf->can_id |= CAN_ERR_RESTARTED;
        }
 
        if (!skb) {
index 0678a38b1af4588135f04074c56b37cfe6d09b70..f3d5bda012a107e430bca91bd09dd1d15be1bbf2 100644 (file)
 #include <linux/slab.h>
 #include <linux/usb.h>
 
-#include <linux/can.h>
-#include <linux/can/dev.h>
-#include <linux/can/error.h>
-
 #define UCAN_DRIVER_NAME "ucan"
 #define UCAN_MAX_RX_URBS 8
 /* the CAN controller needs a while to enable/disable the bus */
@@ -1575,11 +1571,8 @@ err_firmware_needs_update:
 /* disconnect the device */
 static void ucan_disconnect(struct usb_interface *intf)
 {
-       struct usb_device *udev;
        struct ucan_priv *up = usb_get_intfdata(intf);
 
-       udev = interface_to_usbdev(intf);
-
        usb_set_intfdata(intf, NULL);
 
        if (up) {
index 54e0ca6ed7308c511ce42bc6ea3dc6e65fb0662b..86b6464b4525c426e09d4d6a9f98bf9a0ee49111 100644 (file)
@@ -1117,11 +1117,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
        int i;
 
-       mutex_init(&dev->reg_mutex);
-       mutex_init(&dev->stats_mutex);
-       mutex_init(&dev->alu_mutex);
-       mutex_init(&dev->vlan_mutex);
-
        dev->ds->ops = &ksz_switch_ops;
 
        for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
@@ -1206,6 +1201,11 @@ int ksz_switch_register(struct ksz_device *dev)
        if (dev->pdata)
                dev->chip_id = dev->pdata->chip_id;
 
+       mutex_init(&dev->reg_mutex);
+       mutex_init(&dev->stats_mutex);
+       mutex_init(&dev->alu_mutex);
+       mutex_init(&dev->vlan_mutex);
+
        if (ksz_switch_detect(dev))
                return -EINVAL;
 
index d721ccf7d8bed8230fa5fbbac2ecfd5068680cac..38e399e0f30e16cd189cf48874f08e6289565101 100644 (file)
@@ -567,6 +567,8 @@ int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip)
        if (err)
                return err;
 
+       /* Keep the histogram mode bits */
+       val &= MV88E6XXX_G1_STATS_OP_HIST_RX_TX;
        val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL;
 
        err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val);
index 18956e7604a318d72de0ed52cf2a0da2e7602348..a70bb1bb90e7d89dc75f6f3dcc4f1455484057bc 100644 (file)
@@ -1848,6 +1848,8 @@ static void ena_down(struct ena_adapter *adapter)
                rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
                if (rc)
                        dev_err(&adapter->pdev->dev, "Device reset failed\n");
+               /* stop submitting admin commands on a device that was reset */
+               ena_com_set_admin_running_state(adapter->ena_dev, false);
        }
 
        ena_destroy_all_io_queues(adapter);
@@ -1914,6 +1916,9 @@ static int ena_close(struct net_device *netdev)
 
        netif_dbg(adapter, ifdown, netdev, "%s\n", __func__);
 
+       if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
+               return 0;
+
        if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
                ena_down(adapter);
 
@@ -2613,9 +2618,7 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
                ena_down(adapter);
 
        /* Stop the device from sending AENQ events (in case reset flag is set
-        *  and device is up, ena_close already reset the device
-        * In case the reset flag is set and the device is up, ena_down()
-        * already perform the reset, so it can be skipped.
+        *  and device is up, ena_down() already reset the device.
         */
        if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
                ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
@@ -2694,8 +2697,8 @@ err_device_destroy:
        ena_com_abort_admin_commands(ena_dev);
        ena_com_wait_for_abort_completion(ena_dev);
        ena_com_admin_destroy(ena_dev);
-       ena_com_mmio_reg_read_request_destroy(ena_dev);
        ena_com_dev_reset(ena_dev, ENA_REGS_RESET_DRIVER_INVALID_STATE);
+       ena_com_mmio_reg_read_request_destroy(ena_dev);
 err:
        clear_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
        clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
@@ -3452,6 +3455,8 @@ err_rss:
        ena_com_rss_destroy(ena_dev);
 err_free_msix:
        ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR);
+       /* stop submitting admin commands on a device that was reset */
+       ena_com_set_admin_running_state(ena_dev, false);
        ena_free_mgmnt_irq(adapter);
        ena_disable_msix(adapter);
 err_worker_destroy:
@@ -3498,18 +3503,12 @@ static void ena_remove(struct pci_dev *pdev)
 
        cancel_work_sync(&adapter->reset_task);
 
-       unregister_netdev(netdev);
-
-       /* If the device is running then we want to make sure the device will be
-        * reset to make sure no more events will be issued by the device.
-        */
-       if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
-               set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
-
        rtnl_lock();
        ena_destroy_device(adapter, true);
        rtnl_unlock();
 
+       unregister_netdev(netdev);
+
        free_netdev(netdev);
 
        ena_com_rss_destroy(ena_dev);
index 521873642339356fd2053d160ea6ed2230fe4c33..dc8b6173d8d8224a5485480dec81c4f6526d94f0 100644 (file)
@@ -45,7 +45,7 @@
 
 #define DRV_MODULE_VER_MAJOR   2
 #define DRV_MODULE_VER_MINOR   0
-#define DRV_MODULE_VER_SUBMINOR 1
+#define DRV_MODULE_VER_SUBMINOR 2
 
 #define DRV_MODULE_NAME                "ena"
 #ifndef DRV_MODULE_VERSION
index 6a633c70f603d7b70c3819b20f73d4b4f1405e64..99ef1daaa4d8027636cc5b0f7f542b7961f6764e 100644 (file)
@@ -407,13 +407,13 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
                                      struct ethtool_pauseparam *pause)
 {
        struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       u32 fc = aq_nic->aq_nic_cfg.flow_control;
 
        pause->autoneg = 0;
 
-       if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
-               pause->rx_pause = 1;
-       if (aq_nic->aq_hw->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
-               pause->tx_pause = 1;
+       pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
+       pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
+
 }
 
 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
index e8689241204e9086fdb2c8750402ff7467e129ac..a1e70da358ca6910f02a82a6ef2e3949f60ee4fe 100644 (file)
@@ -204,6 +204,10 @@ struct aq_hw_ops {
 
        int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
 
+       int (*hw_set_offload)(struct aq_hw_s *self,
+                             struct aq_nic_cfg_s *aq_nic_cfg);
+
+       int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
 };
 
 struct aq_fw_ops {
@@ -226,6 +230,8 @@ struct aq_fw_ops {
 
        int (*update_stats)(struct aq_hw_s *self);
 
+       u32 (*get_flow_control)(struct aq_hw_s *self, u32 *fcmode);
+
        int (*set_flow_control)(struct aq_hw_s *self);
 
        int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
index e3ae29e523f0e26738b0ab80a2f3ac431083d13b..7c07eef275eb8498ade72b676dc2eeda8532185e 100644 (file)
@@ -99,8 +99,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
        struct aq_nic_s *aq_nic = netdev_priv(ndev);
        struct aq_nic_cfg_s *aq_cfg = aq_nic_get_cfg(aq_nic);
        bool is_lro = false;
+       int err = 0;
+
+       aq_cfg->features = features;
 
-       if (aq_cfg->hw_features & NETIF_F_LRO) {
+       if (aq_cfg->aq_hw_caps->hw_features & NETIF_F_LRO) {
                is_lro = features & NETIF_F_LRO;
 
                if (aq_cfg->is_lro != is_lro) {
@@ -112,8 +115,11 @@ static int aq_ndev_set_features(struct net_device *ndev,
                        }
                }
        }
+       if ((aq_nic->ndev->features ^ features) & NETIF_F_RXCSUM)
+               err = aq_nic->aq_hw_ops->hw_set_offload(aq_nic->aq_hw,
+                                                       aq_cfg);
 
-       return 0;
+       return err;
 }
 
 static int aq_ndev_set_mac_address(struct net_device *ndev, void *addr)
index 5fed244466871cd69b764ffdfcf55d92a9043763..7abdc0952425921330d3639c99824fe5ae7c0e00 100644 (file)
@@ -118,12 +118,13 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
        }
 
        cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
-       cfg->hw_features = cfg->aq_hw_caps->hw_features;
+       cfg->features = cfg->aq_hw_caps->hw_features;
 }
 
 static int aq_nic_update_link_status(struct aq_nic_s *self)
 {
        int err = self->aq_fw_ops->update_link_status(self->aq_hw);
+       u32 fc = 0;
 
        if (err)
                return err;
@@ -133,6 +134,15 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
                        AQ_CFG_DRV_NAME, self->link_status.mbps,
                        self->aq_hw->aq_link_status.mbps);
                aq_nic_update_interrupt_moderation_settings(self);
+
+               /* Driver has to update flow control settings on RX block
+                * on any link event.
+                * We should query FW whether it negotiated FC.
+                */
+               if (self->aq_fw_ops->get_flow_control)
+                       self->aq_fw_ops->get_flow_control(self->aq_hw, &fc);
+               if (self->aq_hw_ops->hw_set_fc)
+                       self->aq_hw_ops->hw_set_fc(self->aq_hw, fc, 0);
        }
 
        self->link_status = self->aq_hw->aq_link_status;
@@ -590,7 +600,7 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
                }
        }
 
-       if (i > 0 && i < AQ_HW_MULTICAST_ADDRESS_MAX) {
+       if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
                packet_filter |= IFF_MULTICAST;
                self->mc_list.count = i;
                self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
@@ -772,7 +782,9 @@ void aq_nic_get_link_ksettings(struct aq_nic_s *self,
                ethtool_link_ksettings_add_link_mode(cmd, advertising,
                                                     Pause);
 
-       if (self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX)
+       /* Asym is when either RX or TX, but not both */
+       if (!!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_TX) ^
+           !!(self->aq_nic_cfg.flow_control & AQ_NIC_FC_RX))
                ethtool_link_ksettings_add_link_mode(cmd, advertising,
                                                     Asym_Pause);
 
index c1582f4e8e1b503f7f5baf60dcd1408e99d19620..44ec47a3d60a57bee0c9b0a62907eb1988ee5a5b 100644 (file)
@@ -23,7 +23,7 @@ struct aq_vec_s;
 
 struct aq_nic_cfg_s {
        const struct aq_hw_caps_s *aq_hw_caps;
-       u64 hw_features;
+       u64 features;
        u32 rxds;               /* rx ring size, descriptors # */
        u32 txds;               /* tx ring size, descriptors # */
        u32 vecs;               /* vecs==allocated irqs */
index 3db91446cc67717b548333e4bd3b95db8281c152..74550ccc7a20ff8437463384e906b718027dc6ef 100644 (file)
@@ -172,6 +172,27 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
        return !!budget;
 }
 
+static void aq_rx_checksum(struct aq_ring_s *self,
+                          struct aq_ring_buff_s *buff,
+                          struct sk_buff *skb)
+{
+       if (!(self->aq_nic->ndev->features & NETIF_F_RXCSUM))
+               return;
+
+       if (unlikely(buff->is_cso_err)) {
+               ++self->stats.rx.errors;
+               skb->ip_summed = CHECKSUM_NONE;
+               return;
+       }
+       if (buff->is_ip_cso) {
+               __skb_incr_checksum_unnecessary(skb);
+               if (buff->is_udp_cso || buff->is_tcp_cso)
+                       __skb_incr_checksum_unnecessary(skb);
+       } else {
+               skb->ip_summed = CHECKSUM_NONE;
+       }
+}
+
 #define AQ_SKB_ALIGN SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
 int aq_ring_rx_clean(struct aq_ring_s *self,
                     struct napi_struct *napi,
@@ -267,18 +288,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
                }
 
                skb->protocol = eth_type_trans(skb, ndev);
-               if (unlikely(buff->is_cso_err)) {
-                       ++self->stats.rx.errors;
-                       skb->ip_summed = CHECKSUM_NONE;
-               } else {
-                       if (buff->is_ip_cso) {
-                               __skb_incr_checksum_unnecessary(skb);
-                               if (buff->is_udp_cso || buff->is_tcp_cso)
-                                       __skb_incr_checksum_unnecessary(skb);
-                       } else {
-                               skb->ip_summed = CHECKSUM_NONE;
-                       }
-               }
+
+               aq_rx_checksum(self, buff, skb);
 
                skb_set_hash(skb, buff->rss_hash,
                             buff->is_hash_l4 ? PKT_HASH_TYPE_L4 :
index 76d25d594a0f62fedf507e50b58701933b1872c2..f02592f43fe36f3af460672746ade204d1f574fb 100644 (file)
@@ -100,12 +100,17 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
        return err;
 }
 
+static int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
+{
+       hw_atl_rpb_rx_xoff_en_per_tc_set(self, !!(fc & AQ_NIC_FC_RX), tc);
+       return 0;
+}
+
 static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
 {
        u32 tc = 0U;
        u32 buff_size = 0U;
        unsigned int i_priority = 0U;
-       bool is_rx_flow_control = false;
 
        /* TPS Descriptor rate init */
        hw_atl_tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
@@ -138,7 +143,6 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
 
        /* QoS Rx buf size per TC */
        tc = 0;
-       is_rx_flow_control = (AQ_NIC_FC_RX & self->aq_nic_cfg->flow_control);
        buff_size = HW_ATL_B0_RXBUF_MAX;
 
        hw_atl_rpb_rx_pkt_buff_size_per_tc_set(self, buff_size, tc);
@@ -150,7 +154,8 @@ static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
                                                   (buff_size *
                                                   (1024U / 32U) * 50U) /
                                                   100U, tc);
-       hw_atl_rpb_rx_xoff_en_per_tc_set(self, is_rx_flow_control ? 1U : 0U, tc);
+
+       hw_atl_b0_set_fc(self, self->aq_nic_cfg->flow_control, tc);
 
        /* QoS 802.1p priority -> TC mapping */
        for (i_priority = 8U; i_priority--;)
@@ -229,8 +234,10 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
        hw_atl_tpo_tcp_udp_crc_offload_en_set(self, 1);
 
        /* RX checksums offloads*/
-       hw_atl_rpo_ipv4header_crc_offload_en_set(self, 1);
-       hw_atl_rpo_tcp_udp_crc_offload_en_set(self, 1);
+       hw_atl_rpo_ipv4header_crc_offload_en_set(self, !!(aq_nic_cfg->features &
+                                                NETIF_F_RXCSUM));
+       hw_atl_rpo_tcp_udp_crc_offload_en_set(self, !!(aq_nic_cfg->features &
+                                             NETIF_F_RXCSUM));
 
        /* LSO offloads*/
        hw_atl_tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
@@ -655,9 +662,9 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
                struct hw_atl_rxd_wb_s *rxd_wb = (struct hw_atl_rxd_wb_s *)
                        &ring->dx_ring[ring->hw_head * HW_ATL_B0_RXD_SIZE];
 
-               unsigned int is_err = 1U;
                unsigned int is_rx_check_sum_enabled = 0U;
                unsigned int pkt_type = 0U;
+               u8 rx_stat = 0U;
 
                if (!(rxd_wb->status & 0x1U)) { /* RxD is not done */
                        break;
@@ -665,35 +672,35 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
 
                buff = &ring->buff_ring[ring->hw_head];
 
-               is_err = (0x0000003CU & rxd_wb->status);
+               rx_stat = (0x0000003CU & rxd_wb->status) >> 2;
 
                is_rx_check_sum_enabled = (rxd_wb->type) & (0x3U << 19);
-               is_err &= ~0x20U; /* exclude validity bit */
 
                pkt_type = 0xFFU & (rxd_wb->type >> 4);
 
-               if (is_rx_check_sum_enabled) {
-                       if (0x0U == (pkt_type & 0x3U))
-                               buff->is_ip_cso = (is_err & 0x08U) ? 0U : 1U;
+               if (is_rx_check_sum_enabled & BIT(0) &&
+                   (0x0U == (pkt_type & 0x3U)))
+                       buff->is_ip_cso = (rx_stat & BIT(1)) ? 0U : 1U;
 
+               if (is_rx_check_sum_enabled & BIT(1)) {
                        if (0x4U == (pkt_type & 0x1CU))
-                               buff->is_udp_cso = buff->is_cso_err ? 0U : 1U;
+                               buff->is_udp_cso = (rx_stat & BIT(2)) ? 0U :
+                                                  !!(rx_stat & BIT(3));
                        else if (0x0U == (pkt_type & 0x1CU))
-                               buff->is_tcp_cso = buff->is_cso_err ? 0U : 1U;
-
-                       /* Checksum offload workaround for small packets */
-                       if (rxd_wb->pkt_len <= 60) {
-                               buff->is_ip_cso = 0U;
-                               buff->is_cso_err = 0U;
-                       }
+                               buff->is_tcp_cso = (rx_stat & BIT(2)) ? 0U :
+                                                  !!(rx_stat & BIT(3));
+               }
+               buff->is_cso_err = !!(rx_stat & 0x6);
+               /* Checksum offload workaround for small packets */
+               if (unlikely(rxd_wb->pkt_len <= 60)) {
+                       buff->is_ip_cso = 0U;
+                       buff->is_cso_err = 0U;
                }
-
-               is_err &= ~0x18U;
 
                dma_unmap_page(ndev, buff->pa, buff->len, DMA_FROM_DEVICE);
 
-               if (is_err || rxd_wb->type & 0x1000U) {
-                       /* status error or DMA error */
+               if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) {
+                       /* MAC error or DMA error */
                        buff->is_error = 1U;
                } else {
                        if (self->aq_nic_cfg->is_rss) {
@@ -915,6 +922,12 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
 static int hw_atl_b0_hw_stop(struct aq_hw_s *self)
 {
        hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK);
+
+       /* Invalidate Descriptor Cache to prevent writing to the cached
+        * descriptors and to the data pointer of those descriptors
+        */
+       hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1);
+
        return aq_hw_err_from_flags(self);
 }
 
@@ -963,4 +976,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
        .hw_get_regs                 = hw_atl_utils_hw_get_regs,
        .hw_get_hw_stats             = hw_atl_utils_get_hw_stats,
        .hw_get_fw_version           = hw_atl_utils_get_fw_version,
+       .hw_set_offload              = hw_atl_b0_hw_offload_set,
+       .hw_set_fc                   = hw_atl_b0_set_fc,
 };
index be0a3a90dfad6ac157ba81ab238ca43631e6df82..5502ec5f0f6993502cd8d4e880032a9606da5c34 100644 (file)
@@ -619,6 +619,14 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode
                            HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode);
 }
 
+void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init)
+{
+       aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR,
+                           HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK,
+                           HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT,
+                           init);
+}
+
 void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
                                            u32 rx_pkt_buff_size_per_tc, u32 buffer)
 {
index 7056c7342afcf2bf426a2e261cacd79b405c75a2..41f239928c157f121b74f086c35c86457f2a3aba 100644 (file)
@@ -325,6 +325,9 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
                                            u32 rx_pkt_buff_size_per_tc,
                                            u32 buffer);
 
+/* set rdm rx dma descriptor cache init */
+void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init);
+
 /* set rx xoff enable (per tc) */
 void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc,
                                      u32 buffer);
index 716674a9b729efc741ef4b434a20dd9dbd415b88..a715fa317b1c822781b4a0422033816b5684e7e3 100644 (file)
 /* default value of bitfield desc{d}_reset */
 #define HW_ATL_RDM_DESCDRESET_DEFAULT 0x0
 
+/* rdm_desc_init_i bitfield definitions
+ * preprocessor definitions for the bitfield rdm_desc_init_i.
+ * port="pif_rdm_desc_init_i"
+ */
+
+/* register address for bitfield rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR 0x00005a00
+/* bitmask for bitfield rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK 0xffffffff
+/* inverted bitmask for bitfield rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSKN 0x00000000
+/* lower bit position of bitfield  rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT 0
+/* width of bitfield rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_WIDTH 32
+/* default value of bitfield rdm_desc_init_i */
+#define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0
+
 /* rx int_desc_wrb_en bitfield definitions
  * preprocessor definitions for the bitfield "int_desc_wrb_en".
  * port="pif_rdm_int_desc_wrb_en_i"
index 096ca5730887c1d4a47861c3a6a456cd240b2bd1..7de3220d9cab7bf99109145c1ccef4a3ea898d87 100644 (file)
@@ -30,6 +30,8 @@
 #define HW_ATL_FW2X_MPI_STATE_ADDR     0x370
 #define HW_ATL_FW2X_MPI_STATE2_ADDR    0x374
 
+#define HW_ATL_FW2X_CAP_PAUSE            BIT(CAPS_HI_PAUSE)
+#define HW_ATL_FW2X_CAP_ASYM_PAUSE       BIT(CAPS_HI_ASYMMETRIC_PAUSE)
 #define HW_ATL_FW2X_CAP_SLEEP_PROXY      BIT(CAPS_HI_SLEEP_PROXY)
 #define HW_ATL_FW2X_CAP_WOL              BIT(CAPS_HI_WOL)
 
@@ -451,6 +453,24 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
        return 0;
 }
 
+static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
+{
+       u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
+
+       if (mpi_state & HW_ATL_FW2X_CAP_PAUSE)
+               if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
+                       *fcmode = AQ_NIC_FC_RX;
+               else
+                       *fcmode = AQ_NIC_FC_RX | AQ_NIC_FC_TX;
+       else
+               if (mpi_state & HW_ATL_FW2X_CAP_ASYM_PAUSE)
+                       *fcmode = AQ_NIC_FC_TX;
+               else
+                       *fcmode = 0;
+
+       return 0;
+}
+
 const struct aq_fw_ops aq_fw_2x_ops = {
        .init = aq_fw2x_init,
        .deinit = aq_fw2x_deinit,
@@ -465,4 +485,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
        .set_eee_rate = aq_fw2x_set_eee_rate,
        .get_eee_rate = aq_fw2x_get_eee_rate,
        .set_flow_control = aq_fw2x_set_flow_control,
+       .get_flow_control = aq_fw2x_get_flow_control
 };
index 78c5de467426f1e4276cebe8ee81cc0091d4c6fa..9d0e74f6b089df4c304ab49c2749d8bbba47c2e7 100644 (file)
@@ -140,6 +140,5 @@ struct alx_priv {
 };
 
 extern const struct ethtool_ops alx_ethtool_ops;
-extern const char alx_drv_name[];
 
 #endif
index 7968c644ad8617fef2fec1360e869a622c525a02..c131cfc1b79df5a62e048bbf1d15d070e7c0fced 100644 (file)
@@ -49,7 +49,7 @@
 #include "hw.h"
 #include "reg.h"
 
-const char alx_drv_name[] = "alx";
+static const char alx_drv_name[] = "alx";
 
 static void alx_free_txbuf(struct alx_tx_queue *txq, int entry)
 {
index 4122553e224b294d4eff1828201e467fcc5a60b9..0e2d99c737e35192b90d0bf3ce541ef2d6ecd4d1 100644 (file)
@@ -1902,9 +1902,6 @@ static void bcm_sysport_netif_start(struct net_device *dev)
                intrl2_1_mask_clear(priv, 0xffffffff);
        else
                intrl2_0_mask_clear(priv, INTRL2_0_TDMA_MBDONE_MASK);
-
-       /* Last call before we start the real business */
-       netif_tx_start_all_queues(dev);
 }
 
 static void rbuf_init(struct bcm_sysport_priv *priv)
@@ -2048,6 +2045,8 @@ static int bcm_sysport_open(struct net_device *dev)
 
        bcm_sysport_netif_start(dev);
 
+       netif_tx_start_all_queues(dev);
+
        return 0;
 
 out_clear_rx_int:
@@ -2071,7 +2070,7 @@ static void bcm_sysport_netif_stop(struct net_device *dev)
        struct bcm_sysport_priv *priv = netdev_priv(dev);
 
        /* stop all software from updating hardware */
-       netif_tx_stop_all_queues(dev);
+       netif_tx_disable(dev);
        napi_disable(&priv->napi);
        cancel_work_sync(&priv->dim.dim.work);
        phy_stop(dev->phydev);
@@ -2658,12 +2657,12 @@ static int __maybe_unused bcm_sysport_suspend(struct device *d)
        if (!netif_running(dev))
                return 0;
 
+       netif_device_detach(dev);
+
        bcm_sysport_netif_stop(dev);
 
        phy_suspend(dev->phydev);
 
-       netif_device_detach(dev);
-
        /* Disable UniMAC RX */
        umac_enable_set(priv, CMD_RX_EN, 0);
 
@@ -2746,8 +2745,6 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
                goto out_free_rx_ring;
        }
 
-       netif_device_attach(dev);
-
        /* RX pipe enable */
        topctrl_writel(priv, 0, RX_FLUSH_CNTL);
 
@@ -2788,6 +2785,8 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
 
        bcm_sysport_netif_start(dev);
 
+       netif_device_attach(dev);
+
        return 0;
 
 out_free_rx_ring:
index be1506169076f0a89f6a621d01dce81afe720ba7..0de487a8f0eb22d7b033c4f9751b68cf2454286e 100644 (file)
@@ -2191,6 +2191,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
 #define PMF_DMAE_C(bp)                 (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
                                         E1HVN_MAX)
 
+/* Following is the DMAE channel number allocation for the clients.
+ *   MFW: OCBB/OCSD implementations use DMAE channels 14/15 respectively.
+ *   Driver: 0-3 and 8-11 (for PF dmae operations)
+ *           4 and 12 (for stats requests)
+ */
+#define BNX2X_FW_DMAE_C                 13 /* Channel for FW DMAE operations */
+
 /* PCIE link and speed */
 #define PCICFG_LINK_WIDTH              0x1f00000
 #define PCICFG_LINK_WIDTH_SHIFT                20
index 3f4d2c8da21a3a848b4149758883333522b6f77a..a9eaaf3e73a4c41f6dc6808f723a400750fd1ba1 100644 (file)
@@ -6149,6 +6149,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,
        rdata->sd_vlan_tag      = cpu_to_le16(start_params->sd_vlan_tag);
        rdata->path_id          = BP_PATH(bp);
        rdata->network_cos_mode = start_params->network_cos_mode;
+       rdata->dmae_cmd_id      = BNX2X_FW_DMAE_C;
 
        rdata->vxlan_dst_port   = cpu_to_le16(start_params->vxlan_dst_port);
        rdata->geneve_dst_port  = cpu_to_le16(start_params->geneve_dst_port);
index dd85d790f638939e552042c642abceb108d61fb3..d4c30011752992ccf6d0f48d6f119e6950041e19 100644 (file)
@@ -1675,7 +1675,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
        } else {
                if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) {
                        if (dev->features & NETIF_F_RXCSUM)
-                               cpr->rx_l4_csum_errors++;
+                               bnapi->cp_ring.rx_l4_csum_errors++;
                }
        }
 
@@ -8714,6 +8714,26 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
        return rc;
 }
 
+static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type,
+                                      u32 ring_id, u32 *prod, u32 *cons)
+{
+       struct hwrm_dbg_ring_info_get_output *resp = bp->hwrm_cmd_resp_addr;
+       struct hwrm_dbg_ring_info_get_input req = {0};
+       int rc;
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_RING_INFO_GET, -1, -1);
+       req.ring_type = ring_type;
+       req.fw_ring_id = cpu_to_le32(ring_id);
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (!rc) {
+               *prod = le32_to_cpu(resp->producer_index);
+               *cons = le32_to_cpu(resp->consumer_index);
+       }
+       mutex_unlock(&bp->hwrm_cmd_lock);
+       return rc;
+}
+
 static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi)
 {
        struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
@@ -8821,6 +8841,11 @@ static void bnxt_timer(struct timer_list *t)
                        bnxt_queue_sp_work(bp);
                }
        }
+
+       if ((bp->flags & BNXT_FLAG_CHIP_P5) && netif_carrier_ok(dev)) {
+               set_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event);
+               bnxt_queue_sp_work(bp);
+       }
 bnxt_restart_timer:
        mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
@@ -8851,6 +8876,44 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
        bnxt_rtnl_unlock_sp(bp);
 }
 
+static void bnxt_chk_missed_irq(struct bnxt *bp)
+{
+       int i;
+
+       if (!(bp->flags & BNXT_FLAG_CHIP_P5))
+               return;
+
+       for (i = 0; i < bp->cp_nr_rings; i++) {
+               struct bnxt_napi *bnapi = bp->bnapi[i];
+               struct bnxt_cp_ring_info *cpr;
+               u32 fw_ring_id;
+               int j;
+
+               if (!bnapi)
+                       continue;
+
+               cpr = &bnapi->cp_ring;
+               for (j = 0; j < 2; j++) {
+                       struct bnxt_cp_ring_info *cpr2 = cpr->cp_ring_arr[j];
+                       u32 val[2];
+
+                       if (!cpr2 || cpr2->has_more_work ||
+                           !bnxt_has_work(bp, cpr2))
+                               continue;
+
+                       if (cpr2->cp_raw_cons != cpr2->last_cp_raw_cons) {
+                               cpr2->last_cp_raw_cons = cpr2->cp_raw_cons;
+                               continue;
+                       }
+                       fw_ring_id = cpr2->cp_ring_struct.fw_ring_id;
+                       bnxt_dbg_hwrm_ring_info_get(bp,
+                               DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL,
+                               fw_ring_id, &val[0], &val[1]);
+                       cpr->missed_irqs++;
+               }
+       }
+}
+
 static void bnxt_cfg_ntp_filters(struct bnxt *);
 
 static void bnxt_sp_task(struct work_struct *work)
@@ -8930,6 +8993,9 @@ static void bnxt_sp_task(struct work_struct *work)
        if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event))
                bnxt_tc_flow_stats_work(bp);
 
+       if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event))
+               bnxt_chk_missed_irq(bp);
+
        /* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
         * must be the last functions to be called before exiting.
         */
@@ -10087,6 +10153,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        bnxt_hwrm_func_qcfg(bp);
+       bnxt_hwrm_vnic_qcaps(bp);
        bnxt_hwrm_port_led_qcaps(bp);
        bnxt_ethtool_init(bp);
        bnxt_dcb_init(bp);
@@ -10120,7 +10187,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                                    VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
        }
 
-       bnxt_hwrm_vnic_qcaps(bp);
        if (bnxt_rfs_supported(bp)) {
                dev->hw_features |= NETIF_F_NTUPLE;
                if (bnxt_rfs_capable(bp)) {
index 498b373c992d372504278eb666d79f0ad83a9cd6..9e99d4ab3e062fe14fee7cd78b8626032fa5c705 100644 (file)
@@ -798,6 +798,8 @@ struct bnxt_cp_ring_info {
        u8                      had_work_done:1;
        u8                      has_more_work:1;
 
+       u32                     last_cp_raw_cons;
+
        struct bnxt_coal        rx_ring_coal;
        u64                     rx_packets;
        u64                     rx_bytes;
@@ -816,6 +818,7 @@ struct bnxt_cp_ring_info {
        dma_addr_t              hw_stats_map;
        u32                     hw_stats_ctx_id;
        u64                     rx_l4_csum_errors;
+       u64                     missed_irqs;
 
        struct bnxt_ring_struct cp_ring_struct;
 
@@ -1527,6 +1530,7 @@ struct bnxt {
 #define BNXT_LINK_SPEED_CHNG_SP_EVENT  14
 #define BNXT_FLOW_STATS_SP_EVENT       15
 #define BNXT_UPDATE_PHY_SP_EVENT       16
+#define BNXT_RING_COAL_NOW_SP_EVENT    17
 
        struct bnxt_hw_resc     hw_resc;
        struct bnxt_pf_info     pf;
index 48078564f0258cf2d862bd6d57c9d0da79d072a1..6cc69a58478a5ffaad8b7a0511d68e36a93657f3 100644 (file)
@@ -137,7 +137,7 @@ reset_coalesce:
        return rc;
 }
 
-#define BNXT_NUM_STATS 21
+#define BNXT_NUM_STATS 22
 
 #define BNXT_RX_STATS_ENTRY(counter)   \
        { BNXT_RX_STATS_OFFSET(counter), __stringify(counter) }
@@ -384,6 +384,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
                for (k = 0; k < stat_fields; j++, k++)
                        buf[j] = le64_to_cpu(hw_stats[k]);
                buf[j++] = cpr->rx_l4_csum_errors;
+               buf[j++] = cpr->missed_irqs;
 
                bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter +=
                        le64_to_cpu(cpr->hw_stats->rx_discard_pkts);
@@ -468,6 +469,8 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
                        buf += ETH_GSTRING_LEN;
                        sprintf(buf, "[%d]: rx_l4_csum_errors", i);
                        buf += ETH_GSTRING_LEN;
+                       sprintf(buf, "[%d]: missed_irqs", i);
+                       buf += ETH_GSTRING_LEN;
                }
                for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) {
                        strcpy(buf, bnxt_sw_func_stats[i].string);
@@ -2942,8 +2945,8 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record,
        record->asic_state = 0;
        strlcpy(record->system_name, utsname()->nodename,
                sizeof(record->system_name));
-       record->year = cpu_to_le16(tm.tm_year);
-       record->month = cpu_to_le16(tm.tm_mon);
+       record->year = cpu_to_le16(tm.tm_year + 1900);
+       record->month = cpu_to_le16(tm.tm_mon + 1);
        record->day = cpu_to_le16(tm.tm_mday);
        record->hour = cpu_to_le16(tm.tm_hour);
        record->minute = cpu_to_le16(tm.tm_min);
index beee61292d5e522bae0842e5e76253eeb4e1d1f4..b59b382d34f94277a9a33e52223fda8ab7f19af3 100644 (file)
@@ -43,6 +43,9 @@ static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id,
        if (ulp_id == BNXT_ROCE_ULP) {
                unsigned int max_stat_ctxs;
 
+               if (bp->flags & BNXT_FLAG_CHIP_P5)
+                       return -EOPNOTSUPP;
+
                max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp);
                if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS ||
                    bp->num_stat_ctxs == max_stat_ctxs)
index 20c1681bb1afeea35e23f20242abc0fe34fd1304..2d6f090bf6440cc7253fe4f0764b10bde618ff73 100644 (file)
@@ -2855,7 +2855,6 @@ static void bcmgenet_netif_start(struct net_device *dev)
 
        umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
 
-       netif_tx_start_all_queues(dev);
        bcmgenet_enable_tx_napi(priv);
 
        /* Monitor link interrupts now */
@@ -2937,6 +2936,8 @@ static int bcmgenet_open(struct net_device *dev)
 
        bcmgenet_netif_start(dev);
 
+       netif_tx_start_all_queues(dev);
+
        return 0;
 
 err_irq1:
@@ -2958,7 +2959,7 @@ static void bcmgenet_netif_stop(struct net_device *dev)
        struct bcmgenet_priv *priv = netdev_priv(dev);
 
        bcmgenet_disable_tx_napi(priv);
-       netif_tx_stop_all_queues(dev);
+       netif_tx_disable(dev);
 
        /* Disable MAC receive */
        umac_enable_set(priv, CMD_RX_EN, false);
@@ -3620,13 +3621,13 @@ static int bcmgenet_suspend(struct device *d)
        if (!netif_running(dev))
                return 0;
 
+       netif_device_detach(dev);
+
        bcmgenet_netif_stop(dev);
 
        if (!device_may_wakeup(d))
                phy_suspend(dev->phydev);
 
-       netif_device_detach(dev);
-
        /* Prepare the device for Wake-on-LAN and switch to the slow clock */
        if (device_may_wakeup(d) && priv->wolopts) {
                ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
@@ -3700,8 +3701,6 @@ static int bcmgenet_resume(struct device *d)
        /* Always enable ring 16 - descriptor ring */
        bcmgenet_enable_dma(priv, dma_ctrl);
 
-       netif_device_attach(dev);
-
        if (!device_may_wakeup(d))
                phy_resume(dev->phydev);
 
@@ -3710,6 +3709,8 @@ static int bcmgenet_resume(struct device *d)
 
        bcmgenet_netif_start(dev);
 
+       netif_device_attach(dev);
+
        return 0;
 
 out_clk_disable:
index 75c1c5ed23878441664d2c7db867b67ee8ba21aa..e2cdfa75673fd58cf6dbacd1e67d7a05dd4b33c8 100644 (file)
@@ -67,7 +67,6 @@ config CHELSIO_T3
 config CHELSIO_T4
        tristate "Chelsio Communications T4/T5/T6 Ethernet support"
        depends on PCI && (IPV6 || IPV6=n)
-       depends on THERMAL || !THERMAL
        select FW_LOADER
        select MDIO
        select ZLIB_DEFLATE
index 78e5d17a1d5fb2306f104ce1bf1c4d02c42003ed..91d8a885deba9b8ea82125c3f0f9009fae9a3f91 100644 (file)
@@ -12,6 +12,4 @@ cxgb4-objs := cxgb4_main.o l2t.o smt.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o
 cxgb4-$(CONFIG_CHELSIO_T4_DCB) +=  cxgb4_dcb.o
 cxgb4-$(CONFIG_CHELSIO_T4_FCOE) +=  cxgb4_fcoe.o
 cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o
-ifdef CONFIG_THERMAL
-cxgb4-objs += cxgb4_thermal.o
-endif
+cxgb4-$(CONFIG_THERMAL) += cxgb4_thermal.o
index 05a46926016a5e2d53bc57b0c9c5ca19f5484f29..d49db46254cd7d528f6f181e8237277069c8a916 100644 (file)
@@ -5863,7 +5863,7 @@ fw_attach_fail:
        if (!is_t4(adapter->params.chip))
                cxgb4_ptp_init(adapter);
 
-       if (IS_ENABLED(CONFIG_THERMAL) &&
+       if (IS_REACHABLE(CONFIG_THERMAL) &&
            !is_t4(adapter->params.chip) && (adapter->flags & FW_OK))
                cxgb4_thermal_init(adapter);
 
@@ -5932,7 +5932,7 @@ static void remove_one(struct pci_dev *pdev)
 
                if (!is_t4(adapter->params.chip))
                        cxgb4_ptp_stop(adapter);
-               if (IS_ENABLED(CONFIG_THERMAL))
+               if (IS_REACHABLE(CONFIG_THERMAL))
                        cxgb4_thermal_remove(adapter);
 
                /* If we allocated filters, free up state associated with any
index 3f96aa30068ec3dcf991bec4ed022b3e68d013e7..20fcf0d1c2ce5f8ec986928019aefbd209088731 100644 (file)
@@ -3760,7 +3760,8 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
        /* Hardware table is only clear when pf resets */
        if (!(handle->flags & HNAE3_SUPPORT_VF)) {
                ret = hns3_restore_vlan(netdev);
-               return ret;
+               if (ret)
+                       return ret;
        }
 
        ret = hns3_restore_fd_rules(netdev);
index aa5cb9834d73a807dd18661c10069b7c929cc6d6..494e562fe8c7e9f2322b9659b8e60ec3abce26f0 100644 (file)
@@ -1168,14 +1168,14 @@ static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
  */
 static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
 {
-       struct hclge_vport *vport = hdev->vport;
-       u32 i, k, qs_bitmap;
-       int ret;
+       int i;
 
        for (i = 0; i < HCLGE_BP_GRP_NUM; i++) {
-               qs_bitmap = 0;
+               u32 qs_bitmap = 0;
+               int k, ret;
 
                for (k = 0; k < hdev->num_alloc_vport; k++) {
+                       struct hclge_vport *vport = &hdev->vport[k];
                        u16 qs_id = vport->qs_offset + tc;
                        u8 grp, sub_grp;
 
@@ -1185,8 +1185,6 @@ static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
                                                  HCLGE_BP_SUB_GRP_ID_S);
                        if (i == grp)
                                qs_bitmap |= (1 << sub_grp);
-
-                       vport++;
                }
 
                ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap);
index 7893beffcc714215a5ed47fc8658b9db66ee9d3a..27a6df30eafd28e6f2af2b647769e9f0857546ea 100644 (file)
@@ -1103,20 +1103,15 @@ static int ibmvnic_open(struct net_device *netdev)
                return 0;
        }
 
-       mutex_lock(&adapter->reset_lock);
-
        if (adapter->state != VNIC_CLOSED) {
                rc = ibmvnic_login(netdev);
-               if (rc) {
-                       mutex_unlock(&adapter->reset_lock);
+               if (rc)
                        return rc;
-               }
 
                rc = init_resources(adapter);
                if (rc) {
                        netdev_err(netdev, "failed to initialize resources\n");
                        release_resources(adapter);
-                       mutex_unlock(&adapter->reset_lock);
                        return rc;
                }
        }
@@ -1124,8 +1119,6 @@ static int ibmvnic_open(struct net_device *netdev)
        rc = __ibmvnic_open(netdev);
        netif_carrier_on(netdev);
 
-       mutex_unlock(&adapter->reset_lock);
-
        return rc;
 }
 
@@ -1269,10 +1262,8 @@ static int ibmvnic_close(struct net_device *netdev)
                return 0;
        }
 
-       mutex_lock(&adapter->reset_lock);
        rc = __ibmvnic_close(netdev);
        ibmvnic_cleanup(netdev);
-       mutex_unlock(&adapter->reset_lock);
 
        return rc;
 }
@@ -1545,7 +1536,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
        tx_crq.v1.sge_len = cpu_to_be32(skb->len);
        tx_crq.v1.ioba = cpu_to_be64(data_dma_addr);
 
-       if (adapter->vlan_header_insertion) {
+       if (adapter->vlan_header_insertion && skb_vlan_tag_present(skb)) {
                tx_crq.v1.flags2 |= IBMVNIC_TX_VLAN_INSERT;
                tx_crq.v1.vlan_id = cpu_to_be16(skb->vlan_tci);
        }
@@ -1820,20 +1811,15 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                                return rc;
                } else if (adapter->req_rx_queues != old_num_rx_queues ||
                           adapter->req_tx_queues != old_num_tx_queues) {
-                       adapter->map_id = 1;
                        release_rx_pools(adapter);
                        release_tx_pools(adapter);
-                       rc = init_rx_pools(netdev);
-                       if (rc)
-                               return rc;
-                       rc = init_tx_pools(netdev);
-                       if (rc)
-                               return rc;
-
                        release_napi(adapter);
-                       rc = init_napi(adapter);
+                       release_vpd_data(adapter);
+
+                       rc = init_resources(adapter);
                        if (rc)
                                return rc;
+
                } else {
                        rc = reset_tx_pools(adapter);
                        if (rc)
@@ -1917,17 +1903,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
                adapter->state = VNIC_PROBED;
                return 0;
        }
-       /* netif_set_real_num_xx_queues needs to take rtnl lock here
-        * unless wait_for_reset is set, in which case the rtnl lock
-        * has already been taken before initializing the reset
-        */
-       if (!adapter->wait_for_reset) {
-               rtnl_lock();
-               rc = init_resources(adapter);
-               rtnl_unlock();
-       } else {
-               rc = init_resources(adapter);
-       }
+
+       rc = init_resources(adapter);
        if (rc)
                return rc;
 
@@ -1986,13 +1963,21 @@ static void __ibmvnic_reset(struct work_struct *work)
        struct ibmvnic_rwi *rwi;
        struct ibmvnic_adapter *adapter;
        struct net_device *netdev;
+       bool we_lock_rtnl = false;
        u32 reset_state;
        int rc = 0;
 
        adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
        netdev = adapter->netdev;
 
-       mutex_lock(&adapter->reset_lock);
+       /* netif_set_real_num_xx_queues needs to take rtnl lock here
+        * unless wait_for_reset is set, in which case the rtnl lock
+        * has already been taken before initializing the reset
+        */
+       if (!adapter->wait_for_reset) {
+               rtnl_lock();
+               we_lock_rtnl = true;
+       }
        reset_state = adapter->state;
 
        rwi = get_next_rwi(adapter);
@@ -2020,12 +2005,11 @@ static void __ibmvnic_reset(struct work_struct *work)
        if (rc) {
                netdev_dbg(adapter->netdev, "Reset failed\n");
                free_all_rwi(adapter);
-               mutex_unlock(&adapter->reset_lock);
-               return;
        }
 
        adapter->resetting = false;
-       mutex_unlock(&adapter->reset_lock);
+       if (we_lock_rtnl)
+               rtnl_unlock();
 }
 
 static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
@@ -4768,7 +4752,6 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
 
        INIT_WORK(&adapter->ibmvnic_reset, __ibmvnic_reset);
        INIT_LIST_HEAD(&adapter->rwi_list);
-       mutex_init(&adapter->reset_lock);
        mutex_init(&adapter->rwi_lock);
        adapter->resetting = false;
 
@@ -4840,8 +4823,8 @@ static int ibmvnic_remove(struct vio_dev *dev)
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
 
        adapter->state = VNIC_REMOVING;
-       unregister_netdev(netdev);
-       mutex_lock(&adapter->reset_lock);
+       rtnl_lock();
+       unregister_netdevice(netdev);
 
        release_resources(adapter);
        release_sub_crqs(adapter, 1);
@@ -4852,7 +4835,7 @@ static int ibmvnic_remove(struct vio_dev *dev)
 
        adapter->state = VNIC_REMOVED;
 
-       mutex_unlock(&adapter->reset_lock);
+       rtnl_unlock();
        device_remove_file(&dev->dev, &dev_attr_failover);
        free_netdev(netdev);
        dev_set_drvdata(&dev->dev, NULL);
index 18103b811d4db398df7ce6a6e27c6bda2077c4c2..99c4f8d331ce7c489c4b3badb1d5fbbe57ff8dea 100644 (file)
@@ -1075,7 +1075,7 @@ struct ibmvnic_adapter {
        struct tasklet_struct tasklet;
        enum vnic_state state;
        enum ibmvnic_reset_reason reset_reason;
-       struct mutex reset_lock, rwi_lock;
+       struct mutex rwi_lock;
        struct list_head rwi_list;
        struct work_struct ibmvnic_reset;
        bool resetting;
index bc71a21c1dc2cfe7215a3ea124efd2dc11ccbf99..21c2688d63082ec25bb6f72e921d39ac3beedee8 100644 (file)
@@ -12249,6 +12249,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                          NETIF_F_GSO_GRE               |
                          NETIF_F_GSO_GRE_CSUM          |
                          NETIF_F_GSO_PARTIAL           |
+                         NETIF_F_GSO_IPXIP4            |
+                         NETIF_F_GSO_IPXIP6            |
                          NETIF_F_GSO_UDP_TUNNEL        |
                          NETIF_F_GSO_UDP_TUNNEL_CSUM   |
                          NETIF_F_SCTP_CRC              |
@@ -12266,13 +12268,13 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
        /* record features VLANs can make use of */
        netdev->vlan_features |= hw_enc_features | NETIF_F_TSO_MANGLEID;
 
-       if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
-               netdev->hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
-
        hw_features = hw_enc_features           |
                      NETIF_F_HW_VLAN_CTAG_TX   |
                      NETIF_F_HW_VLAN_CTAG_RX;
 
+       if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
+               hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
+
        netdev->hw_features |= hw_features;
 
        netdev->features |= hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
index 4c4b5717a627de6353f8f4248163f1f7e333714f..b8548370f1c722e61817c4857adae71f1cce18f0 100644 (file)
@@ -76,6 +76,8 @@ extern const char ice_drv_ver[];
 #define ICE_MIN_INTR_PER_VF            (ICE_MIN_QS_PER_VF + 1)
 #define ICE_DFLT_INTR_PER_VF           (ICE_DFLT_QS_PER_VF + 1)
 
+#define ICE_MAX_RESET_WAIT             20
+
 #define ICE_VSIQF_HKEY_ARRAY_SIZE      ((VSIQF_HKEY_MAX_INDEX + 1) *   4)
 
 #define ICE_DFLT_NETIF_M (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
@@ -189,7 +191,6 @@ struct ice_vsi {
        u64 tx_linearize;
        DECLARE_BITMAP(state, __ICE_STATE_NBITS);
        DECLARE_BITMAP(flags, ICE_VSI_FLAG_NBITS);
-       unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
        unsigned int current_netdev_flags;
        u32 tx_restart;
        u32 tx_busy;
@@ -369,5 +370,6 @@ int ice_set_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
 int ice_get_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
 void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);
 void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
+void ice_napi_del(struct ice_vsi *vsi);
 
 #endif /* _ICE_H_ */
index 8cd6a2401fd9f2c1a804ba4ee3920e0309c87a4a..554fd707a6d69f45f165a6b77ef23bb027ac6baa 100644 (file)
@@ -811,6 +811,9 @@ void ice_deinit_hw(struct ice_hw *hw)
        /* Attempt to disable FW logging before shutting down control queues */
        ice_cfg_fw_log(hw, false);
        ice_shutdown_all_ctrlq(hw);
+
+       /* Clear VSI contexts if not already cleared */
+       ice_clear_all_vsi_ctx(hw);
 }
 
 /**
index 96923580f2a6c2fdb88c88c2f1e88f0b4154f67c..648acdb4c644b6c62d08d8f99c4307e1537d041f 100644 (file)
@@ -1517,10 +1517,15 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
        }
 
        if (!test_bit(__ICE_DOWN, pf->state)) {
-               /* Give it a little more time to try to come back */
+               /* Give it a little more time to try to come back. If still
+                * down, restart autoneg link or reinitialize the interface.
+                */
                msleep(75);
                if (!test_bit(__ICE_DOWN, pf->state))
                        return ice_nway_reset(netdev);
+
+               ice_down(vsi);
+               ice_up(vsi);
        }
 
        return err;
index 5fdea6ec7675b6d82b8c71c5bbe133b84280c79d..596b9fb1c510dec854004dd0bce6ef68a74ba8c6 100644 (file)
 #define GLNVM_ULD                              0x000B6008
 #define GLNVM_ULD_CORER_DONE_M                 BIT(3)
 #define GLNVM_ULD_GLOBR_DONE_M                 BIT(4)
+#define GLPCI_CNF2                             0x000BE004
+#define GLPCI_CNF2_CACHELINE_SIZE_M            BIT(1)
 #define PF_FUNC_RID                            0x0009E880
 #define PF_FUNC_RID_FUNC_NUM_S                 0
 #define PF_FUNC_RID_FUNC_NUM_M                 ICE_M(0x7, 0)
index 5bacad01f0c9c1c8cce2b4f56caca05b034688c2..1041fa2a7767878590930f1851c394eb67da80c5 100644 (file)
@@ -1997,7 +1997,7 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena)
        status = ice_update_vsi(&vsi->back->hw, vsi->idx, ctxt, NULL);
        if (status) {
                netdev_err(vsi->netdev, "%sabling VLAN pruning on VSI handle: %d, VSI HW ID: %d failed, err = %d, aq_err = %d\n",
-                          ena ? "Ena" : "Dis", vsi->idx, vsi->vsi_num, status,
+                          ena ? "En" : "Dis", vsi->idx, vsi->vsi_num, status,
                           vsi->back->hw.adminq.sq_last_status);
                goto err_out;
        }
@@ -2458,6 +2458,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
         * on this wq
         */
        if (vsi->netdev && !ice_is_reset_in_progress(pf->state)) {
+               ice_napi_del(vsi);
                unregister_netdev(vsi->netdev);
                free_netdev(vsi->netdev);
                vsi->netdev = NULL;
index 05993451147a09333602f79846f9d39e208d3037..333312a1d59572dfe8cef5bc02d745ab7c2920cf 100644 (file)
@@ -1465,7 +1465,7 @@ skip_req_irq:
  * ice_napi_del - Remove NAPI handler for the VSI
  * @vsi: VSI for which NAPI handler is to be removed
  */
-static void ice_napi_del(struct ice_vsi *vsi)
+void ice_napi_del(struct ice_vsi *vsi)
 {
        int v_idx;
 
@@ -1622,7 +1622,6 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,
 {
        struct ice_netdev_priv *np = netdev_priv(netdev);
        struct ice_vsi *vsi = np->vsi;
-       int ret;
 
        if (vid >= VLAN_N_VID) {
                netdev_err(netdev, "VLAN id requested %d is out of range %d\n",
@@ -1635,7 +1634,8 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,
 
        /* Enable VLAN pruning when VLAN 0 is added */
        if (unlikely(!vid)) {
-               ret = ice_cfg_vlan_pruning(vsi, true);
+               int ret = ice_cfg_vlan_pruning(vsi, true);
+
                if (ret)
                        return ret;
        }
@@ -1644,12 +1644,7 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,
         * needed to continue allowing all untagged packets since VLAN prune
         * list is applied to all packets by the switch
         */
-       ret = ice_vsi_add_vlan(vsi, vid);
-
-       if (!ret)
-               set_bit(vid, vsi->active_vlans);
-
-       return ret;
+       return ice_vsi_add_vlan(vsi, vid);
 }
 
 /**
@@ -1677,8 +1672,6 @@ static int ice_vlan_rx_kill_vid(struct net_device *netdev,
        if (status)
                return status;
 
-       clear_bit(vid, vsi->active_vlans);
-
        /* Disable VLAN pruning when VLAN 0 is removed */
        if (unlikely(!vid))
                status = ice_cfg_vlan_pruning(vsi, false);
@@ -2001,6 +1994,22 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf)
        return 0;
 }
 
+/**
+ * ice_verify_cacheline_size - verify driver's assumption of 64 Byte cache lines
+ * @pf: pointer to the PF structure
+ *
+ * There is no error returned here because the driver should be able to handle
+ * 128 Byte cache lines, so we only print a warning in case issues are seen,
+ * specifically with Tx.
+ */
+static void ice_verify_cacheline_size(struct ice_pf *pf)
+{
+       if (rd32(&pf->hw, GLPCI_CNF2) & GLPCI_CNF2_CACHELINE_SIZE_M)
+               dev_warn(&pf->pdev->dev,
+                        "%d Byte cache line assumption is invalid, driver may have Tx timeouts!\n",
+                        ICE_CACHE_LINE_BYTES);
+}
+
 /**
  * ice_probe - Device initialization routine
  * @pdev: PCI device information struct
@@ -2151,6 +2160,8 @@ static int ice_probe(struct pci_dev *pdev,
        /* since everything is good, start the service timer */
        mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period));
 
+       ice_verify_cacheline_size(pf);
+
        return 0;
 
 err_alloc_sw_unroll:
@@ -2182,6 +2193,12 @@ static void ice_remove(struct pci_dev *pdev)
        if (!pf)
                return;
 
+       for (i = 0; i < ICE_MAX_RESET_WAIT; i++) {
+               if (!ice_is_reset_in_progress(pf->state))
+                       break;
+               msleep(100);
+       }
+
        set_bit(__ICE_DOWN, pf->state);
        ice_service_task_stop(pf);
 
@@ -2509,31 +2526,6 @@ static int ice_vsi_vlan_setup(struct ice_vsi *vsi)
        return ret;
 }
 
-/**
- * ice_restore_vlan - Reinstate VLANs when vsi/netdev comes back up
- * @vsi: the VSI being brought back up
- */
-static int ice_restore_vlan(struct ice_vsi *vsi)
-{
-       int err;
-       u16 vid;
-
-       if (!vsi->netdev)
-               return -EINVAL;
-
-       err = ice_vsi_vlan_setup(vsi);
-       if (err)
-               return err;
-
-       for_each_set_bit(vid, vsi->active_vlans, VLAN_N_VID) {
-               err = ice_vlan_rx_add_vid(vsi->netdev, htons(ETH_P_8021Q), vid);
-               if (err)
-                       break;
-       }
-
-       return err;
-}
-
 /**
  * ice_vsi_cfg - Setup the VSI
  * @vsi: the VSI being configured
@@ -2546,7 +2538,9 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)
 
        if (vsi->netdev) {
                ice_set_rx_mode(vsi->netdev);
-               err = ice_restore_vlan(vsi);
+
+               err = ice_vsi_vlan_setup(vsi);
+
                if (err)
                        return err;
        }
@@ -3296,7 +3290,7 @@ static void ice_rebuild(struct ice_pf *pf)
        struct device *dev = &pf->pdev->dev;
        struct ice_hw *hw = &pf->hw;
        enum ice_status ret;
-       int err;
+       int err, i;
 
        if (test_bit(__ICE_DOWN, pf->state))
                goto clear_recovery;
@@ -3370,6 +3364,22 @@ static void ice_rebuild(struct ice_pf *pf)
        }
 
        ice_reset_all_vfs(pf, true);
+
+       for (i = 0; i < pf->num_alloc_vsi; i++) {
+               bool link_up;
+
+               if (!pf->vsi[i] || pf->vsi[i]->type != ICE_VSI_PF)
+                       continue;
+               ice_get_link_status(pf->vsi[i]->port_info, &link_up);
+               if (link_up) {
+                       netif_carrier_on(pf->vsi[i]->netdev);
+                       netif_tx_wake_all_queues(pf->vsi[i]->netdev);
+               } else {
+                       netif_carrier_off(pf->vsi[i]->netdev);
+                       netif_tx_stop_all_queues(pf->vsi[i]->netdev);
+               }
+       }
+
        /* if we get here, reset flow is successful */
        clear_bit(__ICE_RESET_FAILED, pf->state);
        return;
index 33403f39f1b3f8680dcf5b63c37956a5df2d0fad..40c9c65589568b34a1eb5ec50d842e41ddd030e3 100644 (file)
@@ -347,6 +347,18 @@ static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
        }
 }
 
+/**
+ * ice_clear_all_vsi_ctx - clear all the VSI context entries
+ * @hw: pointer to the hw struct
+ */
+void ice_clear_all_vsi_ctx(struct ice_hw *hw)
+{
+       u16 i;
+
+       for (i = 0; i < ICE_MAX_VSI; i++)
+               ice_clear_vsi_ctx(hw, i);
+}
+
 /**
  * ice_add_vsi - add VSI context to the hardware and VSI handle list
  * @hw: pointer to the hw struct
index b88d96a1ef6935c2564e07e3443378b65f32b7ea..d5ef0bd58bf9789260bbf7575868f16a6123ec81 100644 (file)
@@ -190,6 +190,8 @@ ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
               struct ice_sq_cd *cd);
 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle);
 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle);
+void ice_clear_all_vsi_ctx(struct ice_hw *hw);
+/* Switch config */
 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw);
 
 /* Switch/bridge related commands */
index 5dae968d853e17b88344d3852c0b40a7ac133f66..fe5bbabbb41eacdac1bcd0466196ee835b35b97f 100644 (file)
@@ -1520,7 +1520,7 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
 
        /* update gso_segs and bytecount */
        first->gso_segs = skb_shinfo(skb)->gso_segs;
-       first->bytecount = (first->gso_segs - 1) * off->header_len;
+       first->bytecount += (first->gso_segs - 1) * off->header_len;
 
        cd_tso_len = skb->len - off->header_len;
        cd_mss = skb_shinfo(skb)->gso_size;
@@ -1556,15 +1556,15 @@ int ice_tso(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
  * magnitude greater than our largest possible GSO size.
  *
  * This would then be implemented as:
- *     return (((size >> 12) * 85) >> 8) + 1;
+ *     return (((size >> 12) * 85) >> 8) + ICE_DESCS_FOR_SKB_DATA_PTR;
  *
  * Since multiplication and division are commutative, we can reorder
  * operations into:
- *     return ((size * 85) >> 20) + 1;
+ *     return ((size * 85) >> 20) + ICE_DESCS_FOR_SKB_DATA_PTR;
  */
 static unsigned int ice_txd_use_count(unsigned int size)
 {
-       return ((size * 85) >> 20) + 1;
+       return ((size * 85) >> 20) + ICE_DESCS_FOR_SKB_DATA_PTR;
 }
 
 /**
@@ -1706,7 +1706,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring)
         *       + 1 desc for context descriptor,
         * otherwise try next time
         */
-       if (ice_maybe_stop_tx(tx_ring, count + 4 + 1)) {
+       if (ice_maybe_stop_tx(tx_ring, count + ICE_DESCS_PER_CACHE_LINE +
+                             ICE_DESCS_FOR_CTX_DESC)) {
                tx_ring->tx_stats.tx_busy++;
                return NETDEV_TX_BUSY;
        }
index 1d0f58bd389bd35d9c5aad257e0d41c12c9ff1cd..75d0eaf6c9ddbe18a26c04d1b9edfae4322e16d7 100644 (file)
 #define ICE_RX_BUF_WRITE       16      /* Must be power of 2 */
 #define ICE_MAX_TXQ_PER_TXQG   128
 
-/* Tx Descriptors needed, worst case */
-#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
+/* We are assuming that the cache line is always 64 Bytes here for ice.
+ * In order to make sure that is a correct assumption there is a check in probe
+ * to print a warning if the read from GLPCI_CNF2 tells us that the cache line
+ * size is 128 bytes. We do it this way because we do not want to read the
+ * GLPCI_CNF2 register or a variable containing the value on every pass through
+ * the Tx path.
+ */
+#define ICE_CACHE_LINE_BYTES           64
+#define ICE_DESCS_PER_CACHE_LINE       (ICE_CACHE_LINE_BYTES / \
+                                        sizeof(struct ice_tx_desc))
+#define ICE_DESCS_FOR_CTX_DESC         1
+#define ICE_DESCS_FOR_SKB_DATA_PTR     1
+/* Tx descriptors needed, worst case */
+#define DESC_NEEDED (MAX_SKB_FRAGS + ICE_DESCS_FOR_CTX_DESC + \
+                    ICE_DESCS_PER_CACHE_LINE + ICE_DESCS_FOR_SKB_DATA_PTR)
 #define ICE_DESC_UNUSED(R)     \
        ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
        (R)->next_to_clean - (R)->next_to_use - 1)
index 12f9432abf11099f2c0eecb3bfe289ee801134f7..f4dbc81c198863b5037f6acc07ed053522923065 100644 (file)
@@ -92,12 +92,12 @@ struct ice_link_status {
        u64 phy_type_low;
        u16 max_frame_size;
        u16 link_speed;
+       u16 req_speeds;
        u8 lse_ena;     /* Link Status Event notification */
        u8 link_info;
        u8 an_info;
        u8 ext_info;
        u8 pacing;
-       u8 req_speeds;
        /* Refer to #define from module_type[ICE_MODULE_TYPE_TOTAL_BYTE] of
         * ice_aqc_get_phy_caps structure
         */
index 45f10f8f01dc1ba0e39cd1e87ba16a11c5fbbe7f..e71065f9d3918a7623ac1bb517c14c7c9b632a39 100644 (file)
@@ -348,7 +348,7 @@ static int ice_vsi_set_pvid(struct ice_vsi *vsi, u16 vid)
        struct ice_vsi_ctx ctxt = { 0 };
        enum ice_status status;
 
-       ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_TAGGED |
+       ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_UNTAGGED |
                               ICE_AQ_VSI_PVLAN_INSERT_PVID |
                               ICE_AQ_VSI_VLAN_EMOD_STR;
        ctxt.info.pvid = cpu_to_le16(vid);
@@ -2171,7 +2171,6 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
 
                        if (!ice_vsi_add_vlan(vsi, vid)) {
                                vf->num_vlan++;
-                               set_bit(vid, vsi->active_vlans);
 
                                /* Enable VLAN pruning when VLAN 0 is added */
                                if (unlikely(!vid))
@@ -2190,7 +2189,6 @@ static int ice_vc_process_vlan_msg(struct ice_vf *vf, u8 *msg, bool add_v)
                         */
                        if (!ice_vsi_kill_vlan(vsi, vid)) {
                                vf->num_vlan--;
-                               clear_bit(vid, vsi->active_vlans);
 
                                /* Disable VLAN pruning when removing VLAN 0 */
                                if (unlikely(!vid))
index 29ced6b74d364632113e9674f8d005257e548411..2b95dc9c7a6a8bd3fd0a2d03365e282b26382e70 100644 (file)
  *   2^40 * 10^-9 /  60  = 18.3 minutes.
  *
  * SYSTIM is converted to real time using a timecounter. As
- * timecounter_cyc2time() allows old timestamps, the timecounter
- * needs to be updated at least once per half of the SYSTIM interval.
- * Scheduling of delayed work is not very accurate, so we aim for 8
- * minutes to be sure the actual interval is shorter than 9.16 minutes.
+ * timecounter_cyc2time() allows old timestamps, the timecounter needs
+ * to be updated at least once per half of the SYSTIM interval.
+ * Scheduling of delayed work is not very accurate, and also the NIC
+ * clock can be adjusted to run up to 6% faster and the system clock
+ * up to 10% slower, so we aim for 6 minutes to be sure the actual
+ * interval in the NIC time is shorter than 9.16 minutes.
  */
 
-#define IGB_SYSTIM_OVERFLOW_PERIOD     (HZ * 60 * 8)
+#define IGB_SYSTIM_OVERFLOW_PERIOD     (HZ * 60 * 6)
 #define IGB_PTP_TX_TIMEOUT             (HZ * 15)
 #define INCPERIOD_82576                        BIT(E1000_TIMINCA_16NS_SHIFT)
 #define INCVALUE_82576_MASK            GENMASK(E1000_TIMINCA_16NS_SHIFT - 1, 0)
index 8c5ba4b81fb7332aba15a0f4199155f39a4da8a3..2d4d10a017e59bfc96870e9fd94338986f6ef7f2 100644 (file)
@@ -512,7 +512,8 @@ static int xrx200_probe(struct platform_device *pdev)
        err = register_netdev(net_dev);
        if (err)
                goto err_unprepare_clk;
-       return err;
+
+       return 0;
 
 err_unprepare_clk:
        clk_disable_unprepare(priv->clk);
@@ -520,7 +521,7 @@ err_unprepare_clk:
 err_uninit_dma:
        xrx200_hw_cleanup(priv);
 
-       return 0;
+       return err;
 }
 
 static int xrx200_remove(struct platform_device *pdev)
index 5bfd349bf41ac58ffaa003ecdca1d6493f4f42eb..e5397c8197b9c3713c48e925dad0dfcee732c0b9 100644 (file)
@@ -494,7 +494,7 @@ struct mvneta_port {
 #if defined(__LITTLE_ENDIAN)
 struct mvneta_tx_desc {
        u32  command;           /* Options used by HW for packet transmitting.*/
-       u16  reserverd1;        /* csum_l4 (for future use)             */
+       u16  reserved1;         /* csum_l4 (for future use)             */
        u16  data_size;         /* Data size of transmitted packet in bytes */
        u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
        u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
@@ -519,7 +519,7 @@ struct mvneta_rx_desc {
 #else
 struct mvneta_tx_desc {
        u16  data_size;         /* Data size of transmitted packet in bytes */
-       u16  reserverd1;        /* csum_l4 (for future use)             */
+       u16  reserved1;         /* csum_l4 (for future use)             */
        u32  command;           /* Options used by HW for packet transmitting.*/
        u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
        u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
@@ -3343,7 +3343,6 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
        if (state->interface != PHY_INTERFACE_MODE_NA &&
            state->interface != PHY_INTERFACE_MODE_QSGMII &&
            state->interface != PHY_INTERFACE_MODE_SGMII &&
-           state->interface != PHY_INTERFACE_MODE_2500BASEX &&
            !phy_interface_mode_is_8023z(state->interface) &&
            !phy_interface_mode_is_rgmii(state->interface)) {
                bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
@@ -3357,14 +3356,9 @@ static void mvneta_validate(struct net_device *ndev, unsigned long *supported,
        /* Asymmetric pause is unsupported */
        phylink_set(mask, Pause);
 
-       /* We cannot use 1Gbps when using the 2.5G interface. */
-       if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
-               phylink_set(mask, 2500baseT_Full);
-               phylink_set(mask, 2500baseX_Full);
-       } else {
-               phylink_set(mask, 1000baseT_Full);
-               phylink_set(mask, 1000baseX_Full);
-       }
+       /* Half-duplex at speeds higher than 100Mbit is unsupported */
+       phylink_set(mask, 1000baseT_Full);
+       phylink_set(mask, 1000baseX_Full);
 
        if (!phy_interface_mode_is_8023z(state->interface)) {
                /* 10M and 100M are only supported in non-802.3z mode */
index deef5a998985a9f8398d693b8bd219a5fc083313..9af34e03892c19e780149a3a8405d936fe417d45 100644 (file)
@@ -337,7 +337,7 @@ void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc)
 static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count,
                                  int align, u32 skip_mask, u32 *puid)
 {
-       u32 uid;
+       u32 uid = 0;
        u32 res;
        struct mlx4_zone_allocator *zone_alloc = zone->allocator;
        struct mlx4_zone_entry *curr_node;
index 1857ee0f0871d48285a6d3711f7c3e9a1e08a05f..6f5153afcab4dfc331c099da854c54f1b9500887 100644 (file)
@@ -1006,7 +1006,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                ring->packets++;
        }
        ring->bytes += tx_info->nr_bytes;
-       netdev_tx_sent_queue(ring->tx_queue, tx_info->nr_bytes);
        AVG_PERF_COUNTER(priv->pstats.tx_pktsz_avg, skb->len);
 
        if (tx_info->inl)
@@ -1044,7 +1043,10 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_tx_stop_queue(ring->tx_queue);
                ring->queue_stopped++;
        }
-       send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue);
+
+       send_doorbell = __netdev_tx_sent_queue(ring->tx_queue,
+                                              tx_info->nr_bytes,
+                                              skb->xmit_more);
 
        real_size = (real_size / 16) & 0x3f;
 
index ebcd2778eeb3e1f22524064ff2db7762e1f852ba..23f1b5b512c2198cb664167e42fb91ff9c549f13 100644 (file)
@@ -540,8 +540,8 @@ struct slave_list {
 struct resource_allocator {
        spinlock_t alloc_lock; /* protect quotas */
        union {
-               int res_reserved;
-               int res_port_rsvd[MLX4_MAX_PORTS];
+               unsigned int res_reserved;
+               unsigned int res_port_rsvd[MLX4_MAX_PORTS];
        };
        union {
                int res_free;
index 2e84f10f59ba9ca0a69d980b87368f7310e5bb13..1a11bc0e16123e918e68e7a8f8bed703825665fa 100644 (file)
@@ -363,6 +363,7 @@ int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr,
                        container_of((void *)mpt_entry, struct mlx4_cmd_mailbox,
                                     buf);
 
+               (*mpt_entry)->lkey = 0;
                err = mlx4_SW2HW_MPT(dev, mailbox, key);
        }
 
index a2df12b79f8e915702323f9258972260135c094c..9bec940330a450856d2dba23ed7274321cf82059 100644 (file)
@@ -3568,7 +3568,6 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
                        burst_size = 7;
                        break;
                case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME:
-                       is_bytes = true;
                        rate = 4 * 1024;
                        burst_size = 4;
                        break;
index 8e8fa823d611878c1ce166ae271a082b5ec84acd..69966dfc6e3d12f6b754dd94f0ca7fcc4018713f 100644 (file)
@@ -191,7 +191,7 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data)
 static void
 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
                    struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
-                   bool enable, u8 prio, u8 tc,
+                   bool app_tlv, bool enable, u8 prio, u8 tc,
                    enum dcbx_protocol_type type,
                    enum qed_pci_personality personality)
 {
@@ -210,7 +210,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,
                p_data->arr[type].dont_add_vlan0 = true;
 
        /* QM reconf data */
-       if (p_hwfn->hw_info.personality == personality)
+       if (app_tlv && p_hwfn->hw_info.personality == personality)
                qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc);
 
        /* Configure dcbx vlan priority in doorbell block for roce EDPM */
@@ -225,7 +225,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,
 static void
 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
                         struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
-                        bool enable, u8 prio, u8 tc,
+                        bool app_tlv, bool enable, u8 prio, u8 tc,
                         enum dcbx_protocol_type type)
 {
        enum qed_pci_personality personality;
@@ -240,7 +240,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
 
                personality = qed_dcbx_app_update[i].personality;
 
-               qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable,
+               qed_dcbx_set_params(p_data, p_hwfn, p_ptt, app_tlv, enable,
                                    prio, tc, type, personality);
        }
 }
@@ -319,8 +319,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
                                enable = true;
                        }
 
-                       qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
-                                                priority, tc, type);
+                       qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, true,
+                                                enable, priority, tc, type);
                }
        }
 
@@ -341,7 +341,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
                        continue;
 
                enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
-               qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
+               qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, false, enable,
                                         priority, tc, type);
        }
 
index 7ceb2b97538d25d767c3d8cc7e7ab79d8b03e760..88a8576ca9ceae1b4adc69b8702f1b626e82e54f 100644 (file)
@@ -185,6 +185,10 @@ void qed_resc_free(struct qed_dev *cdev)
                        qed_iscsi_free(p_hwfn);
                        qed_ooo_free(p_hwfn);
                }
+
+               if (QED_IS_RDMA_PERSONALITY(p_hwfn))
+                       qed_rdma_info_free(p_hwfn);
+
                qed_iov_free(p_hwfn);
                qed_l2_free(p_hwfn);
                qed_dmae_info_free(p_hwfn);
@@ -481,8 +485,16 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn,
        struct qed_qm_info *qm_info = &p_hwfn->qm_info;
 
        /* Can't have multiple flags set here */
-       if (bitmap_weight((unsigned long *)&pq_flags, sizeof(pq_flags)) > 1)
+       if (bitmap_weight((unsigned long *)&pq_flags,
+                         sizeof(pq_flags) * BITS_PER_BYTE) > 1) {
+               DP_ERR(p_hwfn, "requested multiple pq flags 0x%x\n", pq_flags);
+               goto err;
+       }
+
+       if (!(qed_get_pq_flags(p_hwfn) & pq_flags)) {
+               DP_ERR(p_hwfn, "pq flag 0x%x is not set\n", pq_flags);
                goto err;
+       }
 
        switch (pq_flags) {
        case PQ_FLAGS_RLS:
@@ -506,8 +518,7 @@ static u16 *qed_init_qm_get_idx_from_flags(struct qed_hwfn *p_hwfn,
        }
 
 err:
-       DP_ERR(p_hwfn, "BAD pq flags %d\n", pq_flags);
-       return NULL;
+       return &qm_info->start_pq;
 }
 
 /* save pq index in qm info */
@@ -531,20 +542,32 @@ u16 qed_get_cm_pq_idx_mcos(struct qed_hwfn *p_hwfn, u8 tc)
 {
        u8 max_tc = qed_init_qm_get_num_tcs(p_hwfn);
 
+       if (max_tc == 0) {
+               DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n",
+                      PQ_FLAGS_MCOS);
+               return p_hwfn->qm_info.start_pq;
+       }
+
        if (tc > max_tc)
                DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc);
 
-       return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + tc;
+       return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + (tc % max_tc);
 }
 
 u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf)
 {
        u16 max_vf = qed_init_qm_get_num_vfs(p_hwfn);
 
+       if (max_vf == 0) {
+               DP_ERR(p_hwfn, "pq with flag 0x%lx do not exist\n",
+                      PQ_FLAGS_VFS);
+               return p_hwfn->qm_info.start_pq;
+       }
+
        if (vf > max_vf)
                DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf);
 
-       return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf;
+       return qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + (vf % max_vf);
 }
 
 u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc)
@@ -1081,6 +1104,12 @@ int qed_resc_alloc(struct qed_dev *cdev)
                                goto alloc_err;
                }
 
+               if (QED_IS_RDMA_PERSONALITY(p_hwfn)) {
+                       rc = qed_rdma_info_alloc(p_hwfn);
+                       if (rc)
+                               goto alloc_err;
+               }
+
                /* DMA info initialization */
                rc = qed_dmae_info_alloc(p_hwfn);
                if (rc)
@@ -2102,11 +2131,8 @@ int qed_hw_start_fastpath(struct qed_hwfn *p_hwfn)
        if (!p_ptt)
                return -EAGAIN;
 
-       /* If roce info is allocated it means roce is initialized and should
-        * be enabled in searcher.
-        */
        if (p_hwfn->p_rdma_info &&
-           p_hwfn->b_rdma_enabled_in_prs)
+           p_hwfn->p_rdma_info->active && p_hwfn->b_rdma_enabled_in_prs)
                qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0x1);
 
        /* Re-open incoming traffic */
index cc1b373c0ace56e08564d3527de9f5da3f87b4e4..46dc93d3b9b53db6586b791bc6ffcf65b756daba 100644 (file)
@@ -147,7 +147,8 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
                       "Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
                       fcoe_pf_params->num_cqs,
                       p_hwfn->hw_info.feat_num[QED_FCOE_CQ]);
-               return -EINVAL;
+               rc = -EINVAL;
+               goto err;
        }
 
        p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu);
@@ -156,14 +157,14 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
 
        rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid);
        if (rc)
-               return rc;
+               goto err;
 
        cxt_info.iid = dummy_cid;
        rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info);
        if (rc) {
                DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n",
                          dummy_cid);
-               return rc;
+               goto err;
        }
        p_cxt = cxt_info.p_cxt;
        SET_FIELD(p_cxt->tstorm_ag_context.flags3,
@@ -240,6 +241,10 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
        rc = qed_spq_post(p_hwfn, p_ent, NULL);
 
        return rc;
+
+err:
+       qed_sp_destroy_request(p_hwfn, p_ent);
+       return rc;
 }
 
 static int
index 0f0aba793352c406404b53306f4bfb454b70a8b6..b22f464ea3fa770e94327640e32a35972ee35745 100644 (file)
@@ -992,6 +992,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn)
         */
        do {
                index = p_sb_attn->sb_index;
+               /* finish reading index before the loop condition */
+               dma_rmb();
                attn_bits = le32_to_cpu(p_sb_attn->atten_bits);
                attn_acks = le32_to_cpu(p_sb_attn->atten_ack);
        } while (index != p_sb_attn->sb_index);
index 1135387bd99d704f517679c4716760e39acce52c..4f8a685d1a55febcf78e3213a1c56130c8535213 100644 (file)
@@ -200,6 +200,7 @@ qed_sp_iscsi_func_start(struct qed_hwfn *p_hwfn,
                       "Cannot satisfy CQ amount. Queues requested %d, CQs available %d. Aborting function start\n",
                       p_params->num_queues,
                       p_hwfn->hw_info.feat_num[QED_ISCSI_CQ]);
+               qed_sp_destroy_request(p_hwfn, p_ent);
                return -EINVAL;
        }
 
index 82a1bd1f8a8ce3fd66acc6b0cc0c9e7bf6a57305..67c02ea939062dea70ae6e806546fd8266dd08cf 100644 (file)
@@ -740,8 +740,7 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn,
 
        rc = qed_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params);
        if (rc) {
-               /* Return spq entry which is taken in qed_sp_init_request()*/
-               qed_spq_return_entry(p_hwfn, p_ent);
+               qed_sp_destroy_request(p_hwfn, p_ent);
                return rc;
        }
 
@@ -1355,6 +1354,7 @@ qed_filter_ucast_common(struct qed_hwfn *p_hwfn,
                        DP_NOTICE(p_hwfn,
                                  "%d is not supported yet\n",
                                  p_filter_cmd->opcode);
+                       qed_sp_destroy_request(p_hwfn, *pp_ent);
                        return -EINVAL;
                }
 
@@ -2056,13 +2056,13 @@ qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn,
        } else {
                rc = qed_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
                if (rc)
-                       return rc;
+                       goto err;
 
                if (p_params->qid != QED_RFS_NTUPLE_QID_RSS) {
                        rc = qed_fw_l2_queue(p_hwfn, p_params->qid,
                                             &abs_rx_q_id);
                        if (rc)
-                               return rc;
+                               goto err;
 
                        p_ramrod->rx_qid_valid = 1;
                        p_ramrod->rx_qid = cpu_to_le16(abs_rx_q_id);
@@ -2083,6 +2083,10 @@ qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn,
                   (u64)p_params->addr, p_params->length);
 
        return qed_spq_post(p_hwfn, p_ent, NULL);
+
+err:
+       qed_sp_destroy_request(p_hwfn, p_ent);
+       return rc;
 }
 
 int qed_get_rxq_coalesce(struct qed_hwfn *p_hwfn,
index 35fd0db6a67777629fbaa7e1ab89c21b8030d31e..fff7f04d4525c51f15f7e349670a698354edc0f3 100644 (file)
@@ -1782,9 +1782,9 @@ static int qed_drain(struct qed_dev *cdev)
                        return -EBUSY;
                }
                rc = qed_mcp_drain(hwfn, ptt);
+               qed_ptt_release(hwfn, ptt);
                if (rc)
                        return rc;
-               qed_ptt_release(hwfn, ptt);
        }
 
        return 0;
index f40f654398a0782457240fa74bf81e0c65d7bf32..a96364df43203dbfe9b326a385a50b53dd1900c9 100644 (file)
@@ -1944,9 +1944,12 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
                             struct qed_ptt *p_ptt, u32 *p_speed_mask)
 {
        u32 transceiver_type, transceiver_state;
+       int ret;
 
-       qed_mcp_get_transceiver_data(p_hwfn, p_ptt, &transceiver_state,
-                                    &transceiver_type);
+       ret = qed_mcp_get_transceiver_data(p_hwfn, p_ptt, &transceiver_state,
+                                          &transceiver_type);
+       if (ret)
+               return ret;
 
        if (qed_is_transceiver_ready(transceiver_state, transceiver_type) ==
                                     false)
index c71391b9c757a1b03f55f21cc641c4718bbce719..7873d6dfd91f55607a6d60b23b568488edf7d360 100644 (file)
@@ -140,22 +140,34 @@ static u32 qed_rdma_get_sb_id(void *p_hwfn, u32 rel_sb_id)
        return FEAT_NUM((struct qed_hwfn *)p_hwfn, QED_PF_L2_QUE) + rel_sb_id;
 }
 
-static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
-                         struct qed_ptt *p_ptt,
-                         struct qed_rdma_start_in_params *params)
+int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn)
 {
        struct qed_rdma_info *p_rdma_info;
-       u32 num_cons, num_tasks;
-       int rc = -ENOMEM;
 
-       DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n");
-
-       /* Allocate a struct with current pf rdma info */
        p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL);
        if (!p_rdma_info)
-               return rc;
+               return -ENOMEM;
+
+       spin_lock_init(&p_rdma_info->lock);
 
        p_hwfn->p_rdma_info = p_rdma_info;
+       return 0;
+}
+
+void qed_rdma_info_free(struct qed_hwfn *p_hwfn)
+{
+       kfree(p_hwfn->p_rdma_info);
+       p_hwfn->p_rdma_info = NULL;
+}
+
+static int qed_rdma_alloc(struct qed_hwfn *p_hwfn)
+{
+       struct qed_rdma_info *p_rdma_info = p_hwfn->p_rdma_info;
+       u32 num_cons, num_tasks;
+       int rc = -ENOMEM;
+
+       DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "Allocating RDMA\n");
+
        if (QED_IS_IWARP_PERSONALITY(p_hwfn))
                p_rdma_info->proto = PROTOCOLID_IWARP;
        else
@@ -183,7 +195,7 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn,
        /* Allocate a struct with device params and fill it */
        p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL);
        if (!p_rdma_info->dev)
-               goto free_rdma_info;
+               return rc;
 
        /* Allocate a struct with port params and fill it */
        p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL);
@@ -298,8 +310,6 @@ free_rdma_port:
        kfree(p_rdma_info->port);
 free_rdma_dev:
        kfree(p_rdma_info->dev);
-free_rdma_info:
-       kfree(p_rdma_info);
 
        return rc;
 }
@@ -370,8 +380,6 @@ static void qed_rdma_resc_free(struct qed_hwfn *p_hwfn)
 
        kfree(p_rdma_info->port);
        kfree(p_rdma_info->dev);
-
-       kfree(p_rdma_info);
 }
 
 static void qed_rdma_free_tid(void *rdma_cxt, u32 itid)
@@ -679,8 +687,6 @@ static int qed_rdma_setup(struct qed_hwfn *p_hwfn,
 
        DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA setup\n");
 
-       spin_lock_init(&p_hwfn->p_rdma_info->lock);
-
        qed_rdma_init_devinfo(p_hwfn, params);
        qed_rdma_init_port(p_hwfn);
        qed_rdma_init_events(p_hwfn, params);
@@ -727,7 +733,7 @@ static int qed_rdma_stop(void *rdma_cxt)
        /* Disable RoCE search */
        qed_wr(p_hwfn, p_ptt, p_hwfn->rdma_prs_search_reg, 0);
        p_hwfn->b_rdma_enabled_in_prs = false;
-
+       p_hwfn->p_rdma_info->active = 0;
        qed_wr(p_hwfn, p_ptt, PRS_REG_ROCE_DEST_QP_MAX_PF, 0);
 
        ll2_ethertype_en = qed_rd(p_hwfn, p_ptt, PRS_REG_LIGHT_L2_ETHERTYPE_EN);
@@ -1236,7 +1242,8 @@ qed_rdma_create_qp(void *rdma_cxt,
        u8 max_stats_queues;
        int rc;
 
-       if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info) {
+       if (!rdma_cxt || !in_params || !out_params ||
+           !p_hwfn->p_rdma_info->active) {
                DP_ERR(p_hwfn->cdev,
                       "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n",
                       rdma_cxt, in_params, out_params);
@@ -1514,6 +1521,7 @@ qed_rdma_register_tid(void *rdma_cxt,
        default:
                rc = -EINVAL;
                DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
+               qed_sp_destroy_request(p_hwfn, p_ent);
                return rc;
        }
        SET_FIELD(p_ramrod->flags1,
@@ -1801,8 +1809,8 @@ bool qed_rdma_allocated_qps(struct qed_hwfn *p_hwfn)
 {
        bool result;
 
-       /* if rdma info has not been allocated, naturally there are no qps */
-       if (!p_hwfn->p_rdma_info)
+       /* if rdma wasn't activated yet, naturally there are no qps */
+       if (!p_hwfn->p_rdma_info->active)
                return false;
 
        spin_lock_bh(&p_hwfn->p_rdma_info->lock);
@@ -1848,7 +1856,7 @@ static int qed_rdma_start(void *rdma_cxt,
        if (!p_ptt)
                goto err;
 
-       rc = qed_rdma_alloc(p_hwfn, p_ptt, params);
+       rc = qed_rdma_alloc(p_hwfn);
        if (rc)
                goto err1;
 
@@ -1857,6 +1865,7 @@ static int qed_rdma_start(void *rdma_cxt,
                goto err2;
 
        qed_ptt_release(p_hwfn, p_ptt);
+       p_hwfn->p_rdma_info->active = 1;
 
        return rc;
 
index 6f722ee8ee945b13ee6f33df82d1692c0ae18304..3689fe3e593542fc487167aae73da99156add030 100644 (file)
@@ -102,6 +102,7 @@ struct qed_rdma_info {
        u16 max_queue_zones;
        enum protocol_type proto;
        struct qed_iwarp_info iwarp;
+       u8 active:1;
 };
 
 struct qed_rdma_qp {
@@ -176,10 +177,14 @@ struct qed_rdma_qp {
 #if IS_ENABLED(CONFIG_QED_RDMA)
 void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
 void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
+int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn);
+void qed_rdma_info_free(struct qed_hwfn *p_hwfn);
 #else
 static inline void qed_rdma_dpm_conf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) {}
 static inline void qed_rdma_dpm_bar(struct qed_hwfn *p_hwfn,
                                    struct qed_ptt *p_ptt) {}
+static inline int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) {return -EINVAL;}
+static inline void qed_rdma_info_free(struct qed_hwfn *p_hwfn) {}
 #endif
 
 int
index f9167d1354bbef3ccf2e972e8c002e64bbc24cce..e49fada854108718bf1dc5ea45fda2d4d264ded2 100644 (file)
@@ -745,6 +745,7 @@ static int qed_roce_sp_destroy_qp_responder(struct qed_hwfn *p_hwfn,
                DP_NOTICE(p_hwfn,
                          "qed destroy responder failed: cannot allocate memory (ramrod). rc = %d\n",
                          rc);
+               qed_sp_destroy_request(p_hwfn, p_ent);
                return rc;
        }
 
index e95431f6acd46fb6ace4c20cfe227388c890cdea..3157c0d9944177e784a62ef983dd2adc3b5c0f11 100644 (file)
@@ -167,6 +167,9 @@ struct qed_spq_entry {
        enum spq_mode                   comp_mode;
        struct qed_spq_comp_cb          comp_cb;
        struct qed_spq_comp_done        comp_done; /* SPQ_MODE_EBLOCK */
+
+       /* Posted entry for unlimited list entry in EBLOCK mode */
+       struct qed_spq_entry            *post_ent;
 };
 
 struct qed_eq {
@@ -396,6 +399,17 @@ struct qed_sp_init_data {
        struct qed_spq_comp_cb *p_comp_data;
 };
 
+/**
+ * @brief Returns a SPQ entry to the pool / frees the entry if allocated.
+ *        Should be called on in error flows after initializing the SPQ entry
+ *        and before posting it.
+ *
+ * @param p_hwfn
+ * @param p_ent
+ */
+void qed_sp_destroy_request(struct qed_hwfn *p_hwfn,
+                           struct qed_spq_entry *p_ent);
+
 int qed_sp_init_request(struct qed_hwfn *p_hwfn,
                        struct qed_spq_entry **pp_ent,
                        u8 cmd,
index 77b6248ad3b97d3a45caf27825faddabf9695a5b..888274fa208bc768b2ab9db2514407573bfab2e1 100644 (file)
 #include "qed_sp.h"
 #include "qed_sriov.h"
 
+void qed_sp_destroy_request(struct qed_hwfn *p_hwfn,
+                           struct qed_spq_entry *p_ent)
+{
+       /* qed_spq_get_entry() can either get an entry from the free_pool,
+        * or, if no entries are left, allocate a new entry and add it to
+        * the unlimited_pending list.
+        */
+       if (p_ent->queue == &p_hwfn->p_spq->unlimited_pending)
+               kfree(p_ent);
+       else
+               qed_spq_return_entry(p_hwfn, p_ent);
+}
+
 int qed_sp_init_request(struct qed_hwfn *p_hwfn,
                        struct qed_spq_entry **pp_ent,
                        u8 cmd, u8 protocol, struct qed_sp_init_data *p_data)
@@ -80,7 +93,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
 
        case QED_SPQ_MODE_BLOCK:
                if (!p_data->p_comp_data)
-                       return -EINVAL;
+                       goto err;
 
                p_ent->comp_cb.cookie = p_data->p_comp_data->cookie;
                break;
@@ -95,7 +108,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
        default:
                DP_NOTICE(p_hwfn, "Unknown SPQE completion mode %d\n",
                          p_ent->comp_mode);
-               return -EINVAL;
+               goto err;
        }
 
        DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
@@ -109,6 +122,11 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
        memset(&p_ent->ramrod, 0, sizeof(p_ent->ramrod));
 
        return 0;
+
+err:
+       qed_sp_destroy_request(p_hwfn, p_ent);
+
+       return -EINVAL;
 }
 
 static enum tunnel_clss qed_tunn_clss_to_fw_clss(u8 type)
index c4a6274dd625c2bf419cc78dfab20f899ada494d..0a9c5bb0fa486658a23132680a1aeddb9a72b518 100644 (file)
@@ -142,6 +142,7 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
 
        DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n");
        rc = qed_mcp_drain(p_hwfn, p_ptt);
+       qed_ptt_release(p_hwfn, p_ptt);
        if (rc) {
                DP_NOTICE(p_hwfn, "MCP drain failed\n");
                goto err;
@@ -150,18 +151,15 @@ static int qed_spq_block(struct qed_hwfn *p_hwfn,
        /* Retry after drain */
        rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
        if (!rc)
-               goto out;
+               return 0;
 
        comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
-       if (comp_done->done == 1)
+       if (comp_done->done == 1) {
                if (p_fw_ret)
                        *p_fw_ret = comp_done->fw_return_code;
-out:
-       qed_ptt_release(p_hwfn, p_ptt);
-       return 0;
-
+               return 0;
+       }
 err:
-       qed_ptt_release(p_hwfn, p_ptt);
        DP_NOTICE(p_hwfn,
                  "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
                  le32_to_cpu(p_ent->elem.hdr.cid),
@@ -685,6 +683,8 @@ static int qed_spq_add_entry(struct qed_hwfn *p_hwfn,
                        /* EBLOCK responsible to free the allocated p_ent */
                        if (p_ent->comp_mode != QED_SPQ_MODE_EBLOCK)
                                kfree(p_ent);
+                       else
+                               p_ent->post_ent = p_en2;
 
                        p_ent = p_en2;
                }
@@ -767,6 +767,25 @@ static int qed_spq_pend_post(struct qed_hwfn *p_hwfn)
                                 SPQ_HIGH_PRI_RESERVE_DEFAULT);
 }
 
+/* Avoid overriding of SPQ entries when getting out-of-order completions, by
+ * marking the completions in a bitmap and increasing the chain consumer only
+ * for the first successive completed entries.
+ */
+static void qed_spq_comp_bmap_update(struct qed_hwfn *p_hwfn, __le16 echo)
+{
+       u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE;
+       struct qed_spq *p_spq = p_hwfn->p_spq;
+
+       __set_bit(pos, p_spq->p_comp_bitmap);
+       while (test_bit(p_spq->comp_bitmap_idx,
+                       p_spq->p_comp_bitmap)) {
+               __clear_bit(p_spq->comp_bitmap_idx,
+                           p_spq->p_comp_bitmap);
+               p_spq->comp_bitmap_idx++;
+               qed_chain_return_produced(&p_spq->chain);
+       }
+}
+
 int qed_spq_post(struct qed_hwfn *p_hwfn,
                 struct qed_spq_entry *p_ent, u8 *fw_return_code)
 {
@@ -824,11 +843,12 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
                                   p_ent->queue == &p_spq->unlimited_pending);
 
                if (p_ent->queue == &p_spq->unlimited_pending) {
-                       /* This is an allocated p_ent which does not need to
-                        * return to pool.
-                        */
+                       struct qed_spq_entry *p_post_ent = p_ent->post_ent;
+
                        kfree(p_ent);
-                       return rc;
+
+                       /* Return the entry which was actually posted */
+                       p_ent = p_post_ent;
                }
 
                if (rc)
@@ -842,7 +862,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
 spq_post_fail2:
        spin_lock_bh(&p_spq->lock);
        list_del(&p_ent->list);
-       qed_chain_return_produced(&p_spq->chain);
+       qed_spq_comp_bmap_update(p_hwfn, p_ent->elem.hdr.echo);
 
 spq_post_fail:
        /* return to the free pool */
@@ -874,25 +894,8 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
        spin_lock_bh(&p_spq->lock);
        list_for_each_entry_safe(p_ent, tmp, &p_spq->completion_pending, list) {
                if (p_ent->elem.hdr.echo == echo) {
-                       u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE;
-
                        list_del(&p_ent->list);
-
-                       /* Avoid overriding of SPQ entries when getting
-                        * out-of-order completions, by marking the completions
-                        * in a bitmap and increasing the chain consumer only
-                        * for the first successive completed entries.
-                        */
-                       __set_bit(pos, p_spq->p_comp_bitmap);
-
-                       while (test_bit(p_spq->comp_bitmap_idx,
-                                       p_spq->p_comp_bitmap)) {
-                               __clear_bit(p_spq->comp_bitmap_idx,
-                                           p_spq->p_comp_bitmap);
-                               p_spq->comp_bitmap_idx++;
-                               qed_chain_return_produced(&p_spq->chain);
-                       }
-
+                       qed_spq_comp_bmap_update(p_hwfn, echo);
                        p_spq->comp_count++;
                        found = p_ent;
                        break;
@@ -931,11 +934,9 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
                           QED_MSG_SPQ,
                           "Got a completion without a callback function\n");
 
-       if ((found->comp_mode != QED_SPQ_MODE_EBLOCK) ||
-           (found->queue == &p_spq->unlimited_pending))
+       if (found->comp_mode != QED_SPQ_MODE_EBLOCK)
                /* EBLOCK  is responsible for returning its own entry into the
-                * free list, unless it originally added the entry into the
-                * unlimited pending list.
+                * free list.
                 */
                qed_spq_return_entry(p_hwfn, found);
 
index 9b08a9d9e15130f0518b1f7608bbaa36e6eb15b0..ca6290fa0f30940265ca1590de148c94eb2cf18e 100644 (file)
@@ -101,6 +101,7 @@ static int qed_sp_vf_start(struct qed_hwfn *p_hwfn, struct qed_vf_info *p_vf)
        default:
                DP_NOTICE(p_hwfn, "Unknown VF personality %d\n",
                          p_hwfn->hw_info.personality);
+               qed_sp_destroy_request(p_hwfn, p_ent);
                return -EINVAL;
        }
 
index 9647578cbe6a8fec82409c4eadf9aee02f6c7971..14f26bf3b388bdce2913241d5790ec52617c249d 100644 (file)
@@ -459,7 +459,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
                         struct cmd_desc_type0 *first_desc, struct sk_buff *skb,
                         struct qlcnic_host_tx_ring *tx_ring)
 {
-       u8 l4proto, opcode = 0, hdr_len = 0;
+       u8 l4proto, opcode = 0, hdr_len = 0, tag_vlan = 0;
        u16 flags = 0, vlan_tci = 0;
        int copied, offset, copy_len, size;
        struct cmd_desc_type0 *hwdesc;
@@ -472,14 +472,16 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
                flags = QLCNIC_FLAGS_VLAN_TAGGED;
                vlan_tci = ntohs(vh->h_vlan_TCI);
                protocol = ntohs(vh->h_vlan_encapsulated_proto);
+               tag_vlan = 1;
        } else if (skb_vlan_tag_present(skb)) {
                flags = QLCNIC_FLAGS_VLAN_OOB;
                vlan_tci = skb_vlan_tag_get(skb);
+               tag_vlan = 1;
        }
        if (unlikely(adapter->tx_pvid)) {
-               if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED))
+               if (tag_vlan && !(adapter->flags & QLCNIC_TAGGING_ENABLED))
                        return -EIO;
-               if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
+               if (tag_vlan && (adapter->flags & QLCNIC_TAGGING_ENABLED))
                        goto set_flags;
 
                flags = QLCNIC_FLAGS_VLAN_OOB;
index 0afc3d335d562d24466b9192aea291b910ebcdfe..d11c16aeb19ad45759c44e1dac2bb259cf976054 100644 (file)
@@ -234,7 +234,7 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
                      struct net_device *real_dev,
                      struct rmnet_endpoint *ep)
 {
-       struct rmnet_priv *priv;
+       struct rmnet_priv *priv = netdev_priv(rmnet_dev);
        int rc;
 
        if (ep->egress_dev)
@@ -247,6 +247,8 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
        rmnet_dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        rmnet_dev->hw_features |= NETIF_F_SG;
 
+       priv->real_dev = real_dev;
+
        rc = register_netdevice(rmnet_dev);
        if (!rc) {
                ep->egress_dev = rmnet_dev;
@@ -255,9 +257,7 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
 
                rmnet_dev->rtnl_link_ops = &rmnet_link_ops;
 
-               priv = netdev_priv(rmnet_dev);
                priv->mux_id = id;
-               priv->real_dev = real_dev;
 
                netdev_dbg(rmnet_dev, "rmnet dev created\n");
        }
index b1b305f8f4143626fc664445182c5e2afc38b87c..272b9ca663148f36ccb7ae45363df773f2dd4c4c 100644 (file)
@@ -365,7 +365,8 @@ struct dma_features {
 
 /* GMAC TX FIFO is 8K, Rx FIFO is 16K */
 #define BUF_SIZE_16KiB 16384
-#define BUF_SIZE_8KiB 8192
+/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */
+#define BUF_SIZE_8KiB 8188
 #define BUF_SIZE_4KiB 4096
 #define BUF_SIZE_2KiB 2048
 
index ca9d7e48034ceb33f5f4eb4db5b99691ed1a278f..40d6356a7e73c213f0d1d073387b8605bb4f3726 100644 (file)
@@ -31,7 +31,7 @@
 /* Enhanced descriptors */
 static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end)
 {
-       p->des1 |= cpu_to_le32(((BUF_SIZE_8KiB - 1)
+       p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
                        << ERDES1_BUFFER2_SIZE_SHIFT)
                   & ERDES1_BUFFER2_SIZE_MASK);
 
index 77914c89d7497de6f9a251196fe079f49364ee13..5ef91a790f9d16fbd122f71e130cf7ecf5249a68 100644 (file)
@@ -262,7 +262,7 @@ static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
                                  int mode, int end)
 {
        p->des0 |= cpu_to_le32(RDES0_OWN);
-       p->des1 |= cpu_to_le32((BUF_SIZE_8KiB - 1) & ERDES1_BUFFER1_SIZE_MASK);
+       p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK);
 
        if (mode == STMMAC_CHAIN_MODE)
                ehn_desc_rx_set_on_chain(p);
index abc3f85270cd0709e667a17112ff2d9d7f4ff8f4..d8c5bc4122195d73f7150f2775797cc6ba9a3393 100644 (file)
@@ -140,7 +140,7 @@ static void clean_desc3(void *priv_ptr, struct dma_desc *p)
 static int set_16kib_bfsize(int mtu)
 {
        int ret = 0;
-       if (unlikely(mtu >= BUF_SIZE_8KiB))
+       if (unlikely(mtu > BUF_SIZE_8KiB))
                ret = BUF_SIZE_16KiB;
        return ret;
 }
index 3b7f10a5f06a660fbf6408f7adbcd0851ad79921..c5cae8e74dc40720eb2db3a3d91118a8ceece281 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0+
 /*     FDDI network adapter driver for DEC FDDIcontroller 700/700-C devices.
  *
  *     Copyright (c) 2018  Maciej W. Rozycki
@@ -56,7 +56,7 @@
 #define DRV_VERSION "v.1.1.4"
 #define DRV_RELDATE "Oct  6 2018"
 
-static char version[] =
+static const char version[] =
        DRV_NAME ": " DRV_VERSION "  " DRV_RELDATE "  Maciej W. Rozycki\n";
 
 MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
@@ -784,7 +784,7 @@ err_rx:
 static void fza_tx_smt(struct net_device *dev)
 {
        struct fza_private *fp = netdev_priv(dev);
-       struct fza_buffer_tx __iomem *smt_tx_ptr, *skb_data_ptr;
+       struct fza_buffer_tx __iomem *smt_tx_ptr;
        int i, len;
        u32 own;
 
@@ -799,6 +799,7 @@ static void fza_tx_smt(struct net_device *dev)
 
                if (!netif_queue_stopped(dev)) {
                        if (dev_nit_active(dev)) {
+                               struct fza_buffer_tx *skb_data_ptr;
                                struct sk_buff *skb;
 
                                /* Length must be a multiple of 4 as only word
index b06acf32738ea5f32083d4403a3b3c95315396d0..93bda61be8e382646f3c9213e519690ef8cf3ab4 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*     FDDI network adapter driver for DEC FDDIcontroller 700/700-C devices.
  *
  *     Copyright (c) 2018  Maciej W. Rozycki
@@ -235,6 +235,7 @@ struct fza_ring_cmd {
 #define FZA_RING_CMD           0x200400        /* command ring address */
 #define FZA_RING_CMD_SIZE      0x40            /* command descriptor ring
                                                 * size
+                                                */
 /* Command constants. */
 #define FZA_RING_CMD_MASK      0x7fffffff
 #define FZA_RING_CMD_NOP       0x00000000      /* nop */
index e86ea105c8022290bf1b02d781fe536d90d74d5a..70453701045371e9d2b64cd3f65e070c4b20faeb 100644 (file)
@@ -92,7 +92,7 @@ static int bcm54612e_config_init(struct phy_device *phydev)
        return 0;
 }
 
-static int bcm5481x_config(struct phy_device *phydev)
+static int bcm54xx_config_clock_delay(struct phy_device *phydev)
 {
        int rc, val;
 
@@ -429,7 +429,7 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
        ret = genphy_config_aneg(phydev);
 
        /* Then we can set up the delay. */
-       bcm5481x_config(phydev);
+       bcm54xx_config_clock_delay(phydev);
 
        if (of_property_read_bool(np, "enet-phy-lane-swap")) {
                /* Lane Swap - Undocumented register...magic! */
@@ -442,6 +442,19 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
        return ret;
 }
 
+static int bcm54616s_config_aneg(struct phy_device *phydev)
+{
+       int ret;
+
+       /* Aneg firsly. */
+       ret = genphy_config_aneg(phydev);
+
+       /* Then we can set up the delay. */
+       bcm54xx_config_clock_delay(phydev);
+
+       return ret;
+}
+
 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
 {
        int val;
@@ -636,6 +649,7 @@ static struct phy_driver broadcom_drivers[] = {
        .features       = PHY_GBIT_FEATURES,
        .flags          = PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
+       .config_aneg    = bcm54616s_config_aneg,
        .ack_interrupt  = bcm_phy_ack_intr,
        .config_intr    = bcm_phy_config_intr,
 }, {
index 33265747bf3994c668cfcb2a8f7f3d9f768d370a..0fbcedcdf6e2ae5b6d9d8ecca66937532db263cb 100644 (file)
@@ -63,7 +63,7 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
                 * assume the pin serves as pull-up. If direction is
                 * output, the default value is high.
                 */
-               gpiod_set_value(bitbang->mdo, 1);
+               gpiod_set_value_cansleep(bitbang->mdo, 1);
                return;
        }
 
@@ -78,7 +78,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl)
        struct mdio_gpio_info *bitbang =
                container_of(ctrl, struct mdio_gpio_info, ctrl);
 
-       return gpiod_get_value(bitbang->mdio);
+       return gpiod_get_value_cansleep(bitbang->mdio);
 }
 
 static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
@@ -87,9 +87,9 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
                container_of(ctrl, struct mdio_gpio_info, ctrl);
 
        if (bitbang->mdo)
-               gpiod_set_value(bitbang->mdo, what);
+               gpiod_set_value_cansleep(bitbang->mdo, what);
        else
-               gpiod_set_value(bitbang->mdio, what);
+               gpiod_set_value_cansleep(bitbang->mdio, what);
 }
 
 static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
@@ -97,7 +97,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
        struct mdio_gpio_info *bitbang =
                container_of(ctrl, struct mdio_gpio_info, ctrl);
 
-       gpiod_set_value(bitbang->mdc, what);
+       gpiod_set_value_cansleep(bitbang->mdc, what);
 }
 
 static const struct mdiobb_ops mdio_gpio_ops = {
index 7fc8508b5231d94beab4c45bf7666d15d4ef786f..271e8adc39f1005dcc48b678ef528d442f12b9f8 100644 (file)
@@ -220,7 +220,7 @@ static struct phy_driver realtek_drvs[] = {
                .flags          = PHY_HAS_INTERRUPT,
        }, {
                .phy_id         = 0x001cc816,
-               .name           = "RTL8201F 10/100Mbps Ethernet",
+               .name           = "RTL8201F Fast Ethernet",
                .phy_id_mask    = 0x001fffff,
                .features       = PHY_BASIC_FEATURES,
                .flags          = PHY_HAS_INTERRUPT,
index 060135ceaf0e1a76615b2e6cd6830d42ac8becdf..e244f5d7512a6e8f8a2a5b5eb141a2024f80a078 100644 (file)
@@ -1536,6 +1536,7 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile,
 
        if (!rx_batched || (!more && skb_queue_empty(queue))) {
                local_bh_disable();
+               skb_record_rx_queue(skb, tfile->queue_index);
                netif_receive_skb(skb);
                local_bh_enable();
                return;
@@ -1555,8 +1556,11 @@ static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile,
                struct sk_buff *nskb;
 
                local_bh_disable();
-               while ((nskb = __skb_dequeue(&process_queue)))
+               while ((nskb = __skb_dequeue(&process_queue))) {
+                       skb_record_rx_queue(nskb, tfile->queue_index);
                        netif_receive_skb(nskb);
+               }
+               skb_record_rx_queue(skb, tfile->queue_index);
                netif_receive_skb(skb);
                local_bh_enable();
        }
@@ -2451,6 +2455,7 @@ build:
        if (!rcu_dereference(tun->steering_prog))
                rxhash = __skb_get_hash_symmetric(skb);
 
+       skb_record_rx_queue(skb, tfile->queue_index);
        netif_receive_skb(skb);
 
        stats = get_cpu_ptr(tun->pcpu_stats);
index 262e7a3c23cb67fbfd66b81ed0d26af0f0480d84..f2d01cb6f958cd3235dba2383950dd5fa57d8c08 100644 (file)
@@ -1321,6 +1321,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
        dev->net->flags |= IFF_MULTICAST;
        dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
+       dev->net->min_mtu = ETH_MIN_MTU;
+       dev->net->max_mtu = ETH_DATA_LEN;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
 
        pdata->dev = dev;
@@ -1598,6 +1600,8 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
                return ret;
        }
 
+       cancel_delayed_work_sync(&pdata->carrier_check);
+
        if (pdata->suspend_flags) {
                netdev_warn(dev->net, "error during last resume\n");
                pdata->suspend_flags = 0;
@@ -1840,6 +1844,11 @@ done:
         */
        if (ret && PMSG_IS_AUTO(message))
                usbnet_resume(intf);
+
+       if (ret)
+               schedule_delayed_work(&pdata->carrier_check,
+                                     CARRIER_CHECK_DELAY);
+
        return ret;
 }
 
index 2e65be8b1387af92a2b099478c36e5a28e6d7ffc..559d567693b8d060b920952e8429d219471b9569 100644 (file)
@@ -1519,8 +1519,10 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
        if (ns->ndev)
                nvme_nvm_update_nvm_info(ns);
 #ifdef CONFIG_NVME_MULTIPATH
-       if (ns->head->disk)
+       if (ns->head->disk) {
                nvme_update_disk_info(ns->head->disk, ns, id);
+               blk_queue_stack_limits(ns->head->disk->queue, ns->queue);
+       }
 #endif
 }
 
index 5e3cc8c59a394fce6ba25f1c621b26903185963d..9901afd804ce3720709c198fb54140d2a2ea3d85 100644 (file)
@@ -285,6 +285,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
        blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
        /* set to a default value for 512 until disk is validated */
        blk_queue_logical_block_size(q, 512);
+       blk_set_stacking_limits(&q->limits);
 
        /* we need to propagate up the VMC settings */
        if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
index f4efe289dc7bc2caa8ce3c2a1a44b97e66cd0324..a5f9bbce863f42dcff6c23759801fa9c48d0b210 100644 (file)
@@ -420,7 +420,7 @@ static void nvmet_p2pmem_ns_add_p2p(struct nvmet_ctrl *ctrl,
        struct pci_dev *p2p_dev;
        int ret;
 
-       if (!ctrl->p2p_client)
+       if (!ctrl->p2p_client || !ns->use_p2pmem)
                return;
 
        if (ns->p2p_dev) {
index ddce100be57a48f883558e147669a3d06f1046bb..3f7971d3706d90d5fbf382072ed8d2da2ac6e8b6 100644 (file)
@@ -122,7 +122,6 @@ struct nvmet_rdma_device {
        int                     inline_page_count;
 };
 
-static struct workqueue_struct *nvmet_rdma_delete_wq;
 static bool nvmet_rdma_use_srq;
 module_param_named(use_srq, nvmet_rdma_use_srq, bool, 0444);
 MODULE_PARM_DESC(use_srq, "Use shared receive queue.");
@@ -1274,12 +1273,12 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
 
        if (queue->host_qid == 0) {
                /* Let inflight controller teardown complete */
-               flush_workqueue(nvmet_rdma_delete_wq);
+               flush_scheduled_work();
        }
 
        ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
        if (ret) {
-               queue_work(nvmet_rdma_delete_wq, &queue->release_work);
+               schedule_work(&queue->release_work);
                /* Destroying rdma_cm id is not needed here */
                return 0;
        }
@@ -1344,7 +1343,7 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue)
 
        if (disconnect) {
                rdma_disconnect(queue->cm_id);
-               queue_work(nvmet_rdma_delete_wq, &queue->release_work);
+               schedule_work(&queue->release_work);
        }
 }
 
@@ -1374,7 +1373,7 @@ static void nvmet_rdma_queue_connect_fail(struct rdma_cm_id *cm_id,
        mutex_unlock(&nvmet_rdma_queue_mutex);
 
        pr_err("failed to connect queue %d\n", queue->idx);
-       queue_work(nvmet_rdma_delete_wq, &queue->release_work);
+       schedule_work(&queue->release_work);
 }
 
 /**
@@ -1656,17 +1655,8 @@ static int __init nvmet_rdma_init(void)
        if (ret)
                goto err_ib_client;
 
-       nvmet_rdma_delete_wq = alloc_workqueue("nvmet-rdma-delete-wq",
-                       WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
-       if (!nvmet_rdma_delete_wq) {
-               ret = -ENOMEM;
-               goto err_unreg_transport;
-       }
-
        return 0;
 
-err_unreg_transport:
-       nvmet_unregister_transport(&nvmet_rdma_ops);
 err_ib_client:
        ib_unregister_client(&nvmet_rdma_ib_client);
        return ret;
@@ -1674,7 +1664,6 @@ err_ib_client:
 
 static void __exit nvmet_rdma_exit(void)
 {
-       destroy_workqueue(nvmet_rdma_delete_wq);
        nvmet_unregister_transport(&nvmet_rdma_ops);
        ib_unregister_client(&nvmet_rdma_ib_client);
        WARN_ON_ONCE(!list_empty(&nvmet_rdma_queue_list));
index 0f27fad9fe940de645f61f868d0578795e073abc..5592437bb3d155aa415ee23511e404aa2afe9ba3 100644 (file)
@@ -149,9 +149,11 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
         * set by the driver.
         */
        mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
-       dev->bus_dma_mask = mask;
        dev->coherent_dma_mask &= mask;
        *dev->dma_mask &= mask;
+       /* ...but only set bus mask if we found valid dma-ranges earlier */
+       if (!ret)
+               dev->bus_dma_mask = mask;
 
        coherent = of_dma_is_coherent(np);
        dev_dbg(dev, "device is%sdma coherent\n",
index 35c64a4295e07edc9b5f59ebaed18d3ab2ef1c52..fe6b13608e5101458254d4f522454df65dc2e8fa 100644 (file)
@@ -104,9 +104,14 @@ static int __init of_numa_parse_distance_map_v1(struct device_node *map)
                distance = of_read_number(matrix, 1);
                matrix++;
 
+               if ((nodea == nodeb && distance != LOCAL_DISTANCE) ||
+                   (nodea != nodeb && distance <= LOCAL_DISTANCE)) {
+                       pr_err("Invalid distance[node%d -> node%d] = %d\n",
+                              nodea, nodeb, distance);
+                       return -EINVAL;
+               }
+
                numa_set_distance(nodea, nodeb, distance);
-               pr_debug("distance[node%d -> node%d] = %d\n",
-                        nodea, nodeb, distance);
 
                /* Set default distance of node B->A same as A->B */
                if (nodeb > nodea)
index 2a4aa64685794434f9ffdc5c38613035e63038f3..921db6f803403a27f7f4f8bb4394b9a94d95e0bd 100644 (file)
@@ -793,15 +793,10 @@ static void pci_acpi_setup(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
        struct acpi_device *adev = ACPI_COMPANION(dev);
-       int node;
 
        if (!adev)
                return;
 
-       node = acpi_get_node(adev->handle);
-       if (node != NUMA_NO_NODE)
-               set_dev_node(dev, node);
-
        pci_acpi_optimize_delay(pci_dev, adev->handle);
 
        pci_acpi_add_pm_notifier(adev, pci_dev);
index 4ceb06f8a33c965aa51cb317b56e8a672b55a090..4edeb4cae72aa28ba251558a499ce5a13436d237 100644 (file)
@@ -830,7 +830,7 @@ static struct meson_bank meson_gxbb_periphs_banks[] = {
 
 static struct meson_bank meson_gxbb_aobus_banks[] = {
        /*   name    first      last       irq    pullen  pull    dir     out     in  */
-       BANK("AO",   GPIOAO_0,  GPIOAO_13, 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+       BANK("AO",   GPIOAO_0,  GPIOAO_13, 0, 13, 0,  16, 0, 0,   0,  0,  0, 16,  1,  0),
 };
 
 static struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
index 7dae1d7bf6b0a50f75c9d104f43f93972abaf27d..158f618f169570d07dcbd2b9850c72f7334ca495 100644 (file)
@@ -807,7 +807,7 @@ static struct meson_bank meson_gxl_periphs_banks[] = {
 
 static struct meson_bank meson_gxl_aobus_banks[] = {
        /*   name    first      last      irq   pullen  pull    dir     out     in  */
-       BANK("AO",   GPIOAO_0,  GPIOAO_9, 0, 9, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+       BANK("AO",   GPIOAO_0,  GPIOAO_9, 0, 9, 0,  16, 0, 0,   0,  0,  0, 16,  1,  0),
 };
 
 static struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
index f8b778a7d47174b902d398fba74ba1845d88b126..53d449076dee32bb64cf3f0093b4a7e9016b9fa7 100644 (file)
@@ -192,7 +192,7 @@ static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
                        dev_dbg(pc->dev, "pin %u: disable bias\n", pin);
 
                        meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
-                       ret = regmap_update_bits(pc->reg_pull, reg,
+                       ret = regmap_update_bits(pc->reg_pullen, reg,
                                                 BIT(bit), 0);
                        if (ret)
                                return ret;
index c6d79315218fa69cadcdde9aa49d657d6916f5bb..86466173114da013ff7dff4e6a89195c9399a82d 100644 (file)
@@ -1053,7 +1053,7 @@ static struct meson_bank meson8_cbus_banks[] = {
 
 static struct meson_bank meson8_aobus_banks[] = {
        /*   name    first     last         irq    pullen  pull    dir     out     in  */
-       BANK("AO",   GPIOAO_0, GPIO_TEST_N, 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+       BANK("AO",   GPIOAO_0, GPIO_TEST_N, 0, 13, 0, 16,  0,  0,  0,  0,  0, 16,  1,  0),
 };
 
 static struct meson_pinctrl_data meson8_cbus_pinctrl_data = {
index bb2a30964fc69a20bfe488a8904ebd6badaf8e71..647ad15d5c3c41ee538688ade979145efa459b9b 100644 (file)
@@ -906,7 +906,7 @@ static struct meson_bank meson8b_cbus_banks[] = {
 
 static struct meson_bank meson8b_aobus_banks[] = {
        /*   name    first     lastc        irq    pullen  pull    dir     out     in  */
-       BANK("AO",   GPIOAO_0, GPIO_TEST_N, 0, 13, 0,  0,  0, 16,  0,  0,  0, 16,  1,  0),
+       BANK("AO",   GPIOAO_0, GPIO_TEST_N, 0, 13, 0,  16, 0, 0,  0,  0,  0, 16,  1,  0),
 };
 
 static struct meson_pinctrl_data meson8b_cbus_pinctrl_data = {
index e79f2a181ad24217a3e3bc232593184b82d494fd..b9ec4a16db1f6b6fd113c5661a28aa0e9153eeaa 100644 (file)
@@ -50,8 +50,10 @@ static int __init rtc_hctosys(void)
        tv64.tv_sec = rtc_tm_to_time64(&tm);
 
 #if BITS_PER_LONG == 32
-       if (tv64.tv_sec > INT_MAX)
+       if (tv64.tv_sec > INT_MAX) {
+               err = -ERANGE;
                goto err_read;
+       }
 #endif
 
        err = do_settimeofday64(&tv64);
index df0c5776d49bb6f5553dbbf2bc97b3235beae902..a5a19ff10535463d91d39d69ced1f13110ff139d 100644 (file)
@@ -257,6 +257,7 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
        unsigned char   rtc_control;
 
+       /* This not only a rtc_op, but also called directly */
        if (!is_valid_irq(cmos->irq))
                return -EIO;
 
@@ -452,6 +453,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        unsigned char mon, mday, hrs, min, sec, rtc_control;
        int ret;
 
+       /* This not only a rtc_op, but also called directly */
        if (!is_valid_irq(cmos->irq))
                return -EIO;
 
@@ -516,9 +518,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
        unsigned long   flags;
 
-       if (!is_valid_irq(cmos->irq))
-               return -EINVAL;
-
        spin_lock_irqsave(&rtc_lock, flags);
 
        if (enabled)
@@ -579,6 +578,12 @@ static const struct rtc_class_ops cmos_rtc_ops = {
        .alarm_irq_enable       = cmos_alarm_irq_enable,
 };
 
+static const struct rtc_class_ops cmos_rtc_ops_no_alarm = {
+       .read_time              = cmos_read_time,
+       .set_time               = cmos_set_time,
+       .proc                   = cmos_procfs,
+};
+
 /*----------------------------------------------------------------*/
 
 /*
@@ -855,9 +860,12 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                        dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
                        goto cleanup1;
                }
+
+               cmos_rtc.rtc->ops = &cmos_rtc_ops;
+       } else {
+               cmos_rtc.rtc->ops = &cmos_rtc_ops_no_alarm;
        }
 
-       cmos_rtc.rtc->ops = &cmos_rtc_ops;
        cmos_rtc.rtc->nvram_old_abi = true;
        retval = rtc_register_device(cmos_rtc.rtc);
        if (retval)
index 9f99a0966550b5e77672e83cc707eda26b22ede5..7cb786d76e3c1da81bf5055bf01375546a74e9ff 100644 (file)
@@ -303,6 +303,9 @@ static int pcf2127_i2c_gather_write(void *context,
        memcpy(buf + 1, val, val_size);
 
        ret = i2c_master_send(client, buf, val_size + 1);
+
+       kfree(buf);
+
        if (ret != val_size + 1)
                return ret < 0 ? ret : -EIO;
 
index f96ec68af2e58aabfa0bdb71dde1f05ff8ad4151..dcbf5c857743782871d9be3dfe51f9fee3d83d91 100644 (file)
@@ -415,9 +415,9 @@ static irqreturn_t ism_handle_irq(int irq, void *data)
                        break;
 
                clear_bit_inv(bit, bv);
+               ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0;
                barrier();
                smcd_handle_irq(ism->smcd, bit + ISM_DMB_BIT_OFFSET);
-               ism->sba->dmbe_mask[bit + ISM_DMB_BIT_OFFSET] = 0;
        }
 
        if (ism->sba->e) {
index 6843bc7ee9f24525789e3bd5100ee8278fd3e413..04e294d1d16d7ea68f8c9aea0d2f56bc5cb6ec11 100644 (file)
@@ -87,6 +87,18 @@ struct qeth_dbf_info {
 #define SENSE_RESETTING_EVENT_BYTE 1
 #define SENSE_RESETTING_EVENT_FLAG 0x80
 
+static inline u32 qeth_get_device_id(struct ccw_device *cdev)
+{
+       struct ccw_dev_id dev_id;
+       u32 id;
+
+       ccw_device_get_id(cdev, &dev_id);
+       id = dev_id.devno;
+       id |= (u32) (dev_id.ssid << 16);
+
+       return id;
+}
+
 /*
  * Common IO related definitions
  */
@@ -97,7 +109,8 @@ struct qeth_dbf_info {
 #define CARD_RDEV_ID(card) dev_name(&card->read.ccwdev->dev)
 #define CARD_WDEV_ID(card) dev_name(&card->write.ccwdev->dev)
 #define CARD_DDEV_ID(card) dev_name(&card->data.ccwdev->dev)
-#define CHANNEL_ID(channel) dev_name(&channel->ccwdev->dev)
+#define CCW_DEVID(cdev)                (qeth_get_device_id(cdev))
+#define CARD_DEVID(card)       (CCW_DEVID(CARD_RDEV(card)))
 
 /**
  * card stuff
@@ -830,6 +843,11 @@ struct qeth_trap_id {
 /*some helper functions*/
 #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
 
+static inline bool qeth_netdev_is_registered(struct net_device *dev)
+{
+       return dev->netdev_ops != NULL;
+}
+
 static inline void qeth_scrub_qdio_buffer(struct qdio_buffer *buf,
                                          unsigned int elements)
 {
@@ -973,7 +991,7 @@ int qeth_wait_for_threads(struct qeth_card *, unsigned long);
 int qeth_do_run_thread(struct qeth_card *, unsigned long);
 void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
 void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
-int qeth_core_hardsetup_card(struct qeth_card *);
+int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok);
 void qeth_print_status_message(struct qeth_card *);
 int qeth_init_qdio_queues(struct qeth_card *);
 int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
@@ -1028,11 +1046,6 @@ int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
 int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
 void qeth_trace_features(struct qeth_card *);
 void qeth_close_dev(struct qeth_card *);
-int qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, __u16,
-                         long,
-                         int (*reply_cb)(struct qeth_card *,
-                                         struct qeth_reply *, unsigned long),
-                         void *);
 int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long);
 struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
                                                 enum qeth_ipa_funcs,
index 3274f13aad57612967cbcfd832a2349572a0b122..4bce5ae65a55c193ec84c0d64137adde497daf6b 100644 (file)
@@ -167,6 +167,8 @@ const char *qeth_get_cardname_short(struct qeth_card *card)
                                return "OSD_1000";
                        case QETH_LINK_TYPE_10GBIT_ETH:
                                return "OSD_10GIG";
+                       case QETH_LINK_TYPE_25GBIT_ETH:
+                               return "OSD_25GIG";
                        case QETH_LINK_TYPE_LANE_ETH100:
                                return "OSD_FE_LANE";
                        case QETH_LINK_TYPE_LANE_TR:
@@ -554,8 +556,8 @@ static int __qeth_issue_next_read(struct qeth_card *card)
        if (!iob) {
                dev_warn(&card->gdev->dev, "The qeth device driver "
                        "failed to recover an error on the device\n");
-               QETH_DBF_MESSAGE(2, "%s issue_next_read failed: no iob "
-                       "available\n", dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(2, "issue_next_read on device %x failed: no iob available\n",
+                                CARD_DEVID(card));
                return -ENOMEM;
        }
        qeth_setup_ccw(channel->ccw, CCW_CMD_READ, QETH_BUFSIZE, iob->data);
@@ -563,8 +565,8 @@ static int __qeth_issue_next_read(struct qeth_card *card)
        rc = ccw_device_start(channel->ccwdev, channel->ccw,
                              (addr_t) iob, 0, 0);
        if (rc) {
-               QETH_DBF_MESSAGE(2, "%s error in starting next read ccw! "
-                       "rc=%i\n", dev_name(&card->gdev->dev), rc);
+               QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n",
+                                rc, CARD_DEVID(card));
                atomic_set(&channel->irq_pending, 0);
                card->read_or_write_problem = 1;
                qeth_schedule_recovery(card);
@@ -613,16 +615,14 @@ static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
        const char *ipa_name;
        int com = cmd->hdr.command;
        ipa_name = qeth_get_ipa_cmd_name(com);
+
        if (rc)
-               QETH_DBF_MESSAGE(2, "IPA: %s(x%X) for %s/%s returned "
-                               "x%X \"%s\"\n",
-                               ipa_name, com, dev_name(&card->gdev->dev),
-                               QETH_CARD_IFNAME(card), rc,
-                               qeth_get_ipa_msg(rc));
+               QETH_DBF_MESSAGE(2, "IPA: %s(%#x) for device %x returned %#x \"%s\"\n",
+                                ipa_name, com, CARD_DEVID(card), rc,
+                                qeth_get_ipa_msg(rc));
        else
-               QETH_DBF_MESSAGE(5, "IPA: %s(x%X) for %s/%s succeeded\n",
-                               ipa_name, com, dev_name(&card->gdev->dev),
-                               QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(5, "IPA: %s(%#x) for device %x succeeded\n",
+                                ipa_name, com, CARD_DEVID(card));
 }
 
 static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
@@ -711,7 +711,7 @@ static int qeth_check_idx_response(struct qeth_card *card,
 
        QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN);
        if ((buffer[2] & 0xc0) == 0xc0) {
-               QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#02x\n",
+               QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#04x\n",
                                 buffer[4]);
                QETH_CARD_TEXT(card, 2, "ckidxres");
                QETH_CARD_TEXT(card, 2, " idxterm");
@@ -972,8 +972,8 @@ static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev,
                QETH_CARD_TEXT(card, 2, "CGENCHK");
                dev_warn(&cdev->dev, "The qeth device driver "
                        "failed to recover an error on the device\n");
-               QETH_DBF_MESSAGE(2, "%s check on device dstat=x%x, cstat=x%x\n",
-                       dev_name(&cdev->dev), dstat, cstat);
+               QETH_DBF_MESSAGE(2, "check on channel %x with dstat=%#x, cstat=%#x\n",
+                                CCW_DEVID(cdev), dstat, cstat);
                print_hex_dump(KERN_WARNING, "qeth: irb ", DUMP_PREFIX_OFFSET,
                                16, 1, irb, 64, 1);
                return 1;
@@ -1013,8 +1013,8 @@ static long qeth_check_irb_error(struct qeth_card *card,
 
        switch (PTR_ERR(irb)) {
        case -EIO:
-               QETH_DBF_MESSAGE(2, "%s i/o-error on device\n",
-                       dev_name(&cdev->dev));
+               QETH_DBF_MESSAGE(2, "i/o-error on channel %x\n",
+                                CCW_DEVID(cdev));
                QETH_CARD_TEXT(card, 2, "ckirberr");
                QETH_CARD_TEXT_(card, 2, "  rc%d", -EIO);
                break;
@@ -1031,8 +1031,8 @@ static long qeth_check_irb_error(struct qeth_card *card,
                }
                break;
        default:
-               QETH_DBF_MESSAGE(2, "%s unknown error %ld on device\n",
-                       dev_name(&cdev->dev), PTR_ERR(irb));
+               QETH_DBF_MESSAGE(2, "unknown error %ld on channel %x\n",
+                                PTR_ERR(irb), CCW_DEVID(cdev));
                QETH_CARD_TEXT(card, 2, "ckirberr");
                QETH_CARD_TEXT(card, 2, "  rc???");
        }
@@ -1114,9 +1114,9 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                        dev_warn(&channel->ccwdev->dev,
                                "The qeth device driver failed to recover "
                                "an error on the device\n");
-                       QETH_DBF_MESSAGE(2, "%s sense data available. cstat "
-                               "0x%X dstat 0x%X\n",
-                               dev_name(&channel->ccwdev->dev), cstat, dstat);
+                       QETH_DBF_MESSAGE(2, "sense data available on channel %x: cstat %#X dstat %#X\n",
+                                        CCW_DEVID(channel->ccwdev), cstat,
+                                        dstat);
                        print_hex_dump(KERN_WARNING, "qeth: irb ",
                                DUMP_PREFIX_OFFSET, 16, 1, irb, 32, 1);
                        print_hex_dump(KERN_WARNING, "qeth: sense data ",
@@ -1890,8 +1890,8 @@ static int qeth_idx_activate_channel(struct qeth_card *card,
        if (channel->state != CH_STATE_ACTIVATING) {
                dev_warn(&channel->ccwdev->dev, "The qeth device driver"
                        " failed to recover an error on the device\n");
-               QETH_DBF_MESSAGE(2, "%s IDX activate timed out\n",
-                       dev_name(&channel->ccwdev->dev));
+               QETH_DBF_MESSAGE(2, "IDX activate timed out on channel %x\n",
+                                CCW_DEVID(channel->ccwdev));
                QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME);
                return -ETIME;
        }
@@ -1926,17 +1926,15 @@ static void qeth_idx_write_cb(struct qeth_card *card,
                                "The adapter is used exclusively by another "
                                "host\n");
                else
-                       QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on write channel:"
-                               " negative reply\n",
-                               dev_name(&channel->ccwdev->dev));
+                       QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: negative reply\n",
+                                        CCW_DEVID(channel->ccwdev));
                goto out;
        }
        memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
        if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
-               QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on write channel: "
-                       "function level mismatch (sent: 0x%x, received: "
-                       "0x%x)\n", dev_name(&channel->ccwdev->dev),
-                       card->info.func_level, temp);
+               QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: function level mismatch (sent: %#x, received: %#x)\n",
+                                CCW_DEVID(channel->ccwdev),
+                                card->info.func_level, temp);
                goto out;
        }
        channel->state = CH_STATE_UP;
@@ -1973,9 +1971,8 @@ static void qeth_idx_read_cb(struct qeth_card *card,
                                "insufficient authorization\n");
                        break;
                default:
-                       QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel:"
-                               " negative reply\n",
-                               dev_name(&channel->ccwdev->dev));
+                       QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: negative reply\n",
+                                        CCW_DEVID(channel->ccwdev));
                }
                QETH_CARD_TEXT_(card, 2, "idxread%c",
                        QETH_IDX_ACT_CAUSE_CODE(iob->data));
@@ -1984,10 +1981,9 @@ static void qeth_idx_read_cb(struct qeth_card *card,
 
        memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
        if (temp != qeth_peer_func_level(card->info.func_level)) {
-               QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel: function "
-                       "level mismatch (sent: 0x%x, received: 0x%x)\n",
-                       dev_name(&channel->ccwdev->dev),
-                       card->info.func_level, temp);
+               QETH_DBF_MESSAGE(2, "IDX_ACTIVATE on channel %x: function level mismatch (sent: %#x, received: %#x)\n",
+                                CCW_DEVID(channel->ccwdev),
+                                card->info.func_level, temp);
                goto out;
        }
        memcpy(&card->token.issuer_rm_r,
@@ -2096,9 +2092,8 @@ int qeth_send_control_data(struct qeth_card *card, int len,
                                      (addr_t) iob, 0, 0, event_timeout);
        spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
        if (rc) {
-               QETH_DBF_MESSAGE(2, "%s qeth_send_control_data: "
-                       "ccw_device_start rc = %i\n",
-                       dev_name(&channel->ccwdev->dev), rc);
+               QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n",
+                                CARD_DEVID(card), rc);
                QETH_CARD_TEXT_(card, 2, " err%d", rc);
                spin_lock_irq(&card->lock);
                list_del_init(&reply->list);
@@ -2853,8 +2848,8 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
        } else {
                dev_warn(&card->gdev->dev,
                         "The qeth driver ran out of channel command buffers\n");
-               QETH_DBF_MESSAGE(1, "%s The qeth driver ran out of channel command buffers",
-                                dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(1, "device %x ran out of channel command buffers",
+                                CARD_DEVID(card));
        }
 
        return iob;
@@ -2989,10 +2984,9 @@ static int qeth_query_ipassists_cb(struct qeth_card *card,
                return 0;
        default:
                if (cmd->hdr.return_code) {
-                       QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled "
-                                               "rc=%d\n",
-                                               dev_name(&card->gdev->dev),
-                                               cmd->hdr.return_code);
+                       QETH_DBF_MESSAGE(1, "IPA_CMD_QIPASSIST on device %x: Unhandled rc=%#x\n",
+                                        CARD_DEVID(card),
+                                        cmd->hdr.return_code);
                        return 0;
                }
        }
@@ -3004,8 +2998,8 @@ static int qeth_query_ipassists_cb(struct qeth_card *card,
                card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
                card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
        } else
-               QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected"
-                                       "\n", dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(1, "IPA_CMD_QIPASSIST on device %x: Flawed LIC detected\n",
+                                CARD_DEVID(card));
        return 0;
 }
 
@@ -4297,10 +4291,9 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
                cmd->data.setadapterparms.hdr.return_code);
        if (cmd->data.setadapterparms.hdr.return_code !=
                                                SET_ACCESS_CTRL_RC_SUCCESS)
-               QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%s,%d)==%d\n",
-                               card->gdev->dev.kobj.name,
-                               access_ctrl_req->subcmd_code,
-                               cmd->data.setadapterparms.hdr.return_code);
+               QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n",
+                                access_ctrl_req->subcmd_code, CARD_DEVID(card),
+                                cmd->data.setadapterparms.hdr.return_code);
        switch (cmd->data.setadapterparms.hdr.return_code) {
        case SET_ACCESS_CTRL_RC_SUCCESS:
                if (card->options.isolation == ISOLATION_MODE_NONE) {
@@ -4312,14 +4305,14 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card,
                }
                break;
        case SET_ACCESS_CTRL_RC_ALREADY_NOT_ISOLATED:
-               QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already "
-                               "deactivated\n", dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already deactivated\n",
+                                CARD_DEVID(card));
                if (fallback)
                        card->options.isolation = card->options.prev_isolation;
                break;
        case SET_ACCESS_CTRL_RC_ALREADY_ISOLATED:
-               QETH_DBF_MESSAGE(2, "%s QDIO data connection isolation already"
-                               " activated\n", dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(2, "QDIO data connection isolation on device %x already activated\n",
+                                CARD_DEVID(card));
                if (fallback)
                        card->options.isolation = card->options.prev_isolation;
                break;
@@ -4405,10 +4398,8 @@ int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback)
                rc = qeth_setadpparms_set_access_ctrl(card,
                        card->options.isolation, fallback);
                if (rc) {
-                       QETH_DBF_MESSAGE(3,
-                               "IPA(SET_ACCESS_CTRL,%s,%d) sent failed\n",
-                               card->gdev->dev.kobj.name,
-                               rc);
+                       QETH_DBF_MESSAGE(3, "IPA(SET_ACCESS_CTRL(%d) on device %x: sent failed\n",
+                                        rc, CARD_DEVID(card));
                        rc = -EOPNOTSUPP;
                }
        } else if (card->options.isolation != ISOLATION_MODE_NONE) {
@@ -4443,7 +4434,8 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
                rc = BMCR_FULLDPLX;
                if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH) &&
                    (card->info.link_type != QETH_LINK_TYPE_OSN) &&
-                   (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
+                   (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH) &&
+                   (card->info.link_type != QETH_LINK_TYPE_25GBIT_ETH))
                        rc |= BMCR_SPEED100;
                break;
        case MII_BMSR: /* Basic mode status register */
@@ -4634,8 +4626,8 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
        rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
                                    qeth_snmp_command_cb, (void *)&qinfo);
        if (rc)
-               QETH_DBF_MESSAGE(2, "SNMP command failed on %s: (0x%x)\n",
-                          QETH_CARD_IFNAME(card), rc);
+               QETH_DBF_MESSAGE(2, "SNMP command failed on device %x: (%#x)\n",
+                                CARD_DEVID(card), rc);
        else {
                if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
                        rc = -EFAULT;
@@ -4869,8 +4861,8 @@ static void qeth_determine_capabilities(struct qeth_card *card)
 
        rc = qeth_read_conf_data(card, (void **) &prcd, &length);
        if (rc) {
-               QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
-                       dev_name(&card->gdev->dev), rc);
+               QETH_DBF_MESSAGE(2, "qeth_read_conf_data on device %x returned %i\n",
+                                CARD_DEVID(card), rc);
                QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
                goto out_offline;
        }
@@ -5086,7 +5078,7 @@ static struct ccw_driver qeth_ccw_driver = {
        .remove = ccwgroup_remove_ccwdev,
 };
 
-int qeth_core_hardsetup_card(struct qeth_card *card)
+int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok)
 {
        int retries = 3;
        int rc;
@@ -5096,8 +5088,8 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
        qeth_update_from_chp_desc(card);
 retry:
        if (retries < 3)
-               QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n",
-                       dev_name(&card->gdev->dev));
+               QETH_DBF_MESSAGE(2, "Retrying to do IDX activates on device %x.\n",
+                                CARD_DEVID(card));
        rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD);
        ccw_device_set_offline(CARD_DDEV(card));
        ccw_device_set_offline(CARD_WDEV(card));
@@ -5161,13 +5153,20 @@ retriable:
                if (rc == IPA_RC_LAN_OFFLINE) {
                        dev_warn(&card->gdev->dev,
                                "The LAN is offline\n");
-                       netif_carrier_off(card->dev);
+                       *carrier_ok = false;
                } else {
                        rc = -ENODEV;
                        goto out;
                }
        } else {
-               netif_carrier_on(card->dev);
+               *carrier_ok = true;
+       }
+
+       if (qeth_netdev_is_registered(card->dev)) {
+               if (*carrier_ok)
+                       netif_carrier_on(card->dev);
+               else
+                       netif_carrier_off(card->dev);
        }
 
        card->options.ipa4.supported_funcs = 0;
@@ -5201,8 +5200,8 @@ retriable:
 out:
        dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
                "an error on the device\n");
-       QETH_DBF_MESSAGE(2, "%s Initialization in hardsetup failed! rc=%d\n",
-               dev_name(&card->gdev->dev), rc);
+       QETH_DBF_MESSAGE(2, "Initialization for device %x failed in hardsetup! rc=%d\n",
+                        CARD_DEVID(card), rc);
        return rc;
 }
 EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);
@@ -5481,11 +5480,12 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
 }
 EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd);
 
-int qeth_send_setassparms(struct qeth_card *card,
-                         struct qeth_cmd_buffer *iob, __u16 len, long data,
-                         int (*reply_cb)(struct qeth_card *,
-                                         struct qeth_reply *, unsigned long),
-                         void *reply_param)
+static int qeth_send_setassparms(struct qeth_card *card,
+                                struct qeth_cmd_buffer *iob, u16 len,
+                                long data, int (*reply_cb)(struct qeth_card *,
+                                                           struct qeth_reply *,
+                                                           unsigned long),
+                                void *reply_param)
 {
        int rc;
        struct qeth_ipa_cmd *cmd;
@@ -5501,7 +5501,6 @@ int qeth_send_setassparms(struct qeth_card *card,
        rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
        return rc;
 }
-EXPORT_SYMBOL_GPL(qeth_send_setassparms);
 
 int qeth_send_simple_setassparms_prot(struct qeth_card *card,
                                      enum qeth_ipa_funcs ipa_func,
@@ -6170,8 +6169,14 @@ static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd,
                WARN_ON_ONCE(1);
        }
 
-       /* fallthrough from high to low, to select all legal speeds: */
+       /* partially does fall through, to also select lower speeds */
        switch (maxspeed) {
+       case SPEED_25000:
+               ethtool_link_ksettings_add_link_mode(cmd, supported,
+                                                    25000baseSR_Full);
+               ethtool_link_ksettings_add_link_mode(cmd, advertising,
+                                                    25000baseSR_Full);
+               break;
        case SPEED_10000:
                ethtool_link_ksettings_add_link_mode(cmd, supported,
                                                     10000baseT_Full);
@@ -6254,6 +6259,10 @@ int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev,
                cmd->base.speed = SPEED_10000;
                cmd->base.port = PORT_FIBRE;
                break;
+       case QETH_LINK_TYPE_25GBIT_ETH:
+               cmd->base.speed = SPEED_25000;
+               cmd->base.port = PORT_FIBRE;
+               break;
        default:
                cmd->base.speed = SPEED_10;
                cmd->base.port = PORT_TP;
@@ -6320,6 +6329,9 @@ int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev,
        case CARD_INFO_PORTS_10G:
                cmd->base.speed = SPEED_10000;
                break;
+       case CARD_INFO_PORTS_25G:
+               cmd->base.speed = SPEED_25000;
+               break;
        }
 
        return 0;
index e85090467afe0a9e05b6d9b00355713ce53b2ef6..3e54be201b279f07b09481fd9c1c746802496c1e 100644 (file)
@@ -90,6 +90,7 @@ enum qeth_link_types {
        QETH_LINK_TYPE_GBIT_ETH     = 0x03,
        QETH_LINK_TYPE_OSN          = 0x04,
        QETH_LINK_TYPE_10GBIT_ETH   = 0x10,
+       QETH_LINK_TYPE_25GBIT_ETH   = 0x12,
        QETH_LINK_TYPE_LANE_ETH100  = 0x81,
        QETH_LINK_TYPE_LANE_TR      = 0x82,
        QETH_LINK_TYPE_LANE_ETH1000 = 0x83,
@@ -347,6 +348,7 @@ enum qeth_card_info_port_speed {
        CARD_INFO_PORTS_100M            = 0x00000006,
        CARD_INFO_PORTS_1G              = 0x00000007,
        CARD_INFO_PORTS_10G             = 0x00000008,
+       CARD_INFO_PORTS_25G             = 0x0000000A,
 };
 
 /* (SET)DELIP(M) IPA stuff ***************************************************/
@@ -436,7 +438,7 @@ struct qeth_ipacmd_setassparms {
                __u32 flags_32bit;
                struct qeth_ipa_caps caps;
                struct qeth_checksum_cmd chksum;
-               struct qeth_arp_cache_entry add_arp_entry;
+               struct qeth_arp_cache_entry arp_entry;
                struct qeth_arp_query_data query_arp;
                struct qeth_tso_start_data tso;
                __u8 ip[16];
index 23aaf373f631e2283e7c84ddc43f913d876f7058..2914a1a69f8300a36c1bf0580094532cb9ccecd4 100644 (file)
@@ -146,11 +146,11 @@ static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac)
        QETH_CARD_TEXT(card, 2, "L2Wmac");
        rc = qeth_l2_send_setdelmac(card, mac, cmd);
        if (rc == -EEXIST)
-               QETH_DBF_MESSAGE(2, "MAC %pM already registered on %s\n",
-                                mac, QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(2, "MAC already registered on device %x\n",
+                                CARD_DEVID(card));
        else if (rc)
-               QETH_DBF_MESSAGE(2, "Failed to register MAC %pM on %s: %d\n",
-                                mac, QETH_CARD_IFNAME(card), rc);
+               QETH_DBF_MESSAGE(2, "Failed to register MAC on device %x: %d\n",
+                                CARD_DEVID(card), rc);
        return rc;
 }
 
@@ -163,8 +163,8 @@ static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac)
        QETH_CARD_TEXT(card, 2, "L2Rmac");
        rc = qeth_l2_send_setdelmac(card, mac, cmd);
        if (rc)
-               QETH_DBF_MESSAGE(2, "Failed to delete MAC %pM on %s: %d\n",
-                                mac, QETH_CARD_IFNAME(card), rc);
+               QETH_DBF_MESSAGE(2, "Failed to delete MAC on device %u: %d\n",
+                                CARD_DEVID(card), rc);
        return rc;
 }
 
@@ -260,9 +260,9 @@ static int qeth_l2_send_setdelvlan_cb(struct qeth_card *card,
 
        QETH_CARD_TEXT(card, 2, "L2sdvcb");
        if (cmd->hdr.return_code) {
-               QETH_DBF_MESSAGE(2, "Error in processing VLAN %i on %s: 0x%x.\n",
+               QETH_DBF_MESSAGE(2, "Error in processing VLAN %u on device %x: %#x.\n",
                                 cmd->data.setdelvlan.vlan_id,
-                                QETH_CARD_IFNAME(card), cmd->hdr.return_code);
+                                CARD_DEVID(card), cmd->hdr.return_code);
                QETH_CARD_TEXT_(card, 2, "L2VL%4x", cmd->hdr.command);
                QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code);
        }
@@ -455,8 +455,8 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
                rc = qeth_vm_request_mac(card);
                if (!rc)
                        goto out;
-               QETH_DBF_MESSAGE(2, "z/VM MAC Service failed on device %s: x%x\n",
-                                CARD_BUS_ID(card), rc);
+               QETH_DBF_MESSAGE(2, "z/VM MAC Service failed on device %x: %#x\n",
+                                CARD_DEVID(card), rc);
                QETH_DBF_TEXT_(SETUP, 2, "err%04x", rc);
                /* fall back to alternative mechanism: */
        }
@@ -468,8 +468,8 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
                rc = qeth_setadpparms_change_macaddr(card);
                if (!rc)
                        goto out;
-               QETH_DBF_MESSAGE(2, "READ_MAC Assist failed on device %s: x%x\n",
-                                CARD_BUS_ID(card), rc);
+               QETH_DBF_MESSAGE(2, "READ_MAC Assist failed on device %x: %#x\n",
+                                CARD_DEVID(card), rc);
                QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc);
                /* fall back once more: */
        }
@@ -826,7 +826,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 
        if (cgdev->state == CCWGROUP_ONLINE)
                qeth_l2_set_offline(cgdev);
-       unregister_netdev(card->dev);
+       if (qeth_netdev_is_registered(card->dev))
+               unregister_netdev(card->dev);
 }
 
 static const struct ethtool_ops qeth_l2_ethtool_ops = {
@@ -862,11 +863,11 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
        .ndo_set_features       = qeth_set_features
 };
 
-static int qeth_l2_setup_netdev(struct qeth_card *card)
+static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
 {
        int rc;
 
-       if (card->dev->netdev_ops)
+       if (qeth_netdev_is_registered(card->dev))
                return 0;
 
        card->dev->priv_flags |= IFF_UNICAST_FLT;
@@ -919,6 +920,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
        qeth_l2_request_initial_mac(card);
        netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
        rc = register_netdev(card->dev);
+       if (!rc && carrier_ok)
+               netif_carrier_on(card->dev);
+
        if (rc)
                card->dev->netdev_ops = NULL;
        return rc;
@@ -949,6 +953,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
        int rc = 0;
        enum qeth_card_states recover_flag;
+       bool carrier_ok;
 
        mutex_lock(&card->discipline_mutex);
        mutex_lock(&card->conf_mutex);
@@ -956,7 +961,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
        QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
        recover_flag = card->state;
-       rc = qeth_core_hardsetup_card(card);
+       rc = qeth_core_hardsetup_card(card, &carrier_ok);
        if (rc) {
                QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
                rc = -ENODEV;
@@ -967,7 +972,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
                dev_info(&card->gdev->dev,
                "The device represents a Bridge Capable Port\n");
 
-       rc = qeth_l2_setup_netdev(card);
+       rc = qeth_l2_setup_netdev(card, carrier_ok);
        if (rc)
                goto out_remove;
 
index 0b161cc1fd2e62f2251be71e939813ed58b5529c..f08b745c20073b92bd2a78da983ff2a9ade3ca77 100644 (file)
@@ -278,9 +278,6 @@ static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover)
 
        QETH_CARD_TEXT(card, 4, "clearip");
 
-       if (recover && card->options.sniffer)
-               return;
-
        spin_lock_bh(&card->ip_lock);
 
        hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
@@ -494,9 +491,8 @@ int qeth_l3_setrouting_v4(struct qeth_card *card)
                                  QETH_PROT_IPV4);
        if (rc) {
                card->options.route4.type = NO_ROUTER;
-               QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type"
-                       " on %s. Type set to 'no router'.\n", rc,
-                       QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(2, "Error (%#06x) while setting routing type on device %x. Type set to 'no router'.\n",
+                                rc, CARD_DEVID(card));
        }
        return rc;
 }
@@ -518,9 +514,8 @@ int qeth_l3_setrouting_v6(struct qeth_card *card)
                                  QETH_PROT_IPV6);
        if (rc) {
                card->options.route6.type = NO_ROUTER;
-               QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type"
-                       " on %s. Type set to 'no router'.\n", rc,
-                       QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(2, "Error (%#06x) while setting routing type on device %x. Type set to 'no router'.\n",
+                                rc, CARD_DEVID(card));
        }
        return rc;
 }
@@ -663,6 +658,8 @@ static int qeth_l3_register_addr_entry(struct qeth_card *card,
        int rc = 0;
        int cnt = 3;
 
+       if (card->options.sniffer)
+               return 0;
 
        if (addr->proto == QETH_PROT_IPV4) {
                QETH_CARD_TEXT(card, 2, "setaddr4");
@@ -697,6 +694,9 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
 {
        int rc = 0;
 
+       if (card->options.sniffer)
+               return 0;
+
        if (addr->proto == QETH_PROT_IPV4) {
                QETH_CARD_TEXT(card, 2, "deladdr4");
                QETH_CARD_HEX(card, 3, &addr->u.a4.addr, sizeof(int));
@@ -1070,8 +1070,8 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply,
                }
                break;
        default:
-               QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n",
-                       cmd->data.diagass.action, QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(2, "Unknown sniffer action (%#06x) on device %x\n",
+                                cmd->data.diagass.action, CARD_DEVID(card));
        }
 
        return 0;
@@ -1517,32 +1517,25 @@ static void qeth_l3_set_rx_mode(struct net_device *dev)
        qeth_l3_handle_promisc_mode(card);
 }
 
-static const char *qeth_l3_arp_get_error_cause(int *rc)
+static int qeth_l3_arp_makerc(int rc)
 {
-       switch (*rc) {
-       case QETH_IPA_ARP_RC_FAILED:
-               *rc = -EIO;
-               return "operation failed";
+       switch (rc) {
+       case IPA_RC_SUCCESS:
+               return 0;
        case QETH_IPA_ARP_RC_NOTSUPP:
-               *rc = -EOPNOTSUPP;
-               return "operation not supported";
-       case QETH_IPA_ARP_RC_OUT_OF_RANGE:
-               *rc = -EINVAL;
-               return "argument out of range";
        case QETH_IPA_ARP_RC_Q_NOTSUPP:
-               *rc = -EOPNOTSUPP;
-               return "query operation not supported";
+               return -EOPNOTSUPP;
+       case QETH_IPA_ARP_RC_OUT_OF_RANGE:
+               return -EINVAL;
        case QETH_IPA_ARP_RC_Q_NO_DATA:
-               *rc = -ENOENT;
-               return "no query data available";
+               return -ENOENT;
        default:
-               return "unknown error";
+               return -EIO;
        }
 }
 
 static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries)
 {
-       int tmp;
        int rc;
 
        QETH_CARD_TEXT(card, 3, "arpstnoe");
@@ -1560,13 +1553,10 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries)
        rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
                                          IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
                                          no_entries);
-       if (rc) {
-               tmp = rc;
-               QETH_DBF_MESSAGE(2, "Could not set number of ARP entries on "
-                       "%s: %s (0x%x/%d)\n", QETH_CARD_IFNAME(card),
-                       qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
-       }
-       return rc;
+       if (rc)
+               QETH_DBF_MESSAGE(2, "Could not set number of ARP entries on device %x: %#x\n",
+                                CARD_DEVID(card), rc);
+       return qeth_l3_arp_makerc(rc);
 }
 
 static __u32 get_arp_entry_size(struct qeth_card *card,
@@ -1716,7 +1706,6 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
 {
        struct qeth_cmd_buffer *iob;
        struct qeth_ipa_cmd *cmd;
-       int tmp;
        int rc;
 
        QETH_CARD_TEXT_(card, 3, "qarpipv%i", prot);
@@ -1735,15 +1724,10 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
        rc = qeth_l3_send_ipa_arp_cmd(card, iob,
                           QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
                           qeth_l3_arp_query_cb, (void *)qinfo);
-       if (rc) {
-               tmp = rc;
-               QETH_DBF_MESSAGE(2,
-                       "Error while querying ARP cache on %s: %s "
-                       "(0x%x/%d)\n", QETH_CARD_IFNAME(card),
-                       qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
-       }
-
-       return rc;
+       if (rc)
+               QETH_DBF_MESSAGE(2, "Error while querying ARP cache on device %x: %#x\n",
+                                CARD_DEVID(card), rc);
+       return qeth_l3_arp_makerc(rc);
 }
 
 static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata)
@@ -1793,15 +1777,18 @@ out:
        return rc;
 }
 
-static int qeth_l3_arp_add_entry(struct qeth_card *card,
-                               struct qeth_arp_cache_entry *entry)
+static int qeth_l3_arp_modify_entry(struct qeth_card *card,
+                                   struct qeth_arp_cache_entry *entry,
+                                   enum qeth_arp_process_subcmds arp_cmd)
 {
+       struct qeth_arp_cache_entry *cmd_entry;
        struct qeth_cmd_buffer *iob;
-       char buf[16];
-       int tmp;
        int rc;
 
-       QETH_CARD_TEXT(card, 3, "arpadent");
+       if (arp_cmd == IPA_CMD_ASS_ARP_ADD_ENTRY)
+               QETH_CARD_TEXT(card, 3, "arpadd");
+       else
+               QETH_CARD_TEXT(card, 3, "arpdel");
 
        /*
         * currently GuestLAN only supports the ARP assist function
@@ -1814,71 +1801,25 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card,
                return -EOPNOTSUPP;
        }
 
-       iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
-                                      IPA_CMD_ASS_ARP_ADD_ENTRY,
-                                      sizeof(struct qeth_arp_cache_entry),
-                                      QETH_PROT_IPV4);
+       iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING, arp_cmd,
+                                      sizeof(*cmd_entry), QETH_PROT_IPV4);
        if (!iob)
                return -ENOMEM;
-       rc = qeth_send_setassparms(card, iob,
-                                  sizeof(struct qeth_arp_cache_entry),
-                                  (unsigned long) entry,
-                                  qeth_setassparms_cb, NULL);
-       if (rc) {
-               tmp = rc;
-               qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
-               QETH_DBF_MESSAGE(2, "Could not add ARP entry for address %s "
-                       "on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card),
-                       qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
-       }
-       return rc;
-}
-
-static int qeth_l3_arp_remove_entry(struct qeth_card *card,
-                               struct qeth_arp_cache_entry *entry)
-{
-       struct qeth_cmd_buffer *iob;
-       char buf[16] = {0, };
-       int tmp;
-       int rc;
 
-       QETH_CARD_TEXT(card, 3, "arprment");
+       cmd_entry = &__ipa_cmd(iob)->data.setassparms.data.arp_entry;
+       ether_addr_copy(cmd_entry->macaddr, entry->macaddr);
+       memcpy(cmd_entry->ipaddr, entry->ipaddr, 4);
+       rc = qeth_send_ipa_cmd(card, iob, qeth_setassparms_cb, NULL);
+       if (rc)
+               QETH_DBF_MESSAGE(2, "Could not modify (cmd: %#x) ARP entry on device %x: %#x\n",
+                                arp_cmd, CARD_DEVID(card), rc);
 
-       /*
-        * currently GuestLAN only supports the ARP assist function
-        * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
-        * thus we say EOPNOTSUPP for this ARP function
-        */
-       if (card->info.guestlan)
-               return -EOPNOTSUPP;
-       if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
-               return -EOPNOTSUPP;
-       }
-       memcpy(buf, entry, 12);
-       iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
-                                      IPA_CMD_ASS_ARP_REMOVE_ENTRY,
-                                      12,
-                                      QETH_PROT_IPV4);
-       if (!iob)
-               return -ENOMEM;
-       rc = qeth_send_setassparms(card, iob,
-                                  12, (unsigned long)buf,
-                                  qeth_setassparms_cb, NULL);
-       if (rc) {
-               tmp = rc;
-               memset(buf, 0, 16);
-               qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
-               QETH_DBF_MESSAGE(2, "Could not delete ARP entry for address %s"
-                       " on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card),
-                       qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
-       }
-       return rc;
+       return qeth_l3_arp_makerc(rc);
 }
 
 static int qeth_l3_arp_flush_cache(struct qeth_card *card)
 {
        int rc;
-       int tmp;
 
        QETH_CARD_TEXT(card, 3, "arpflush");
 
@@ -1894,19 +1835,17 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card)
        }
        rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
                                          IPA_CMD_ASS_ARP_FLUSH_CACHE, 0);
-       if (rc) {
-               tmp = rc;
-               QETH_DBF_MESSAGE(2, "Could not flush ARP cache on %s: %s "
-                       "(0x%x/%d)\n", QETH_CARD_IFNAME(card),
-                       qeth_l3_arp_get_error_cause(&rc), tmp, tmp);
-       }
-       return rc;
+       if (rc)
+               QETH_DBF_MESSAGE(2, "Could not flush ARP cache on device %x: %#x\n",
+                                CARD_DEVID(card), rc);
+       return qeth_l3_arp_makerc(rc);
 }
 
 static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct qeth_card *card = dev->ml_priv;
        struct qeth_arp_cache_entry arp_entry;
+       enum qeth_arp_process_subcmds arp_cmd;
        int rc = 0;
 
        switch (cmd) {
@@ -1925,27 +1864,16 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                rc = qeth_l3_arp_query(card, rq->ifr_ifru.ifru_data);
                break;
        case SIOC_QETH_ARP_ADD_ENTRY:
-               if (!capable(CAP_NET_ADMIN)) {
-                       rc = -EPERM;
-                       break;
-               }
-               if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
-                                  sizeof(struct qeth_arp_cache_entry)))
-                       rc = -EFAULT;
-               else
-                       rc = qeth_l3_arp_add_entry(card, &arp_entry);
-               break;
        case SIOC_QETH_ARP_REMOVE_ENTRY:
-               if (!capable(CAP_NET_ADMIN)) {
-                       rc = -EPERM;
-                       break;
-               }
-               if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
-                                  sizeof(struct qeth_arp_cache_entry)))
-                       rc = -EFAULT;
-               else
-                       rc = qeth_l3_arp_remove_entry(card, &arp_entry);
-               break;
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               if (copy_from_user(&arp_entry, rq->ifr_data, sizeof(arp_entry)))
+                       return -EFAULT;
+
+               arp_cmd = (cmd == SIOC_QETH_ARP_ADD_ENTRY) ?
+                               IPA_CMD_ASS_ARP_ADD_ENTRY :
+                               IPA_CMD_ASS_ARP_REMOVE_ENTRY;
+               return qeth_l3_arp_modify_entry(card, &arp_entry, arp_cmd);
        case SIOC_QETH_ARP_FLUSH_CACHE:
                if (!capable(CAP_NET_ADMIN)) {
                        rc = -EPERM;
@@ -2383,12 +2311,12 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = {
        .ndo_neigh_setup        = qeth_l3_neigh_setup,
 };
 
-static int qeth_l3_setup_netdev(struct qeth_card *card)
+static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
 {
        unsigned int headroom;
        int rc;
 
-       if (card->dev->netdev_ops)
+       if (qeth_netdev_is_registered(card->dev))
                return 0;
 
        if (card->info.type == QETH_CARD_TYPE_OSD ||
@@ -2457,6 +2385,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
 
        netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
        rc = register_netdev(card->dev);
+       if (!rc && carrier_ok)
+               netif_carrier_on(card->dev);
+
 out:
        if (rc)
                card->dev->netdev_ops = NULL;
@@ -2497,7 +2428,8 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
        if (cgdev->state == CCWGROUP_ONLINE)
                qeth_l3_set_offline(cgdev);
 
-       unregister_netdev(card->dev);
+       if (qeth_netdev_is_registered(card->dev))
+               unregister_netdev(card->dev);
        qeth_l3_clear_ip_htable(card, 0);
        qeth_l3_clear_ipato_list(card);
 }
@@ -2507,6 +2439,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
        int rc = 0;
        enum qeth_card_states recover_flag;
+       bool carrier_ok;
 
        mutex_lock(&card->discipline_mutex);
        mutex_lock(&card->conf_mutex);
@@ -2514,14 +2447,14 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
        QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
        recover_flag = card->state;
-       rc = qeth_core_hardsetup_card(card);
+       rc = qeth_core_hardsetup_card(card, &carrier_ok);
        if (rc) {
                QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
                rc = -ENODEV;
                goto out_remove;
        }
 
-       rc = qeth_l3_setup_netdev(card);
+       rc = qeth_l3_setup_netdev(card, carrier_ok);
        if (rc)
                goto out_remove;
 
index f07444d30b216dace2eb7b7adcc59e818c95192e..640cd1b31a18d2bfc164e50adaf819ce27d6d754 100644 (file)
@@ -578,6 +578,7 @@ config SCSI_MYRB
 config SCSI_MYRS
        tristate "Mylex DAC960/DAC1100 PCI RAID Controller (SCSI Interface)"
        depends on PCI
+       depends on !CPU_BIG_ENDIAN || COMPILE_TEST
        select RAID_ATTRS
        help
          This driver adds support for the Mylex DAC960, AcceleRAID, and
index 8429c855701fca200b56df1453a4fc5188a9a38e..01c23d27f290b114c3f9e0b20b713edd30e2d884 100644 (file)
@@ -1198,7 +1198,7 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 
 out:
        if (!hostdata->selecting)
-               return NULL;
+               return false;
        hostdata->selecting = NULL;
        return ret;
 }
index f0e457e6884e5ca9c92d84c12c1db2cf6906104b..8df822a4a1bd6624abb8814a70e8bdc502274192 100644 (file)
@@ -904,11 +904,9 @@ static void start_delivery_v1_hw(struct hisi_sas_dq *dq)
 {
        struct hisi_hba *hisi_hba = dq->hisi_hba;
        struct hisi_sas_slot *s, *s1, *s2 = NULL;
-       struct list_head *dq_list;
        int dlvry_queue = dq->id;
        int wp;
 
-       dq_list = &dq->list;
        list_for_each_entry_safe(s, s1, &dq->list, delivery) {
                if (!s->ready)
                        break;
index cc36b6473e986b3191f88160ac41f24f730999d6..77a85ead483e098a8e1d837c8130bfb873dc3671 100644 (file)
@@ -1670,11 +1670,9 @@ static void start_delivery_v2_hw(struct hisi_sas_dq *dq)
 {
        struct hisi_hba *hisi_hba = dq->hisi_hba;
        struct hisi_sas_slot *s, *s1, *s2 = NULL;
-       struct list_head *dq_list;
        int dlvry_queue = dq->id;
        int wp;
 
-       dq_list = &dq->list;
        list_for_each_entry_safe(s, s1, &dq->list, delivery) {
                if (!s->ready)
                        break;
index bd4ce38b98d229ad56fb4a224621929b34d11640..a369450a1fa7bfd71160c06211969609cc056f15 100644 (file)
@@ -886,11 +886,9 @@ static void start_delivery_v3_hw(struct hisi_sas_dq *dq)
 {
        struct hisi_hba *hisi_hba = dq->hisi_hba;
        struct hisi_sas_slot *s, *s1, *s2 = NULL;
-       struct list_head *dq_list;
        int dlvry_queue = dq->id;
        int wp;
 
-       dq_list = &dq->list;
        list_for_each_entry_safe(s, s1, &dq->list, delivery) {
                if (!s->ready)
                        break;
index 0c8005bb0f53f271e958c4b1f51eadd7551474b8..34d311a7dbef1b5a0ad9e0cff3ef52d2f0e9103d 100644 (file)
@@ -698,6 +698,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
                rport = lpfc_ndlp_get_nrport(ndlp);
                if (rport)
                        nrport = rport->remoteport;
+               else
+                       nrport = NULL;
                spin_unlock(&phba->hbalock);
                if (!nrport)
                        continue;
index aeb282f617c5c43fd182065e1fd9dbab7e6f69d5..0642f2d0a3bb687a1c7ca3de09e24865afa637a7 100644 (file)
@@ -1049,7 +1049,8 @@ static int myrb_get_hba_config(struct myrb_hba *cb)
                enquiry2->fw.firmware_type = '0';
                enquiry2->fw.turn_id = 0;
        }
-       sprintf(cb->fw_version, "%d.%02d-%c-%02d",
+       snprintf(cb->fw_version, sizeof(cb->fw_version),
+               "%d.%02d-%c-%02d",
                enquiry2->fw.major_version,
                enquiry2->fw.minor_version,
                enquiry2->fw.firmware_type,
index 0264a2e2bc190e068832a89452215919b9b22c30..b8d54ef8cf6dfb84c6d4cb3ce2714071cc2de1d6 100644 (file)
@@ -163,9 +163,12 @@ static unsigned char myrs_get_ctlr_info(struct myrs_hba *cs)
        dma_addr_t ctlr_info_addr;
        union myrs_sgl *sgl;
        unsigned char status;
-       struct myrs_ctlr_info old;
+       unsigned short ldev_present, ldev_critical, ldev_offline;
+
+       ldev_present = cs->ctlr_info->ldev_present;
+       ldev_critical = cs->ctlr_info->ldev_critical;
+       ldev_offline = cs->ctlr_info->ldev_offline;
 
-       memcpy(&old, cs->ctlr_info, sizeof(struct myrs_ctlr_info));
        ctlr_info_addr = dma_map_single(&cs->pdev->dev, cs->ctlr_info,
                                        sizeof(struct myrs_ctlr_info),
                                        DMA_FROM_DEVICE);
@@ -198,9 +201,9 @@ static unsigned char myrs_get_ctlr_info(struct myrs_hba *cs)
                    cs->ctlr_info->rbld_active +
                    cs->ctlr_info->exp_active != 0)
                        cs->needs_update = true;
-               if (cs->ctlr_info->ldev_present != old.ldev_present ||
-                   cs->ctlr_info->ldev_critical != old.ldev_critical ||
-                   cs->ctlr_info->ldev_offline != old.ldev_offline)
+               if (cs->ctlr_info->ldev_present != ldev_present ||
+                   cs->ctlr_info->ldev_critical != ldev_critical ||
+                   cs->ctlr_info->ldev_offline != ldev_offline)
                        shost_printk(KERN_INFO, cs->host,
                                     "Logical drive count changes (%d/%d/%d)\n",
                                     cs->ctlr_info->ldev_critical,
index 6fe20c27acc16e54aaf02112735d2b657c61852d..eb59c796a795de06af7d2fa19a64a30e022a3b87 100644 (file)
@@ -4763,6 +4763,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        fcport->loop_id = FC_NO_LOOP_ID;
        qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED);
        fcport->supported_classes = FC_COS_UNSPECIFIED;
+       fcport->fp_speed = PORT_SPEED_UNKNOWN;
 
        fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
                sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
index 518f15141170e733d8acee71cf288c31db6c9261..20c85eed1a7504997a9ab60d2c8247f04ab82995 100644 (file)
@@ -67,7 +67,7 @@ module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql2xplogiabsentdevice,
                "Option to enable PLOGI to devices that are not present after "
                "a Fabric scan.  This is needed for several broken switches. "
-               "Default is 0 - no PLOGI. 1 - perfom PLOGI.");
+               "Default is 0 - no PLOGI. 1 - perform PLOGI.");
 
 int ql2xloginretrycount = 0;
 module_param(ql2xloginretrycount, int, S_IRUGO);
index c7fccbb8f5545e463537389bc34b607de3dc9cb3..fa6e0c3b3aa678cd1e62f91021dc89036211aa8a 100644 (file)
@@ -697,6 +697,12 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
                 */
                scsi_mq_uninit_cmd(cmd);
 
+               /*
+                * queue is still alive, so grab the ref for preventing it
+                * from being cleaned up during running queue.
+                */
+               percpu_ref_get(&q->q_usage_counter);
+
                __blk_mq_end_request(req, error);
 
                if (scsi_target(sdev)->single_lun ||
@@ -704,6 +710,8 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
                        kblockd_schedule_work(&sdev->requeue_work);
                else
                        blk_mq_run_hw_queues(q, true);
+
+               percpu_ref_put(&q->q_usage_counter);
        } else {
                unsigned long flags;
 
index 23d7cca36ff031b6463aae8a639b061bfd2c825c..27db55b0ca7f860787d34f35d30ec2919937e490 100644 (file)
@@ -8099,13 +8099,6 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
                err = -ENOMEM;
                goto out_error;
        }
-
-       /*
-        * Do not use blk-mq at this time because blk-mq does not support
-        * runtime pm.
-        */
-       host->use_blk_mq = false;
-
        hba = shost_priv(host);
        hba->host = host;
        hba->dev = dev;
index e31e4fc31aa150767c3fc910e6348b6f4a34b7fe..2cfd61d62e9730503414817d52c053c4083ba9e7 100644 (file)
@@ -1778,7 +1778,7 @@ EXPORT_SYMBOL(target_submit_tmr);
 void transport_generic_request_failure(struct se_cmd *cmd,
                sense_reason_t sense_reason)
 {
-       int ret = 0;
+       int ret = 0, post_ret;
 
        pr_debug("-----[ Storage Engine Exception; sense_reason %d\n",
                 sense_reason);
@@ -1790,7 +1790,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
        transport_complete_task_attr(cmd);
 
        if (cmd->transport_complete_callback)
-               cmd->transport_complete_callback(cmd, false, NULL);
+               cmd->transport_complete_callback(cmd, false, &post_ret);
 
        if (transport_check_aborted_status(cmd, 1))
                return;
index ff6ba6d86cd8bf9ba43349fde40ec2d576ffed05..cc56cb3b3ecaa222222587da30460a58b2685bd7 100644 (file)
@@ -1614,10 +1614,10 @@ static void sci_request_dma(struct uart_port *port)
                hrtimer_init(&s->rx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
                s->rx_timer.function = rx_timer_fn;
 
+               s->chan_rx_saved = s->chan_rx = chan;
+
                if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
                        sci_submit_rx(s);
-
-               s->chan_rx_saved = s->chan_rx = chan;
        }
 }
 
@@ -3102,6 +3102,7 @@ static struct uart_driver sci_uart_driver = {
 static int sci_remove(struct platform_device *dev)
 {
        struct sci_port *port = platform_get_drvdata(dev);
+       unsigned int type = port->port.type;    /* uart_remove_... clears it */
 
        sci_ports_in_use &= ~BIT(port->port.line);
        uart_remove_one_port(&sci_uart_driver, &port->port);
@@ -3112,8 +3113,7 @@ static int sci_remove(struct platform_device *dev)
                sysfs_remove_file(&dev->dev.kobj,
                                  &dev_attr_rx_fifo_trigger.attr);
        }
-       if (port->port.type == PORT_SCIFA || port->port.type == PORT_SCIFB ||
-           port->port.type == PORT_HSCIF) {
+       if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF) {
                sysfs_remove_file(&dev->dev.kobj,
                                  &dev_attr_rx_fifo_timeout.attr);
        }
index 7576ceace57151a21007847f14dcf091005f09bb..f438eaa682463bffe42c27d923fe8426adef0926 100644 (file)
@@ -77,7 +77,7 @@ speed_t tty_termios_baud_rate(struct ktermios *termios)
                else
                        cbaud += 15;
        }
-       return baud_table[cbaud];
+       return cbaud >= n_baud_table ? 0 : baud_table[cbaud];
 }
 EXPORT_SYMBOL(tty_termios_baud_rate);
 
@@ -113,7 +113,7 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios)
                else
                        cbaud += 15;
        }
-       return baud_table[cbaud];
+       return cbaud >= n_baud_table ? 0 : baud_table[cbaud];
 #else  /* IBSHIFT */
        return tty_termios_baud_rate(termios);
 #endif /* IBSHIFT */
index 55370e651db31424db2330b80bd6bd4c4f9d02b8..41ec8e5010f30a544b82ca439cc5a481fe499b19 100644 (file)
@@ -1548,7 +1548,7 @@ static void csi_K(struct vc_data *vc, int vpar)
        scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
        vc->vc_need_wrap = 0;
        if (con_should_update(vc))
-               do_update_region(vc, (unsigned long) start, count);
+               do_update_region(vc, (unsigned long)(start + offset), count);
 }
 
 static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
index e36d6c73c4a4184c6246b14ab27b8e0ecb393be8..78118883f96c8ffdf868a4474ba569be59857865 100644 (file)
@@ -23,6 +23,16 @@ config TYPEC_UCSI
 
 if TYPEC_UCSI
 
+config UCSI_CCG
+       tristate "UCSI Interface Driver for Cypress CCGx"
+       depends on I2C
+       help
+         This driver enables UCSI support on platforms that expose a
+         Cypress CCGx Type-C controller over I2C interface.
+
+         To compile the driver as a module, choose M here: the module will be
+         called ucsi_ccg.
+
 config UCSI_ACPI
        tristate "UCSI ACPI Interface Driver"
        depends on ACPI
index 7afbea5122077b3dd0cbe217ad7c839837f499b4..2f4900b26210e245a65115ed1280bab41c19f62d 100644 (file)
@@ -8,3 +8,5 @@ typec_ucsi-y                    := ucsi.o
 typec_ucsi-$(CONFIG_TRACING)   += trace.o
 
 obj-$(CONFIG_UCSI_ACPI)                += ucsi_acpi.o
+
+obj-$(CONFIG_UCSI_CCG)         += ucsi_ccg.o
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
new file mode 100644 (file)
index 0000000..de8a43b
--- /dev/null
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * UCSI driver for Cypress CCGx Type-C controller
+ *
+ * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved.
+ * Author: Ajay Gupta <ajayg@nvidia.com>
+ *
+ * Some code borrowed from drivers/usb/typec/ucsi/ucsi_acpi.c
+ */
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include <asm/unaligned.h>
+#include "ucsi.h"
+
+struct ucsi_ccg {
+       struct device *dev;
+       struct ucsi *ucsi;
+       struct ucsi_ppm ppm;
+       struct i2c_client *client;
+};
+
+#define CCGX_RAB_INTR_REG                      0x06
+#define CCGX_RAB_UCSI_CONTROL                  0x39
+#define CCGX_RAB_UCSI_CONTROL_START            BIT(0)
+#define CCGX_RAB_UCSI_CONTROL_STOP             BIT(1)
+#define CCGX_RAB_UCSI_DATA_BLOCK(offset)       (0xf000 | ((offset) & 0xff))
+
+static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
+{
+       struct i2c_client *client = uc->client;
+       const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
+       unsigned char buf[2];
+       struct i2c_msg msgs[] = {
+               {
+                       .addr   = client->addr,
+                       .flags  = 0x0,
+                       .len    = sizeof(buf),
+                       .buf    = buf,
+               },
+               {
+                       .addr   = client->addr,
+                       .flags  = I2C_M_RD,
+                       .buf    = data,
+               },
+       };
+       u32 rlen, rem_len = len, max_read_len = len;
+       int status;
+
+       /* check any max_read_len limitation on i2c adapter */
+       if (quirks && quirks->max_read_len)
+               max_read_len = quirks->max_read_len;
+
+       while (rem_len > 0) {
+               msgs[1].buf = &data[len - rem_len];
+               rlen = min_t(u16, rem_len, max_read_len);
+               msgs[1].len = rlen;
+               put_unaligned_le16(rab, buf);
+               status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+               if (status < 0) {
+                       dev_err(uc->dev, "i2c_transfer failed %d\n", status);
+                       return status;
+               }
+               rab += rlen;
+               rem_len -= rlen;
+       }
+
+       return 0;
+}
+
+static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
+{
+       struct i2c_client *client = uc->client;
+       unsigned char *buf;
+       struct i2c_msg msgs[] = {
+               {
+                       .addr   = client->addr,
+                       .flags  = 0x0,
+               }
+       };
+       int status;
+
+       buf = kzalloc(len + sizeof(rab), GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       put_unaligned_le16(rab, buf);
+       memcpy(buf + sizeof(rab), data, len);
+
+       msgs[0].len = len + sizeof(rab);
+       msgs[0].buf = buf;
+
+       status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (status < 0) {
+               dev_err(uc->dev, "i2c_transfer failed %d\n", status);
+               kfree(buf);
+               return status;
+       }
+
+       kfree(buf);
+       return 0;
+}
+
+static int ucsi_ccg_init(struct ucsi_ccg *uc)
+{
+       unsigned int count = 10;
+       u8 data;
+       int status;
+
+       data = CCGX_RAB_UCSI_CONTROL_STOP;
+       status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
+       if (status < 0)
+               return status;
+
+       data = CCGX_RAB_UCSI_CONTROL_START;
+       status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
+       if (status < 0)
+               return status;
+
+       /*
+        * Flush CCGx RESPONSE queue by acking interrupts. Above ucsi control
+        * register write will push response which must be cleared.
+        */
+       do {
+               status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
+               if (status < 0)
+                       return status;
+
+               if (!data)
+                       return 0;
+
+               status = ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
+               if (status < 0)
+                       return status;
+
+               usleep_range(10000, 11000);
+       } while (--count);
+
+       return -ETIMEDOUT;
+}
+
+static int ucsi_ccg_send_data(struct ucsi_ccg *uc)
+{
+       u8 *ppm = (u8 *)uc->ppm.data;
+       int status;
+       u16 rab;
+
+       rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_out));
+       status = ccg_write(uc, rab, ppm +
+                          offsetof(struct ucsi_data, message_out),
+                          sizeof(uc->ppm.data->message_out));
+       if (status < 0)
+               return status;
+
+       rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, ctrl));
+       return ccg_write(uc, rab, ppm + offsetof(struct ucsi_data, ctrl),
+                        sizeof(uc->ppm.data->ctrl));
+}
+
+static int ucsi_ccg_recv_data(struct ucsi_ccg *uc)
+{
+       u8 *ppm = (u8 *)uc->ppm.data;
+       int status;
+       u16 rab;
+
+       rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, cci));
+       status = ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, cci),
+                         sizeof(uc->ppm.data->cci));
+       if (status < 0)
+               return status;
+
+       rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, message_in));
+       return ccg_read(uc, rab, ppm + offsetof(struct ucsi_data, message_in),
+                       sizeof(uc->ppm.data->message_in));
+}
+
+static int ucsi_ccg_ack_interrupt(struct ucsi_ccg *uc)
+{
+       int status;
+       unsigned char data;
+
+       status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
+       if (status < 0)
+               return status;
+
+       return ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
+}
+
+static int ucsi_ccg_sync(struct ucsi_ppm *ppm)
+{
+       struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm);
+       int status;
+
+       status = ucsi_ccg_recv_data(uc);
+       if (status < 0)
+               return status;
+
+       /* ack interrupt to allow next command to run */
+       return ucsi_ccg_ack_interrupt(uc);
+}
+
+static int ucsi_ccg_cmd(struct ucsi_ppm *ppm, struct ucsi_control *ctrl)
+{
+       struct ucsi_ccg *uc = container_of(ppm, struct ucsi_ccg, ppm);
+
+       ppm->data->ctrl.raw_cmd = ctrl->raw_cmd;
+       return ucsi_ccg_send_data(uc);
+}
+
+static irqreturn_t ccg_irq_handler(int irq, void *data)
+{
+       struct ucsi_ccg *uc = data;
+
+       ucsi_notify(uc->ucsi);
+
+       return IRQ_HANDLED;
+}
+
+static int ucsi_ccg_probe(struct i2c_client *client,
+                         const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct ucsi_ccg *uc;
+       int status;
+       u16 rab;
+
+       uc = devm_kzalloc(dev, sizeof(*uc), GFP_KERNEL);
+       if (!uc)
+               return -ENOMEM;
+
+       uc->ppm.data = devm_kzalloc(dev, sizeof(struct ucsi_data), GFP_KERNEL);
+       if (!uc->ppm.data)
+               return -ENOMEM;
+
+       uc->ppm.cmd = ucsi_ccg_cmd;
+       uc->ppm.sync = ucsi_ccg_sync;
+       uc->dev = dev;
+       uc->client = client;
+
+       /* reset ccg device and initialize ucsi */
+       status = ucsi_ccg_init(uc);
+       if (status < 0) {
+               dev_err(uc->dev, "ucsi_ccg_init failed - %d\n", status);
+               return status;
+       }
+
+       status = devm_request_threaded_irq(dev, client->irq, NULL,
+                                          ccg_irq_handler,
+                                          IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+                                          dev_name(dev), uc);
+       if (status < 0) {
+               dev_err(uc->dev, "request_threaded_irq failed - %d\n", status);
+               return status;
+       }
+
+       uc->ucsi = ucsi_register_ppm(dev, &uc->ppm);
+       if (IS_ERR(uc->ucsi)) {
+               dev_err(uc->dev, "ucsi_register_ppm failed\n");
+               return PTR_ERR(uc->ucsi);
+       }
+
+       rab = CCGX_RAB_UCSI_DATA_BLOCK(offsetof(struct ucsi_data, version));
+       status = ccg_read(uc, rab, (u8 *)(uc->ppm.data) +
+                         offsetof(struct ucsi_data, version),
+                         sizeof(uc->ppm.data->version));
+       if (status < 0) {
+               ucsi_unregister_ppm(uc->ucsi);
+               return status;
+       }
+
+       i2c_set_clientdata(client, uc);
+       return 0;
+}
+
+static int ucsi_ccg_remove(struct i2c_client *client)
+{
+       struct ucsi_ccg *uc = i2c_get_clientdata(client);
+
+       ucsi_unregister_ppm(uc->ucsi);
+
+       return 0;
+}
+
+static const struct i2c_device_id ucsi_ccg_device_id[] = {
+       {"ccgx-ucsi", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id);
+
+static struct i2c_driver ucsi_ccg_driver = {
+       .driver = {
+               .name = "ucsi_ccg",
+       },
+       .probe = ucsi_ccg_probe,
+       .remove = ucsi_ccg_remove,
+       .id_table = ucsi_ccg_device_id,
+};
+
+module_i2c_driver(ucsi_ccg_driver);
+
+MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
+MODULE_DESCRIPTION("UCSI driver for Cypress CCGx Type-C controller");
+MODULE_LICENSE("GPL v2");
index f15f89df1f3653675da3b84b1c7ce47debd1bac6..7ea6fb6a2e5dd78c53a79bfea140e2e297858f7d 100644 (file)
@@ -914,7 +914,7 @@ int gnttab_dma_free_pages(struct gnttab_dma_alloc_args *args)
 
        ret = xenmem_reservation_increase(args->nr_pages, args->frames);
        if (ret != args->nr_pages) {
-               pr_debug("Failed to decrease reservation for DMA buffer\n");
+               pr_debug("Failed to increase reservation for DMA buffer\n");
                ret = -EFAULT;
        } else {
                ret = 0;
index df1ed37c3269ebd8170a21583676b80efe50a47f..de01a6d0059dc4adcb98a24197750f72b0b4ceaf 100644 (file)
 
 MODULE_LICENSE("GPL");
 
-static unsigned int limit = 64;
-module_param(limit, uint, 0644);
-MODULE_PARM_DESC(limit, "Maximum number of pages that may be allocated by "
-                       "the privcmd-buf device per open file");
-
 struct privcmd_buf_private {
        struct mutex lock;
        struct list_head list;
-       unsigned int allocated;
 };
 
 struct privcmd_buf_vma_private {
@@ -60,13 +54,10 @@ static void privcmd_buf_vmapriv_free(struct privcmd_buf_vma_private *vma_priv)
 {
        unsigned int i;
 
-       vma_priv->file_priv->allocated -= vma_priv->n_pages;
-
        list_del(&vma_priv->list);
 
        for (i = 0; i < vma_priv->n_pages; i++)
-               if (vma_priv->pages[i])
-                       __free_page(vma_priv->pages[i]);
+               __free_page(vma_priv->pages[i]);
 
        kfree(vma_priv);
 }
@@ -146,8 +137,7 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
        unsigned int i;
        int ret = 0;
 
-       if (!(vma->vm_flags & VM_SHARED) || count > limit ||
-           file_priv->allocated + count > limit)
+       if (!(vma->vm_flags & VM_SHARED))
                return -EINVAL;
 
        vma_priv = kzalloc(sizeof(*vma_priv) + count * sizeof(void *),
@@ -155,19 +145,15 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma)
        if (!vma_priv)
                return -ENOMEM;
 
-       vma_priv->n_pages = count;
-       count = 0;
-       for (i = 0; i < vma_priv->n_pages; i++) {
+       for (i = 0; i < count; i++) {
                vma_priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
                if (!vma_priv->pages[i])
                        break;
-               count++;
+               vma_priv->n_pages++;
        }
 
        mutex_lock(&file_priv->lock);
 
-       file_priv->allocated += count;
-
        vma_priv->file_priv = file_priv;
        vma_priv->users = 1;
 
index 59970886690f1b6a3767b72ec33c3c2fe81fd61f..a7b44863d502e95cbb28a1f7ed2f2a17d7ba1043 100644 (file)
@@ -576,6 +576,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
 {
        signed long rtt2, timeout;
        long ret;
+       bool stalled = false;
        u64 rtt;
        u32 life, last_life;
 
@@ -609,12 +610,20 @@ static long afs_wait_for_call_to_complete(struct afs_call *call,
 
                life = rxrpc_kernel_check_life(call->net->socket, call->rxcall);
                if (timeout == 0 &&
-                   life == last_life && signal_pending(current))
+                   life == last_life && signal_pending(current)) {
+                       if (stalled)
                                break;
+                       __set_current_state(TASK_RUNNING);
+                       rxrpc_kernel_probe_life(call->net->socket, call->rxcall);
+                       timeout = rtt2;
+                       stalled = true;
+                       continue;
+               }
 
                if (life != last_life) {
                        timeout = rtt2;
                        last_life = life;
+                       stalled = false;
                }
 
                timeout = schedule_timeout(timeout);
index 80953528572db52af07ceae9ec782b284ab29610..68f322f600a0677813867c5278b5aca9c23a6e8f 100644 (file)
@@ -3163,6 +3163,9 @@ void btrfs_destroy_inode(struct inode *inode);
 int btrfs_drop_inode(struct inode *inode);
 int __init btrfs_init_cachep(void);
 void __cold btrfs_destroy_cachep(void);
+struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location,
+                             struct btrfs_root *root, int *new,
+                             struct btrfs_path *path);
 struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
                         struct btrfs_root *root, int *was_new);
 struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
index b0ab41da91d122b8cd8c8010cd56973af2afd240..3f0b6d1936e8ecd05dc0bf4957bb6aa691204dd4 100644 (file)
@@ -1664,9 +1664,8 @@ static int cleaner_kthread(void *arg)
        struct btrfs_root *root = arg;
        struct btrfs_fs_info *fs_info = root->fs_info;
        int again;
-       struct btrfs_trans_handle *trans;
 
-       do {
+       while (1) {
                again = 0;
 
                /* Make the cleaner go to sleep early. */
@@ -1715,42 +1714,16 @@ static int cleaner_kthread(void *arg)
                 */
                btrfs_delete_unused_bgs(fs_info);
 sleep:
+               if (kthread_should_park())
+                       kthread_parkme();
+               if (kthread_should_stop())
+                       return 0;
                if (!again) {
                        set_current_state(TASK_INTERRUPTIBLE);
-                       if (!kthread_should_stop())
-                               schedule();
+                       schedule();
                        __set_current_state(TASK_RUNNING);
                }
-       } while (!kthread_should_stop());
-
-       /*
-        * Transaction kthread is stopped before us and wakes us up.
-        * However we might have started a new transaction and COWed some
-        * tree blocks when deleting unused block groups for example. So
-        * make sure we commit the transaction we started to have a clean
-        * shutdown when evicting the btree inode - if it has dirty pages
-        * when we do the final iput() on it, eviction will trigger a
-        * writeback for it which will fail with null pointer dereferences
-        * since work queues and other resources were already released and
-        * destroyed by the time the iput/eviction/writeback is made.
-        */
-       trans = btrfs_attach_transaction(root);
-       if (IS_ERR(trans)) {
-               if (PTR_ERR(trans) != -ENOENT)
-                       btrfs_err(fs_info,
-                                 "cleaner transaction attach returned %ld",
-                                 PTR_ERR(trans));
-       } else {
-               int ret;
-
-               ret = btrfs_commit_transaction(trans);
-               if (ret)
-                       btrfs_err(fs_info,
-                                 "cleaner open transaction commit returned %d",
-                                 ret);
        }
-
-       return 0;
 }
 
 static int transaction_kthread(void *arg)
@@ -3931,6 +3904,13 @@ void close_ctree(struct btrfs_fs_info *fs_info)
        int ret;
 
        set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags);
+       /*
+        * We don't want the cleaner to start new transactions, add more delayed
+        * iputs, etc. while we're closing. We can't use kthread_stop() yet
+        * because that frees the task_struct, and the transaction kthread might
+        * still try to wake up the cleaner.
+        */
+       kthread_park(fs_info->cleaner_kthread);
 
        /* wait for the qgroup rescan worker to stop */
        btrfs_qgroup_wait_for_completion(fs_info, false);
@@ -3958,9 +3938,8 @@ void close_ctree(struct btrfs_fs_info *fs_info)
 
        if (!sb_rdonly(fs_info->sb)) {
                /*
-                * If the cleaner thread is stopped and there are
-                * block groups queued for removal, the deletion will be
-                * skipped when we quit the cleaner thread.
+                * The cleaner kthread is stopped, so do one final pass over
+                * unused block groups.
                 */
                btrfs_delete_unused_bgs(fs_info);
 
@@ -4359,13 +4338,23 @@ static int btrfs_destroy_pinned_extent(struct btrfs_fs_info *fs_info,
        unpin = pinned_extents;
 again:
        while (1) {
+               /*
+                * The btrfs_finish_extent_commit() may get the same range as
+                * ours between find_first_extent_bit and clear_extent_dirty.
+                * Hence, hold the unused_bg_unpin_mutex to avoid double unpin
+                * the same extent range.
+                */
+               mutex_lock(&fs_info->unused_bg_unpin_mutex);
                ret = find_first_extent_bit(unpin, 0, &start, &end,
                                            EXTENT_DIRTY, NULL);
-               if (ret)
+               if (ret) {
+                       mutex_unlock(&fs_info->unused_bg_unpin_mutex);
                        break;
+               }
 
                clear_extent_dirty(unpin, start, end);
                btrfs_error_unpin_extent_range(fs_info, start, end);
+               mutex_unlock(&fs_info->unused_bg_unpin_mutex);
                cond_resched();
        }
 
index 4ba0aedc878bd4422e67d47879b1de297ed848c8..74aa552f47930699aa2a81134c3200bf2f5d5c5e 100644 (file)
@@ -75,7 +75,8 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
         * sure NOFS is set to keep us from deadlocking.
         */
        nofs_flag = memalloc_nofs_save();
-       inode = btrfs_iget(fs_info->sb, &location, root, NULL);
+       inode = btrfs_iget_path(fs_info->sb, &location, root, NULL, path);
+       btrfs_release_path(path);
        memalloc_nofs_restore(nofs_flag);
        if (IS_ERR(inode))
                return inode;
@@ -838,6 +839,25 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
        path->search_commit_root = 1;
        path->skip_locking = 1;
 
+       /*
+        * We must pass a path with search_commit_root set to btrfs_iget in
+        * order to avoid a deadlock when allocating extents for the tree root.
+        *
+        * When we are COWing an extent buffer from the tree root, when looking
+        * for a free extent, at extent-tree.c:find_free_extent(), we can find
+        * block group without its free space cache loaded. When we find one
+        * we must load its space cache which requires reading its free space
+        * cache's inode item from the root tree. If this inode item is located
+        * in the same leaf that we started COWing before, then we end up in
+        * deadlock on the extent buffer (trying to read lock it when we
+        * previously write locked it).
+        *
+        * It's safe to read the inode item using the commit root because
+        * block groups, once loaded, stay in memory forever (until they are
+        * removed) as well as their space caches once loaded. New block groups
+        * once created get their ->cached field set to BTRFS_CACHE_FINISHED so
+        * we will never try to read their inode item while the fs is mounted.
+        */
        inode = lookup_free_space_inode(fs_info, block_group, path);
        if (IS_ERR(inode)) {
                btrfs_free_path(path);
index d3df5b52278cea06c05384ef7bf63aaed6b5404f..9ea4c6f0352f06e828a400890c50122c7ec33ee5 100644 (file)
@@ -1531,12 +1531,11 @@ out_check:
        }
        btrfs_release_path(path);
 
-       if (cur_offset <= end && cow_start == (u64)-1) {
+       if (cur_offset <= end && cow_start == (u64)-1)
                cow_start = cur_offset;
-               cur_offset = end;
-       }
 
        if (cow_start != (u64)-1) {
+               cur_offset = end;
                ret = cow_file_range(inode, locked_page, cow_start, end, end,
                                     page_started, nr_written, 1, NULL);
                if (ret)
@@ -3570,10 +3569,11 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf,
 /*
  * read an inode from the btree into the in-memory inode
  */
-static int btrfs_read_locked_inode(struct inode *inode)
+static int btrfs_read_locked_inode(struct inode *inode,
+                                  struct btrfs_path *in_path)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_path *path;
+       struct btrfs_path *path = in_path;
        struct extent_buffer *leaf;
        struct btrfs_inode_item *inode_item;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3589,15 +3589,18 @@ static int btrfs_read_locked_inode(struct inode *inode)
        if (!ret)
                filled = true;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
+       if (!path) {
+               path = btrfs_alloc_path();
+               if (!path)
+                       return -ENOMEM;
+       }
 
        memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));
 
        ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
        if (ret) {
-               btrfs_free_path(path);
+               if (path != in_path)
+                       btrfs_free_path(path);
                return ret;
        }
 
@@ -3722,7 +3725,8 @@ cache_acl:
                                  btrfs_ino(BTRFS_I(inode)),
                                  root->root_key.objectid, ret);
        }
-       btrfs_free_path(path);
+       if (path != in_path)
+               btrfs_free_path(path);
 
        if (!maybe_acls)
                cache_no_acl(inode);
@@ -5644,8 +5648,9 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
 /* Get an inode object given its location and corresponding root.
  * Returns in *is_new if the inode was read from disk
  */
-struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-                        struct btrfs_root *root, int *new)
+struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location,
+                             struct btrfs_root *root, int *new,
+                             struct btrfs_path *path)
 {
        struct inode *inode;
 
@@ -5656,7 +5661,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
        if (inode->i_state & I_NEW) {
                int ret;
 
-               ret = btrfs_read_locked_inode(inode);
+               ret = btrfs_read_locked_inode(inode, path);
                if (!ret) {
                        inode_tree_add(inode);
                        unlock_new_inode(inode);
@@ -5678,6 +5683,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
        return inode;
 }
 
+struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
+                        struct btrfs_root *root, int *new)
+{
+       return btrfs_iget_path(s, location, root, new, NULL);
+}
+
 static struct inode *new_simple_dir(struct super_block *s,
                                    struct btrfs_key *key,
                                    struct btrfs_root *root)
index 3ca6943827ef88e536b2d6c924e7664a3ab835e7..802a628e9f7d7fe629a76e8d108b75c04ed4246e 100644 (file)
@@ -3488,6 +3488,8 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
                        const u64 sz = BTRFS_I(src)->root->fs_info->sectorsize;
 
                        len = round_down(i_size_read(src), sz) - loff;
+                       if (len == 0)
+                               return 0;
                        olen = len;
                }
        }
@@ -4257,9 +4259,17 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src,
                goto out_unlock;
        if (len == 0)
                olen = len = src->i_size - off;
-       /* if we extend to eof, continue to block boundary */
-       if (off + len == src->i_size)
+       /*
+        * If we extend to eof, continue to block boundary if and only if the
+        * destination end offset matches the destination file's size, otherwise
+        * we would be corrupting data by placing the eof block into the middle
+        * of a file.
+        */
+       if (off + len == src->i_size) {
+               if (!IS_ALIGNED(len, bs) && destoff + len < inode->i_size)
+                       goto out_unlock;
                len = ALIGN(src->i_size, bs) - off;
+       }
 
        if (len == 0) {
                ret = 0;
index b362b45dd7578ff2517baf86ac8779a211aba098..cbc9d0d2c12de42786da57c41ebbc9f0364ffabd 100644 (file)
@@ -1916,7 +1916,7 @@ restore:
 }
 
 /* Used to sort the devices by max_avail(descending sort) */
-static int btrfs_cmp_device_free_bytes(const void *dev_info1,
+static inline int btrfs_cmp_device_free_bytes(const void *dev_info1,
                                       const void *dev_info2)
 {
        if (((struct btrfs_device_info *)dev_info1)->max_avail >
@@ -1945,8 +1945,8 @@ static inline void btrfs_descending_sort_devices(
  * The helper to calc the free space on the devices that can be used to store
  * file data.
  */
-static int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
-                                      u64 *free_bytes)
+static inline int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info,
+                                             u64 *free_bytes)
 {
        struct btrfs_device_info *devices_info;
        struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
index cab0b1f1f741797c32b8d399194554642ecf8a64..efcf89a8ba44c3300f1a214f01ed935ce933c188 100644 (file)
@@ -440,7 +440,7 @@ static int check_block_group_item(struct btrfs_fs_info *fs_info,
            type != (BTRFS_BLOCK_GROUP_METADATA |
                           BTRFS_BLOCK_GROUP_DATA)) {
                block_group_err(fs_info, leaf, slot,
-"invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llu or 0x%llx",
+"invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llx or 0x%llx",
                        type, hweight64(type),
                        BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA,
                        BTRFS_BLOCK_GROUP_SYSTEM,
index e07f3376b7dfc0c9350117bf3db956781e57d45e..a5ce99a6c936558f820d94a63d1301a111f8486b 100644 (file)
@@ -4396,6 +4396,23 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
        logged_end = end;
 
        list_for_each_entry_safe(em, n, &tree->modified_extents, list) {
+               /*
+                * Skip extents outside our logging range. It's important to do
+                * it for correctness because if we don't ignore them, we may
+                * log them before their ordered extent completes, and therefore
+                * we could log them without logging their respective checksums
+                * (the checksum items are added to the csum tree at the very
+                * end of btrfs_finish_ordered_io()). Also leave such extents
+                * outside of our range in the list, since we may have another
+                * ranged fsync in the near future that needs them. If an extent
+                * outside our range corresponds to a hole, log it to avoid
+                * leaving gaps between extents (fsck will complain when we are
+                * not using the NO_HOLES feature).
+                */
+               if ((em->start > end || em->start + em->len <= start) &&
+                   em->block_start != EXTENT_MAP_HOLE)
+                       continue;
+
                list_del_init(&em->list);
                /*
                 * Just an arbitrary number, this can be really CPU intensive
index 27cad84dab23a9cf94008b3c76bff5440e7780ec..189df668b6a0cf0dc2d000184d170ce58d248076 100644 (file)
@@ -1931,10 +1931,17 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off,
        if (!prealloc_cf)
                return -ENOMEM;
 
-       /* Start by sync'ing the source file */
+       /* Start by sync'ing the source and destination files */
        ret = file_write_and_wait_range(src_file, src_off, (src_off + len));
-       if (ret < 0)
+       if (ret < 0) {
+               dout("failed to write src file (%zd)\n", ret);
+               goto out;
+       }
+       ret = file_write_and_wait_range(dst_file, dst_off, (dst_off + len));
+       if (ret < 0) {
+               dout("failed to write dst file (%zd)\n", ret);
                goto out;
+       }
 
        /*
         * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other
index 67a9aeb2f4ecdc66ea3cfd6131bf0e4082cb0691..bd13a3267ae03c401d7b0dd0c1f37626bbc42b0a 100644 (file)
@@ -80,12 +80,8 @@ static int parse_reply_info_in(void **p, void *end,
        info->symlink = *p;
        *p += info->symlink_len;
 
-       if (features & CEPH_FEATURE_DIRLAYOUTHASH)
-               ceph_decode_copy_safe(p, end, &info->dir_layout,
-                                     sizeof(info->dir_layout), bad);
-       else
-               memset(&info->dir_layout, 0, sizeof(info->dir_layout));
-
+       ceph_decode_copy_safe(p, end, &info->dir_layout,
+                             sizeof(info->dir_layout), bad);
        ceph_decode_32_safe(p, end, info->xattr_len, bad);
        ceph_decode_need(p, end, info->xattr_len, bad);
        info->xattr_data = *p;
@@ -3182,10 +3178,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
        recon_state.pagelist = pagelist;
        if (session->s_con.peer_features & CEPH_FEATURE_MDSENC)
                recon_state.msg_version = 3;
-       else if (session->s_con.peer_features & CEPH_FEATURE_FLOCK)
-               recon_state.msg_version = 2;
        else
-               recon_state.msg_version = 1;
+               recon_state.msg_version = 2;
        err = iterate_session_caps(session, encode_caps_cb, &recon_state);
        if (err < 0)
                goto fail;
index 32d4f13784ba5da85e420a565297eff6b3bf132a..03f4d24db8fe009dc4384b83162979c34f11d1e0 100644 (file)
@@ -237,7 +237,8 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
                ceph_put_snap_realm(mdsc, realm);
                realm = next;
        }
-       ceph_put_snap_realm(mdsc, realm);
+       if (realm)
+               ceph_put_snap_realm(mdsc, realm);
        up_read(&mdsc->snap_rwsem);
 
        return exceeded;
index 05f01fbd9c7fb868ecf5502cb6217e862461ef8e..22a9d81597206ce8c7aca27ab5df823c3493c991 100644 (file)
@@ -5835,9 +5835,10 @@ int ext4_mark_iloc_dirty(handle_t *handle,
 {
        int err = 0;
 
-       if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
+       if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) {
+               put_bh(iloc->bh);
                return -EIO;
-
+       }
        if (IS_I_VERSION(inode))
                inode_inc_iversion(inode);
 
index 17adcb16a9c85f8fee50f2796ed10c79f7e32cd7..437f71fe83ae557ad36af1092026aba6d58ccbc6 100644 (file)
@@ -126,6 +126,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
        if (!is_dx_block && type == INDEX) {
                ext4_error_inode(inode, func, line, block,
                       "directory leaf block found instead of index block");
+               brelse(bh);
                return ERR_PTR(-EFSCORRUPTED);
        }
        if (!ext4_has_metadata_csum(inode->i_sb) ||
@@ -2811,7 +2812,9 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
                        list_del_init(&EXT4_I(inode)->i_orphan);
                        mutex_unlock(&sbi->s_orphan_lock);
                }
-       }
+       } else
+               brelse(iloc.bh);
+
        jbd_debug(4, "superblock will point to %lu\n", inode->i_ino);
        jbd_debug(4, "orphan inode %lu will point to %d\n",
                        inode->i_ino, NEXT_ORPHAN(inode));
index ebbc663d07985038ef17520fb41c5fae0e5d3637..a5efee34415fe5a6560522f5b3c48b08c3aac0d8 100644 (file)
@@ -459,16 +459,18 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
 
                BUFFER_TRACE(bh, "get_write_access");
                err = ext4_journal_get_write_access(handle, bh);
-               if (err)
+               if (err) {
+                       brelse(bh);
                        return err;
+               }
                ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n",
                           first_cluster, first_cluster - start, count2);
                ext4_set_bits(bh->b_data, first_cluster - start, count2);
 
                err = ext4_handle_dirty_metadata(handle, NULL, bh);
+               brelse(bh);
                if (unlikely(err))
                        return err;
-               brelse(bh);
        }
 
        return 0;
@@ -605,7 +607,6 @@ handle_bb:
                bh = bclean(handle, sb, block);
                if (IS_ERR(bh)) {
                        err = PTR_ERR(bh);
-                       bh = NULL;
                        goto out;
                }
                overhead = ext4_group_overhead_blocks(sb, group);
@@ -618,9 +619,9 @@ handle_bb:
                ext4_mark_bitmap_end(EXT4_B2C(sbi, group_data[i].blocks_count),
                                     sb->s_blocksize * 8, bh->b_data);
                err = ext4_handle_dirty_metadata(handle, NULL, bh);
+               brelse(bh);
                if (err)
                        goto out;
-               brelse(bh);
 
 handle_ib:
                if (bg_flags[i] & EXT4_BG_INODE_UNINIT)
@@ -635,18 +636,16 @@ handle_ib:
                bh = bclean(handle, sb, block);
                if (IS_ERR(bh)) {
                        err = PTR_ERR(bh);
-                       bh = NULL;
                        goto out;
                }
 
                ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb),
                                     sb->s_blocksize * 8, bh->b_data);
                err = ext4_handle_dirty_metadata(handle, NULL, bh);
+               brelse(bh);
                if (err)
                        goto out;
-               brelse(bh);
        }
-       bh = NULL;
 
        /* Mark group tables in block bitmap */
        for (j = 0; j < GROUP_TABLE_COUNT; j++) {
@@ -685,7 +684,6 @@ handle_ib:
        }
 
 out:
-       brelse(bh);
        err2 = ext4_journal_stop(handle);
        if (err2 && !err)
                err = err2;
@@ -873,6 +871,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
        err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh);
        if (unlikely(err)) {
                ext4_std_error(sb, err);
+               iloc.bh = NULL;
                goto exit_inode;
        }
        brelse(dind);
@@ -924,6 +923,7 @@ static int add_new_gdb_meta_bg(struct super_block *sb,
                                     sizeof(struct buffer_head *),
                                     GFP_NOFS);
        if (!n_group_desc) {
+               brelse(gdb_bh);
                err = -ENOMEM;
                ext4_warning(sb, "not enough memory for %lu groups",
                             gdb_num + 1);
@@ -939,8 +939,6 @@ static int add_new_gdb_meta_bg(struct super_block *sb,
        kvfree(o_group_desc);
        BUFFER_TRACE(gdb_bh, "get_write_access");
        err = ext4_journal_get_write_access(handle, gdb_bh);
-       if (unlikely(err))
-               brelse(gdb_bh);
        return err;
 }
 
@@ -1124,8 +1122,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
                           backup_block, backup_block -
                           ext4_group_first_block_no(sb, group));
                BUFFER_TRACE(bh, "get_write_access");
-               if ((err = ext4_journal_get_write_access(handle, bh)))
+               if ((err = ext4_journal_get_write_access(handle, bh))) {
+                       brelse(bh);
                        break;
+               }
                lock_buffer(bh);
                memcpy(bh->b_data, data, size);
                if (rest)
@@ -2023,7 +2023,7 @@ retry:
 
        err = ext4_alloc_flex_bg_array(sb, n_group + 1);
        if (err)
-               return err;
+               goto out;
 
        err = ext4_mb_alloc_groupinfo(sb, n_group + 1);
        if (err)
@@ -2059,6 +2059,10 @@ retry:
                n_blocks_count_retry = 0;
                free_flex_gd(flex_gd);
                flex_gd = NULL;
+               if (resize_inode) {
+                       iput(resize_inode);
+                       resize_inode = NULL;
+               }
                goto retry;
        }
 
index a221f1cdf70464db0d6551236eb5ecf0f2b76326..53ff6c2a26ed999e008f17c3b0170af9a05e158e 100644 (file)
@@ -4075,6 +4075,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_groups_count = blocks_count;
        sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count,
                        (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
+       if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
+           le32_to_cpu(es->s_inodes_count)) {
+               ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
+                        le32_to_cpu(es->s_inodes_count),
+                        ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
+               ret = -EINVAL;
+               goto failed_mount;
+       }
        db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
                   EXT4_DESC_PER_BLOCK(sb);
        if (ext4_has_feature_meta_bg(sb)) {
@@ -4094,14 +4102,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                ret = -ENOMEM;
                goto failed_mount;
        }
-       if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
-           le32_to_cpu(es->s_inodes_count)) {
-               ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
-                        le32_to_cpu(es->s_inodes_count),
-                        ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
-               ret = -EINVAL;
-               goto failed_mount;
-       }
 
        bgl_lock_init(sbi->s_blockgroup_lock);
 
@@ -4510,6 +4510,7 @@ failed_mount6:
        percpu_counter_destroy(&sbi->s_freeinodes_counter);
        percpu_counter_destroy(&sbi->s_dirs_counter);
        percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
+       percpu_free_rwsem(&sbi->s_journal_flag_rwsem);
 failed_mount5:
        ext4_ext_release(sb);
        ext4_release_system_zone(sb);
index f36fc5d5b257438666641028b8660c0ce3462e91..7643d52c776c61188ca6ac4a7ddd18d303c96e47 100644 (file)
@@ -1031,10 +1031,8 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
        inode_lock(ea_inode);
 
        ret = ext4_reserve_inode_write(handle, ea_inode, &iloc);
-       if (ret) {
-               iloc.bh = NULL;
+       if (ret)
                goto out;
-       }
 
        ref_count = ext4_xattr_inode_get_ref(ea_inode);
        ref_count += ref_change;
@@ -1080,12 +1078,10 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
        }
 
        ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc);
-       iloc.bh = NULL;
        if (ret)
                ext4_warning_inode(ea_inode,
                                   "ext4_mark_iloc_dirty() failed ret=%d", ret);
 out:
-       brelse(iloc.bh);
        inode_unlock(ea_inode);
        return ret;
 }
@@ -1388,6 +1384,12 @@ retry:
                bh = ext4_getblk(handle, ea_inode, block, 0);
                if (IS_ERR(bh))
                        return PTR_ERR(bh);
+               if (!bh) {
+                       WARN_ON_ONCE(1);
+                       EXT4_ERROR_INODE(ea_inode,
+                                        "ext4_getblk() return bh = NULL");
+                       return -EFSCORRUPTED;
+               }
                ret = ext4_journal_get_write_access(handle, bh);
                if (ret)
                        goto out;
@@ -2276,8 +2278,10 @@ static struct buffer_head *ext4_xattr_get_block(struct inode *inode)
        if (!bh)
                return ERR_PTR(-EIO);
        error = ext4_xattr_check_block(inode, bh);
-       if (error)
+       if (error) {
+               brelse(bh);
                return ERR_PTR(error);
+       }
        return bh;
 }
 
@@ -2397,6 +2401,8 @@ retry_inode:
                        error = ext4_xattr_block_set(handle, inode, &i, &bs);
                } else if (error == -ENOSPC) {
                        if (EXT4_I(inode)->i_file_acl && !bs.s.base) {
+                               brelse(bs.bh);
+                               bs.bh = NULL;
                                error = ext4_xattr_block_find(inode, &i, &bs);
                                if (error)
                                        goto cleanup;
@@ -2617,6 +2623,8 @@ out:
        kfree(buffer);
        if (is)
                brelse(is->iloc.bh);
+       if (bs)
+               brelse(bs->bh);
        kfree(is);
        kfree(bs);
 
@@ -2696,7 +2704,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
                               struct ext4_inode *raw_inode, handle_t *handle)
 {
        struct ext4_xattr_ibody_header *header;
-       struct buffer_head *bh;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        static unsigned int mnt_count;
        size_t min_offs;
@@ -2737,13 +2744,17 @@ retry:
         * EA block can hold new_extra_isize bytes.
         */
        if (EXT4_I(inode)->i_file_acl) {
+               struct buffer_head *bh;
+
                bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
                error = -EIO;
                if (!bh)
                        goto cleanup;
                error = ext4_xattr_check_block(inode, bh);
-               if (error)
+               if (error) {
+                       brelse(bh);
                        goto cleanup;
+               }
                base = BHDR(bh);
                end = bh->b_data + bh->b_size;
                min_offs = end - base;
index ae813e609932168ec2e74056fb598aca0ad65907..a5e516a40e7a359cdae8b2bf289175e971b6e6c9 100644 (file)
@@ -165,9 +165,13 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
 
 static void fuse_drop_waiting(struct fuse_conn *fc)
 {
-       if (fc->connected) {
-               atomic_dec(&fc->num_waiting);
-       } else if (atomic_dec_and_test(&fc->num_waiting)) {
+       /*
+        * lockess check of fc->connected is okay, because atomic_dec_and_test()
+        * provides a memory barrier mached with the one in fuse_wait_aborted()
+        * to ensure no wake-up is missed.
+        */
+       if (atomic_dec_and_test(&fc->num_waiting) &&
+           !READ_ONCE(fc->connected)) {
                /* wake up aborters */
                wake_up_all(&fc->blocked_waitq);
        }
@@ -1768,8 +1772,10 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
        req->in.args[1].size = total_len;
 
        err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
-       if (err)
+       if (err) {
                fuse_retrieve_end(fc, req);
+               fuse_put_request(fc, req);
+       }
 
        return err;
 }
@@ -2219,6 +2225,8 @@ EXPORT_SYMBOL_GPL(fuse_abort_conn);
 
 void fuse_wait_aborted(struct fuse_conn *fc)
 {
+       /* matches implicit memory barrier in fuse_drop_waiting() */
+       smp_mb();
        wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
 }
 
index cc2121b37bf5f7d3bb0a57398a2abfc6948ad321..b52f9baaa3e7b9c98478a8c115748ae71fb7b0e1 100644 (file)
@@ -2924,10 +2924,12 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
        }
 
        if (io->async) {
+               bool blocking = io->blocking;
+
                fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
 
                /* we have a non-extending, async request, so return */
-               if (!io->blocking)
+               if (!blocking)
                        return -EIOCBQUEUED;
 
                wait_for_completion(&wait);
index a683d9b27d76033a191b72f81528a7b255de4f08..9a4a15d646ebb2f556828c410cb38c0bd1f30dd5 100644 (file)
@@ -826,7 +826,7 @@ static int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
        ret = gfs2_meta_inode_buffer(ip, &dibh);
        if (ret)
                goto unlock;
-       iomap->private = dibh;
+       mp->mp_bh[0] = dibh;
 
        if (gfs2_is_stuffed(ip)) {
                if (flags & IOMAP_WRITE) {
@@ -863,9 +863,6 @@ unstuff:
        len = lblock_stop - lblock + 1;
        iomap->length = len << inode->i_blkbits;
 
-       get_bh(dibh);
-       mp->mp_bh[0] = dibh;
-
        height = ip->i_height;
        while ((lblock + 1) * sdp->sd_sb.sb_bsize > sdp->sd_heightsize[height])
                height++;
@@ -898,8 +895,6 @@ out:
        iomap->bdev = inode->i_sb->s_bdev;
 unlock:
        up_read(&ip->i_rw_mutex);
-       if (ret && dibh)
-               brelse(dibh);
        return ret;
 
 do_alloc:
@@ -980,9 +975,9 @@ static void gfs2_iomap_journaled_page_done(struct inode *inode, loff_t pos,
 
 static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
                                  loff_t length, unsigned flags,
-                                 struct iomap *iomap)
+                                 struct iomap *iomap,
+                                 struct metapath *mp)
 {
-       struct metapath mp = { .mp_aheight = 1, };
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
@@ -996,9 +991,9 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
        unstuff = gfs2_is_stuffed(ip) &&
                  pos + length > gfs2_max_stuffed_size(ip);
 
-       ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
+       ret = gfs2_iomap_get(inode, pos, length, flags, iomap, mp);
        if (ret)
-               goto out_release;
+               goto out_unlock;
 
        alloc_required = unstuff || iomap->type == IOMAP_HOLE;
 
@@ -1013,7 +1008,7 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
 
                ret = gfs2_quota_lock_check(ip, &ap);
                if (ret)
-                       goto out_release;
+                       goto out_unlock;
 
                ret = gfs2_inplace_reserve(ip, &ap);
                if (ret)
@@ -1038,17 +1033,15 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
                ret = gfs2_unstuff_dinode(ip, NULL);
                if (ret)
                        goto out_trans_end;
-               release_metapath(&mp);
-               brelse(iomap->private);
-               iomap->private = NULL;
+               release_metapath(mp);
                ret = gfs2_iomap_get(inode, iomap->offset, iomap->length,
-                                    flags, iomap, &mp);
+                                    flags, iomap, mp);
                if (ret)
                        goto out_trans_end;
        }
 
        if (iomap->type == IOMAP_HOLE) {
-               ret = gfs2_iomap_alloc(inode, iomap, flags, &mp);
+               ret = gfs2_iomap_alloc(inode, iomap, flags, mp);
                if (ret) {
                        gfs2_trans_end(sdp);
                        gfs2_inplace_release(ip);
@@ -1056,7 +1049,6 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
                        goto out_qunlock;
                }
        }
-       release_metapath(&mp);
        if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip))
                iomap->page_done = gfs2_iomap_journaled_page_done;
        return 0;
@@ -1069,10 +1061,7 @@ out_trans_fail:
 out_qunlock:
        if (alloc_required)
                gfs2_quota_unlock(ip);
-out_release:
-       if (iomap->private)
-               brelse(iomap->private);
-       release_metapath(&mp);
+out_unlock:
        gfs2_write_unlock(inode);
        return ret;
 }
@@ -1088,10 +1077,10 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
 
        trace_gfs2_iomap_start(ip, pos, length, flags);
        if ((flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)) {
-               ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap);
+               ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
        } else {
                ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
-               release_metapath(&mp);
+
                /*
                 * Silently fall back to buffered I/O for stuffed files or if
                 * we've hot a hole (see gfs2_file_direct_write).
@@ -1100,6 +1089,11 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
                    iomap->type != IOMAP_MAPPED)
                        ret = -ENOTBLK;
        }
+       if (!ret) {
+               get_bh(mp.mp_bh[0]);
+               iomap->private = mp.mp_bh[0];
+       }
+       release_metapath(&mp);
        trace_gfs2_iomap_end(ip, iomap, ret);
        return ret;
 }
@@ -1908,10 +1902,16 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
                        if (ret < 0)
                                goto out;
 
-                       /* issue read-ahead on metadata */
-                       if (mp.mp_aheight > 1) {
-                               for (; ret > 1; ret--) {
-                                       metapointer_range(&mp, mp.mp_aheight - ret,
+                       /* On the first pass, issue read-ahead on metadata. */
+                       if (mp.mp_aheight > 1 && strip_h == ip->i_height - 1) {
+                               unsigned int height = mp.mp_aheight - 1;
+
+                               /* No read-ahead for data blocks. */
+                               if (mp.mp_aheight - 1 == strip_h)
+                                       height--;
+
+                               for (; height >= mp.mp_aheight - ret; height--) {
+                                       metapointer_range(&mp, height,
                                                          start_list, start_aligned,
                                                          end_list, end_aligned,
                                                          &start, &end);
index ffe3032b1043deafc6730158f3d262d7a66279af..b08a530433adfb56560fedbf4d741205afdfbd41 100644 (file)
@@ -733,6 +733,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
 
                if (gl) {
                        glock_clear_object(gl, rgd);
+                       gfs2_rgrp_brelse(rgd);
                        gfs2_glock_put(gl);
                }
 
@@ -1174,7 +1175,7 @@ static u32 count_unlinked(struct gfs2_rgrpd *rgd)
  * @rgd: the struct gfs2_rgrpd describing the RG to read in
  *
  * Read in all of a Resource Group's header and bitmap blocks.
- * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps.
+ * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps.
  *
  * Returns: errno
  */
index 9e198f00b64c6f59e7e4a50b1bc8ddf4ec73cdbf..35d2108d567c25d0de1376a84e8a2a4333859ddf 100644 (file)
@@ -730,8 +730,11 @@ static enum lru_status inode_lru_isolate(struct list_head *item,
                return LRU_REMOVED;
        }
 
-       /* recently referenced inodes get one more pass */
-       if (inode->i_state & I_REFERENCED) {
+       /*
+        * Recently referenced inodes and inodes with many attached pages
+        * get one more pass.
+        */
+       if (inode->i_state & I_REFERENCED || inode->i_data.nrpages > 1) {
                inode->i_state &= ~I_REFERENCED;
                spin_unlock(&inode->i_lock);
                return LRU_ROTATE;
index 98d27da43304706f4c8dcc572a397d89ff34cef2..a7f91265ea671d0f6ebe59d2b9fb0f91bd6155cf 100644 (file)
@@ -695,9 +695,6 @@ static struct mountpoint *lookup_mountpoint(struct dentry *dentry)
 
        hlist_for_each_entry(mp, chain, m_hash) {
                if (mp->m_dentry == dentry) {
-                       /* might be worth a WARN_ON() */
-                       if (d_unlinked(dentry))
-                               return ERR_PTR(-ENOENT);
                        mp->m_count++;
                        return mp;
                }
@@ -711,6 +708,9 @@ static struct mountpoint *get_mountpoint(struct dentry *dentry)
        int ret;
 
        if (d_mountpoint(dentry)) {
+               /* might be worth a WARN_ON() */
+               if (d_unlinked(dentry))
+                       return ERR_PTR(-ENOENT);
 mountpoint:
                read_seqlock_excl(&mount_lock);
                mp = lookup_mountpoint(dentry);
@@ -1540,8 +1540,13 @@ static int do_umount(struct mount *mnt, int flags)
 
        namespace_lock();
        lock_mount_hash();
-       event++;
 
+       /* Recheck MNT_LOCKED with the locks held */
+       retval = -EINVAL;
+       if (mnt->mnt.mnt_flags & MNT_LOCKED)
+               goto out;
+
+       event++;
        if (flags & MNT_DETACH) {
                if (!list_empty(&mnt->mnt_list))
                        umount_tree(mnt, UMOUNT_PROPAGATE);
@@ -1555,6 +1560,7 @@ static int do_umount(struct mount *mnt, int flags)
                        retval = 0;
                }
        }
+out:
        unlock_mount_hash();
        namespace_unlock();
        return retval;
@@ -1645,7 +1651,7 @@ int ksys_umount(char __user *name, int flags)
                goto dput_and_out;
        if (!check_mnt(mnt))
                goto dput_and_out;
-       if (mnt->mnt.mnt_flags & MNT_LOCKED)
+       if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
                goto dput_and_out;
        retval = -EPERM;
        if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
@@ -1728,8 +1734,14 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
                for (s = r; s; s = next_mnt(s, r)) {
                        if (!(flag & CL_COPY_UNBINDABLE) &&
                            IS_MNT_UNBINDABLE(s)) {
-                               s = skip_mnt_tree(s);
-                               continue;
+                               if (s->mnt.mnt_flags & MNT_LOCKED) {
+                                       /* Both unbindable and locked. */
+                                       q = ERR_PTR(-EPERM);
+                                       goto out;
+                               } else {
+                                       s = skip_mnt_tree(s);
+                                       continue;
+                               }
                        }
                        if (!(flag & CL_COPY_MNT_NS_FILE) &&
                            is_mnt_ns_file(s->mnt.mnt_root)) {
@@ -1782,7 +1794,7 @@ void drop_collected_mounts(struct vfsmount *mnt)
 {
        namespace_lock();
        lock_mount_hash();
-       umount_tree(real_mount(mnt), UMOUNT_SYNC);
+       umount_tree(real_mount(mnt), 0);
        unlock_mount_hash();
        namespace_unlock();
 }
index fa515d5ea5ba12e0e47fb0c6e3c67ea898bc0003..7b861bbc0b43f38285866dd0d0b2eb6afd45a9b8 100644 (file)
@@ -66,7 +66,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp,
 out_iput:
        rcu_read_unlock();
        trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status));
-       iput(inode);
+       nfs_iput_and_deactive(inode);
 out:
        dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status));
        return res->status;
@@ -108,7 +108,7 @@ __be32 nfs4_callback_recall(void *argp, void *resp,
        }
        trace_nfs4_cb_recall(cps->clp, &args->fh, inode,
                        &args->stateid, -ntohl(res));
-       iput(inode);
+       nfs_iput_and_deactive(inode);
 out:
        dprintk("%s: exit with status = %d\n", __func__, ntohl(res));
        return res;
index 07b83956057627913ac64b44307d19a5765e03e4..6ec2f78c1e191ef3b7b3666fe458856d1fc547bc 100644 (file)
@@ -850,16 +850,23 @@ nfs_delegation_find_inode_server(struct nfs_server *server,
                                 const struct nfs_fh *fhandle)
 {
        struct nfs_delegation *delegation;
-       struct inode *res = NULL;
+       struct inode *freeme, *res = NULL;
 
        list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
                spin_lock(&delegation->lock);
                if (delegation->inode != NULL &&
                    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
-                       res = igrab(delegation->inode);
+                       freeme = igrab(delegation->inode);
+                       if (freeme && nfs_sb_active(freeme->i_sb))
+                               res = freeme;
                        spin_unlock(&delegation->lock);
                        if (res != NULL)
                                return res;
+                       if (freeme) {
+                               rcu_read_unlock();
+                               iput(freeme);
+                               rcu_read_lock();
+                       }
                        return ERR_PTR(-EAGAIN);
                }
                spin_unlock(&delegation->lock);
index 62ae0fd345ad6751d5dbbf1ab8aefca85eff9e68..ffea5788539490467fcf83a4950a42ccce2e0ed3 100644 (file)
@@ -2601,11 +2601,12 @@ static void nfs4_state_manager(struct nfs_client *clp)
                nfs4_clear_state_manager_bit(clp);
                /* Did we race with an attempt to give us more work? */
                if (clp->cl_state == 0)
-                       break;
+                       return;
                if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
-                       break;
-       } while (refcount_read(&clp->cl_count) > 1);
-       return;
+                       return;
+       } while (refcount_read(&clp->cl_count) > 1 && !signalled());
+       goto out_drain;
+
 out_error:
        if (strlen(section))
                section_sep = ": ";
@@ -2613,6 +2614,7 @@ out_error:
                        " with error %d\n", section_sep, section,
                        clp->cl_hostname, -status);
        ssleep(1);
+out_drain:
        nfs4_end_drain_session(clp);
        nfs4_clear_state_manager_bit(clp);
 }
index edff074d38c75c19a06a6ae5c634ba1fd1688d98..d505990dac7c9137b33120762b4606af655a0fc2 100644 (file)
@@ -1038,6 +1038,9 @@ nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        __be32 status;
 
+       if (!cstate->save_fh.fh_dentry)
+               return nfserr_nofilehandle;
+
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh,
                                            src_stateid, RD_STATE, src, NULL);
        if (status) {
index 5769cf3ff035a4b500154eb4e1a4027d3245cbe3..e08a6647267b17d927641c2ef8f34de01c9bbcb3 100644 (file)
@@ -115,12 +115,12 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
                        continue;
                mark = iter_info->marks[type];
                /*
-                * if the event is for a child and this inode doesn't care about
-                * events on the child, don't send it!
+                * If the event is for a child and this mark doesn't care about
+                * events on a child, don't send it!
                 */
-               if (type == FSNOTIFY_OBJ_TYPE_INODE &&
-                   (event_mask & FS_EVENT_ON_CHILD) &&
-                   !(mark->mask & FS_EVENT_ON_CHILD))
+               if (event_mask & FS_EVENT_ON_CHILD &&
+                   (type != FSNOTIFY_OBJ_TYPE_INODE ||
+                    !(mark->mask & FS_EVENT_ON_CHILD)))
                        continue;
 
                marks_mask |= mark->mask;
index 2172ba516c61d536f5f05045e0a47d7dae30cfc1..d2c34900ae05da81e941b2a2d7503714ec09d8d0 100644 (file)
@@ -167,9 +167,9 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
        parent = dget_parent(dentry);
        p_inode = parent->d_inode;
 
-       if (unlikely(!fsnotify_inode_watches_children(p_inode)))
+       if (unlikely(!fsnotify_inode_watches_children(p_inode))) {
                __fsnotify_update_child_dentry_flags(p_inode);
-       else if (p_inode->i_fsnotify_mask & mask) {
+       } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) {
                struct name_snapshot name;
 
                /* we are notifying a parent so come up with the new mask which
@@ -339,6 +339,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
                sb = mnt->mnt.mnt_sb;
                mnt_or_sb_mask = mnt->mnt_fsnotify_mask | sb->s_fsnotify_mask;
        }
+       /* An event "on child" is not intended for a mount/sb mark */
+       if (mask & FS_EVENT_ON_CHILD)
+               mnt_or_sb_mask = 0;
 
        /*
         * Optimization: srcu_read_lock() has a memory barrier which can
index da578ad4c08f4b5f5f66d3e7f3e5b5af77cff812..eb1ce30412dc3e09d1fbd4c8e890d86c2d0a4c9f 100644 (file)
@@ -2411,8 +2411,16 @@ static int ocfs2_dio_end_io(struct kiocb *iocb,
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
 
-       if (bytes > 0 && private)
-               ret = ocfs2_dio_end_io_write(inode, private, offset, bytes);
+       if (bytes <= 0)
+               mlog_ratelimited(ML_ERROR, "Direct IO failed, bytes = %lld",
+                                (long long)bytes);
+       if (private) {
+               if (bytes > 0)
+                       ret = ocfs2_dio_end_io_write(inode, private, offset,
+                                                    bytes);
+               else
+                       ocfs2_dio_free_write_ctx(inode, private);
+       }
 
        ocfs2_iocb_clear_rw_locked(iocb);
 
index 308ea0eb35fd112f29a5546c23dba6f80e60c787..a396096a5099f93e95f43b2db71d4f64ce996448 100644 (file)
@@ -178,6 +178,15 @@ do {                                                                       \
                              ##__VA_ARGS__);                           \
 } while (0)
 
+#define mlog_ratelimited(mask, fmt, ...)                               \
+do {                                                                   \
+       static DEFINE_RATELIMIT_STATE(_rs,                              \
+                                     DEFAULT_RATELIMIT_INTERVAL,       \
+                                     DEFAULT_RATELIMIT_BURST);         \
+       if (__ratelimit(&_rs))                                          \
+               mlog(mask, fmt, ##__VA_ARGS__);                         \
+} while (0)
+
 #define mlog_errno(st) ({                                              \
        int _st = (st);                                                 \
        if (_st != -ERESTARTSYS && _st != -EINTR &&                     \
index 6fc5425b1474a52694b4860aa79cefc52d3fd826..2652d00842d6ba8c6479f816765c87dfc622d1cb 100644 (file)
@@ -243,7 +243,7 @@ xfs_attr3_leaf_verify(
        struct xfs_mount                *mp = bp->b_target->bt_mount;
        struct xfs_attr_leafblock       *leaf = bp->b_addr;
        struct xfs_attr_leaf_entry      *entries;
-       uint16_t                        end;
+       uint32_t                        end;    /* must be 32bit - see below */
        int                             i;
 
        xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
@@ -293,6 +293,11 @@ xfs_attr3_leaf_verify(
        /*
         * Quickly check the freemap information.  Attribute data has to be
         * aligned to 4-byte boundaries, and likewise for the free space.
+        *
+        * Note that for 64k block size filesystems, the freemap entries cannot
+        * overflow as they are only be16 fields. However, when checking end
+        * pointer of the freemap, we have to be careful to detect overflows and
+        * so use uint32_t for those checks.
         */
        for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
                if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
@@ -303,7 +308,9 @@ xfs_attr3_leaf_verify(
                        return __this_address;
                if (ichdr.freemap[i].size & 0x3)
                        return __this_address;
-               end = ichdr.freemap[i].base + ichdr.freemap[i].size;
+
+               /* be care of 16 bit overflows here */
+               end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
                if (end < ichdr.freemap[i].base)
                        return __this_address;
                if (end > mp->m_attr_geo->blksize)
index 6e2c08f30f602deb360e737003cc3ae1abf4bfc7..6ecdbb3af7de5c02c86a25d41ed7086ae2f845fc 100644 (file)
@@ -1608,7 +1608,7 @@ xfs_ioc_getbmap(
        error = 0;
 out_free_buf:
        kmem_free(buf);
-       return 0;
+       return error;
 }
 
 struct getfsmap_info {
index 576c375ce12a8f411a49f75cf6bd72f69c96279c..6b736ea58d35402eb7e7975067a4303131cf3d83 100644 (file)
@@ -107,5 +107,5 @@ assfail(char *expr, char *file, int line)
 void
 xfs_hex_dump(void *p, int length)
 {
-       print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_ADDRESS, 16, 1, p, length, 1);
+       print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1);
 }
index 89f3b03b14451af9f4a9707172a97143f2ae9b5e..e3667c9a33a5deea5ef1f849b97cb0c3fe83a404 100644 (file)
@@ -3,7 +3,7 @@
 #define _4LEVEL_FIXUP_H
 
 #define __ARCH_HAS_4LEVEL_HACK
-#define __PAGETABLE_PUD_FOLDED
+#define __PAGETABLE_PUD_FOLDED 1
 
 #define PUD_SHIFT                      PGDIR_SHIFT
 #define PUD_SIZE                       PGDIR_SIZE
index 9c2e0708eb82f4aeb8c009f51f78fc43ae511036..73474bb52344d982abaee00ffcbad322308e06f4 100644 (file)
@@ -3,7 +3,7 @@
 #define _5LEVEL_FIXUP_H
 
 #define __ARCH_HAS_5LEVEL_HACK
-#define __PAGETABLE_P4D_FOLDED
+#define __PAGETABLE_P4D_FOLDED 1
 
 #define P4D_SHIFT                      PGDIR_SHIFT
 #define P4D_SIZE                       PGDIR_SIZE
index 0c34215263b8aec624451b3f04575a1ea6328cf7..1d6dd38c0e5ea8a2155c370cf27bb808f252031e 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef __ASSEMBLY__
 #include <asm-generic/5level-fixup.h>
 
-#define __PAGETABLE_PUD_FOLDED
+#define __PAGETABLE_PUD_FOLDED 1
 
 /*
  * Having the pud type consist of a pgd gets the size right, and allows
index 1a29b2a0282bf20a8541b79096b474d16c5ae50c..04cb913797bc0d534032364c05d53c50d8d7d73f 100644 (file)
@@ -4,7 +4,7 @@
 
 #ifndef __ASSEMBLY__
 
-#define __PAGETABLE_P4D_FOLDED
+#define __PAGETABLE_P4D_FOLDED 1
 
 typedef struct { pgd_t pgd; } p4d_t;
 
index f35f6e8149e47dca34e7cded26574b0786322fc1..b85b8271a73debc1dc58f661ba9073c399fab175 100644 (file)
@@ -8,7 +8,7 @@
 
 struct mm_struct;
 
-#define __PAGETABLE_PMD_FOLDED
+#define __PAGETABLE_PMD_FOLDED 1
 
 /*
  * Having the pmd type consist of a pud gets the size right, and allows
index e950b9c50f34f218284ff0785366c9ef07a6bdf9..9bef475db6fefe1e3b79c04cff754efd1b383de0 100644 (file)
@@ -9,7 +9,7 @@
 #else
 #include <asm-generic/pgtable-nop4d.h>
 
-#define __PAGETABLE_PUD_FOLDED
+#define __PAGETABLE_PUD_FOLDED 1
 
 /*
  * Having the pud type consist of a p4d gets the size right, and allows
index 5657a20e0c599449d9851e08f672b2c2cb7f6d64..359fb935ded6ab0cc418659f6f119d26886db129 100644 (file)
@@ -1127,4 +1127,20 @@ static inline bool arch_has_pfn_modify_check(void)
 #endif
 #endif
 
+/*
+ * On some architectures it depends on the mm if the p4d/pud or pmd
+ * layer of the page table hierarchy is folded or not.
+ */
+#ifndef mm_p4d_folded
+#define mm_p4d_folded(mm)      __is_defined(__PAGETABLE_P4D_FOLDED)
+#endif
+
+#ifndef mm_pud_folded
+#define mm_pud_folded(mm)      __is_defined(__PAGETABLE_PUD_FOLDED)
+#endif
+
+#ifndef mm_pmd_folded
+#define mm_pmd_folded(mm)      __is_defined(__PAGETABLE_PMD_FOLDED)
+#endif
+
 #endif /* _ASM_GENERIC_PGTABLE_H */
index a83e1f632eb70eeda82581403f2916e7c7346f79..f01623aef2f77945514d4b2ef0045f0735e11851 100644 (file)
@@ -169,6 +169,7 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,
 
 void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
                      unsigned int idx);
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr);
 unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
 void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
index cb31683bbe154ab1f5b58319369aa7fe32da1c44..8268811a697e25398b6785b6d8904fc9dca46adf 100644 (file)
@@ -41,7 +41,12 @@ int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *
 int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight);
 int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 reg);
 int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload);
-int can_rx_offload_irq_queue_err_skb(struct can_rx_offload *offload, struct sk_buff *skb);
+int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
+                               struct sk_buff *skb, u32 timestamp);
+unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload,
+                                        unsigned int idx, u32 timestamp);
+int can_rx_offload_queue_tail(struct can_rx_offload *offload,
+                             struct sk_buff *skb);
 void can_rx_offload_reset(struct can_rx_offload *offload);
 void can_rx_offload_del(struct can_rx_offload *offload);
 void can_rx_offload_enable(struct can_rx_offload *offload);
index 6b92b3395fa9954ec140df3ed5b2b6d7b4f527f1..65a38c4a02a18d59ff5837447264f7f00998e4fb 100644 (file)
@@ -213,12 +213,6 @@ DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facin
         CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \
         CEPH_FEATURE_CEPHX_V2)
 
-#define CEPH_FEATURES_REQUIRED_DEFAULT   \
-       (CEPH_FEATURE_NOSRCADDR |        \
-        CEPH_FEATURE_SUBSCRIBE2 |       \
-        CEPH_FEATURE_RECONNECT_SEQ |    \
-        CEPH_FEATURE_PGID64 |           \
-        CEPH_FEATURE_PGPOOL3 |          \
-        CEPH_FEATURE_OSDENC)
+#define CEPH_FEATURES_REQUIRED_DEFAULT 0
 
 #endif
index c0f5db3a962174953a0e8bf19873b7a22334448d..2010493e1040846c999804e2e157233c27ccef60 100644 (file)
 #define KASAN_ABI_VERSION 3
 #endif
 
-/*
- * Because __no_sanitize_address conflicts with inlining:
- *   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
- * we do one or the other. 
- */
-#ifdef CONFIG_KASAN
-#define __no_sanitize_address_or_inline                                        \
-       __no_sanitize_address __maybe_unused notrace
-#else
-#define __no_sanitize_address_or_inline inline
-#endif
-
 #if GCC_VERSION >= 50100
 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
 #endif
index 18c80cfa4fc485efeb3f85aa3ddcaeadf49ad7d6..06396c1cf127f75bb357326883f1dcb69161ccf1 100644 (file)
@@ -189,7 +189,7 @@ void __read_once_size(const volatile void *p, void *res, int size)
  *     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
  * '__maybe_unused' allows us to avoid defined-but-not-used warnings.
  */
-# define __no_kasan_or_inline __no_sanitize_address __maybe_unused
+# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
 #else
 # define __no_kasan_or_inline __always_inline
 #endif
index 6b28c1b7310c0176bddb490f9443eb15b101400e..f8c400ba1929ee503be1b09824e1606860fac0fc 100644 (file)
@@ -4,22 +4,26 @@
 
 /*
  * The attributes in this file are unconditionally defined and they directly
- * map to compiler attribute(s) -- except those that are optional.
+ * map to compiler attribute(s), unless one of the compilers does not support
+ * the attribute. In that case, __has_attribute is used to check for support
+ * and the reason is stated in its comment ("Optional: ...").
  *
  * Any other "attributes" (i.e. those that depend on a configuration option,
  * on a compiler, on an architecture, on plugins, on other attributes...)
  * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
+ * The intention is to keep this file as simple as possible, as well as
+ * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
  *
  * This file is meant to be sorted (by actual attribute name,
  * not by #define identifier). Use the __attribute__((__name__)) syntax
  * (i.e. with underscores) to avoid future collisions with other macros.
- * If an attribute is optional, state the reason in the comment.
+ * Provide links to the documentation of each supported compiler, if it exists.
  */
 
 /*
- * To check for optional attributes, we use __has_attribute, which is supported
- * on gcc >= 5, clang >= 2.9 and icc >= 17. In the meantime, to support
- * 4.6 <= gcc < 5, we implement __has_attribute by hand.
+ * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17.
+ * In the meantime, to support 4.6 <= gcc < 5, we implement __has_attribute
+ * by hand.
  *
  * sparse does not support __has_attribute (yet) and defines __GNUC_MINOR__
  * depending on the compiler used to build it; however, these attributes have
index 3439d7d0249aa592bc0100a9f8058fb2b3a2c249..4a3f9c09c92d04583f9a0d4fa335a1fb9ce44ab8 100644 (file)
@@ -130,6 +130,10 @@ struct ftrace_likely_data {
 # define randomized_struct_fields_end
 #endif
 
+#ifndef asm_volatile_goto
+#define asm_volatile_goto(x...) asm goto(x)
+#endif
+
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
index 845174e113ce9b360e899553b7e97f837a5abff7..100ce4a4aff6ce1808a0993a7bc24ebeb3612468 100644 (file)
@@ -1167,6 +1167,8 @@ static inline bool efi_enabled(int feature)
 extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
 
 extern bool efi_is_table_address(unsigned long phys_addr);
+
+extern int efi_apply_persistent_mem_reservations(void);
 #else
 static inline bool efi_enabled(int feature)
 {
@@ -1185,6 +1187,11 @@ static inline bool efi_is_table_address(unsigned long phys_addr)
 {
        return false;
 }
+
+static inline int efi_apply_persistent_mem_reservations(void)
+{
+       return 0;
+}
 #endif
 
 extern int efi_status_to_err(efi_status_t status);
index 2827b87590d8d55893c87a1593be582994f4a7e5..387c70df6f29cc215f4678d6d19292e1f0b7ff20 100644 (file)
@@ -722,8 +722,8 @@ struct hid_usage_id {
  * input will not be passed to raw_event unless hid_device_io_start is
  * called.
  *
- * raw_event and event should return 0 on no action performed, 1 when no
- * further processing should be done and negative on error
+ * raw_event and event should return negative on error, any other value will
+ * pass the event on to .event() typically return 0 for success.
  *
  * input_mapping shall return a negative value to completely ignore this usage
  * (e.g. doubled or invalid usage), zero to continue with parsing of this
index e6bb36a97519b00f1aa5e438dc2f72501f93c682..8336b2f6f834627c462a0add39f4502aecfb5ed6 100644 (file)
@@ -21,6 +21,7 @@
 #define PIT_LATCH      ((PIT_TICK_RATE + HZ/2) / HZ)
 
 extern raw_spinlock_t i8253_lock;
+extern bool i8253_clear_counter_on_shutdown;
 extern struct clock_event_device i8253_clockevent;
 extern void clockevent_i8253_init(bool oneshot);
 
index fcf9cc9d535faf54c6b0fa463b6cf09643d0e5c4..5411de93a363e8a14bb980a30c8e5af67f25907e 100644 (file)
@@ -1744,11 +1744,15 @@ int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address);
 
 static inline void mm_inc_nr_puds(struct mm_struct *mm)
 {
+       if (mm_pud_folded(mm))
+               return;
        atomic_long_add(PTRS_PER_PUD * sizeof(pud_t), &mm->pgtables_bytes);
 }
 
 static inline void mm_dec_nr_puds(struct mm_struct *mm)
 {
+       if (mm_pud_folded(mm))
+               return;
        atomic_long_sub(PTRS_PER_PUD * sizeof(pud_t), &mm->pgtables_bytes);
 }
 #endif
@@ -1768,11 +1772,15 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
 
 static inline void mm_inc_nr_pmds(struct mm_struct *mm)
 {
+       if (mm_pmd_folded(mm))
+               return;
        atomic_long_add(PTRS_PER_PMD * sizeof(pmd_t), &mm->pgtables_bytes);
 }
 
 static inline void mm_dec_nr_pmds(struct mm_struct *mm)
 {
+       if (mm_pmd_folded(mm))
+               return;
        atomic_long_sub(PTRS_PER_PMD * sizeof(pmd_t), &mm->pgtables_bytes);
 }
 #endif
index abe975c87b9003a7301f0e879f6bdad733e6c583..7f53ece2c039aeb849ca929b2b13cb29bd172292 100644 (file)
@@ -324,9 +324,8 @@ static inline unsigned int nanddev_ntargets(const struct nand_device *nand)
  */
 static inline unsigned int nanddev_neraseblocks(const struct nand_device *nand)
 {
-       return (u64)nand->memorg.luns_per_target *
-              nand->memorg.eraseblocks_per_lun *
-              nand->memorg.pages_per_eraseblock;
+       return nand->memorg.ntargets * nand->memorg.luns_per_target *
+              nand->memorg.eraseblocks_per_lun;
 }
 
 /**
@@ -569,7 +568,7 @@ static inline void nanddev_pos_next_eraseblock(struct nand_device *nand,
 }
 
 /**
- * nanddev_pos_next_eraseblock() - Move a position to the next page
+ * nanddev_pos_next_page() - Move a position to the next page
  * @nand: NAND device
  * @pos: the position to update
  *
index dc1d9ed33b3192e9406b17c3107b3235b28ff1b9..857f8abf7b91bc79731873fc8f68e31f6bff4d03 100644 (file)
@@ -3190,6 +3190,26 @@ static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
 #endif
 }
 
+/* Variant of netdev_tx_sent_queue() for drivers that are aware
+ * that they should not test BQL status themselves.
+ * We do want to change __QUEUE_STATE_STACK_XOFF only for the last
+ * skb of a batch.
+ * Returns true if the doorbell must be used to kick the NIC.
+ */
+static inline bool __netdev_tx_sent_queue(struct netdev_queue *dev_queue,
+                                         unsigned int bytes,
+                                         bool xmit_more)
+{
+       if (xmit_more) {
+#ifdef CONFIG_BQL
+               dql_queued(&dev_queue->dql, bytes);
+#endif
+               return netif_tx_queue_stopped(dev_queue);
+       }
+       netdev_tx_sent_queue(dev_queue, bytes);
+       return true;
+}
+
 /**
  *     netdev_sent_queue - report the number of bytes queued to hardware
  *     @dev: network device
index 34fc80f3eb900deb8e4c21b10edf8909c469e7b4..1d100efe74ec76861084a4272327b662cf1de478 100644 (file)
@@ -314,7 +314,7 @@ enum {
 extern ip_set_id_t ip_set_get_byname(struct net *net,
                                     const char *name, struct ip_set **set);
 extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
-extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
+extern void ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name);
 extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
 extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
 
index 8e2bab1e8e90930f954ec7dc3a1b7a8179eecd13..70877f8de7e919d30716f0483610dfb12eeec433 100644 (file)
@@ -43,11 +43,11 @@ ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment,
        rcu_assign_pointer(comment->c, c);
 }
 
-/* Used only when dumping a set, protected by rcu_read_lock_bh() */
+/* Used only when dumping a set, protected by rcu_read_lock() */
 static inline int
 ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment)
 {
-       struct ip_set_comment_rcu *c = rcu_dereference_bh(comment->c);
+       struct ip_set_comment_rcu *c = rcu_dereference(comment->c);
 
        if (!c)
                return 0;
index 08f9247e9827e0056eb4d82c5c83a73a19cebd11..9003e29cde4615eb9a9e7785c675d36e1f24b8df 100644 (file)
@@ -119,6 +119,8 @@ static inline int hardlockup_detector_perf_init(void) { return 0; }
 void watchdog_nmi_stop(void);
 void watchdog_nmi_start(void);
 int watchdog_nmi_probe(void);
+int watchdog_nmi_enable(unsigned int cpu);
+void watchdog_nmi_disable(unsigned int cpu);
 
 /**
  * touch_nmi_watchdog - restart NMI watchdog timeout.
index 14b789a123e7d9240cea72fc01bf0d4d7acdba9b..1656c59784987bd486ace6be1f10705fb47ac5c6 100644 (file)
@@ -317,6 +317,8 @@ bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
                         const struct in6_addr *addr);
 bool ipv6_chk_acast_addr_src(struct net *net, struct net_device *dev,
                             const struct in6_addr *addr);
+int ipv6_anycast_init(void);
+void ipv6_anycast_cleanup(void);
 
 /* Device notifier */
 int register_inet6addr_notifier(struct notifier_block *nb);
index de587948042a4ab6ce9e00dac021ce492a026621..1adefe42c0a689b839492d500327ef891c4c395c 100644 (file)
@@ -77,7 +77,8 @@ int rxrpc_kernel_retry_call(struct socket *, struct rxrpc_call *,
                            struct sockaddr_rxrpc *, struct key *);
 int rxrpc_kernel_check_call(struct socket *, struct rxrpc_call *,
                            enum rxrpc_call_completion *, u32 *);
-u32 rxrpc_kernel_check_life(struct socket *, struct rxrpc_call *);
+u32 rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *);
+void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *);
 u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *);
 bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *,
                                 ktime_t *);
index d7578cf49c3af85f2cd164a0b242d064b25ed23b..c9c78c15bce04eea71172ecad8693eb363bc2d60 100644 (file)
@@ -146,10 +146,12 @@ struct ifacaddr6 {
        struct in6_addr         aca_addr;
        struct fib6_info        *aca_rt;
        struct ifacaddr6        *aca_next;
+       struct hlist_node       aca_addr_lst;
        int                     aca_users;
        refcount_t              aca_refcnt;
        unsigned long           aca_cstamp;
        unsigned long           aca_tstamp;
+       struct rcu_head         rcu;
 };
 
 #define        IFA_HOST        IPV6_ADDR_LOOPBACK
index eed04af9b75e56b6c33d0887cdefa4c8f827251e..ae7b86f587f2c77c5e2e05972d67b070a39b8711 100644 (file)
@@ -153,4 +153,43 @@ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
                               const char *fmt, ...) { }
 #endif /* CONFIG_SYSCTL */
 
+static inline struct nf_generic_net *nf_generic_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.generic;
+}
+
+static inline struct nf_tcp_net *nf_tcp_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.tcp;
+}
+
+static inline struct nf_udp_net *nf_udp_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.udp;
+}
+
+static inline struct nf_icmp_net *nf_icmp_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.icmp;
+}
+
+static inline struct nf_icmp_net *nf_icmpv6_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.icmpv6;
+}
+
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+static inline struct nf_dccp_net *nf_dccp_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.dccp;
+}
+#endif
+
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+static inline struct nf_sctp_net *nf_sctp_pernet(struct net *net)
+{
+       return &net->ct.nf_ct_proto.sctp;
+}
+#endif
+
 #endif /*_NF_CONNTRACK_PROTOCOL_H*/
index 8c2caa370e0f683ea764bc0d72da6dfa93699673..ab9242e51d9e04ac6f4a18d50710c03dbc82ff24 100644 (file)
@@ -608,4 +608,16 @@ static inline __u32 sctp_dst_mtu(const struct dst_entry *dst)
                                 SCTP_DEFAULT_MINSEGMENT));
 }
 
+static inline bool sctp_transport_pmtu_check(struct sctp_transport *t)
+{
+       __u32 pmtu = sctp_dst_mtu(t->dst);
+
+       if (t->pathmtu == pmtu)
+               return true;
+
+       t->pathmtu = pmtu;
+
+       return false;
+}
+
 #endif /* __net_sctp_h__ */
index a9834c37ac40061d0e18209756c1d3be2c0497d7..c0e7d24ca25682acf384d56d7b0c87e71e6c456b 100644 (file)
@@ -31,8 +31,8 @@ TRACE_EVENT(kyber_latency,
 
        TP_fast_assign(
                __entry->dev            = disk_devt(dev_to_disk(kobj_to_dev(q->kobj.parent)));
-               strlcpy(__entry->domain, domain, DOMAIN_LEN);
-               strlcpy(__entry->type, type, DOMAIN_LEN);
+               strlcpy(__entry->domain, domain, sizeof(__entry->domain));
+               strlcpy(__entry->type, type, sizeof(__entry->type));
                __entry->percentile     = percentile;
                __entry->numerator      = numerator;
                __entry->denominator    = denominator;
@@ -60,7 +60,7 @@ TRACE_EVENT(kyber_adjust,
 
        TP_fast_assign(
                __entry->dev            = disk_devt(dev_to_disk(kobj_to_dev(q->kobj.parent)));
-               strlcpy(__entry->domain, domain, DOMAIN_LEN);
+               strlcpy(__entry->domain, domain, sizeof(__entry->domain));
                __entry->depth          = depth;
        ),
 
@@ -82,7 +82,7 @@ TRACE_EVENT(kyber_throttled,
 
        TP_fast_assign(
                __entry->dev            = disk_devt(dev_to_disk(kobj_to_dev(q->kobj.parent)));
-               strlcpy(__entry->domain, domain, DOMAIN_LEN);
+               strlcpy(__entry->domain, domain, sizeof(__entry->domain));
        ),
 
        TP_printk("%d,%d %s", MAJOR(__entry->dev), MINOR(__entry->dev),
index 573d5b901fb11886590a2672cf396af64476efeb..5b50fe4906d2ef95d5121a80109fdb1f130ead2b 100644 (file)
@@ -181,6 +181,7 @@ enum rxrpc_timer_trace {
 enum rxrpc_propose_ack_trace {
        rxrpc_propose_ack_client_tx_end,
        rxrpc_propose_ack_input_data,
+       rxrpc_propose_ack_ping_for_check_life,
        rxrpc_propose_ack_ping_for_keepalive,
        rxrpc_propose_ack_ping_for_lost_ack,
        rxrpc_propose_ack_ping_for_lost_reply,
@@ -380,6 +381,7 @@ enum rxrpc_tx_point {
 #define rxrpc_propose_ack_traces \
        EM(rxrpc_propose_ack_client_tx_end,     "ClTxEnd") \
        EM(rxrpc_propose_ack_input_data,        "DataIn ") \
+       EM(rxrpc_propose_ack_ping_for_check_life, "ChkLife") \
        EM(rxrpc_propose_ack_ping_for_keepalive, "KeepAlv") \
        EM(rxrpc_propose_ack_ping_for_lost_ack, "LostAck") \
        EM(rxrpc_propose_ack_ping_for_lost_reply, "LostRpl") \
index f5ff8a76e208fc45584bb76503860c6fdf6650fd..b01eb502d49c55d04f33cace28a410171239eaf5 100644 (file)
@@ -83,11 +83,11 @@ struct kfd_ioctl_set_cu_mask_args {
 };
 
 struct kfd_ioctl_get_queue_wave_state_args {
-       uint64_t ctl_stack_address;     /* to KFD */
-       uint32_t ctl_stack_used_size;   /* from KFD */
-       uint32_t save_area_used_size;   /* from KFD */
-       uint32_t queue_id;              /* to KFD */
-       uint32_t pad;
+       __u64 ctl_stack_address;        /* to KFD */
+       __u32 ctl_stack_used_size;      /* from KFD */
+       __u32 save_area_used_size;      /* from KFD */
+       __u32 queue_id;                 /* to KFD */
+       __u32 pad;
 };
 
 /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */
@@ -255,10 +255,10 @@ struct kfd_hsa_memory_exception_data {
 
 /* hw exception data */
 struct kfd_hsa_hw_exception_data {
-       uint32_t reset_type;
-       uint32_t reset_cause;
-       uint32_t memory_lost;
-       uint32_t gpu_id;
+       __u32 reset_type;
+       __u32 reset_cause;
+       __u32 memory_lost;
+       __u32 gpu_id;
 };
 
 /* Event data */
index 579974b0bf0d8140882ff2a48f96184f0f829456..7de4f1bdaf06a28a7e64fb9d72fba3d42d0032b8 100644 (file)
@@ -1635,8 +1635,8 @@ enum nft_ng_attributes {
        NFTA_NG_MODULUS,
        NFTA_NG_TYPE,
        NFTA_NG_OFFSET,
-       NFTA_NG_SET_NAME,
-       NFTA_NG_SET_ID,
+       NFTA_NG_SET_NAME,       /* deprecated */
+       NFTA_NG_SET_ID,         /* deprecated */
        __NFTA_NG_MAX
 };
 #define NFTA_NG_MAX    (__NFTA_NG_MAX - 1)
index 156ccd089df184853c180a240bfaaaa27774a4fe..1610fdbab98dfc89212ee653a573da8c39bdefe8 100644 (file)
 #include <linux/if_vlan.h>
 #include <linux/if_pppox.h>
 
+#ifndef __KERNEL__
+#include <limits.h> /* for INT_MIN, INT_MAX */
+#endif
+
 /* Bridge Hooks */
 /* After promisc drops, checksum checks. */
 #define NF_BR_PRE_ROUTING      0
index 34dd3d497f2cc52b6742d5bf89fa1e88aa947d57..c81feb373d3ea597a7d2c66ad203ad18ed821189 100644 (file)
@@ -568,6 +568,8 @@ struct sctp_assoc_reset_event {
 
 #define SCTP_ASSOC_CHANGE_DENIED       0x0004
 #define SCTP_ASSOC_CHANGE_FAILED       0x0008
+#define SCTP_STREAM_CHANGE_DENIED      SCTP_ASSOC_CHANGE_DENIED
+#define SCTP_STREAM_CHANGE_FAILED      SCTP_ASSOC_CHANGE_FAILED
 struct sctp_stream_change_event {
        __u16 strchange_type;
        __u16 strchange_flags;
@@ -1151,6 +1153,7 @@ struct sctp_add_streams {
 /* SCTP Stream schedulers */
 enum sctp_sched_type {
        SCTP_SS_FCFS,
+       SCTP_SS_DEFAULT = SCTP_SS_FCFS,
        SCTP_SS_PRIO,
        SCTP_SS_RR,
        SCTP_SS_MAX = SCTP_SS_RR
index 18803ff76e27808bc8263284bbd089c32877ba05..4969817124a8d7c6b462aeb18f54105d1d49e2e3 100644 (file)
@@ -42,16 +42,12 @@ int xen_setup_shutdown_event(void);
 
 extern unsigned long *xen_contiguous_bitmap;
 
-#ifdef CONFIG_XEN_PV
+#if defined(CONFIG_XEN_PV) || defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
                                unsigned int address_bits,
                                dma_addr_t *dma_handle);
 
 void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
-
-int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
-                 xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
-                 unsigned int domid, bool no_translate, struct page **pages);
 #else
 static inline int xen_create_contiguous_region(phys_addr_t pstart,
                                               unsigned int order,
@@ -63,7 +59,13 @@ static inline int xen_create_contiguous_region(phys_addr_t pstart,
 
 static inline void xen_destroy_contiguous_region(phys_addr_t pstart,
                                                 unsigned int order) { }
+#endif
 
+#if defined(CONFIG_XEN_PV)
+int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
+                 xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
+                 unsigned int domid, bool no_translate, struct page **pages);
+#else
 static inline int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
                                xen_pfn_t *pfn, int nr, int *err_ptr,
                                pgprot_t prot,  unsigned int domid,
index 6377225b208204c1c2d8829a778f50ebaa7d816d..1a796e0799ec4a524aee5c325734f0ab22a410ac 100644 (file)
@@ -553,7 +553,6 @@ bool is_bpf_text_address(unsigned long addr)
 int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
                    char *sym)
 {
-       unsigned long symbol_start, symbol_end;
        struct bpf_prog_aux *aux;
        unsigned int it = 0;
        int ret = -ERANGE;
@@ -566,10 +565,9 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
                if (it++ != symnum)
                        continue;
 
-               bpf_get_prog_addr_region(aux->prog, &symbol_start, &symbol_end);
                bpf_get_prog_name(aux->prog, sym);
 
-               *value = symbol_start;
+               *value = (unsigned long)aux->prog->bpf_func;
                *type  = BPF_SYM_ELF_TYPE;
 
                ret = 0;
index ccb93277aae2c607e7b6ef079e5432d89ef4a1f6..cf5040fd54344dd798f73464eadb5b9684300f1c 100644 (file)
@@ -2078,6 +2078,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
                info.jited_prog_len = 0;
                info.xlated_prog_len = 0;
                info.nr_jited_ksyms = 0;
+               info.nr_jited_func_lens = 0;
                goto done;
        }
 
@@ -2158,11 +2159,11 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
        }
 
        ulen = info.nr_jited_ksyms;
-       info.nr_jited_ksyms = prog->aux->func_cnt;
+       info.nr_jited_ksyms = prog->aux->func_cnt ? : 1;
        if (info.nr_jited_ksyms && ulen) {
                if (bpf_dump_raw_ok()) {
+                       unsigned long ksym_addr;
                        u64 __user *user_ksyms;
-                       ulong ksym_addr;
                        u32 i;
 
                        /* copy the address of the kernel symbol
@@ -2170,10 +2171,17 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
                         */
                        ulen = min_t(u32, info.nr_jited_ksyms, ulen);
                        user_ksyms = u64_to_user_ptr(info.jited_ksyms);
-                       for (i = 0; i < ulen; i++) {
-                               ksym_addr = (ulong) prog->aux->func[i]->bpf_func;
-                               ksym_addr &= PAGE_MASK;
-                               if (put_user((u64) ksym_addr, &user_ksyms[i]))
+                       if (prog->aux->func_cnt) {
+                               for (i = 0; i < ulen; i++) {
+                                       ksym_addr = (unsigned long)
+                                               prog->aux->func[i]->bpf_func;
+                                       if (put_user((u64) ksym_addr,
+                                                    &user_ksyms[i]))
+                                               return -EFAULT;
+                               }
+                       } else {
+                               ksym_addr = (unsigned long) prog->bpf_func;
+                               if (put_user((u64) ksym_addr, &user_ksyms[0]))
                                        return -EFAULT;
                        }
                } else {
@@ -2182,7 +2190,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
        }
 
        ulen = info.nr_jited_func_lens;
-       info.nr_jited_func_lens = prog->aux->func_cnt;
+       info.nr_jited_func_lens = prog->aux->func_cnt ? : 1;
        if (info.nr_jited_func_lens && ulen) {
                if (bpf_dump_raw_ok()) {
                        u32 __user *user_lens;
@@ -2191,9 +2199,16 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
                        /* copy the JITed image lengths for each function */
                        ulen = min_t(u32, info.nr_jited_func_lens, ulen);
                        user_lens = u64_to_user_ptr(info.jited_func_lens);
-                       for (i = 0; i < ulen; i++) {
-                               func_len = prog->aux->func[i]->jited_len;
-                               if (put_user(func_len, &user_lens[i]))
+                       if (prog->aux->func_cnt) {
+                               for (i = 0; i < ulen; i++) {
+                                       func_len =
+                                               prog->aux->func[i]->jited_len;
+                                       if (put_user(func_len, &user_lens[i]))
+                                               return -EFAULT;
+                               }
+                       } else {
+                               func_len = prog->jited_len;
+                               if (put_user(func_len, &user_lens[0]))
                                        return -EFAULT;
                        }
                } else {
index 6ad4a9fcbd6f7012ca577070455bec9a1cd03e57..7921ae4fca8de92513fb5b71cbc36fd96ed0e04f 100644 (file)
@@ -179,14 +179,14 @@ kdb_bt(int argc, const char **argv)
                                kdb_printf("no process for cpu %ld\n", cpu);
                                return 0;
                        }
-                       sprintf(buf, "btt 0x%p\n", KDB_TSK(cpu));
+                       sprintf(buf, "btt 0x%px\n", KDB_TSK(cpu));
                        kdb_parse(buf);
                        return 0;
                }
                kdb_printf("btc: cpu status: ");
                kdb_parse("cpu\n");
                for_each_online_cpu(cpu) {
-                       sprintf(buf, "btt 0x%p\n", KDB_TSK(cpu));
+                       sprintf(buf, "btt 0x%px\n", KDB_TSK(cpu));
                        kdb_parse(buf);
                        touch_nmi_watchdog();
                }
index ed5d34925ad0617a40aeed3774b0e393aec03e99..6a4b41484afe654572f3b4f37186046c4541c8e5 100644 (file)
@@ -216,7 +216,7 @@ static char *kdb_read(char *buffer, size_t bufsize)
        int count;
        int i;
        int diag, dtab_count;
-       int key;
+       int key, buf_size, ret;
 
 
        diag = kdbgetintenv("DTABCOUNT", &dtab_count);
@@ -336,9 +336,8 @@ poll_again:
                else
                        p_tmp = tmpbuffer;
                len = strlen(p_tmp);
-               count = kallsyms_symbol_complete(p_tmp,
-                                                sizeof(tmpbuffer) -
-                                                (p_tmp - tmpbuffer));
+               buf_size = sizeof(tmpbuffer) - (p_tmp - tmpbuffer);
+               count = kallsyms_symbol_complete(p_tmp, buf_size);
                if (tab == 2 && count > 0) {
                        kdb_printf("\n%d symbols are found.", count);
                        if (count > dtab_count) {
@@ -350,9 +349,13 @@ poll_again:
                        }
                        kdb_printf("\n");
                        for (i = 0; i < count; i++) {
-                               if (WARN_ON(!kallsyms_symbol_next(p_tmp, i)))
+                               ret = kallsyms_symbol_next(p_tmp, i, buf_size);
+                               if (WARN_ON(!ret))
                                        break;
-                               kdb_printf("%s ", p_tmp);
+                               if (ret != -E2BIG)
+                                       kdb_printf("%s ", p_tmp);
+                               else
+                                       kdb_printf("%s... ", p_tmp);
                                *(p_tmp + len) = '\0';
                        }
                        if (i >= dtab_count)
index 118527aa60eae183f6d3b882ff2102a0c9a6012a..750497b0003a6decd80a97051aec97347079fd93 100644 (file)
@@ -173,11 +173,11 @@ int kdb_get_kbd_char(void)
        case KT_LATIN:
                if (isprint(keychar))
                        break;          /* printable characters */
-               /* drop through */
+               /* fall through */
        case KT_SPEC:
                if (keychar == K_ENTER)
                        break;
-               /* drop through */
+               /* fall through */
        default:
                return -1;      /* ignore unprintables */
        }
index bb4fe4e1a601b5252197f20babd6da394aaa0bc9..d72b32c66f7dd3ba3f5cf254b4d8a66da21d259d 100644 (file)
@@ -1192,7 +1192,7 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
        if (reason == KDB_REASON_DEBUG) {
                /* special case below */
        } else {
-               kdb_printf("\nEntering kdb (current=0x%p, pid %d) ",
+               kdb_printf("\nEntering kdb (current=0x%px, pid %d) ",
                           kdb_current, kdb_current ? kdb_current->pid : 0);
 #if defined(CONFIG_SMP)
                kdb_printf("on processor %d ", raw_smp_processor_id());
@@ -1208,7 +1208,7 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
                 */
                switch (db_result) {
                case KDB_DB_BPT:
-                       kdb_printf("\nEntering kdb (0x%p, pid %d) ",
+                       kdb_printf("\nEntering kdb (0x%px, pid %d) ",
                                   kdb_current, kdb_current->pid);
 #if defined(CONFIG_SMP)
                        kdb_printf("on processor %d ", raw_smp_processor_id());
@@ -1493,6 +1493,7 @@ static void kdb_md_line(const char *fmtstr, unsigned long addr,
        char cbuf[32];
        char *c = cbuf;
        int i;
+       int j;
        unsigned long word;
 
        memset(cbuf, '\0', sizeof(cbuf));
@@ -1538,25 +1539,9 @@ static void kdb_md_line(const char *fmtstr, unsigned long addr,
                        wc.word = word;
 #define printable_char(c) \
        ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.'; })
-                       switch (bytesperword) {
-                       case 8:
+                       for (j = 0; j < bytesperword; j++)
                                *c++ = printable_char(*cp++);
-                               *c++ = printable_char(*cp++);
-                               *c++ = printable_char(*cp++);
-                               *c++ = printable_char(*cp++);
-                               addr += 4;
-                       case 4:
-                               *c++ = printable_char(*cp++);
-                               *c++ = printable_char(*cp++);
-                               addr += 2;
-                       case 2:
-                               *c++ = printable_char(*cp++);
-                               addr++;
-                       case 1:
-                               *c++ = printable_char(*cp++);
-                               addr++;
-                               break;
-                       }
+                       addr += bytesperword;
 #undef printable_char
                }
        }
@@ -2048,7 +2033,7 @@ static int kdb_lsmod(int argc, const char **argv)
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
 
-               kdb_printf("%-20s%8u  0x%p ", mod->name,
+               kdb_printf("%-20s%8u  0x%px ", mod->name,
                           mod->core_layout.size, (void *)mod);
 #ifdef CONFIG_MODULE_UNLOAD
                kdb_printf("%4d ", module_refcount(mod));
@@ -2059,7 +2044,7 @@ static int kdb_lsmod(int argc, const char **argv)
                        kdb_printf(" (Loading)");
                else
                        kdb_printf(" (Live)");
-               kdb_printf(" 0x%p", mod->core_layout.base);
+               kdb_printf(" 0x%px", mod->core_layout.base);
 
 #ifdef CONFIG_MODULE_UNLOAD
                {
@@ -2341,7 +2326,7 @@ void kdb_ps1(const struct task_struct *p)
                return;
 
        cpu = kdb_process_cpu(p);
-       kdb_printf("0x%p %8d %8d  %d %4d   %c  0x%p %c%s\n",
+       kdb_printf("0x%px %8d %8d  %d %4d   %c  0x%px %c%s\n",
                   (void *)p, p->pid, p->parent->pid,
                   kdb_task_has_cpu(p), kdb_process_cpu(p),
                   kdb_task_state_char(p),
@@ -2354,7 +2339,7 @@ void kdb_ps1(const struct task_struct *p)
                } else {
                        if (KDB_TSK(cpu) != p)
                                kdb_printf("  Error: does not match running "
-                                  "process table (0x%p)\n", KDB_TSK(cpu));
+                                  "process table (0x%px)\n", KDB_TSK(cpu));
                }
        }
 }
@@ -2687,7 +2672,7 @@ int kdb_register_flags(char *cmd,
        for_each_kdbcmd(kp, i) {
                if (kp->cmd_name && (strcmp(kp->cmd_name, cmd) == 0)) {
                        kdb_printf("Duplicate kdb command registered: "
-                               "%s, func %p help %s\n", cmd, func, help);
+                               "%s, func %px help %s\n", cmd, func, help);
                        return 1;
                }
        }
index 1e5a502ba4a7b44787a097540cc21787cce41f5d..2118d8258b7c9a3d66b917f10575f7b109b5d665 100644 (file)
@@ -83,7 +83,7 @@ typedef struct __ksymtab {
                unsigned long sym_start;
                unsigned long sym_end;
                } kdb_symtab_t;
-extern int kallsyms_symbol_next(char *prefix_name, int flag);
+extern int kallsyms_symbol_next(char *prefix_name, int flag, int buf_size);
 extern int kallsyms_symbol_complete(char *prefix_name, int max_len);
 
 /* Exported Symbols for kernel loadable modules to use. */
index 990b3cc526c80d2162d79f0524dbd83932418cdf..50bf9b119bad04952c767451a4e29315b0234ab0 100644 (file)
@@ -40,7 +40,7 @@
 int kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
 {
        if (KDB_DEBUG(AR))
-               kdb_printf("kdbgetsymval: symname=%s, symtab=%p\n", symname,
+               kdb_printf("kdbgetsymval: symname=%s, symtab=%px\n", symname,
                           symtab);
        memset(symtab, 0, sizeof(*symtab));
        symtab->sym_start = kallsyms_lookup_name(symname);
@@ -88,7 +88,7 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
        char *knt1 = NULL;
 
        if (KDB_DEBUG(AR))
-               kdb_printf("kdbnearsym: addr=0x%lx, symtab=%p\n", addr, symtab);
+               kdb_printf("kdbnearsym: addr=0x%lx, symtab=%px\n", addr, symtab);
        memset(symtab, 0, sizeof(*symtab));
 
        if (addr < 4096)
@@ -149,7 +149,7 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
                symtab->mod_name = "kernel";
        if (KDB_DEBUG(AR))
                kdb_printf("kdbnearsym: returns %d symtab->sym_start=0x%lx, "
-                  "symtab->mod_name=%p, symtab->sym_name=%p (%s)\n", ret,
+                  "symtab->mod_name=%px, symtab->sym_name=%px (%s)\n", ret,
                   symtab->sym_start, symtab->mod_name, symtab->sym_name,
                   symtab->sym_name);
 
@@ -221,11 +221,13 @@ int kallsyms_symbol_complete(char *prefix_name, int max_len)
  * Parameters:
  *     prefix_name     prefix of a symbol name to lookup
  *     flag    0 means search from the head, 1 means continue search.
+ *     buf_size        maximum length that can be written to prefix_name
+ *                     buffer
  * Returns:
  *     1 if a symbol matches the given prefix.
  *     0 if no string found
  */
-int kallsyms_symbol_next(char *prefix_name, int flag)
+int kallsyms_symbol_next(char *prefix_name, int flag, int buf_size)
 {
        int prefix_len = strlen(prefix_name);
        static loff_t pos;
@@ -235,10 +237,8 @@ int kallsyms_symbol_next(char *prefix_name, int flag)
                pos = 0;
 
        while ((name = kdb_walk_kallsyms(&pos))) {
-               if (strncmp(name, prefix_name, prefix_len) == 0) {
-                       strncpy(prefix_name, name, strlen(name)+1);
-                       return 1;
-               }
+               if (!strncmp(name, prefix_name, prefix_len))
+                       return strscpy(prefix_name, name, buf_size);
        }
        return 0;
 }
@@ -432,7 +432,7 @@ int kdb_getphysword(unsigned long *word, unsigned long addr, size_t size)
                                *word = w8;
                        break;
                }
-               /* drop through */
+               /* fall through */
        default:
                diag = KDB_BADWIDTH;
                kdb_printf("kdb_getphysword: bad width %ld\n", (long) size);
@@ -481,7 +481,7 @@ int kdb_getword(unsigned long *word, unsigned long addr, size_t size)
                                *word = w8;
                        break;
                }
-               /* drop through */
+               /* fall through */
        default:
                diag = KDB_BADWIDTH;
                kdb_printf("kdb_getword: bad width %ld\n", (long) size);
@@ -525,7 +525,7 @@ int kdb_putword(unsigned long addr, unsigned long word, size_t size)
                        diag = kdb_putarea(addr, w8);
                        break;
                }
-               /* drop through */
+               /* fall through */
        default:
                diag = KDB_BADWIDTH;
                kdb_printf("kdb_putword: bad width %ld\n", (long) size);
@@ -887,13 +887,13 @@ void debug_kusage(void)
                   __func__, dah_first);
        if (dah_first) {
                h_used = (struct debug_alloc_header *)debug_alloc_pool;
-               kdb_printf("%s: h_used %p size %d\n", __func__, h_used,
+               kdb_printf("%s: h_used %px size %d\n", __func__, h_used,
                           h_used->size);
        }
        do {
                h_used = (struct debug_alloc_header *)
                          ((char *)h_free + dah_overhead + h_free->size);
-               kdb_printf("%s: h_used %p size %d caller %p\n",
+               kdb_printf("%s: h_used %px size %d caller %px\n",
                           __func__, h_used, h_used->size, h_used->caller);
                h_free = (struct debug_alloc_header *)
                          (debug_alloc_pool + h_free->next);
@@ -902,7 +902,7 @@ void debug_kusage(void)
                  ((char *)h_free + dah_overhead + h_free->size);
        if ((char *)h_used - debug_alloc_pool !=
            sizeof(debug_alloc_pool_aligned))
-               kdb_printf("%s: h_used %p size %d caller %p\n",
+               kdb_printf("%s: h_used %px size %d caller %px\n",
                           __func__, h_used, h_used->size, h_used->caller);
 out:
        spin_unlock(&dap_lock);
index b3a3a1fc499eaf386b3b3e1c51f2100b7226ff37..b0fbf685c77a52ba45dc4c3e2044782080a74953 100644 (file)
@@ -319,16 +319,23 @@ int release_resource(struct resource *old)
 EXPORT_SYMBOL(release_resource);
 
 /**
- * Finds the lowest iomem resource that covers part of [start..end].  The
- * caller must specify start, end, flags, and desc (which may be
+ * Finds the lowest iomem resource that covers part of [@start..@end].  The
+ * caller must specify @start, @end, @flags, and @desc (which may be
  * IORES_DESC_NONE).
  *
- * If a resource is found, returns 0 and *res is overwritten with the part
- * of the resource that's within [start..end]; if none is found, returns
- * -1.
+ * If a resource is found, returns 0 and @*res is overwritten with the part
+ * of the resource that's within [@start..@end]; if none is found, returns
+ * -1 or -EINVAL for other invalid parameters.
  *
  * This function walks the whole tree and not just first level children
  * unless @first_lvl is true.
+ *
+ * @start:     start address of the resource searched for
+ * @end:       end address of same resource
+ * @flags:     flags which the resource must have
+ * @desc:      descriptor the resource must have
+ * @first_lvl: walk only the first level children, if set
+ * @res:       return ptr, if resource found
  */
 static int find_next_iomem_res(resource_size_t start, resource_size_t end,
                               unsigned long flags, unsigned long desc,
@@ -399,6 +406,8 @@ static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
  * @flags: I/O resource flags
  * @start: start addr
  * @end: end addr
+ * @arg: function argument for the callback @func
+ * @func: callback function that is called for each qualifying resource area
  *
  * NOTE: For a new descriptor search, define a new IORES_DESC in
  * <linux/ioport.h> and set it in 'desc' of a target resource entry.
index f12225f26b70a630ac185cfccba2b140f191c47e..091e089063be1dc25ab1180fec3f99a4408fb024 100644 (file)
@@ -5851,11 +5851,14 @@ void __init sched_init_smp(void)
        /*
         * There's no userspace yet to cause hotplug operations; hence all the
         * CPU masks are stable and all blatant races in the below code cannot
-        * happen.
+        * happen. The hotplug lock is nevertheless taken to satisfy lockdep,
+        * but there won't be any contention on it.
         */
+       cpus_read_lock();
        mutex_lock(&sched_domains_mutex);
        sched_init_domains(cpu_active_mask);
        mutex_unlock(&sched_domains_mutex);
+       cpus_read_unlock();
 
        /* Move init over to a non-isolated CPU */
        if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0)
index ee271bb661cc923dfa67ae5d5c45a18c71df7cb1..ac855b2f47746efa80ed91081442626d15169568 100644 (file)
@@ -2400,8 +2400,8 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags)
                local = 1;
 
        /*
-        * Retry task to preferred node migration periodically, in case it
-        * case it previously failed, or the scheduler moved us.
+        * Retry to migrate task to preferred node periodically, in case it
+        * previously failed, or the scheduler moved us.
         */
        if (time_after(jiffies, p->numa_migrate_retry)) {
                task_numa_placement(p);
@@ -5674,11 +5674,11 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p,
        return target;
 }
 
-static unsigned long cpu_util_wake(int cpu, struct task_struct *p);
+static unsigned long cpu_util_without(int cpu, struct task_struct *p);
 
-static unsigned long capacity_spare_wake(int cpu, struct task_struct *p)
+static unsigned long capacity_spare_without(int cpu, struct task_struct *p)
 {
-       return max_t(long, capacity_of(cpu) - cpu_util_wake(cpu, p), 0);
+       return max_t(long, capacity_of(cpu) - cpu_util_without(cpu, p), 0);
 }
 
 /*
@@ -5738,7 +5738,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p,
 
                        avg_load += cfs_rq_load_avg(&cpu_rq(i)->cfs);
 
-                       spare_cap = capacity_spare_wake(i, p);
+                       spare_cap = capacity_spare_without(i, p);
 
                        if (spare_cap > max_spare_cap)
                                max_spare_cap = spare_cap;
@@ -5889,8 +5889,8 @@ static inline int find_idlest_cpu(struct sched_domain *sd, struct task_struct *p
                return prev_cpu;
 
        /*
-        * We need task's util for capacity_spare_wake, sync it up to prev_cpu's
-        * last_update_time.
+        * We need task's util for capacity_spare_without, sync it up to
+        * prev_cpu's last_update_time.
         */
        if (!(sd_flag & SD_BALANCE_FORK))
                sync_entity_load_avg(&p->se);
@@ -6216,10 +6216,19 @@ static inline unsigned long cpu_util(int cpu)
 }
 
 /*
- * cpu_util_wake: Compute CPU utilization with any contributions from
- * the waking task p removed.
+ * cpu_util_without: compute cpu utilization without any contributions from *p
+ * @cpu: the CPU which utilization is requested
+ * @p: the task which utilization should be discounted
+ *
+ * The utilization of a CPU is defined by the utilization of tasks currently
+ * enqueued on that CPU as well as tasks which are currently sleeping after an
+ * execution on that CPU.
+ *
+ * This method returns the utilization of the specified CPU by discounting the
+ * utilization of the specified task, whenever the task is currently
+ * contributing to the CPU utilization.
  */
-static unsigned long cpu_util_wake(int cpu, struct task_struct *p)
+static unsigned long cpu_util_without(int cpu, struct task_struct *p)
 {
        struct cfs_rq *cfs_rq;
        unsigned int util;
@@ -6231,7 +6240,7 @@ static unsigned long cpu_util_wake(int cpu, struct task_struct *p)
        cfs_rq = &cpu_rq(cpu)->cfs;
        util = READ_ONCE(cfs_rq->avg.util_avg);
 
-       /* Discount task's blocked util from CPU's util */
+       /* Discount task's util from CPU's util */
        util -= min_t(unsigned int, util, task_util(p));
 
        /*
@@ -6240,14 +6249,14 @@ static unsigned long cpu_util_wake(int cpu, struct task_struct *p)
         * a) if *p is the only task sleeping on this CPU, then:
         *      cpu_util (== task_util) > util_est (== 0)
         *    and thus we return:
-        *      cpu_util_wake = (cpu_util - task_util) = 0
+        *      cpu_util_without = (cpu_util - task_util) = 0
         *
         * b) if other tasks are SLEEPING on this CPU, which is now exiting
         *    IDLE, then:
         *      cpu_util >= task_util
         *      cpu_util > util_est (== 0)
         *    and thus we discount *p's blocked utilization to return:
-        *      cpu_util_wake = (cpu_util - task_util) >= 0
+        *      cpu_util_without = (cpu_util - task_util) >= 0
         *
         * c) if other tasks are RUNNABLE on that CPU and
         *      util_est > cpu_util
@@ -6260,8 +6269,33 @@ static unsigned long cpu_util_wake(int cpu, struct task_struct *p)
         * covered by the following code when estimated utilization is
         * enabled.
         */
-       if (sched_feat(UTIL_EST))
-               util = max(util, READ_ONCE(cfs_rq->avg.util_est.enqueued));
+       if (sched_feat(UTIL_EST)) {
+               unsigned int estimated =
+                       READ_ONCE(cfs_rq->avg.util_est.enqueued);
+
+               /*
+                * Despite the following checks we still have a small window
+                * for a possible race, when an execl's select_task_rq_fair()
+                * races with LB's detach_task():
+                *
+                *   detach_task()
+                *     p->on_rq = TASK_ON_RQ_MIGRATING;
+                *     ---------------------------------- A
+                *     deactivate_task()                   \
+                *       dequeue_task()                     + RaceTime
+                *         util_est_dequeue()              /
+                *     ---------------------------------- B
+                *
+                * The additional check on "current == p" it's required to
+                * properly fix the execl regression and it helps in further
+                * reducing the chances for the above race.
+                */
+               if (unlikely(task_on_rq_queued(p) || current == p)) {
+                       estimated -= min_t(unsigned int, estimated,
+                                          (_task_util_est(p) | UTIL_AVG_UNCHANGED));
+               }
+               util = max(util, estimated);
+       }
 
        /*
         * Utilization (estimated) can exceed the CPU capacity, thus let's
index 7cdecfc010af83f1f5d8679536433f288aa847d7..3d7355d7c3e3852a085a2d68de6e7bbc705c5071 100644 (file)
@@ -633,38 +633,39 @@ void psi_cgroup_free(struct cgroup *cgroup)
  */
 void cgroup_move_task(struct task_struct *task, struct css_set *to)
 {
-       bool move_psi = !psi_disabled;
        unsigned int task_flags = 0;
        struct rq_flags rf;
        struct rq *rq;
 
-       if (move_psi) {
-               rq = task_rq_lock(task, &rf);
+       if (psi_disabled) {
+               /*
+                * Lame to do this here, but the scheduler cannot be locked
+                * from the outside, so we move cgroups from inside sched/.
+                */
+               rcu_assign_pointer(task->cgroups, to);
+               return;
+       }
 
-               if (task_on_rq_queued(task))
-                       task_flags = TSK_RUNNING;
-               else if (task->in_iowait)
-                       task_flags = TSK_IOWAIT;
+       rq = task_rq_lock(task, &rf);
 
-               if (task->flags & PF_MEMSTALL)
-                       task_flags |= TSK_MEMSTALL;
+       if (task_on_rq_queued(task))
+               task_flags = TSK_RUNNING;
+       else if (task->in_iowait)
+               task_flags = TSK_IOWAIT;
 
-               if (task_flags)
-                       psi_task_change(task, task_flags, 0);
-       }
+       if (task->flags & PF_MEMSTALL)
+               task_flags |= TSK_MEMSTALL;
 
-       /*
-        * Lame to do this here, but the scheduler cannot be locked
-        * from the outside, so we move cgroups from inside sched/.
-        */
+       if (task_flags)
+               psi_task_change(task, task_flags, 0);
+
+       /* See comment above */
        rcu_assign_pointer(task->cgroups, to);
 
-       if (move_psi) {
-               if (task_flags)
-                       psi_task_change(task, 0, task_flags);
+       if (task_flags)
+               psi_task_change(task, 0, task_flags);
 
-               task_rq_unlock(rq, task, &rf);
-       }
+       task_rq_unlock(rq, task, &rf);
 }
 #endif /* CONFIG_CGROUPS */
 
index ce32cf741b250939de562ab05bd598fb30f10986..8f0644af40be7e5869f8f664775183bdb07a0f56 100644 (file)
@@ -917,9 +917,6 @@ static void check_process_timers(struct task_struct *tsk,
        struct task_cputime cputime;
        unsigned long soft;
 
-       if (dl_task(tsk))
-               check_dl_overrun(tsk);
-
        /*
         * If cputimer is not running, then there are no active
         * process wide timers (POSIX 1.b, itimers, RLIMIT_CPU).
index 3ef15a6683c002bc2c5402b5be8ad07c903021bc..bd30e9398d2a8b2afbc49839c969efd277ae2728 100644 (file)
@@ -535,7 +535,7 @@ int traceprobe_update_arg(struct probe_arg *arg)
                        if (code[1].op != FETCH_OP_IMM)
                                return -EINVAL;
 
-                       tmp = strpbrk("+-", code->data);
+                       tmp = strpbrk(code->data, "+-");
                        if (tmp)
                                c = *tmp;
                        ret = traceprobe_split_symbol_offset(code->data,
index e5222b5fb4fe6c3868c78ee3602518ce835c85e3..923414a246e9e4eb4bd422e8146133cad50db45f 100644 (file)
@@ -974,10 +974,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (!new_idmap_permitted(file, ns, cap_setid, &new_map))
                goto out;
 
-       ret = sort_idmaps(&new_map);
-       if (ret < 0)
-               goto out;
-
        ret = -EPERM;
        /* Map the lower ids from the parent user namespace to the
         * kernel global id space.
@@ -1004,6 +1000,14 @@ static ssize_t map_write(struct file *file, const char __user *buf,
                e->lower_first = lower_first;
        }
 
+       /*
+        * If we want to use binary search for lookup, this clones the extent
+        * array and sorts both copies.
+        */
+       ret = sort_idmaps(&new_map);
+       if (ret < 0)
+               goto out;
+
        /* Install the map */
        if (new_map.nr_extents <= UID_GID_MAP_MAX_BASE_EXTENTS) {
                memcpy(map->extent, new_map.extent,
index 5d73f5cb4d8a78f0887cc6cfbf10a29ec5d5f51c..79777645cac9c1243518f4f4bf403cdc567aa9ea 100644 (file)
@@ -27,7 +27,7 @@ ifeq ($(ARCH),arm)
         CFLAGS += -I../../../arch/arm/include -mfpu=neon
         HAS_NEON = yes
 endif
-ifeq ($(ARCH),arm64)
+ifeq ($(ARCH),aarch64)
         CFLAGS += -I../../../arch/arm64/include
         HAS_NEON = yes
 endif
@@ -41,7 +41,7 @@ ifeq ($(IS_X86),yes)
                    gcc -c -x assembler - >&/dev/null &&        \
                    rm ./-.o && echo -DCONFIG_AS_AVX512=1)
 else ifeq ($(HAS_NEON),yes)
-        OBJS   += neon.o neon1.o neon2.o neon4.o neon8.o
+        OBJS   += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o
         CFLAGS += -DCONFIG_KERNEL_MODE_NEON=1
 else
         HAS_ALTIVEC := $(shell printf '\#include <altivec.h>\nvector int a;\n' |\
index 59fee96c29a0f1fb83fe67282482bc5d941bd6f3..e4162f59a81ccacda275cd218193fb2ad34d71d3 100644 (file)
@@ -427,8 +427,7 @@ void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
 EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
 
 
-void __noreturn
-__ubsan_handle_builtin_unreachable(struct unreachable_data *data)
+void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
 {
        unsigned long flags;
 
index f76e77a2d34b79afec5f3032366a6bd954d1aead..aa43620a3270ec08040f75e587d4cbe7617754ff 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -385,11 +385,17 @@ static struct page *follow_p4d_mask(struct vm_area_struct *vma,
  * @vma: vm_area_struct mapping @address
  * @address: virtual address to look up
  * @flags: flags modifying lookup behaviour
- * @page_mask: on output, *page_mask is set according to the size of the page
+ * @ctx: contains dev_pagemap for %ZONE_DEVICE memory pinning and a
+ *       pointer to output page_mask
  *
  * @flags can have FOLL_ flags set, defined in <linux/mm.h>
  *
- * Returns the mapped (struct page *), %NULL if no mapping exists, or
+ * When getting pages from ZONE_DEVICE memory, the @ctx->pgmap caches
+ * the device's dev_pagemap metadata to avoid repeating expensive lookups.
+ *
+ * On output, the @ctx->page_mask is set according to the size of the page.
+ *
+ * Return: the mapped (struct page *), %NULL if no mapping exists, or
  * an error pointer if there is a mapping to something not represented
  * by a page descriptor (see also vm_normal_page()).
  */
index c007fb5fb8d5f6547dc916e5ab468753028a862b..7f2a28ab46d537ff4ed5034cce0ea46b95991477 100644 (file)
@@ -3233,7 +3233,7 @@ static int is_hugetlb_entry_hwpoisoned(pte_t pte)
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
                            struct vm_area_struct *vma)
 {
-       pte_t *src_pte, *dst_pte, entry;
+       pte_t *src_pte, *dst_pte, entry, dst_entry;
        struct page *ptepage;
        unsigned long addr;
        int cow;
@@ -3261,15 +3261,30 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
                        break;
                }
 
-               /* If the pagetables are shared don't copy or take references */
-               if (dst_pte == src_pte)
+               /*
+                * If the pagetables are shared don't copy or take references.
+                * dst_pte == src_pte is the common case of src/dest sharing.
+                *
+                * However, src could have 'unshared' and dst shares with
+                * another vma.  If dst_pte !none, this implies sharing.
+                * Check here before taking page table lock, and once again
+                * after taking the lock below.
+                */
+               dst_entry = huge_ptep_get(dst_pte);
+               if ((dst_pte == src_pte) || !huge_pte_none(dst_entry))
                        continue;
 
                dst_ptl = huge_pte_lock(h, dst, dst_pte);
                src_ptl = huge_pte_lockptr(h, src, src_pte);
                spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
                entry = huge_ptep_get(src_pte);
-               if (huge_pte_none(entry)) { /* skip none entry */
+               dst_entry = huge_ptep_get(dst_pte);
+               if (huge_pte_none(entry) || !huge_pte_none(dst_entry)) {
+                       /*
+                        * Skip if src entry none.  Also, skip in the
+                        * unlikely case dst entry !none as this implies
+                        * sharing with another vma.
+                        */
                        ;
                } else if (unlikely(is_hugetlb_entry_migration(entry) ||
                                    is_hugetlb_entry_hwpoisoned(entry))) {
index 7df468c8ebc8c0ada5b560ed70c9c821e5127c05..9a2d5ae81ae1cf4217ed3174d72667be276769da 100644 (file)
@@ -1179,7 +1179,7 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid,
 
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 /*
- * Common iterator interface used to define for_each_mem_range().
+ * Common iterator interface used to define for_each_mem_pfn_range().
  */
 void __init_memblock __next_mem_pfn_range(int *idx, int nid,
                                unsigned long *out_start_pfn,
index a919ba5cb3c845e03e4a070eff354acf19ec7c4a..6847177dc4a1a89ce098c6ab6f4b19e46dab2428 100644 (file)
@@ -4060,17 +4060,6 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
        unsigned int cpuset_mems_cookie;
        int reserve_flags;
 
-       /*
-        * In the slowpath, we sanity check order to avoid ever trying to
-        * reclaim >= MAX_ORDER areas which will never succeed. Callers may
-        * be using allocators in order of preference for an area that is
-        * too large.
-        */
-       if (order >= MAX_ORDER) {
-               WARN_ON_ONCE(!(gfp_mask & __GFP_NOWARN));
-               return NULL;
-       }
-
        /*
         * We also sanity check to catch abuse of atomic reserves being used by
         * callers that are not in atomic context.
@@ -4364,6 +4353,15 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
        gfp_t alloc_mask; /* The gfp_t that was actually used for allocation */
        struct alloc_context ac = { };
 
+       /*
+        * There are several places where we assume that the order value is sane
+        * so bail out early if the request is out of bound.
+        */
+       if (unlikely(order >= MAX_ORDER)) {
+               WARN_ON_ONCE(!(gfp_mask & __GFP_NOWARN));
+               return NULL;
+       }
+
        gfp_mask &= gfp_allowed_mask;
        alloc_mask = gfp_mask;
        if (!prepare_alloc_pages(gfp_mask, order, preferred_nid, nodemask, &ac, &alloc_mask, &alloc_flags))
@@ -7788,6 +7786,14 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                if (PageReserved(page))
                        goto unmovable;
 
+               /*
+                * If the zone is movable and we have ruled out all reserved
+                * pages then it should be reasonably safe to assume the rest
+                * is movable.
+                */
+               if (zone_idx(zone) == ZONE_MOVABLE)
+                       continue;
+
                /*
                 * Hugepages are not in LRU lists, but they're movable.
                 * We need not scan over tail pages bacause we don't
index ea26d7a0342d77ac67f47e813a73f125c873a1e5..d44991ea5ed4b7612482525ebaa502457cbf1ead 100644 (file)
@@ -2563,9 +2563,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
        inode_lock(inode);
        /* We're holding i_mutex so we can access i_size directly */
 
-       if (offset < 0)
-               offset = -EINVAL;
-       else if (offset >= inode->i_size)
+       if (offset < 0 || offset >= inode->i_size)
                offset = -ENXIO;
        else {
                start = offset >> PAGE_SHIFT;
index 644f746e167acd65e8244088f483e50c71afbf20..8688ae65ef58ac639b0b2202039fa22577309350 100644 (file)
@@ -2813,7 +2813,7 @@ static struct swap_info_struct *alloc_swap_info(void)
        unsigned int type;
        int i;
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kvzalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
                return ERR_PTR(-ENOMEM);
 
@@ -2824,7 +2824,7 @@ static struct swap_info_struct *alloc_swap_info(void)
        }
        if (type >= MAX_SWAPFILES) {
                spin_unlock(&swap_lock);
-               kfree(p);
+               kvfree(p);
                return ERR_PTR(-EPERM);
        }
        if (type >= nr_swapfiles) {
@@ -2838,7 +2838,7 @@ static struct swap_info_struct *alloc_swap_info(void)
                smp_wmb();
                nr_swapfiles++;
        } else {
-               kfree(p);
+               kvfree(p);
                p = swap_info[type];
                /*
                 * Do not memset this entry: a racing procfs swap_next()
index 6038ce593ce3e1ca4cce34a02bc0bbd4c1d3a296..9c624595e90416bc9114fc11721e14d56183a1b6 100644 (file)
@@ -1827,12 +1827,13 @@ static bool need_update(int cpu)
 
                /*
                 * The fast way of checking if there are any vmstat diffs.
-                * This works because the diffs are byte sized items.
                 */
-               if (memchr_inv(p->vm_stat_diff, 0, NR_VM_ZONE_STAT_ITEMS))
+               if (memchr_inv(p->vm_stat_diff, 0, NR_VM_ZONE_STAT_ITEMS *
+                              sizeof(p->vm_stat_diff[0])))
                        return true;
 #ifdef CONFIG_NUMA
-               if (memchr_inv(p->vm_numa_stat_diff, 0, NR_VM_NUMA_STAT_ITEMS))
+               if (memchr_inv(p->vm_numa_stat_diff, 0, NR_VM_NUMA_STAT_ITEMS *
+                              sizeof(p->vm_numa_stat_diff[0])))
                        return true;
 #endif
        }
index 4b366d181f35d12f9a1e600bb7083bbf4dfe7fff..aee9b0b8d9078a0bbf59a06509c6f7f7aa1360f3 100644 (file)
@@ -99,6 +99,7 @@ struct z3fold_header {
 #define NCHUNKS                ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT)
 
 #define BUDDY_MASK     (0x3)
+#define BUDDY_SHIFT    2
 
 /**
  * struct z3fold_pool - stores metadata for each z3fold pool
@@ -145,7 +146,7 @@ enum z3fold_page_flags {
        MIDDLE_CHUNK_MAPPED,
        NEEDS_COMPACTING,
        PAGE_STALE,
-       UNDER_RECLAIM
+       PAGE_CLAIMED, /* by either reclaim or free */
 };
 
 /*****************
@@ -174,7 +175,7 @@ static struct z3fold_header *init_z3fold_page(struct page *page,
        clear_bit(MIDDLE_CHUNK_MAPPED, &page->private);
        clear_bit(NEEDS_COMPACTING, &page->private);
        clear_bit(PAGE_STALE, &page->private);
-       clear_bit(UNDER_RECLAIM, &page->private);
+       clear_bit(PAGE_CLAIMED, &page->private);
 
        spin_lock_init(&zhdr->page_lock);
        kref_init(&zhdr->refcount);
@@ -223,8 +224,11 @@ static unsigned long encode_handle(struct z3fold_header *zhdr, enum buddy bud)
        unsigned long handle;
 
        handle = (unsigned long)zhdr;
-       if (bud != HEADLESS)
-               handle += (bud + zhdr->first_num) & BUDDY_MASK;
+       if (bud != HEADLESS) {
+               handle |= (bud + zhdr->first_num) & BUDDY_MASK;
+               if (bud == LAST)
+                       handle |= (zhdr->last_chunks << BUDDY_SHIFT);
+       }
        return handle;
 }
 
@@ -234,6 +238,12 @@ static struct z3fold_header *handle_to_z3fold_header(unsigned long handle)
        return (struct z3fold_header *)(handle & PAGE_MASK);
 }
 
+/* only for LAST bud, returns zero otherwise */
+static unsigned short handle_to_chunks(unsigned long handle)
+{
+       return (handle & ~PAGE_MASK) >> BUDDY_SHIFT;
+}
+
 /*
  * (handle & BUDDY_MASK) < zhdr->first_num is possible in encode_handle
  *  but that doesn't matter. because the masking will result in the
@@ -720,37 +730,39 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
        page = virt_to_page(zhdr);
 
        if (test_bit(PAGE_HEADLESS, &page->private)) {
-               /* HEADLESS page stored */
-               bud = HEADLESS;
-       } else {
-               z3fold_page_lock(zhdr);
-               bud = handle_to_buddy(handle);
-
-               switch (bud) {
-               case FIRST:
-                       zhdr->first_chunks = 0;
-                       break;
-               case MIDDLE:
-                       zhdr->middle_chunks = 0;
-                       zhdr->start_middle = 0;
-                       break;
-               case LAST:
-                       zhdr->last_chunks = 0;
-                       break;
-               default:
-                       pr_err("%s: unknown bud %d\n", __func__, bud);
-                       WARN_ON(1);
-                       z3fold_page_unlock(zhdr);
-                       return;
+               /* if a headless page is under reclaim, just leave.
+                * NB: we use test_and_set_bit for a reason: if the bit
+                * has not been set before, we release this page
+                * immediately so we don't care about its value any more.
+                */
+               if (!test_and_set_bit(PAGE_CLAIMED, &page->private)) {
+                       spin_lock(&pool->lock);
+                       list_del(&page->lru);
+                       spin_unlock(&pool->lock);
+                       free_z3fold_page(page);
+                       atomic64_dec(&pool->pages_nr);
                }
+               return;
        }
 
-       if (bud == HEADLESS) {
-               spin_lock(&pool->lock);
-               list_del(&page->lru);
-               spin_unlock(&pool->lock);
-               free_z3fold_page(page);
-               atomic64_dec(&pool->pages_nr);
+       /* Non-headless case */
+       z3fold_page_lock(zhdr);
+       bud = handle_to_buddy(handle);
+
+       switch (bud) {
+       case FIRST:
+               zhdr->first_chunks = 0;
+               break;
+       case MIDDLE:
+               zhdr->middle_chunks = 0;
+               break;
+       case LAST:
+               zhdr->last_chunks = 0;
+               break;
+       default:
+               pr_err("%s: unknown bud %d\n", __func__, bud);
+               WARN_ON(1);
+               z3fold_page_unlock(zhdr);
                return;
        }
 
@@ -758,7 +770,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
                atomic64_dec(&pool->pages_nr);
                return;
        }
-       if (test_bit(UNDER_RECLAIM, &page->private)) {
+       if (test_bit(PAGE_CLAIMED, &page->private)) {
                z3fold_page_unlock(zhdr);
                return;
        }
@@ -836,20 +848,30 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
                }
                list_for_each_prev(pos, &pool->lru) {
                        page = list_entry(pos, struct page, lru);
+
+                       /* this bit could have been set by free, in which case
+                        * we pass over to the next page in the pool.
+                        */
+                       if (test_and_set_bit(PAGE_CLAIMED, &page->private))
+                               continue;
+
+                       zhdr = page_address(page);
                        if (test_bit(PAGE_HEADLESS, &page->private))
-                               /* candidate found */
                                break;
 
-                       zhdr = page_address(page);
-                       if (!z3fold_page_trylock(zhdr))
+                       if (!z3fold_page_trylock(zhdr)) {
+                               zhdr = NULL;
                                continue; /* can't evict at this point */
+                       }
                        kref_get(&zhdr->refcount);
                        list_del_init(&zhdr->buddy);
                        zhdr->cpu = -1;
-                       set_bit(UNDER_RECLAIM, &page->private);
                        break;
                }
 
+               if (!zhdr)
+                       break;
+
                list_del_init(&page->lru);
                spin_unlock(&pool->lock);
 
@@ -898,6 +920,7 @@ next:
                if (test_bit(PAGE_HEADLESS, &page->private)) {
                        if (ret == 0) {
                                free_z3fold_page(page);
+                               atomic64_dec(&pool->pages_nr);
                                return 0;
                        }
                        spin_lock(&pool->lock);
@@ -905,7 +928,7 @@ next:
                        spin_unlock(&pool->lock);
                } else {
                        z3fold_page_lock(zhdr);
-                       clear_bit(UNDER_RECLAIM, &page->private);
+                       clear_bit(PAGE_CLAIMED, &page->private);
                        if (kref_put(&zhdr->refcount,
                                        release_z3fold_page_locked)) {
                                atomic64_dec(&pool->pages_nr);
@@ -964,7 +987,7 @@ static void *z3fold_map(struct z3fold_pool *pool, unsigned long handle)
                set_bit(MIDDLE_CHUNK_MAPPED, &page->private);
                break;
        case LAST:
-               addr += PAGE_SIZE - (zhdr->last_chunks << CHUNK_SHIFT);
+               addr += PAGE_SIZE - (handle_to_chunks(handle) << CHUNK_SHIFT);
                break;
        default:
                pr_err("unknown buddy id %d\n", buddy);
index 9f481cfdf77dace2fa594585fde5079d46474c66..e8090f099eb805626ffaa1445d3d0f8254f6c9a7 100644 (file)
@@ -352,19 +352,21 @@ out:
  */
 int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
 {
+       static const size_t tvlv_padding = sizeof(__be32);
        struct batadv_elp_packet *elp_packet;
        unsigned char *elp_buff;
        u32 random_seqno;
        size_t size;
        int res = -ENOMEM;
 
-       size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN;
+       size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding;
        hard_iface->bat_v.elp_skb = dev_alloc_skb(size);
        if (!hard_iface->bat_v.elp_skb)
                goto out;
 
        skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
-       elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
+       elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb,
+                               BATADV_ELP_HLEN + tvlv_padding);
        elp_packet = (struct batadv_elp_packet *)elp_buff;
 
        elp_packet->packet_type = BATADV_ELP;
index 0fddc17106bd8a0e3f064fee9adba7c226f34682..5b71a289d04fc80de6c20e7a24d621727c77825a 100644 (file)
@@ -275,7 +275,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
        kfree(entry);
 
        packet = (struct batadv_frag_packet *)skb_out->data;
-       size = ntohs(packet->total_size);
+       size = ntohs(packet->total_size) + hdr_size;
 
        /* Make room for the rest of the fragments. */
        if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
index 2920e06a540329ffb8f1286c65bc5acc6f53afad..04c19a37e500e872d564497c9410509c0df61fce 100644 (file)
@@ -102,12 +102,18 @@ struct br_tunnel_info {
        struct metadata_dst     *tunnel_dst;
 };
 
+/* private vlan flags */
+enum {
+       BR_VLFLAG_PER_PORT_STATS = BIT(0),
+};
+
 /**
  * struct net_bridge_vlan - per-vlan entry
  *
  * @vnode: rhashtable member
  * @vid: VLAN id
  * @flags: bridge vlan flags
+ * @priv_flags: private (in-kernel) bridge vlan flags
  * @stats: per-cpu VLAN statistics
  * @br: if MASTER flag set, this points to a bridge struct
  * @port: if MASTER flag unset, this points to a port struct
@@ -127,6 +133,7 @@ struct net_bridge_vlan {
        struct rhash_head               tnode;
        u16                             vid;
        u16                             flags;
+       u16                             priv_flags;
        struct br_vlan_stats __percpu   *stats;
        union {
                struct net_bridge       *br;
index 8c9297a019475fe68ee110a85cda1647deaf9075..e84be08b82854916d91bc0195ad2a9ab7dae8564 100644 (file)
@@ -197,7 +197,7 @@ static void nbp_vlan_rcu_free(struct rcu_head *rcu)
        v = container_of(rcu, struct net_bridge_vlan, rcu);
        WARN_ON(br_vlan_is_master(v));
        /* if we had per-port stats configured then free them here */
-       if (v->brvlan->stats != v->stats)
+       if (v->priv_flags & BR_VLFLAG_PER_PORT_STATS)
                free_percpu(v->stats);
        v->stats = NULL;
        kfree(v);
@@ -264,6 +264,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
                                err = -ENOMEM;
                                goto out_filt;
                        }
+                       v->priv_flags |= BR_VLFLAG_PER_PORT_STATS;
                } else {
                        v->stats = masterv->stats;
                }
index 1051eee8258184f33d15a6142ee8b387839c9adc..3aab7664933fdc67770cdbc8b80a231b41dc2555 100644 (file)
@@ -745,18 +745,19 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
        } else
                ifindex = ro->ifindex;
 
-       if (ro->fd_frames) {
+       dev = dev_get_by_index(sock_net(sk), ifindex);
+       if (!dev)
+               return -ENXIO;
+
+       err = -EINVAL;
+       if (ro->fd_frames && dev->mtu == CANFD_MTU) {
                if (unlikely(size != CANFD_MTU && size != CAN_MTU))
-                       return -EINVAL;
+                       goto put_dev;
        } else {
                if (unlikely(size != CAN_MTU))
-                       return -EINVAL;
+                       goto put_dev;
        }
 
-       dev = dev_get_by_index(sock_net(sk), ifindex);
-       if (!dev)
-               return -ENXIO;
-
        skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
                                  msg->msg_flags & MSG_DONTWAIT, &err);
        if (!skb)
index 77d43ae2a7bbe1267f8430d5c35637d1984f463c..066aa902d85c3e3f5ad83244b1506a446bebcb88 100644 (file)
@@ -3272,7 +3272,7 @@ struct sk_buff *dev_hard_start_xmit(struct sk_buff *first, struct net_device *de
                }
 
                skb = next;
-               if (netif_xmit_stopped(txq) && skb) {
+               if (netif_tx_queue_stopped(txq) && skb) {
                        rc = NETDEV_TX_BUSY;
                        break;
                }
@@ -5655,6 +5655,10 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
        skb->vlan_tci = 0;
        skb->dev = napi->dev;
        skb->skb_iif = 0;
+
+       /* eth_type_trans() assumes pkt_type is PACKET_HOST */
+       skb->pkt_type = PACKET_HOST;
+
        skb->encapsulation = 0;
        skb_shinfo(skb)->gso_type = 0;
        skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
index 676f3ad629f95625422aa55f0f54157001ac477c..588f475019d47c9d6bae8883acebab48aaf63b48 100644 (file)
@@ -1166,8 +1166,8 @@ ip_proto_again:
                break;
        }
 
-       if (dissector_uses_key(flow_dissector,
-                              FLOW_DISSECTOR_KEY_PORTS)) {
+       if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS) &&
+           !(key_control->flags & FLOW_DIS_IS_FRAGMENT)) {
                key_ports = skb_flow_dissector_target(flow_dissector,
                                                      FLOW_DISSECTOR_KEY_PORTS,
                                                      target_container);
index 5da9552b186bc853904f7c85bbf872925463896c..2b9fdbc43205f3d8cf826b2074493aa5e72401fb 100644 (file)
@@ -717,7 +717,8 @@ int netpoll_setup(struct netpoll *np)
 
                                read_lock_bh(&idev->lock);
                                list_for_each_entry(ifp, &idev->addr_list, if_list) {
-                                       if (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)
+                                       if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
+                                           !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
                                                continue;
                                        np->local_ip.in6 = ifp->addr;
                                        err = 0;
index e01274bd5e3e21addd346a887e24e2c709ef44c9..33d9227a8b8077a8cf6edbcaaa9f5b92d4fee48e 100644 (file)
@@ -3367,7 +3367,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
                        cb->seq = 0;
                }
                ret = dumpit(skb, cb);
-               if (ret < 0)
+               if (ret)
                        break;
        }
        cb->family = idx;
index 946de0e24c876bbbe63de71b5c7cef91cb967708..b4ee5c8b928f07879b3c7ed08ed5e9b67b08fcb4 100644 (file)
@@ -4944,6 +4944,8 @@ static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb)
  *
  * This is a helper to do that correctly considering GSO_BY_FRAGS.
  *
+ * @skb: GSO skb
+ *
  * @seg_len: The segmented length (from skb_gso_*_seglen). In the
  *           GSO_BY_FRAGS case this will be [header sizes + GSO_BY_FRAGS].
  *
index 6fcc4bc07d19bd929648f03b136225a69f2eddfc..080a880a1761b8e0efafaddf0ddac5bb87c64f88 100644 (file)
@@ -3279,6 +3279,7 @@ int sock_load_diag_module(int family, int protocol)
 
 #ifdef CONFIG_INET
        if (family == AF_INET &&
+           protocol != IPPROTO_RAW &&
            !rcu_access_pointer(inet_protos[protocol]))
                return -ENOENT;
 #endif
index bcb11f3a27c0c34115af05034a5a20f57842eb0a..760a9e52e02b91b36af323c92f7027e150858f88 100644 (file)
@@ -178,21 +178,22 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
 }
 
 static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
-                                               void *arg)
+                                               void *arg,
+                                               struct inet_frag_queue **prev)
 {
        struct inet_frags *f = nf->f;
        struct inet_frag_queue *q;
-       int err;
 
        q = inet_frag_alloc(nf, f, arg);
-       if (!q)
+       if (!q) {
+               *prev = ERR_PTR(-ENOMEM);
                return NULL;
-
+       }
        mod_timer(&q->timer, jiffies + nf->timeout);
 
-       err = rhashtable_insert_fast(&nf->rhashtable, &q->node,
-                                    f->rhash_params);
-       if (err < 0) {
+       *prev = rhashtable_lookup_get_insert_key(&nf->rhashtable, &q->key,
+                                                &q->node, f->rhash_params);
+       if (*prev) {
                q->flags |= INET_FRAG_COMPLETE;
                inet_frag_kill(q);
                inet_frag_destroy(q);
@@ -204,22 +205,22 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
 /* TODO : call from rcu_read_lock() and no longer use refcount_inc_not_zero() */
 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key)
 {
-       struct inet_frag_queue *fq;
+       struct inet_frag_queue *fq = NULL, *prev;
 
        if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh)
                return NULL;
 
        rcu_read_lock();
 
-       fq = rhashtable_lookup(&nf->rhashtable, key, nf->f->rhash_params);
-       if (fq) {
+       prev = rhashtable_lookup(&nf->rhashtable, key, nf->f->rhash_params);
+       if (!prev)
+               fq = inet_frag_create(nf, key, &prev);
+       if (prev && !IS_ERR(prev)) {
+               fq = prev;
                if (!refcount_inc_not_zero(&fq->refcnt))
                        fq = NULL;
-               rcu_read_unlock();
-               return fq;
        }
        rcu_read_unlock();
-
-       return inet_frag_create(nf, key);
+       return fq;
 }
 EXPORT_SYMBOL(inet_frag_find);
index 9b0158fa431f2245c0fa7e21d62e3ac01296dc20..d6ee343fdb8647ea96240d017b72aef2f6790299 100644 (file)
@@ -722,10 +722,14 @@ struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user)
        if (ip_is_fragment(&iph)) {
                skb = skb_share_check(skb, GFP_ATOMIC);
                if (skb) {
-                       if (!pskb_may_pull(skb, netoff + iph.ihl * 4))
-                               return skb;
-                       if (pskb_trim_rcsum(skb, netoff + len))
-                               return skb;
+                       if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) {
+                               kfree_skb(skb);
+                               return NULL;
+                       }
+                       if (pskb_trim_rcsum(skb, netoff + len)) {
+                               kfree_skb(skb);
+                               return NULL;
+                       }
                        memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
                        if (ip_defrag(net, skb, user))
                                return NULL;
index 26c36cccabdc2c8cc95cfd609672d412c493fc42..fffcc130900e518874027562272b1052cf0bdd16 100644 (file)
@@ -1246,7 +1246,7 @@ int ip_setsockopt(struct sock *sk, int level,
                return -ENOPROTOOPT;
 
        err = do_ip_setsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_BPFILTER
+#if IS_ENABLED(CONFIG_BPFILTER_UMH)
        if (optname >= BPFILTER_IPT_SO_SET_REPLACE &&
            optname < BPFILTER_IPT_SET_MAX)
                err = bpfilter_ip_set_sockopt(sk, optname, optval, optlen);
@@ -1559,7 +1559,7 @@ int ip_getsockopt(struct sock *sk, int level,
        int err;
 
        err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
-#ifdef CONFIG_BPFILTER
+#if IS_ENABLED(CONFIG_BPFILTER_UMH)
        if (optname >= BPFILTER_IPT_SO_GET_INFO &&
            optname < BPFILTER_IPT_GET_MAX)
                err = bpfilter_ip_get_sockopt(sk, optname, optval, optlen);
@@ -1596,7 +1596,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
        err = do_ip_getsockopt(sk, level, optname, optval, optlen,
                MSG_CMSG_COMPAT);
 
-#ifdef CONFIG_BPFILTER
+#if IS_ENABLED(CONFIG_BPFILTER_UMH)
        if (optname >= BPFILTER_IPT_SO_GET_INFO &&
            optname < BPFILTER_IPT_GET_MAX)
                err = bpfilter_ip_get_sockopt(sk, optname, optval, optlen);
index dde671e978298b5b0239f975fe134b232db9049b..c248e0dccbe17afa397910b0d68260daf2a9eb3f 100644 (file)
@@ -80,7 +80,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
 
        iph->version    =       4;
        iph->ihl        =       sizeof(struct iphdr) >> 2;
-       iph->frag_off   =       df;
+       iph->frag_off   =       ip_mtu_locked(&rt->dst) ? 0 : df;
        iph->protocol   =       proto;
        iph->tos        =       tos;
        iph->daddr      =       dst;
index 3f4d61017a6947c9dfb5cd1a38e5a25f1665928f..f0cd291034f0fa8ece55acd0fccf79e02629c98a 100644 (file)
@@ -1001,6 +1001,9 @@ static int __init inet6_init(void)
        err = ip6_flowlabel_init();
        if (err)
                goto ip6_flowlabel_fail;
+       err = ipv6_anycast_init();
+       if (err)
+               goto ipv6_anycast_fail;
        err = addrconf_init();
        if (err)
                goto addrconf_fail;
@@ -1091,6 +1094,8 @@ ipv6_frag_fail:
 ipv6_exthdrs_fail:
        addrconf_cleanup();
 addrconf_fail:
+       ipv6_anycast_cleanup();
+ipv6_anycast_fail:
        ip6_flowlabel_cleanup();
 ip6_flowlabel_fail:
        ndisc_late_cleanup();
index 4e0ff7031edd55ce6dbb3f2c62e22b9040cc7fec..94999058e11029b637b6ab8201f8706599e49284 100644 (file)
 
 #include <net/checksum.h>
 
+#define IN6_ADDR_HSIZE_SHIFT   8
+#define IN6_ADDR_HSIZE         BIT(IN6_ADDR_HSIZE_SHIFT)
+/*     anycast address hash table
+ */
+static struct hlist_head inet6_acaddr_lst[IN6_ADDR_HSIZE];
+static DEFINE_SPINLOCK(acaddr_hash_lock);
+
 static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr);
 
+static u32 inet6_acaddr_hash(struct net *net, const struct in6_addr *addr)
+{
+       u32 val = ipv6_addr_hash(addr) ^ net_hash_mix(net);
+
+       return hash_32(val, IN6_ADDR_HSIZE_SHIFT);
+}
+
 /*
  *     socket join an anycast group
  */
@@ -204,16 +218,39 @@ void ipv6_sock_ac_close(struct sock *sk)
        rtnl_unlock();
 }
 
+static void ipv6_add_acaddr_hash(struct net *net, struct ifacaddr6 *aca)
+{
+       unsigned int hash = inet6_acaddr_hash(net, &aca->aca_addr);
+
+       spin_lock(&acaddr_hash_lock);
+       hlist_add_head_rcu(&aca->aca_addr_lst, &inet6_acaddr_lst[hash]);
+       spin_unlock(&acaddr_hash_lock);
+}
+
+static void ipv6_del_acaddr_hash(struct ifacaddr6 *aca)
+{
+       spin_lock(&acaddr_hash_lock);
+       hlist_del_init_rcu(&aca->aca_addr_lst);
+       spin_unlock(&acaddr_hash_lock);
+}
+
 static void aca_get(struct ifacaddr6 *aca)
 {
        refcount_inc(&aca->aca_refcnt);
 }
 
+static void aca_free_rcu(struct rcu_head *h)
+{
+       struct ifacaddr6 *aca = container_of(h, struct ifacaddr6, rcu);
+
+       fib6_info_release(aca->aca_rt);
+       kfree(aca);
+}
+
 static void aca_put(struct ifacaddr6 *ac)
 {
        if (refcount_dec_and_test(&ac->aca_refcnt)) {
-               fib6_info_release(ac->aca_rt);
-               kfree(ac);
+               call_rcu(&ac->rcu, aca_free_rcu);
        }
 }
 
@@ -229,6 +266,7 @@ static struct ifacaddr6 *aca_alloc(struct fib6_info *f6i,
        aca->aca_addr = *addr;
        fib6_info_hold(f6i);
        aca->aca_rt = f6i;
+       INIT_HLIST_NODE(&aca->aca_addr_lst);
        aca->aca_users = 1;
        /* aca_tstamp should be updated upon changes */
        aca->aca_cstamp = aca->aca_tstamp = jiffies;
@@ -285,6 +323,8 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
        aca_get(aca);
        write_unlock_bh(&idev->lock);
 
+       ipv6_add_acaddr_hash(net, aca);
+
        ip6_ins_rt(net, f6i);
 
        addrconf_join_solict(idev->dev, &aca->aca_addr);
@@ -325,6 +365,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
        else
                idev->ac_list = aca->aca_next;
        write_unlock_bh(&idev->lock);
+       ipv6_del_acaddr_hash(aca);
        addrconf_leave_solict(idev, &aca->aca_addr);
 
        ip6_del_rt(dev_net(idev->dev), aca->aca_rt);
@@ -352,6 +393,8 @@ void ipv6_ac_destroy_dev(struct inet6_dev *idev)
                idev->ac_list = aca->aca_next;
                write_unlock_bh(&idev->lock);
 
+               ipv6_del_acaddr_hash(aca);
+
                addrconf_leave_solict(idev, &aca->aca_addr);
 
                ip6_del_rt(dev_net(idev->dev), aca->aca_rt);
@@ -390,17 +433,25 @@ static bool ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *ad
 bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
                         const struct in6_addr *addr)
 {
+       unsigned int hash = inet6_acaddr_hash(net, addr);
+       struct net_device *nh_dev;
+       struct ifacaddr6 *aca;
        bool found = false;
 
        rcu_read_lock();
        if (dev)
                found = ipv6_chk_acast_dev(dev, addr);
        else
-               for_each_netdev_rcu(net, dev)
-                       if (ipv6_chk_acast_dev(dev, addr)) {
+               hlist_for_each_entry_rcu(aca, &inet6_acaddr_lst[hash],
+                                        aca_addr_lst) {
+                       nh_dev = fib6_info_nh_dev(aca->aca_rt);
+                       if (!nh_dev || !net_eq(dev_net(nh_dev), net))
+                               continue;
+                       if (ipv6_addr_equal(&aca->aca_addr, addr)) {
                                found = true;
                                break;
                        }
+               }
        rcu_read_unlock();
        return found;
 }
@@ -540,3 +591,24 @@ void ac6_proc_exit(struct net *net)
        remove_proc_entry("anycast6", net->proc_net);
 }
 #endif
+
+/*     Init / cleanup code
+ */
+int __init ipv6_anycast_init(void)
+{
+       int i;
+
+       for (i = 0; i < IN6_ADDR_HSIZE; i++)
+               INIT_HLIST_HEAD(&inet6_acaddr_lst[i]);
+       return 0;
+}
+
+void ipv6_anycast_cleanup(void)
+{
+       int i;
+
+       spin_lock(&acaddr_hash_lock);
+       for (i = 0; i < IN6_ADDR_HSIZE; i++)
+               WARN_ON(!hlist_empty(&inet6_acaddr_lst[i]));
+       spin_unlock(&acaddr_hash_lock);
+}
index 1b8bc008b53b642adef3ba9335563d430a99c1a9..ae3786132c236b2bcde4f8f3008fceb2d6bc1cdd 100644 (file)
@@ -591,7 +591,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 
        /* fib entries are never clones */
        if (arg.filter.flags & RTM_F_CLONED)
-               return skb->len;
+               goto out;
 
        w = (void *)cb->args[2];
        if (!w) {
@@ -621,7 +621,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
                tb = fib6_get_table(net, arg.filter.table_id);
                if (!tb) {
                        if (arg.filter.dump_all_families)
-                               return skb->len;
+                               goto out;
 
                        NL_SET_ERR_MSG_MOD(cb->extack, "FIB table does not exist");
                        return -ENOENT;
index b8ac369f98ad877f6cf9114b1dbcfcb6c4c95ec5..d219979c3e529c32e029865debc788109d05ad83 100644 (file)
@@ -587,11 +587,16 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
         */
        ret = -EINPROGRESS;
        if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
-           fq->q.meat == fq->q.len &&
-           nf_ct_frag6_reasm(fq, skb, dev))
-               ret = 0;
-       else
+           fq->q.meat == fq->q.len) {
+               unsigned long orefdst = skb->_skb_refdst;
+
+               skb->_skb_refdst = 0UL;
+               if (nf_ct_frag6_reasm(fq, skb, dev))
+                       ret = 0;
+               skb->_skb_refdst = orefdst;
+       } else {
                skb_dst_drop(skb);
+       }
 
 out_unlock:
        spin_unlock_bh(&fq->q.lock);
index 2a7423c394560c0bc70d6f0398781a0b35fa9fa0..059f0531f7c1c86133afcab0f8e7388c60eeaf58 100644 (file)
@@ -2232,8 +2232,7 @@ static void ip6_link_failure(struct sk_buff *skb)
        if (rt) {
                rcu_read_lock();
                if (rt->rt6i_flags & RTF_CACHE) {
-                       if (dst_hold_safe(&rt->dst))
-                               rt6_remove_exception_rt(rt);
+                       rt6_remove_exception_rt(rt);
                } else {
                        struct fib6_info *from;
                        struct fib6_node *fn;
@@ -2360,10 +2359,13 @@ EXPORT_SYMBOL_GPL(ip6_update_pmtu);
 
 void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu)
 {
+       int oif = sk->sk_bound_dev_if;
        struct dst_entry *dst;
 
-       ip6_update_pmtu(skb, sock_net(sk), mtu,
-                       sk->sk_bound_dev_if, sk->sk_mark, sk->sk_uid);
+       if (!oif && skb->dev)
+               oif = l3mdev_master_ifindex(skb->dev);
+
+       ip6_update_pmtu(skb, sock_net(sk), mtu, oif, sk->sk_mark, sk->sk_uid);
 
        dst = __sk_dst_get(sk);
        if (!dst || !dst->obsolete ||
@@ -3214,8 +3216,8 @@ static int ip6_del_cached_rt(struct rt6_info *rt, struct fib6_config *cfg)
        if (cfg->fc_flags & RTF_GATEWAY &&
            !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
                goto out;
-       if (dst_hold_safe(&rt->dst))
-               rc = rt6_remove_exception_rt(rt);
+
+       rc = rt6_remove_exception_rt(rt);
 out:
        return rc;
 }
index 82cdf9020b53921c1ed86cd6122ebe6007ea263c..26f1d435696a628aca844edb2a88f8b793839d91 100644 (file)
@@ -1490,12 +1490,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
                        goto err_sock;
        }
 
-       sk = sock->sk;
-
-       sock_hold(sk);
-       tunnel->sock = sk;
        tunnel->l2tp_net = net;
-
        pn = l2tp_pernet(net);
 
        spin_lock_bh(&pn->l2tp_tunnel_list_lock);
@@ -1510,6 +1505,10 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
        list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
        spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
 
+       sk = sock->sk;
+       sock_hold(sk);
+       tunnel->sock = sk;
+
        if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
                struct udp_tunnel_sock_cfg udp_cfg = {
                        .sk_user_data = tunnel,
index bc4bd247bb7d42767eb860c05fb4b0b40408304b..1577f2f76060dcd816f94078412f52943568ce40 100644 (file)
@@ -55,11 +55,15 @@ MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
 MODULE_DESCRIPTION("core IP set support");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET);
 
-/* When the nfnl mutex is held: */
+/* When the nfnl mutex or ip_set_ref_lock is held: */
 #define ip_set_dereference(p)          \
-       rcu_dereference_protected(p, lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET))
+       rcu_dereference_protected(p,    \
+               lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \
+               lockdep_is_held(&ip_set_ref_lock))
 #define ip_set(inst, id)               \
        ip_set_dereference((inst)->ip_set_list)[id]
+#define ip_set_ref_netlink(inst,id)    \
+       rcu_dereference_raw((inst)->ip_set_list)[id]
 
 /* The set types are implemented in modules and registered set types
  * can be found in ip_set_type_list. Adding/deleting types is
@@ -693,21 +697,20 @@ ip_set_put_byindex(struct net *net, ip_set_id_t index)
 EXPORT_SYMBOL_GPL(ip_set_put_byindex);
 
 /* Get the name of a set behind a set index.
- * We assume the set is referenced, so it does exist and
- * can't be destroyed. The set cannot be renamed due to
- * the referencing either.
- *
+ * Set itself is protected by RCU, but its name isn't: to protect against
+ * renaming, grab ip_set_ref_lock as reader (see ip_set_rename()) and copy the
+ * name.
  */
-const char *
-ip_set_name_byindex(struct net *net, ip_set_id_t index)
+void
+ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name)
 {
-       const struct ip_set *set = ip_set_rcu_get(net, index);
+       struct ip_set *set = ip_set_rcu_get(net, index);
 
        BUG_ON(!set);
-       BUG_ON(set->ref == 0);
 
-       /* Referenced, so it's safe */
-       return set->name;
+       read_lock_bh(&ip_set_ref_lock);
+       strncpy(name, set->name, IPSET_MAXNAMELEN);
+       read_unlock_bh(&ip_set_ref_lock);
 }
 EXPORT_SYMBOL_GPL(ip_set_name_byindex);
 
@@ -961,7 +964,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
                        /* Wraparound */
                        goto cleanup;
 
-               list = kcalloc(i, sizeof(struct ip_set *), GFP_KERNEL);
+               list = kvcalloc(i, sizeof(struct ip_set *), GFP_KERNEL);
                if (!list)
                        goto cleanup;
                /* nfnl mutex is held, both lists are valid */
@@ -973,7 +976,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
                /* Use new list */
                index = inst->ip_set_max;
                inst->ip_set_max = i;
-               kfree(tmp);
+               kvfree(tmp);
                ret = 0;
        } else if (ret) {
                goto cleanup;
@@ -1153,7 +1156,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
        if (!set)
                return -ENOENT;
 
-       read_lock_bh(&ip_set_ref_lock);
+       write_lock_bh(&ip_set_ref_lock);
        if (set->ref != 0) {
                ret = -IPSET_ERR_REFERENCED;
                goto out;
@@ -1170,7 +1173,7 @@ static int ip_set_rename(struct net *net, struct sock *ctnl,
        strncpy(set->name, name2, IPSET_MAXNAMELEN);
 
 out:
-       read_unlock_bh(&ip_set_ref_lock);
+       write_unlock_bh(&ip_set_ref_lock);
        return ret;
 }
 
@@ -1252,7 +1255,7 @@ ip_set_dump_done(struct netlink_callback *cb)
                struct ip_set_net *inst =
                        (struct ip_set_net *)cb->args[IPSET_CB_NET];
                ip_set_id_t index = (ip_set_id_t)cb->args[IPSET_CB_INDEX];
-               struct ip_set *set = ip_set(inst, index);
+               struct ip_set *set = ip_set_ref_netlink(inst, index);
 
                if (set->variant->uref)
                        set->variant->uref(set, cb, false);
@@ -1441,7 +1444,7 @@ next_set:
 release_refcount:
        /* If there was an error or set is done, release set */
        if (ret || !cb->args[IPSET_CB_ARG0]) {
-               set = ip_set(inst, index);
+               set = ip_set_ref_netlink(inst, index);
                if (set->variant->uref)
                        set->variant->uref(set, cb, false);
                pr_debug("release set %s\n", set->name);
@@ -2059,7 +2062,7 @@ ip_set_net_init(struct net *net)
        if (inst->ip_set_max >= IPSET_INVALID_ID)
                inst->ip_set_max = IPSET_INVALID_ID - 1;
 
-       list = kcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL);
+       list = kvcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL);
        if (!list)
                return -ENOMEM;
        inst->is_deleted = false;
@@ -2087,7 +2090,7 @@ ip_set_net_exit(struct net *net)
                }
        }
        nfnl_unlock(NFNL_SUBSYS_IPSET);
-       kfree(rcu_dereference_protected(inst->ip_set_list, 1));
+       kvfree(rcu_dereference_protected(inst->ip_set_list, 1));
 }
 
 static struct pernet_operations ip_set_net_ops = {
index d391485a6acdc2ff3523d5b7d39c20ab4a8add80..613e18e720a44777754428666b9f021de952de9a 100644 (file)
@@ -213,13 +213,13 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (tb[IPSET_ATTR_CIDR]) {
                e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
-               if (!e.cidr[0] || e.cidr[0] > HOST_MASK)
+               if (e.cidr[0] > HOST_MASK)
                        return -IPSET_ERR_INVALID_CIDR;
        }
 
        if (tb[IPSET_ATTR_CIDR2]) {
                e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
-               if (!e.cidr[1] || e.cidr[1] > HOST_MASK)
+               if (e.cidr[1] > HOST_MASK)
                        return -IPSET_ERR_INVALID_CIDR;
        }
 
@@ -493,13 +493,13 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (tb[IPSET_ATTR_CIDR]) {
                e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
-               if (!e.cidr[0] || e.cidr[0] > HOST_MASK)
+               if (e.cidr[0] > HOST_MASK)
                        return -IPSET_ERR_INVALID_CIDR;
        }
 
        if (tb[IPSET_ATTR_CIDR2]) {
                e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
-               if (!e.cidr[1] || e.cidr[1] > HOST_MASK)
+               if (e.cidr[1] > HOST_MASK)
                        return -IPSET_ERR_INVALID_CIDR;
        }
 
index 072a658fde047c5d9d59ac08e796b25759cc68a1..4eef55da0878e299d0bb912fa7ea69d3d4e91441 100644 (file)
@@ -148,9 +148,7 @@ __list_set_del_rcu(struct rcu_head * rcu)
 {
        struct set_elem *e = container_of(rcu, struct set_elem, rcu);
        struct ip_set *set = e->set;
-       struct list_set *map = set->data;
 
-       ip_set_put_byindex(map->net, e->id);
        ip_set_ext_destroy(set, e);
        kfree(e);
 }
@@ -158,15 +156,21 @@ __list_set_del_rcu(struct rcu_head * rcu)
 static inline void
 list_set_del(struct ip_set *set, struct set_elem *e)
 {
+       struct list_set *map = set->data;
+
        set->elements--;
        list_del_rcu(&e->list);
+       ip_set_put_byindex(map->net, e->id);
        call_rcu(&e->rcu, __list_set_del_rcu);
 }
 
 static inline void
-list_set_replace(struct set_elem *e, struct set_elem *old)
+list_set_replace(struct ip_set *set, struct set_elem *e, struct set_elem *old)
 {
+       struct list_set *map = set->data;
+
        list_replace_rcu(&old->list, &e->list);
+       ip_set_put_byindex(map->net, old->id);
        call_rcu(&old->rcu, __list_set_del_rcu);
 }
 
@@ -298,7 +302,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        INIT_LIST_HEAD(&e->list);
        list_set_init_extensions(set, ext, e);
        if (n)
-               list_set_replace(e, n);
+               list_set_replace(set, e, n);
        else if (next)
                list_add_tail_rcu(&e->list, &next->list);
        else if (prev)
@@ -486,6 +490,7 @@ list_set_list(const struct ip_set *set,
        const struct list_set *map = set->data;
        struct nlattr *atd, *nested;
        u32 i = 0, first = cb->args[IPSET_CB_ARG0];
+       char name[IPSET_MAXNAMELEN];
        struct set_elem *e;
        int ret = 0;
 
@@ -504,8 +509,8 @@ list_set_list(const struct ip_set *set,
                nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
                if (!nested)
                        goto nla_put_failure;
-               if (nla_put_string(skb, IPSET_ATTR_NAME,
-                                  ip_set_name_byindex(map->net, e->id)))
+               ip_set_name_byindex(map->net, e->id, name);
+               if (nla_put_string(skb, IPSET_ATTR_NAME, name))
                        goto nla_put_failure;
                if (ip_set_put_extensions(skb, set, e, true))
                        goto nla_put_failure;
index ca1168d67fac6c0fc1eaef5dfeb1db8428e51db3..e92e749aff53e46c60718b55593e72d70838e9be 100644 (file)
@@ -1073,19 +1073,22 @@ static unsigned int early_drop_list(struct net *net,
        return drops;
 }
 
-static noinline int early_drop(struct net *net, unsigned int _hash)
+static noinline int early_drop(struct net *net, unsigned int hash)
 {
-       unsigned int i;
+       unsigned int i, bucket;
 
        for (i = 0; i < NF_CT_EVICTION_RANGE; i++) {
                struct hlist_nulls_head *ct_hash;
-               unsigned int hash, hsize, drops;
+               unsigned int hsize, drops;
 
                rcu_read_lock();
                nf_conntrack_get_ht(&ct_hash, &hsize);
-               hash = reciprocal_scale(_hash++, hsize);
+               if (!i)
+                       bucket = reciprocal_scale(hash, hsize);
+               else
+                       bucket = (bucket + 1) % hsize;
 
-               drops = early_drop_list(net, &ct_hash[hash]);
+               drops = early_drop_list(net, &ct_hash[bucket]);
                rcu_read_unlock();
 
                if (drops) {
index 171e9e122e5f1e8b8840e41013d86246ba8025b9..023c1445bc3960de8c3d2350d9fb5c8d743e920f 100644 (file)
@@ -384,11 +384,6 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
        },
 };
 
-static inline struct nf_dccp_net *dccp_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.dccp;
-}
-
 static noinline bool
 dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
         const struct dccp_hdr *dh)
@@ -401,7 +396,7 @@ dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
        state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
        switch (state) {
        default:
-               dn = dccp_pernet(net);
+               dn = nf_dccp_pernet(net);
                if (dn->dccp_loose == 0) {
                        msg = "not picking up existing connection ";
                        goto out_invalid;
@@ -568,7 +563,7 @@ static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
 
        timeouts = nf_ct_timeout_lookup(ct);
        if (!timeouts)
-               timeouts = dccp_pernet(nf_ct_net(ct))->dccp_timeout;
+               timeouts = nf_dccp_pernet(nf_ct_net(ct))->dccp_timeout;
        nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
 
        return NF_ACCEPT;
@@ -681,7 +676,7 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
 static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
                                      struct net *net, void *data)
 {
-       struct nf_dccp_net *dn = dccp_pernet(net);
+       struct nf_dccp_net *dn = nf_dccp_pernet(net);
        unsigned int *timeouts = data;
        int i;
 
@@ -814,7 +809,7 @@ static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
 
 static int dccp_init_net(struct net *net)
 {
-       struct nf_dccp_net *dn = dccp_pernet(net);
+       struct nf_dccp_net *dn = nf_dccp_pernet(net);
        struct nf_proto_net *pn = &dn->pn;
 
        if (!pn->users) {
index e10e867e0b55f3203e8a50d4ac7c884201ac1186..5da19d5fbc767f2ca8f22ac4eba09aebb6c59fda 100644 (file)
@@ -27,11 +27,6 @@ static bool nf_generic_should_process(u8 proto)
        }
 }
 
-static inline struct nf_generic_net *generic_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.generic;
-}
-
 static bool generic_pkt_to_tuple(const struct sk_buff *skb,
                                 unsigned int dataoff,
                                 struct net *net, struct nf_conntrack_tuple *tuple)
@@ -58,7 +53,7 @@ static int generic_packet(struct nf_conn *ct,
        }
 
        if (!timeout)
-               timeout = &generic_pernet(nf_ct_net(ct))->timeout;
+               timeout = &nf_generic_pernet(nf_ct_net(ct))->timeout;
 
        nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
        return NF_ACCEPT;
@@ -72,7 +67,7 @@ static int generic_packet(struct nf_conn *ct,
 static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
                                         struct net *net, void *data)
 {
-       struct nf_generic_net *gn = generic_pernet(net);
+       struct nf_generic_net *gn = nf_generic_pernet(net);
        unsigned int *timeout = data;
 
        if (!timeout)
@@ -138,7 +133,7 @@ static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int generic_init_net(struct net *net)
 {
-       struct nf_generic_net *gn = generic_pernet(net);
+       struct nf_generic_net *gn = nf_generic_pernet(net);
        struct nf_proto_net *pn = &gn->pn;
 
        gn->timeout = nf_ct_generic_timeout;
index 3598520bd19b7b76dbd91bb42e4b8b91713abf2c..de64d8a5fdfd137aca48a9e62a143a01f63bec07 100644 (file)
 
 static const unsigned int nf_ct_icmp_timeout = 30*HZ;
 
-static inline struct nf_icmp_net *icmp_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.icmp;
-}
-
 static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
                              struct net *net, struct nf_conntrack_tuple *tuple)
 {
@@ -103,7 +98,7 @@ static int icmp_packet(struct nf_conn *ct,
        }
 
        if (!timeout)
-               timeout = &icmp_pernet(nf_ct_net(ct))->timeout;
+               timeout = &nf_icmp_pernet(nf_ct_net(ct))->timeout;
 
        nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
        return NF_ACCEPT;
@@ -275,7 +270,7 @@ static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[],
                                      struct net *net, void *data)
 {
        unsigned int *timeout = data;
-       struct nf_icmp_net *in = icmp_pernet(net);
+       struct nf_icmp_net *in = nf_icmp_pernet(net);
 
        if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) {
                if (!timeout)
@@ -337,7 +332,7 @@ static int icmp_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int icmp_init_net(struct net *net)
 {
-       struct nf_icmp_net *in = icmp_pernet(net);
+       struct nf_icmp_net *in = nf_icmp_pernet(net);
        struct nf_proto_net *pn = &in->pn;
 
        in->timeout = nf_ct_icmp_timeout;
index 378618feed5da7df50e09c8ec4f72618953306b0..a15eefb8e3173c5d89268bd7f2a6c076ff787b1c 100644 (file)
 
 static const unsigned int nf_ct_icmpv6_timeout = 30*HZ;
 
-static inline struct nf_icmp_net *icmpv6_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.icmpv6;
-}
-
 static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb,
                                unsigned int dataoff,
                                struct net *net,
@@ -87,7 +82,7 @@ static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
 
 static unsigned int *icmpv6_get_timeouts(struct net *net)
 {
-       return &icmpv6_pernet(net)->timeout;
+       return &nf_icmpv6_pernet(net)->timeout;
 }
 
 /* Returns verdict for packet, or -1 for invalid. */
@@ -286,7 +281,7 @@ static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[],
                                        struct net *net, void *data)
 {
        unsigned int *timeout = data;
-       struct nf_icmp_net *in = icmpv6_pernet(net);
+       struct nf_icmp_net *in = nf_icmpv6_pernet(net);
 
        if (!timeout)
                timeout = icmpv6_get_timeouts(net);
@@ -348,7 +343,7 @@ static int icmpv6_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int icmpv6_init_net(struct net *net)
 {
-       struct nf_icmp_net *in = icmpv6_pernet(net);
+       struct nf_icmp_net *in = nf_icmpv6_pernet(net);
        struct nf_proto_net *pn = &in->pn;
 
        in->timeout = nf_ct_icmpv6_timeout;
index 3d719d3eb9a38c7709b8d224facdad8820ebded4..d53e3e78f6052a1f8d8fde973ee03b0763470b30 100644 (file)
@@ -146,11 +146,6 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
        }
 };
 
-static inline struct nf_sctp_net *sctp_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.sctp;
-}
-
 #ifdef CONFIG_NF_CONNTRACK_PROCFS
 /* Print out the private part of the conntrack. */
 static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
@@ -480,7 +475,7 @@ static int sctp_packet(struct nf_conn *ct,
 
        timeouts = nf_ct_timeout_lookup(ct);
        if (!timeouts)
-               timeouts = sctp_pernet(nf_ct_net(ct))->timeouts;
+               timeouts = nf_sctp_pernet(nf_ct_net(ct))->timeouts;
 
        nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
 
@@ -599,7 +594,7 @@ static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
                                      struct net *net, void *data)
 {
        unsigned int *timeouts = data;
-       struct nf_sctp_net *sn = sctp_pernet(net);
+       struct nf_sctp_net *sn = nf_sctp_pernet(net);
        int i;
 
        /* set default SCTP timeouts. */
@@ -736,7 +731,7 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int sctp_init_net(struct net *net)
 {
-       struct nf_sctp_net *sn = sctp_pernet(net);
+       struct nf_sctp_net *sn = nf_sctp_pernet(net);
        struct nf_proto_net *pn = &sn->pn;
 
        if (!pn->users) {
index 1bcf9984d45e8601646cb2b99dc5f3113a5c8b0a..4dcbd51a8e97f04ad8056374ed892887d2f0798e 100644 (file)
@@ -272,11 +272,6 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
        }
 };
 
-static inline struct nf_tcp_net *tcp_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.tcp;
-}
-
 #ifdef CONFIG_NF_CONNTRACK_PROCFS
 /* Print out the private part of the conntrack. */
 static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
@@ -475,7 +470,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
                          const struct tcphdr *tcph)
 {
        struct net *net = nf_ct_net(ct);
-       struct nf_tcp_net *tn = tcp_pernet(net);
+       struct nf_tcp_net *tn = nf_tcp_pernet(net);
        struct ip_ct_tcp_state *sender = &state->seen[dir];
        struct ip_ct_tcp_state *receiver = &state->seen[!dir];
        const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -767,7 +762,7 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
 {
        enum tcp_conntrack new_state;
        struct net *net = nf_ct_net(ct);
-       const struct nf_tcp_net *tn = tcp_pernet(net);
+       const struct nf_tcp_net *tn = nf_tcp_pernet(net);
        const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
        const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
 
@@ -841,7 +836,7 @@ static int tcp_packet(struct nf_conn *ct,
                      const struct nf_hook_state *state)
 {
        struct net *net = nf_ct_net(ct);
-       struct nf_tcp_net *tn = tcp_pernet(net);
+       struct nf_tcp_net *tn = nf_tcp_pernet(net);
        struct nf_conntrack_tuple *tuple;
        enum tcp_conntrack new_state, old_state;
        unsigned int index, *timeouts;
@@ -1283,7 +1278,7 @@ static unsigned int tcp_nlattr_tuple_size(void)
 static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
                                     struct net *net, void *data)
 {
-       struct nf_tcp_net *tn = tcp_pernet(net);
+       struct nf_tcp_net *tn = nf_tcp_pernet(net);
        unsigned int *timeouts = data;
        int i;
 
@@ -1508,7 +1503,7 @@ static int tcp_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int tcp_init_net(struct net *net)
 {
-       struct nf_tcp_net *tn = tcp_pernet(net);
+       struct nf_tcp_net *tn = nf_tcp_pernet(net);
        struct nf_proto_net *pn = &tn->pn;
 
        if (!pn->users) {
index a7aa70370913ce7e8914343270152fb009eb2a63..c879d8d78cfde88a223b961bb203bf7bb48ef1b2 100644 (file)
@@ -32,14 +32,9 @@ static const unsigned int udp_timeouts[UDP_CT_MAX] = {
        [UDP_CT_REPLIED]        = 180*HZ,
 };
 
-static inline struct nf_udp_net *udp_pernet(struct net *net)
-{
-       return &net->ct.nf_ct_proto.udp;
-}
-
 static unsigned int *udp_get_timeouts(struct net *net)
 {
-       return udp_pernet(net)->timeouts;
+       return nf_udp_pernet(net)->timeouts;
 }
 
 static void udp_error_log(const struct sk_buff *skb,
@@ -212,7 +207,7 @@ static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
                                     struct net *net, void *data)
 {
        unsigned int *timeouts = data;
-       struct nf_udp_net *un = udp_pernet(net);
+       struct nf_udp_net *un = nf_udp_pernet(net);
 
        if (!timeouts)
                timeouts = un->timeouts;
@@ -292,7 +287,7 @@ static int udp_kmemdup_sysctl_table(struct nf_proto_net *pn,
 
 static int udp_init_net(struct net *net)
 {
-       struct nf_udp_net *un = udp_pernet(net);
+       struct nf_udp_net *un = nf_udp_pernet(net);
        struct nf_proto_net *pn = &un->pn;
 
        if (!pn->users) {
index e7a50af1b3d61a6e12fb74eaa9a9ba02f0a8d22b..a518eb162344e6692e69989cf5ba0cdf03da1333 100644 (file)
@@ -382,7 +382,8 @@ err:
 static int
 cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
                            u32 seq, u32 type, int event, u16 l3num,
-                           const struct nf_conntrack_l4proto *l4proto)
+                           const struct nf_conntrack_l4proto *l4proto,
+                           const unsigned int *timeouts)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
@@ -408,7 +409,7 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
        if (!nest_parms)
                goto nla_put_failure;
 
-       ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, NULL);
+       ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
        if (ret < 0)
                goto nla_put_failure;
 
@@ -430,6 +431,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
                                 struct netlink_ext_ack *extack)
 {
        const struct nf_conntrack_l4proto *l4proto;
+       unsigned int *timeouts = NULL;
        struct sk_buff *skb2;
        int ret, err;
        __u16 l3num;
@@ -442,12 +444,44 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
        l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
        l4proto = nf_ct_l4proto_find_get(l4num);
 
-       /* This protocol is not supported, skip. */
-       if (l4proto->l4proto != l4num) {
-               err = -EOPNOTSUPP;
+       err = -EOPNOTSUPP;
+       if (l4proto->l4proto != l4num)
                goto err;
+
+       switch (l4proto->l4proto) {
+       case IPPROTO_ICMP:
+               timeouts = &nf_icmp_pernet(net)->timeout;
+               break;
+       case IPPROTO_TCP:
+               timeouts = nf_tcp_pernet(net)->timeouts;
+               break;
+       case IPPROTO_UDP:
+               timeouts = nf_udp_pernet(net)->timeouts;
+               break;
+       case IPPROTO_DCCP:
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+               timeouts = nf_dccp_pernet(net)->dccp_timeout;
+#endif
+               break;
+       case IPPROTO_ICMPV6:
+               timeouts = &nf_icmpv6_pernet(net)->timeout;
+               break;
+       case IPPROTO_SCTP:
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+               timeouts = nf_sctp_pernet(net)->timeouts;
+#endif
+               break;
+       case 255:
+               timeouts = &nf_generic_pernet(net)->timeout;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
        }
 
+       if (!timeouts)
+               goto err;
+
        skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (skb2 == NULL) {
                err = -ENOMEM;
@@ -458,8 +492,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
                                          nlh->nlmsg_seq,
                                          NFNL_MSG_TYPE(nlh->nlmsg_type),
                                          IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
-                                         l3num,
-                                         l4proto);
+                                         l3num, l4proto, timeouts);
        if (ret <= 0) {
                kfree_skb(skb2);
                err = -ENOMEM;
index 768292eac2a46afe84df3b8a949a70bf77baf478..9d0ede4742240f544bbdff40553b73b8e755c7b4 100644 (file)
@@ -54,9 +54,11 @@ static bool nft_xt_put(struct nft_xt *xt)
        return false;
 }
 
-static int nft_compat_chain_validate_dependency(const char *tablename,
-                                               const struct nft_chain *chain)
+static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
+                                               const char *tablename)
 {
+       enum nft_chain_types type = NFT_CHAIN_T_DEFAULT;
+       const struct nft_chain *chain = ctx->chain;
        const struct nft_base_chain *basechain;
 
        if (!tablename ||
@@ -64,9 +66,12 @@ static int nft_compat_chain_validate_dependency(const char *tablename,
                return 0;
 
        basechain = nft_base_chain(chain);
-       if (strcmp(tablename, "nat") == 0 &&
-           basechain->type->type != NFT_CHAIN_T_NAT)
-               return -EINVAL;
+       if (strcmp(tablename, "nat") == 0) {
+               if (ctx->family != NFPROTO_BRIDGE)
+                       type = NFT_CHAIN_T_NAT;
+               if (basechain->type->type != type)
+                       return -EINVAL;
+       }
 
        return 0;
 }
@@ -342,8 +347,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
                if (target->hooks && !(hook_mask & target->hooks))
                        return -EINVAL;
 
-               ret = nft_compat_chain_validate_dependency(target->table,
-                                                          ctx->chain);
+               ret = nft_compat_chain_validate_dependency(ctx, target->table);
                if (ret < 0)
                        return ret;
        }
@@ -590,8 +594,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
                if (match->hooks && !(hook_mask & match->hooks))
                        return -EINVAL;
 
-               ret = nft_compat_chain_validate_dependency(match->table,
-                                                          ctx->chain);
+               ret = nft_compat_chain_validate_dependency(ctx, match->table);
                if (ret < 0)
                        return ret;
        }
index 649d1700ec5ba026307c46596112b6b3fb667255..3cc1b3dc3c3cdb2508cef7825f3bd9c485679fdb 100644 (file)
@@ -24,7 +24,6 @@ struct nft_ng_inc {
        u32                     modulus;
        atomic_t                counter;
        u32                     offset;
-       struct nft_set          *map;
 };
 
 static u32 nft_ng_inc_gen(struct nft_ng_inc *priv)
@@ -48,34 +47,11 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
        regs->data[priv->dreg] = nft_ng_inc_gen(priv);
 }
 
-static void nft_ng_inc_map_eval(const struct nft_expr *expr,
-                               struct nft_regs *regs,
-                               const struct nft_pktinfo *pkt)
-{
-       struct nft_ng_inc *priv = nft_expr_priv(expr);
-       const struct nft_set *map = priv->map;
-       const struct nft_set_ext *ext;
-       u32 result;
-       bool found;
-
-       result = nft_ng_inc_gen(priv);
-       found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
-
-       if (!found)
-               return;
-
-       nft_data_copy(&regs->data[priv->dreg],
-                     nft_set_ext_data(ext), map->dlen);
-}
-
 static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
        [NFTA_NG_DREG]          = { .type = NLA_U32 },
        [NFTA_NG_MODULUS]       = { .type = NLA_U32 },
        [NFTA_NG_TYPE]          = { .type = NLA_U32 },
        [NFTA_NG_OFFSET]        = { .type = NLA_U32 },
-       [NFTA_NG_SET_NAME]      = { .type = NLA_STRING,
-                                   .len = NFT_SET_MAXNAMELEN - 1 },
-       [NFTA_NG_SET_ID]        = { .type = NLA_U32 },
 };
 
 static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -101,22 +77,6 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
                                           NFT_DATA_VALUE, sizeof(u32));
 }
 
-static int nft_ng_inc_map_init(const struct nft_ctx *ctx,
-                              const struct nft_expr *expr,
-                              const struct nlattr * const tb[])
-{
-       struct nft_ng_inc *priv = nft_expr_priv(expr);
-       u8 genmask = nft_genmask_next(ctx->net);
-
-       nft_ng_inc_init(ctx, expr, tb);
-
-       priv->map = nft_set_lookup_global(ctx->net, ctx->table,
-                                         tb[NFTA_NG_SET_NAME],
-                                         tb[NFTA_NG_SET_ID], genmask);
-
-       return PTR_ERR_OR_ZERO(priv->map);
-}
-
 static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
                       u32 modulus, enum nft_ng_types type, u32 offset)
 {
@@ -143,27 +103,10 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr)
                           priv->offset);
 }
 
-static int nft_ng_inc_map_dump(struct sk_buff *skb,
-                              const struct nft_expr *expr)
-{
-       const struct nft_ng_inc *priv = nft_expr_priv(expr);
-
-       if (nft_ng_dump(skb, priv->dreg, priv->modulus,
-                       NFT_NG_INCREMENTAL, priv->offset) ||
-           nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
-               goto nla_put_failure;
-
-       return 0;
-
-nla_put_failure:
-       return -1;
-}
-
 struct nft_ng_random {
        enum nft_registers      dreg:8;
        u32                     modulus;
        u32                     offset;
-       struct nft_set          *map;
 };
 
 static u32 nft_ng_random_gen(struct nft_ng_random *priv)
@@ -183,25 +126,6 @@ static void nft_ng_random_eval(const struct nft_expr *expr,
        regs->data[priv->dreg] = nft_ng_random_gen(priv);
 }
 
-static void nft_ng_random_map_eval(const struct nft_expr *expr,
-                                  struct nft_regs *regs,
-                                  const struct nft_pktinfo *pkt)
-{
-       struct nft_ng_random *priv = nft_expr_priv(expr);
-       const struct nft_set *map = priv->map;
-       const struct nft_set_ext *ext;
-       u32 result;
-       bool found;
-
-       result = nft_ng_random_gen(priv);
-       found = map->ops->lookup(nft_net(pkt), map, &result, &ext);
-       if (!found)
-               return;
-
-       nft_data_copy(&regs->data[priv->dreg],
-                     nft_set_ext_data(ext), map->dlen);
-}
-
 static int nft_ng_random_init(const struct nft_ctx *ctx,
                              const struct nft_expr *expr,
                              const struct nlattr * const tb[])
@@ -226,21 +150,6 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
                                           NFT_DATA_VALUE, sizeof(u32));
 }
 
-static int nft_ng_random_map_init(const struct nft_ctx *ctx,
-                                 const struct nft_expr *expr,
-                                 const struct nlattr * const tb[])
-{
-       struct nft_ng_random *priv = nft_expr_priv(expr);
-       u8 genmask = nft_genmask_next(ctx->net);
-
-       nft_ng_random_init(ctx, expr, tb);
-       priv->map = nft_set_lookup_global(ctx->net, ctx->table,
-                                         tb[NFTA_NG_SET_NAME],
-                                         tb[NFTA_NG_SET_ID], genmask);
-
-       return PTR_ERR_OR_ZERO(priv->map);
-}
-
 static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
 {
        const struct nft_ng_random *priv = nft_expr_priv(expr);
@@ -249,22 +158,6 @@ static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
                           priv->offset);
 }
 
-static int nft_ng_random_map_dump(struct sk_buff *skb,
-                                 const struct nft_expr *expr)
-{
-       const struct nft_ng_random *priv = nft_expr_priv(expr);
-
-       if (nft_ng_dump(skb, priv->dreg, priv->modulus,
-                       NFT_NG_RANDOM, priv->offset) ||
-           nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
-               goto nla_put_failure;
-
-       return 0;
-
-nla_put_failure:
-       return -1;
-}
-
 static struct nft_expr_type nft_ng_type;
 static const struct nft_expr_ops nft_ng_inc_ops = {
        .type           = &nft_ng_type,
@@ -274,14 +167,6 @@ static const struct nft_expr_ops nft_ng_inc_ops = {
        .dump           = nft_ng_inc_dump,
 };
 
-static const struct nft_expr_ops nft_ng_inc_map_ops = {
-       .type           = &nft_ng_type,
-       .size           = NFT_EXPR_SIZE(sizeof(struct nft_ng_inc)),
-       .eval           = nft_ng_inc_map_eval,
-       .init           = nft_ng_inc_map_init,
-       .dump           = nft_ng_inc_map_dump,
-};
-
 static const struct nft_expr_ops nft_ng_random_ops = {
        .type           = &nft_ng_type,
        .size           = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
@@ -290,14 +175,6 @@ static const struct nft_expr_ops nft_ng_random_ops = {
        .dump           = nft_ng_random_dump,
 };
 
-static const struct nft_expr_ops nft_ng_random_map_ops = {
-       .type           = &nft_ng_type,
-       .size           = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
-       .eval           = nft_ng_random_map_eval,
-       .init           = nft_ng_random_map_init,
-       .dump           = nft_ng_random_map_dump,
-};
-
 static const struct nft_expr_ops *
 nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
 {
@@ -312,12 +189,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
 
        switch (type) {
        case NFT_NG_INCREMENTAL:
-               if (tb[NFTA_NG_SET_NAME])
-                       return &nft_ng_inc_map_ops;
                return &nft_ng_inc_ops;
        case NFT_NG_RANDOM:
-               if (tb[NFTA_NG_SET_NAME])
-                       return &nft_ng_random_map_ops;
                return &nft_ng_random_ops;
        }
 
index ca5e5d8c5ef8b91cd61cb039d652f4549c343948..b13618c764ec296377778ee405b9067515ada25a 100644 (file)
@@ -50,7 +50,7 @@ static int nft_osf_init(const struct nft_ctx *ctx,
        int err;
        u8 ttl;
 
-       if (nla_get_u8(tb[NFTA_OSF_TTL])) {
+       if (tb[NFTA_OSF_TTL]) {
                ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
                if (ttl > 2)
                        return -EINVAL;
index c6acfc2d9c8414d36173e3cf09f94ea64f0d7515..eb4cbd244c3d311e2630a4c4cae868f0343c30f0 100644 (file)
@@ -114,6 +114,22 @@ static void idletimer_tg_expired(struct timer_list *t)
        schedule_work(&timer->work);
 }
 
+static int idletimer_check_sysfs_name(const char *name, unsigned int size)
+{
+       int ret;
+
+       ret = xt_check_proc_name(name, size);
+       if (ret < 0)
+               return ret;
+
+       if (!strcmp(name, "power") ||
+           !strcmp(name, "subsystem") ||
+           !strcmp(name, "uevent"))
+               return -EINVAL;
+
+       return 0;
+}
+
 static int idletimer_tg_create(struct idletimer_tg_info *info)
 {
        int ret;
@@ -124,6 +140,10 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
                goto out;
        }
 
+       ret = idletimer_check_sysfs_name(info->label, sizeof(info->label));
+       if (ret < 0)
+               goto out_free_timer;
+
        sysfs_attr_init(&info->timer->attr.attr);
        info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL);
        if (!info->timer->attr.attr.name) {
index 6bec37ab4472796ecd1f453966b27bb911bf8fa8..a4660c48ff0149ad1798cd646d4edb2ed5c7770f 100644 (file)
@@ -1203,7 +1203,8 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
                                         &info->labels.mask);
                if (err)
                        return err;
-       } else if (labels_nonzero(&info->labels.mask)) {
+       } else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
+                  labels_nonzero(&info->labels.mask)) {
                err = ovs_ct_set_labels(ct, key, &info->labels.value,
                                        &info->labels.mask);
                if (err)
index 64362d078da846daead402d0f0a5b88bae04b223..a2522f9d71e266d338f1c0d223ce5bcb670fd00f 100644 (file)
@@ -375,16 +375,35 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call);
  * getting ACKs from the server.  Returns a number representing the life state
  * which can be compared to that returned by a previous call.
  *
- * If this is a client call, ping ACKs will be sent to the server to find out
- * whether it's still responsive and whether the call is still alive on the
- * server.
+ * If the life state stalls, rxrpc_kernel_probe_life() should be called and
+ * then 2RTT waited.
  */
-u32 rxrpc_kernel_check_life(struct socket *sock, struct rxrpc_call *call)
+u32 rxrpc_kernel_check_life(const struct socket *sock,
+                           const struct rxrpc_call *call)
 {
        return call->acks_latest;
 }
 EXPORT_SYMBOL(rxrpc_kernel_check_life);
 
+/**
+ * rxrpc_kernel_probe_life - Poke the peer to see if it's still alive
+ * @sock: The socket the call is on
+ * @call: The call to check
+ *
+ * In conjunction with rxrpc_kernel_check_life(), allow a kernel service to
+ * find out whether a call is still alive by pinging it.  This should cause the
+ * life state to be bumped in about 2*RTT.
+ *
+ * The must be called in TASK_RUNNING state on pain of might_sleep() objecting.
+ */
+void rxrpc_kernel_probe_life(struct socket *sock, struct rxrpc_call *call)
+{
+       rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false,
+                         rxrpc_propose_ack_ping_for_check_life);
+       rxrpc_send_ack_packet(call, true, NULL);
+}
+EXPORT_SYMBOL(rxrpc_kernel_probe_life);
+
 /**
  * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call.
  * @sock: The socket the call is on
index 382196e57a26c137f03fea19cb2ff5d8d69c728b..bc628acf4f4ffe7172e1be6591811e056ccb4f1b 100644 (file)
@@ -611,6 +611,7 @@ struct rxrpc_call {
                                                 * not hard-ACK'd packet follows this.
                                                 */
        rxrpc_seq_t             tx_top;         /* Highest Tx slot allocated. */
+       u16                     tx_backoff;     /* Delay to insert due to Tx failure */
 
        /* TCP-style slow-start congestion control [RFC5681].  Since the SMSS
         * is fixed, we keep these numbers in terms of segments (ie. DATA
index 8e7434e92097e8f0a2676bcf87df090daf43ee2e..468efc3660c03805608d5e4f2f146f007e03f9b1 100644 (file)
@@ -123,6 +123,7 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
                else
                        ack_at = expiry;
 
+               ack_at += READ_ONCE(call->tx_backoff);
                ack_at += now;
                if (time_before(ack_at, call->ack_at)) {
                        WRITE_ONCE(call->ack_at, ack_at);
@@ -311,6 +312,7 @@ void rxrpc_process_call(struct work_struct *work)
                container_of(work, struct rxrpc_call, processor);
        rxrpc_serial_t *send_ack;
        unsigned long now, next, t;
+       unsigned int iterations = 0;
 
        rxrpc_see_call(call);
 
@@ -319,6 +321,11 @@ void rxrpc_process_call(struct work_struct *work)
               call->debug_id, rxrpc_call_states[call->state], call->events);
 
 recheck_state:
+       /* Limit the number of times we do this before returning to the manager */
+       iterations++;
+       if (iterations > 5)
+               goto requeue;
+
        if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) {
                rxrpc_send_abort_packet(call);
                goto recheck_state;
@@ -447,13 +454,16 @@ recheck_state:
        rxrpc_reduce_call_timer(call, next, now, rxrpc_timer_restart);
 
        /* other events may have been raised since we started checking */
-       if (call->events && call->state < RXRPC_CALL_COMPLETE) {
-               __rxrpc_queue_call(call);
-               goto out;
-       }
+       if (call->events && call->state < RXRPC_CALL_COMPLETE)
+               goto requeue;
 
 out_put:
        rxrpc_put_call(call, rxrpc_call_put);
 out:
        _leave("");
+       return;
+
+requeue:
+       __rxrpc_queue_call(call);
+       goto out;
 }
index 1894188888391fca2ef98a5324de7bc99c4b381f..736aa92811004cfe5d157abd4827710783f8d57c 100644 (file)
@@ -34,6 +34,21 @@ struct rxrpc_abort_buffer {
 
 static const char rxrpc_keepalive_string[] = "";
 
+/*
+ * Increase Tx backoff on transmission failure and clear it on success.
+ */
+static void rxrpc_tx_backoff(struct rxrpc_call *call, int ret)
+{
+       if (ret < 0) {
+               u16 tx_backoff = READ_ONCE(call->tx_backoff);
+
+               if (tx_backoff < HZ)
+                       WRITE_ONCE(call->tx_backoff, tx_backoff + 1);
+       } else {
+               WRITE_ONCE(call->tx_backoff, 0);
+       }
+}
+
 /*
  * Arrange for a keepalive ping a certain time after we last transmitted.  This
  * lets the far side know we're still interested in this call and helps keep
@@ -210,6 +225,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
        else
                trace_rxrpc_tx_packet(call->debug_id, &pkt->whdr,
                                      rxrpc_tx_point_call_ack);
+       rxrpc_tx_backoff(call, ret);
 
        if (call->state < RXRPC_CALL_COMPLETE) {
                if (ret < 0) {
@@ -218,7 +234,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
                        rxrpc_propose_ACK(call, pkt->ack.reason,
                                          ntohs(pkt->ack.maxSkew),
                                          ntohl(pkt->ack.serial),
-                                         true, true,
+                                         false, true,
                                          rxrpc_propose_ack_retry_tx);
                } else {
                        spin_lock_bh(&call->lock);
@@ -300,7 +316,7 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
        else
                trace_rxrpc_tx_packet(call->debug_id, &pkt.whdr,
                                      rxrpc_tx_point_call_abort);
-
+       rxrpc_tx_backoff(call, ret);
 
        rxrpc_put_connection(conn);
        return ret;
@@ -413,6 +429,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
        else
                trace_rxrpc_tx_packet(call->debug_id, &whdr,
                                      rxrpc_tx_point_call_data_nofrag);
+       rxrpc_tx_backoff(call, ret);
        if (ret == -EMSGSIZE)
                goto send_fragmentable;
 
@@ -445,9 +462,18 @@ done:
                        rxrpc_reduce_call_timer(call, expect_rx_by, nowj,
                                                rxrpc_timer_set_for_normal);
                }
-       }
 
-       rxrpc_set_keepalive(call);
+               rxrpc_set_keepalive(call);
+       } else {
+               /* Cancel the call if the initial transmission fails,
+                * particularly if that's due to network routing issues that
+                * aren't going away anytime soon.  The layer above can arrange
+                * the retransmission.
+                */
+               if (!test_and_set_bit(RXRPC_CALL_BEGAN_RX_TIMER, &call->flags))
+                       rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR,
+                                                 RX_USER_ABORT, ret);
+       }
 
        _leave(" = %d [%u]", ret, call->peer->maxdata);
        return ret;
@@ -506,6 +532,7 @@ send_fragmentable:
        else
                trace_rxrpc_tx_packet(call->debug_id, &whdr,
                                      rxrpc_tx_point_call_data_frag);
+       rxrpc_tx_backoff(call, ret);
 
        up_write(&conn->params.local->defrag_sem);
        goto done;
index 1dae5f2b358fcf3dac2bbc0ef80f53b0dba16c91..c8cf4d10c4355f934c02d407ec725670e36433b8 100644 (file)
@@ -258,7 +258,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a,
        if (is_redirect) {
                skb2->tc_redirected = 1;
                skb2->tc_from_ingress = skb2->tc_at_ingress;
-
+               if (skb2->tc_from_ingress)
+                       skb2->tstamp = 0;
                /* let's the caller reinsert the packet, if possible */
                if (use_reinsert) {
                        res->ingress = want_ingress;
index da3dd0f68cc24d2c2b1828b43afc323a5786a3f8..2b372a06b432aec5b48209a3ac0e9424c9ae0b10 100644 (file)
@@ -201,7 +201,8 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
                        goto out_release;
                }
        } else {
-               return err;
+               ret = err;
+               goto out_free;
        }
 
        p = to_pedit(*a);
index 9aada2d0ef06567a962f5bb2e929370278e5a2af..c6c327874abcc9974adf2675c8326a967c6df6f6 100644 (file)
@@ -709,11 +709,23 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
                          struct netlink_ext_ack *extack)
 {
        const struct nlattr *nla_enc_key, *nla_opt_key, *nla_opt_msk = NULL;
-       int option_len, key_depth, msk_depth = 0;
+       int err, option_len, key_depth, msk_depth = 0;
+
+       err = nla_validate_nested(tb[TCA_FLOWER_KEY_ENC_OPTS],
+                                 TCA_FLOWER_KEY_ENC_OPTS_MAX,
+                                 enc_opts_policy, extack);
+       if (err)
+               return err;
 
        nla_enc_key = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS]);
 
        if (tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]) {
+               err = nla_validate_nested(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK],
+                                         TCA_FLOWER_KEY_ENC_OPTS_MAX,
+                                         enc_opts_policy, extack);
+               if (err)
+                       return err;
+
                nla_opt_msk = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
                msk_depth = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
        }
index 4b1af706896c07e5a0fe6d542dfcd530acdcf8f5..25a7cf6d380fd1ef5610a43a06dea488121b8206 100644 (file)
@@ -469,22 +469,29 @@ begin:
                goto begin;
        }
        prefetch(&skb->end);
-       f->credit -= qdisc_pkt_len(skb);
+       plen = qdisc_pkt_len(skb);
+       f->credit -= plen;
 
-       if (ktime_to_ns(skb->tstamp) || !q->rate_enable)
+       if (!q->rate_enable)
                goto out;
 
        rate = q->flow_max_rate;
-       if (skb->sk)
-               rate = min(skb->sk->sk_pacing_rate, rate);
-
-       if (rate <= q->low_rate_threshold) {
-               f->credit = 0;
-               plen = qdisc_pkt_len(skb);
-       } else {
-               plen = max(qdisc_pkt_len(skb), q->quantum);
-               if (f->credit > 0)
-                       goto out;
+
+       /* If EDT time was provided for this skb, we need to
+        * update f->time_next_packet only if this qdisc enforces
+        * a flow max rate.
+        */
+       if (!skb->tstamp) {
+               if (skb->sk)
+                       rate = min(skb->sk->sk_pacing_rate, rate);
+
+               if (rate <= q->low_rate_threshold) {
+                       f->credit = 0;
+               } else {
+                       plen = max(plen, q->quantum);
+                       if (f->credit > 0)
+                               goto out;
+               }
        }
        if (rate != ~0UL) {
                u64 len = (u64)plen * NSEC_PER_SEC;
index 57b3ad9394ad7a9f42c48d7645a61a6a03b2efe0..2c38e3d0792468162ee0dc4137f1400160ab9276 100644 (file)
@@ -648,15 +648,6 @@ deliver:
                         */
                        skb->dev = qdisc_dev(sch);
 
-#ifdef CONFIG_NET_CLS_ACT
-                       /*
-                        * If it's at ingress let's pretend the delay is
-                        * from the network (tstamp will be updated).
-                        */
-                       if (skb->tc_redirected && skb->tc_from_ingress)
-                               skb->tstamp = 0;
-#endif
-
                        if (q->slot.slot_next) {
                                q->slot.packets_left--;
                                q->slot.bytes_left -= qdisc_pkt_len(skb);
index 67939ad99c01335267c3cb21ade4b7dc3259f86f..b0e74a3e77ec507c87a54ecc10dbce1c6a7b554b 100644 (file)
@@ -118,6 +118,9 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
                sctp_transport_route(tp, NULL, sp);
                if (asoc->param_flags & SPP_PMTUD_ENABLE)
                        sctp_assoc_sync_pmtu(asoc);
+       } else if (!sctp_transport_pmtu_check(tp)) {
+               if (asoc->param_flags & SPP_PMTUD_ENABLE)
+                       sctp_assoc_sync_pmtu(asoc);
        }
 
        if (asoc->pmtu_pending) {
@@ -396,25 +399,6 @@ finish:
        return retval;
 }
 
-static void sctp_packet_release_owner(struct sk_buff *skb)
-{
-       sk_free(skb->sk);
-}
-
-static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
-{
-       skb_orphan(skb);
-       skb->sk = sk;
-       skb->destructor = sctp_packet_release_owner;
-
-       /*
-        * The data chunks have already been accounted for in sctp_sendmsg(),
-        * therefore only reserve a single byte to keep socket around until
-        * the packet has been transmitted.
-        */
-       refcount_inc(&sk->sk_wmem_alloc);
-}
-
 static void sctp_packet_gso_append(struct sk_buff *head, struct sk_buff *skb)
 {
        if (SCTP_OUTPUT_CB(head)->last == head)
@@ -601,7 +585,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
        if (!head)
                goto out;
        skb_reserve(head, packet->overhead + MAX_HEADER);
-       sctp_packet_set_owner_w(head, sk);
+       skb_set_owner_w(head, sk);
 
        /* set sctp header */
        sh = skb_push(head, sizeof(struct sctphdr));
index 9cb854b05342e57a6743ee1fd7e91cab7c09bbd2..c37e1c2dec9d451f5bfc8ffd8a0f8b9d00358316 100644 (file)
@@ -212,7 +212,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
        INIT_LIST_HEAD(&q->retransmit);
        INIT_LIST_HEAD(&q->sacked);
        INIT_LIST_HEAD(&q->abandoned);
-       sctp_sched_set_sched(asoc, SCTP_SS_FCFS);
+       sctp_sched_set_sched(asoc, SCTP_SS_DEFAULT);
 }
 
 /* Free the outqueue structure and any related pending chunks.
index 739f3e50120ddf61c508cc677b46e0239054131c..bf618d1b41fd20d0799726a4f3bc9081f4e48599 100644 (file)
@@ -3940,32 +3940,16 @@ static int sctp_setsockopt_pr_supported(struct sock *sk,
                                        unsigned int optlen)
 {
        struct sctp_assoc_value params;
-       struct sctp_association *asoc;
-       int retval = -EINVAL;
 
        if (optlen != sizeof(params))
-               goto out;
-
-       if (copy_from_user(&params, optval, optlen)) {
-               retval = -EFAULT;
-               goto out;
-       }
-
-       asoc = sctp_id2assoc(sk, params.assoc_id);
-       if (asoc) {
-               asoc->prsctp_enable = !!params.assoc_value;
-       } else if (!params.assoc_id) {
-               struct sctp_sock *sp = sctp_sk(sk);
+               return -EINVAL;
 
-               sp->ep->prsctp_enable = !!params.assoc_value;
-       } else {
-               goto out;
-       }
+       if (copy_from_user(&params, optval, optlen))
+               return -EFAULT;
 
-       retval = 0;
+       sctp_sk(sk)->ep->prsctp_enable = !!params.assoc_value;
 
-out:
-       return retval;
+       return 0;
 }
 
 static int sctp_setsockopt_default_prinfo(struct sock *sk,
index ffb940d3b57c1ca90dec8861b33da6d40f01824f..3892e7630f3adf6d42b57244b761c9e1aa558e95 100644 (file)
@@ -535,7 +535,6 @@ int sctp_send_add_streams(struct sctp_association *asoc,
                goto out;
        }
 
-       stream->incnt = incnt;
        stream->outcnt = outcnt;
 
        asoc->strreset_outstanding = !!out + !!in;
index 593826e11a5376bd1301b2cf19c61c377653c653..334fcc617ef2737acd0a84f7921e28a88771756f 100644 (file)
@@ -853,7 +853,7 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
        struct socket *sock = file->private_data;
 
        if (unlikely(!sock->ops->splice_read))
-               return -EINVAL;
+               return generic_file_splice_read(file, ppos, pipe, len, flags);
 
        return sock->ops->splice_read(sock, ppos, pipe, len, flags);
 }
index d8831b988b1e7a3273c73ee2457615b26c24b529..ab4a3be1542a0a6fcfb35153da1a62b3f852c2b6 100644 (file)
@@ -281,13 +281,7 @@ static bool generic_key_to_expire(struct rpc_cred *cred)
 {
        struct auth_cred *acred = &container_of(cred, struct generic_cred,
                                                gc_base)->acred;
-       bool ret;
-
-       get_rpccred(cred);
-       ret = test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
-       put_rpccred(cred);
-
-       return ret;
+       return test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
 }
 
 static const struct rpc_credops generic_credops = {
index 30f970cdc7f66375d45e5363dfa07cab233f4978..5d3f252659f191fe040452e6b55a862d850450e8 100644 (file)
@@ -1239,36 +1239,59 @@ gss_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
        return &gss_auth->rpc_auth;
 }
 
+static struct gss_cred *
+gss_dup_cred(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
+{
+       struct gss_cred *new;
+
+       /* Make a copy of the cred so that we can reference count it */
+       new = kzalloc(sizeof(*gss_cred), GFP_NOIO);
+       if (new) {
+               struct auth_cred acred = {
+                       .uid = gss_cred->gc_base.cr_uid,
+               };
+               struct gss_cl_ctx *ctx =
+                       rcu_dereference_protected(gss_cred->gc_ctx, 1);
+
+               rpcauth_init_cred(&new->gc_base, &acred,
+                               &gss_auth->rpc_auth,
+                               &gss_nullops);
+               new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
+               new->gc_service = gss_cred->gc_service;
+               new->gc_principal = gss_cred->gc_principal;
+               kref_get(&gss_auth->kref);
+               rcu_assign_pointer(new->gc_ctx, ctx);
+               gss_get_ctx(ctx);
+       }
+       return new;
+}
+
 /*
- * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
+ * gss_send_destroy_context will cause the RPCSEC_GSS to send a NULL RPC call
  * to the server with the GSS control procedure field set to
  * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
  * all RPCSEC_GSS state associated with that context.
  */
-static int
-gss_destroying_context(struct rpc_cred *cred)
+static void
+gss_send_destroy_context(struct rpc_cred *cred)
 {
        struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
        struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
        struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1);
+       struct gss_cred *new;
        struct rpc_task *task;
 
-       if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
-               return 0;
-
-       ctx->gc_proc = RPC_GSS_PROC_DESTROY;
-       cred->cr_ops = &gss_nullops;
-
-       /* Take a reference to ensure the cred will be destroyed either
-        * by the RPC call or by the put_rpccred() below */
-       get_rpccred(cred);
+       new = gss_dup_cred(gss_auth, gss_cred);
+       if (new) {
+               ctx->gc_proc = RPC_GSS_PROC_DESTROY;
 
-       task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
-       if (!IS_ERR(task))
-               rpc_put_task(task);
+               task = rpc_call_null(gss_auth->client, &new->gc_base,
+                               RPC_TASK_ASYNC|RPC_TASK_SOFT);
+               if (!IS_ERR(task))
+                       rpc_put_task(task);
 
-       put_rpccred(cred);
-       return 1;
+               put_rpccred(&new->gc_base);
+       }
 }
 
 /* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
@@ -1330,8 +1353,8 @@ static void
 gss_destroy_cred(struct rpc_cred *cred)
 {
 
-       if (gss_destroying_context(cred))
-               return;
+       if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0)
+               gss_send_destroy_context(cred);
        gss_destroy_nullcred(cred);
 }
 
index 2bbb8d38d2bf5f6eeb87a5771aeb92683d25543f..f302c6eb8779063a71b9a590325a96b8026ab3e6 100644 (file)
@@ -546,7 +546,7 @@ EXPORT_SYMBOL_GPL(xdr_commit_encode);
 static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
                size_t nbytes)
 {
-       static __be32 *p;
+       __be32 *p;
        int space_left;
        int frag1bytes, frag2bytes;
 
@@ -673,11 +673,10 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
                WARN_ON_ONCE(xdr->iov);
                return;
        }
-       if (fraglen) {
+       if (fraglen)
                xdr->end = head->iov_base + head->iov_len;
-               xdr->page_ptr--;
-       }
        /* (otherwise assume xdr->end is already set) */
+       xdr->page_ptr--;
        head->iov_len = len;
        buf->len = len;
        xdr->p = head->iov_base + head->iov_len;
index 2830709957bddeb13adf0f352abb9aaacba3ec55..c138d68e8a695fde8fb1464f03a539cef5a03bd4 100644 (file)
@@ -166,7 +166,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
 
        /* Apply trial address if we just left trial period */
        if (!trial && !self) {
-               tipc_net_finalize(net, tn->trial_addr);
+               tipc_sched_net_finalize(net, tn->trial_addr);
+               msg_set_prevnode(buf_msg(d->skb), tn->trial_addr);
                msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
        }
 
@@ -300,14 +301,12 @@ static void tipc_disc_timeout(struct timer_list *t)
                goto exit;
        }
 
-       /* Trial period over ? */
-       if (!time_before(jiffies, tn->addr_trial_end)) {
-               /* Did we just leave it ? */
-               if (!tipc_own_addr(net))
-                       tipc_net_finalize(net, tn->trial_addr);
-
-               msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
-               msg_set_prevnode(buf_msg(d->skb), tipc_own_addr(net));
+       /* Did we just leave trial period ? */
+       if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) {
+               mod_timer(&d->timer, jiffies + TIPC_DISC_INIT);
+               spin_unlock_bh(&d->lock);
+               tipc_sched_net_finalize(net, tn->trial_addr);
+               return;
        }
 
        /* Adjust timeout interval according to discovery phase */
@@ -319,6 +318,8 @@ static void tipc_disc_timeout(struct timer_list *t)
                        d->timer_intv = TIPC_DISC_SLOW;
                else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST)
                        d->timer_intv = TIPC_DISC_FAST;
+               msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
+               msg_set_prevnode(buf_msg(d->skb), tn->trial_addr);
        }
 
        mod_timer(&d->timer, jiffies + d->timer_intv);
index 201c3b5bc96be9fb412dbc60522b1513d2494a8f..836727e363c46290ab8ef55e9d7b630f1dfac293 100644 (file)
@@ -1594,14 +1594,17 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
                if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI))
                        l->priority = peers_prio;
 
-               /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
-               if (msg_peer_stopping(hdr))
+               /* If peer is going down we want full re-establish cycle */
+               if (msg_peer_stopping(hdr)) {
                        rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
-               else if ((mtyp == RESET_MSG) || !link_is_up(l))
+                       break;
+               }
+               /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
+               if (mtyp == RESET_MSG || !link_is_up(l))
                        rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT);
 
                /* ACTIVATE_MSG takes up link if it was already locally reset */
-               if ((mtyp == ACTIVATE_MSG) && (l->state == LINK_ESTABLISHING))
+               if (mtyp == ACTIVATE_MSG && l->state == LINK_ESTABLISHING)
                        rc = TIPC_LINK_UP_EVT;
 
                l->peer_session = msg_session(hdr);
index 62199cf5a56c04db99af54dad9fc2564df8d6b05..f076edb74338247f0bad99cfaa5d23e5b14730ab 100644 (file)
  *     - A local spin_lock protecting the queue of subscriber events.
 */
 
+struct tipc_net_work {
+       struct work_struct work;
+       struct net *net;
+       u32 addr;
+};
+
+static void tipc_net_finalize(struct net *net, u32 addr);
+
 int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
 {
        if (tipc_own_id(net)) {
@@ -119,17 +127,38 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
        return 0;
 }
 
-void tipc_net_finalize(struct net *net, u32 addr)
+static void tipc_net_finalize(struct net *net, u32 addr)
 {
        struct tipc_net *tn = tipc_net(net);
 
-       if (!cmpxchg(&tn->node_addr, 0, addr)) {
-               tipc_set_node_addr(net, addr);
-               tipc_named_reinit(net);
-               tipc_sk_reinit(net);
-               tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
-                                    TIPC_CLUSTER_SCOPE, 0, addr);
-       }
+       if (cmpxchg(&tn->node_addr, 0, addr))
+               return;
+       tipc_set_node_addr(net, addr);
+       tipc_named_reinit(net);
+       tipc_sk_reinit(net);
+       tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
+                            TIPC_CLUSTER_SCOPE, 0, addr);
+}
+
+static void tipc_net_finalize_work(struct work_struct *work)
+{
+       struct tipc_net_work *fwork;
+
+       fwork = container_of(work, struct tipc_net_work, work);
+       tipc_net_finalize(fwork->net, fwork->addr);
+       kfree(fwork);
+}
+
+void tipc_sched_net_finalize(struct net *net, u32 addr)
+{
+       struct tipc_net_work *fwork = kzalloc(sizeof(*fwork), GFP_ATOMIC);
+
+       if (!fwork)
+               return;
+       INIT_WORK(&fwork->work, tipc_net_finalize_work);
+       fwork->net = net;
+       fwork->addr = addr;
+       schedule_work(&fwork->work);
 }
 
 void tipc_net_stop(struct net *net)
index 09ad02b50bb1ba1e9798c41810c843d74b5e0185..b7f2e364eb99e774854ea22837107991619ef00a 100644 (file)
@@ -42,7 +42,7 @@
 extern const struct nla_policy tipc_nl_net_policy[];
 
 int tipc_net_init(struct net *net, u8 *node_id, u32 addr);
-void tipc_net_finalize(struct net *net, u32 addr);
+void tipc_sched_net_finalize(struct net *net, u32 addr);
 void tipc_net_stop(struct net *net);
 int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
index 636e6131769d83f9b5f7013a32210ec809835fb2..b57b1be7252baef2f6410710e225864877c08ac1 100644 (file)
@@ -1555,16 +1555,17 @@ static void tipc_sk_set_orig_addr(struct msghdr *m, struct sk_buff *skb)
 /**
  * tipc_sk_anc_data_recv - optionally capture ancillary data for received message
  * @m: descriptor for message info
- * @msg: received message header
+ * @skb: received message buffer
  * @tsk: TIPC port associated with message
  *
  * Note: Ancillary data is not captured if not requested by receiver.
  *
  * Returns 0 if successful, otherwise errno
  */
-static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
+static int tipc_sk_anc_data_recv(struct msghdr *m, struct sk_buff *skb,
                                 struct tipc_sock *tsk)
 {
+       struct tipc_msg *msg;
        u32 anc_data[3];
        u32 err;
        u32 dest_type;
@@ -1573,6 +1574,7 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
 
        if (likely(m->msg_controllen == 0))
                return 0;
+       msg = buf_msg(skb);
 
        /* Optionally capture errored message object(s) */
        err = msg ? msg_errcode(msg) : 0;
@@ -1583,6 +1585,9 @@ static int tipc_sk_anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
                if (res)
                        return res;
                if (anc_data[1]) {
+                       if (skb_linearize(skb))
+                               return -ENOMEM;
+                       msg = buf_msg(skb);
                        res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
                                       msg_data(msg));
                        if (res)
@@ -1744,9 +1749,10 @@ static int tipc_recvmsg(struct socket *sock, struct msghdr *m,
 
        /* Collect msg meta data, including error code and rejected data */
        tipc_sk_set_orig_addr(m, skb);
-       rc = tipc_sk_anc_data_recv(m, hdr, tsk);
+       rc = tipc_sk_anc_data_recv(m, skb, tsk);
        if (unlikely(rc))
                goto exit;
+       hdr = buf_msg(skb);
 
        /* Capture data if non-error msg, otherwise just set return value */
        if (likely(!err)) {
@@ -1856,9 +1862,10 @@ static int tipc_recvstream(struct socket *sock, struct msghdr *m,
                /* Collect msg meta data, incl. error code and rejected data */
                if (!copied) {
                        tipc_sk_set_orig_addr(m, skb);
-                       rc = tipc_sk_anc_data_recv(m, hdr, tsk);
+                       rc = tipc_sk_anc_data_recv(m, skb, tsk);
                        if (rc)
                                break;
+                       hdr = buf_msg(skb);
                }
 
                /* Copy data if msg ok, otherwise return error/partial data */
index a0149db00be752555ff4178f66540543a5835955..6c6439f69a725f4bd46210fb3bb2c3e80a49fab2 100755 (executable)
@@ -71,7 +71,7 @@ die() {
 
 # Try to figure out the source directory prefix so we can remove it from the
 # addr2line output.  HACK ALERT: This assumes that start_kernel() is in
-# kernel/init.c!  This only works for vmlinux.  Otherwise it falls back to
+# init/main.c!  This only works for vmlinux.  Otherwise it falls back to
 # printing the absolute path.
 find_dir_prefix() {
        local objfile=$1
index da66e7742282a65eb8457d3427b5bfab7f950415..0ef906499646b57293bb85dea54234c601bfcafa 100755 (executable)
@@ -102,7 +102,8 @@ if [ ! -r "$INITFILE" ]; then
 fi
 
 MERGE_LIST=$*
-SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)[= ].*/\2/p"
+SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p"
+SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p"
 
 TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
 
@@ -116,7 +117,7 @@ for MERGE_FILE in $MERGE_LIST ; do
                echo "The merge file '$MERGE_FILE' does not exist.  Exit." >&2
                exit 1
        fi
-       CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE)
+       CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE)
 
        for CFG in $CFG_LIST ; do
                grep -q -w $CFG $TMP_FILE || continue
@@ -159,7 +160,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
 
 
 # Check all specified config values took (might have missed-dependency issues)
-for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
+for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do
 
        REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
        ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
index 90c9a8ac7adb81d9dc10d0cb00eda86ee3a35a8f..f43a274f4f1d5b820c00826d939b20d325b2311f 100755 (executable)
@@ -81,11 +81,11 @@ else
        cp System.map "$tmpdir/boot/System.map-$version"
        cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version"
 fi
-cp "$($MAKE -s image_name)" "$tmpdir/$installed_image_path"
+cp "$($MAKE -s -f $srctree/Makefile image_name)" "$tmpdir/$installed_image_path"
 
-if grep -q "^CONFIG_OF=y" $KCONFIG_CONFIG ; then
+if grep -q "^CONFIG_OF_EARLY_FLATTREE=y" $KCONFIG_CONFIG ; then
        # Only some architectures with OF support have this target
-       if grep -q dtbs_install "${srctree}/arch/$SRCARCH/Makefile"; then
+       if [ -d "${srctree}/arch/$SRCARCH/boot/dts" ]; then
                $MAKE KBUILD_SRC= INSTALL_DTBS_PATH="$tmpdir/usr/lib/$packagename" dtbs_install
        fi
 fi
index 663a7f343b42c5417e4769a8da65754fd6eab859..edcad61fe3cdae66b8e8fe497f7f52329591ee0a 100755 (executable)
@@ -88,6 +88,7 @@ set_debarch() {
 version=$KERNELRELEASE
 if [ -n "$KDEB_PKGVERSION" ]; then
        packageversion=$KDEB_PKGVERSION
+       revision=${packageversion##*-}
 else
        revision=$(cat .version 2>/dev/null||echo 1)
        packageversion=$version-$revision
@@ -205,10 +206,12 @@ cat <<EOF > debian/rules
 #!$(command -v $MAKE) -f
 
 build:
-       \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} KBUILD_SRC=
+       \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \
+       KBUILD_BUILD_VERSION=${revision} KBUILD_SRC=
 
 binary-arch:
-       \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} KBUILD_SRC= intdeb-pkg
+       \$(MAKE) KERNELRELEASE=${version} ARCH=${ARCH} \
+       KBUILD_BUILD_VERSION=${revision} KBUILD_SRC= intdeb-pkg
 
 clean:
        rm -rf debian/*tmp debian/files
index e05646dc24dcf633830ce6d8dd3da5f71a29731e..009147d4718eeead8117413a8bdf95108c84e4dd 100755 (executable)
@@ -12,6 +12,7 @@
 # how we were called determines which rpms we build and how we build them
 if [ "$1" = prebuilt ]; then
        S=DEL
+       MAKE="$MAKE -f $srctree/Makefile"
 else
        S=
 fi
@@ -78,19 +79,19 @@ $S  %prep
 $S     %setup -q
 $S
 $S     %build
-$S     make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}
+$S     $MAKE %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}
 $S
        %install
        mkdir -p %{buildroot}/boot
        %ifarch ia64
        mkdir -p %{buildroot}/boot/efi
-       cp \$(make image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
+       cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
        ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/
        %else
-       cp \$(make image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
+       cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
        %endif
-$M     make %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} KBUILD_SRC= modules_install
-       make %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr KBUILD_SRC= headers_install
+$M     $MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install
+       $MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
        cp System.map %{buildroot}/boot/System.map-$KERNELRELEASE
        cp .config %{buildroot}/boot/config-$KERNELRELEASE
        bzip2 -9 --keep vmlinux
index 79f7dd57d571e749dc3e36ed95a473cd599e0056..71f39410691b6be14774102000507c834c8ad493 100755 (executable)
@@ -74,7 +74,7 @@ scm_version()
                fi
 
                # Check for uncommitted changes
-               if git status -uno --porcelain | grep -qv '^.. scripts/package'; then
+               if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then
                        printf '%s' -dirty
                fi
 
index 839e190bbd7a0075ef28040291fca87f44d3170a..5056fb3b897d0094e182bba4fca08ae491dab7cc 100755 (executable)
@@ -168,7 +168,6 @@ class id_parser(object):
         self.curline = 0
         try:
             for line in fd:
-                line = line.decode(locale.getpreferredencoding(False), errors='ignore')
                 self.curline += 1
                 if self.curline > maxlines:
                     break
index 6dc0751445087727f9d1b09a8c1efdbbc9105625..d775e03fbbcc7d87b9724529a4499b9449a9aa46 100644 (file)
@@ -106,6 +106,7 @@ int asymmetric_verify(struct key *keyring, const char *sig,
 
        pks.pkey_algo = "rsa";
        pks.hash_algo = hash_algo_name[hdr->hash_algo];
+       pks.encoding = "pkcs1";
        pks.digest = (u8 *)data;
        pks.digest_size = datalen;
        pks.s = hdr->sig;
index 7ce683259357750cdfd25feb978ee1d6a984312b..a67459eb62d5c8d3066a72c354f13894f68be8ae 100644 (file)
@@ -5318,6 +5318,9 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
        addr_buf = address;
 
        while (walk_size < addrlen) {
+               if (walk_size + sizeof(sa_family_t) > addrlen)
+                       return -EINVAL;
+
                addr = addr_buf;
                switch (addr->sa_family) {
                case AF_UNSPEC:
index 2fe459df3c858dc038e2a5e5f851ee4a0f07fafa..b7efa2296969c617dc292759b61c3c6f1ca450a5 100644 (file)
@@ -245,9 +245,13 @@ int mls_context_to_sid(struct policydb *pol,
        char *rangep[2];
 
        if (!pol->mls_enabled) {
-               if ((def_sid != SECSID_NULL && oldc) || (*scontext) == '\0')
-                       return 0;
-               return -EINVAL;
+               /*
+                * With no MLS, only return -EINVAL if there is a MLS field
+                * and it did not come from an xattr.
+                */
+               if (oldc && def_sid == SECSID_NULL)
+                       return -EINVAL;
+               return 0;
        }
 
        /*
index 97f49b751e6eb3583c948e7e35c0ddc8860cc818..568575b72f2f7269c727a202f6544b6f51a57d03 100644 (file)
@@ -58,8 +58,8 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
                        removefunc = false;
                }
                if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 &&
-                   snd_hda_gen_add_micmute_led(codec,
-                                               update_tpacpi_micmute) > 0)
+                   !snd_hda_gen_add_micmute_led(codec,
+                                                update_tpacpi_micmute))
                        removefunc = false;
        }
 
index 12835ea0e4173c281e5ddfe0883595492e985b09..378c051fa1776534b0e1fca7e56567f9f8a3d2d4 100644 (file)
 #define wmb()          asm volatile("dmb ishst" ::: "memory")
 #define rmb()          asm volatile("dmb ishld" ::: "memory")
 
-#define smp_store_release(p, v)                                        \
-do {                                                           \
-       union { typeof(*p) __val; char __c[1]; } __u =          \
-               { .__val = (__force typeof(*p)) (v) };          \
-                                                               \
-       switch (sizeof(*p)) {                                   \
-       case 1:                                                 \
-               asm volatile ("stlrb %w1, %0"                   \
-                               : "=Q" (*p)                     \
-                               : "r" (*(__u8 *)__u.__c)        \
-                               : "memory");                    \
-               break;                                          \
-       case 2:                                                 \
-               asm volatile ("stlrh %w1, %0"                   \
-                               : "=Q" (*p)                     \
-                               : "r" (*(__u16 *)__u.__c)       \
-                               : "memory");                    \
-               break;                                          \
-       case 4:                                                 \
-               asm volatile ("stlr %w1, %0"                    \
-                               : "=Q" (*p)                     \
-                               : "r" (*(__u32 *)__u.__c)       \
-                               : "memory");                    \
-               break;                                          \
-       case 8:                                                 \
-               asm volatile ("stlr %1, %0"                     \
-                               : "=Q" (*p)                     \
-                               : "r" (*(__u64 *)__u.__c)       \
-                               : "memory");                    \
-               break;                                          \
-       default:                                                \
-               /* Only to shut up gcc ... */                   \
-               mb();                                           \
-               break;                                          \
-       }                                                       \
+#define smp_store_release(p, v)                                                \
+do {                                                                   \
+       union { typeof(*p) __val; char __c[1]; } __u =                  \
+               { .__val = (v) };                                       \
+                                                                       \
+       switch (sizeof(*p)) {                                           \
+       case 1:                                                         \
+               asm volatile ("stlrb %w1, %0"                           \
+                               : "=Q" (*p)                             \
+                               : "r" (*(__u8_alias_t *)__u.__c)        \
+                               : "memory");                            \
+               break;                                                  \
+       case 2:                                                         \
+               asm volatile ("stlrh %w1, %0"                           \
+                               : "=Q" (*p)                             \
+                               : "r" (*(__u16_alias_t *)__u.__c)       \
+                               : "memory");                            \
+               break;                                                  \
+       case 4:                                                         \
+               asm volatile ("stlr %w1, %0"                            \
+                               : "=Q" (*p)                             \
+                               : "r" (*(__u32_alias_t *)__u.__c)       \
+                               : "memory");                            \
+               break;                                                  \
+       case 8:                                                         \
+               asm volatile ("stlr %1, %0"                             \
+                               : "=Q" (*p)                             \
+                               : "r" (*(__u64_alias_t *)__u.__c)       \
+                               : "memory");                            \
+               break;                                                  \
+       default:                                                        \
+               /* Only to shut up gcc ... */                           \
+               mb();                                                   \
+               break;                                                  \
+       }                                                               \
 } while (0)
 
-#define smp_load_acquire(p)                                    \
-({                                                             \
-       union { typeof(*p) __val; char __c[1]; } __u;           \
-                                                               \
-       switch (sizeof(*p)) {                                   \
-       case 1:                                                 \
-               asm volatile ("ldarb %w0, %1"                   \
-                       : "=r" (*(__u8 *)__u.__c)               \
-                       : "Q" (*p) : "memory");                 \
-               break;                                          \
-       case 2:                                                 \
-               asm volatile ("ldarh %w0, %1"                   \
-                       : "=r" (*(__u16 *)__u.__c)              \
-                       : "Q" (*p) : "memory");                 \
-               break;                                          \
-       case 4:                                                 \
-               asm volatile ("ldar %w0, %1"                    \
-                       : "=r" (*(__u32 *)__u.__c)              \
-                       : "Q" (*p) : "memory");                 \
-               break;                                          \
-       case 8:                                                 \
-               asm volatile ("ldar %0, %1"                     \
-                       : "=r" (*(__u64 *)__u.__c)              \
-                       : "Q" (*p) : "memory");                 \
-               break;                                          \
-       default:                                                \
-               /* Only to shut up gcc ... */                   \
-               mb();                                           \
-               break;                                          \
-       }                                                       \
-       __u.__val;                                              \
+#define smp_load_acquire(p)                                            \
+({                                                                     \
+       union { typeof(*p) __val; char __c[1]; } __u =                  \
+               { .__c = { 0 } };                                       \
+                                                                       \
+       switch (sizeof(*p)) {                                           \
+       case 1:                                                         \
+               asm volatile ("ldarb %w0, %1"                           \
+                       : "=r" (*(__u8_alias_t *)__u.__c)               \
+                       : "Q" (*p) : "memory");                         \
+               break;                                                  \
+       case 2:                                                         \
+               asm volatile ("ldarh %w0, %1"                           \
+                       : "=r" (*(__u16_alias_t *)__u.__c)              \
+                       : "Q" (*p) : "memory");                         \
+               break;                                                  \
+       case 4:                                                         \
+               asm volatile ("ldar %w0, %1"                            \
+                       : "=r" (*(__u32_alias_t *)__u.__c)              \
+                       : "Q" (*p) : "memory");                         \
+               break;                                                  \
+       case 8:                                                         \
+               asm volatile ("ldar %0, %1"                             \
+                       : "=r" (*(__u64_alias_t *)__u.__c)              \
+                       : "Q" (*p) : "memory");                         \
+               break;                                                  \
+       default:                                                        \
+               /* Only to shut up gcc ... */                           \
+               mb();                                                   \
+               break;                                                  \
+       }                                                               \
+       __u.__val;                                                      \
 })
 
 #endif /* _TOOLS_LINUX_ASM_AARCH64_BARRIER_H */
index 236b9b97dfdb1d5d52d6cc9dcb9198cfd2ec1739..667c14e56031b5c3ac91c291aed3c876644d1247 100644 (file)
@@ -55,7 +55,6 @@ counted. The following modifiers exist:
  S - read sample value (PERF_SAMPLE_READ)
  D - pin the event to the PMU
  W - group is weak and will fallback to non-group if not schedulable,
-     only supported in 'perf stat' for now.
 
 The 'p' modifier can be used for specifying how precise the instruction
 address should be. The 'p' modifier can be specified multiple times:
index 3ccb4f0bf0883cd80a8b33f612c649e84aaec126..d95655489f7e17adcd16dcca6a772875f6d1c6b2 100644 (file)
@@ -387,7 +387,7 @@ SHELL = $(SHELL_PATH)
 
 linux_uapi_dir := $(srctree)/tools/include/uapi/linux
 asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic
-arch_asm_uapi_dir := $(srctree)/tools/arch/$(ARCH)/include/uapi/asm/
+arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/
 
 beauty_outdir := $(OUTPUT)trace/beauty/generated
 beauty_ioctl_outdir := $(beauty_outdir)/ioctl
index 10cf889c6d75d2db1d78014215e30948ae3b1cb4..488779bc4c8d2f6ed8dbcad69e1de5e477ede138 100644 (file)
@@ -391,7 +391,12 @@ try_again:
                                        ui__warning("%s\n", msg);
                                goto try_again;
                        }
-
+                       if ((errno == EINVAL || errno == EBADF) &&
+                           pos->leader != pos &&
+                           pos->weak_group) {
+                               pos = perf_evlist__reset_weak_group(evlist, pos);
+                               goto try_again;
+                       }
                        rc = -errno;
                        perf_evsel__open_strerror(pos, &opts->target,
                                                  errno, msg, sizeof(msg));
index d1028d7755bbcb946a517c333a3757d91e75c8ed..a635abfa77b6a9e38fa7aa994ea4cfd31608f16a 100644 (file)
@@ -383,32 +383,6 @@ static bool perf_evsel__should_store_id(struct perf_evsel *counter)
        return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
 }
 
-static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
-{
-       struct perf_evsel *c2, *leader;
-       bool is_open = true;
-
-       leader = evsel->leader;
-       pr_debug("Weak group for %s/%d failed\n",
-                       leader->name, leader->nr_members);
-
-       /*
-        * for_each_group_member doesn't work here because it doesn't
-        * include the first entry.
-        */
-       evlist__for_each_entry(evsel_list, c2) {
-               if (c2 == evsel)
-                       is_open = false;
-               if (c2->leader == leader) {
-                       if (is_open)
-                               perf_evsel__close(c2);
-                       c2->leader = c2;
-                       c2->nr_members = 0;
-               }
-       }
-       return leader;
-}
-
 static bool is_target_alive(struct target *_target,
                            struct thread_map *threads)
 {
@@ -477,7 +451,7 @@ try_again:
                        if ((errno == EINVAL || errno == EBADF) &&
                            counter->leader != counter &&
                            counter->weak_group) {
-                               counter = perf_evsel__reset_weak_group(counter);
+                               counter = perf_evlist__reset_weak_group(evsel_list, counter);
                                goto try_again;
                        }
 
index b2838de13de02e29f6ad766eb8de11ec27bfa31b..aa0c73e5792404355c5e8c2de048ff8e5da18e39 100644 (file)
@@ -1429,6 +1429,9 @@ int cmd_top(int argc, const char **argv)
                }
        }
 
+       if (opts->branch_stack && callchain_param.enabled)
+               symbol_conf.show_branchflag_count = true;
+
        sort__mode = SORT_MODE__TOP;
        /* display thread wants entries to be collapsed in a different tree */
        perf_hpp_list.need_collapse = 1;
index dc8a6c4986ce2066b0e76cd58e0edb2f7f09852a..835619476370cc0ae1d43bae705597f819a4c732 100644 (file)
@@ -108,6 +108,7 @@ struct trace {
        } stats;
        unsigned int            max_stack;
        unsigned int            min_stack;
+       bool                    raw_augmented_syscalls;
        bool                    not_ev_qualifier;
        bool                    live;
        bool                    full_time;
@@ -1724,13 +1725,28 @@ static int trace__fprintf_sample(struct trace *trace, struct perf_evsel *evsel,
        return printed;
 }
 
-static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sample, int *augmented_args_size)
+static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sample, int *augmented_args_size, bool raw_augmented)
 {
        void *augmented_args = NULL;
+       /*
+        * For now with BPF raw_augmented we hook into raw_syscalls:sys_enter
+        * and there we get all 6 syscall args plus the tracepoint common
+        * fields (sizeof(long)) and the syscall_nr (another long). So we check
+        * if that is the case and if so don't look after the sc->args_size,
+        * but always after the full raw_syscalls:sys_enter payload, which is
+        * fixed.
+        *
+        * We'll revisit this later to pass s->args_size to the BPF augmenter
+        * (now tools/perf/examples/bpf/augmented_raw_syscalls.c, so that it
+        * copies only what we need for each syscall, like what happens when we
+        * use syscalls:sys_enter_NAME, so that we reduce the kernel/userspace
+        * traffic to just what is needed for each syscall.
+        */
+       int args_size = raw_augmented ? (8 * (int)sizeof(long)) : sc->args_size;
 
-       *augmented_args_size = sample->raw_size - sc->args_size;
+       *augmented_args_size = sample->raw_size - args_size;
        if (*augmented_args_size > 0)
-               augmented_args = sample->raw_data + sc->args_size;
+               augmented_args = sample->raw_data + args_size;
 
        return augmented_args;
 }
@@ -1780,7 +1796,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
         * here and avoid using augmented syscalls when the evsel is the raw_syscalls one.
         */
        if (evsel != trace->syscalls.events.sys_enter)
-               augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size);
+               augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls);
        ttrace->entry_time = sample->time;
        msg = ttrace->entry_str;
        printed += scnprintf(msg + printed, trace__entry_str_size - printed, "%s(", sc->name);
@@ -1833,7 +1849,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct perf_evsel *evse
                goto out_put;
 
        args = perf_evsel__sc_tp_ptr(evsel, args, sample);
-       augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size);
+       augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls);
        syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread);
        fprintf(trace->output, "%s", msg);
        err = 0;
@@ -3501,7 +3517,15 @@ int cmd_trace(int argc, const char **argv)
                evsel->handler = trace__sys_enter;
 
                evlist__for_each_entry(trace.evlist, evsel) {
+                       bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0;
+
+                       if (raw_syscalls_sys_exit) {
+                               trace.raw_augmented_syscalls = true;
+                               goto init_augmented_syscall_tp;
+                       }
+
                        if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) {
+init_augmented_syscall_tp:
                                perf_evsel__init_augmented_syscall_tp(evsel);
                                perf_evsel__init_augmented_syscall_tp_ret(evsel);
                                evsel->handler = trace__sys_exit;
diff --git a/tools/perf/examples/bpf/augmented_raw_syscalls.c b/tools/perf/examples/bpf/augmented_raw_syscalls.c
new file mode 100644 (file)
index 0000000..90a1933
--- /dev/null
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Augment the raw_syscalls tracepoints with the contents of the pointer arguments.
+ *
+ * Test it with:
+ *
+ * perf trace -e tools/perf/examples/bpf/augmented_raw_syscalls.c cat /etc/passwd > /dev/null
+ *
+ * This exactly matches what is marshalled into the raw_syscall:sys_enter
+ * payload expected by the 'perf trace' beautifiers.
+ *
+ * For now it just uses the existing tracepoint augmentation code in 'perf
+ * trace', in the next csets we'll hook up these with the sys_enter/sys_exit
+ * code that will combine entry/exit in a strace like way.
+ */
+
+#include <stdio.h>
+#include <linux/socket.h>
+
+/* bpf-output associated map */
+struct bpf_map SEC("maps") __augmented_syscalls__ = {
+       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(u32),
+       .max_entries = __NR_CPUS__,
+};
+
+struct syscall_enter_args {
+       unsigned long long common_tp_fields;
+       long               syscall_nr;
+       unsigned long      args[6];
+};
+
+struct syscall_exit_args {
+       unsigned long long common_tp_fields;
+       long               syscall_nr;
+       long               ret;
+};
+
+struct augmented_filename {
+       unsigned int    size;
+       int             reserved;
+       char            value[256];
+};
+
+#define SYS_OPEN 2
+#define SYS_OPENAT 257
+
+SEC("raw_syscalls:sys_enter")
+int sys_enter(struct syscall_enter_args *args)
+{
+       struct {
+               struct syscall_enter_args args;
+               struct augmented_filename filename;
+       } augmented_args;
+       unsigned int len = sizeof(augmented_args);
+       const void *filename_arg = NULL;
+
+       probe_read(&augmented_args.args, sizeof(augmented_args.args), args);
+       /*
+        * Yonghong and Edward Cree sayz:
+        *
+        * https://www.spinics.net/lists/netdev/msg531645.html
+        *
+        * >>   R0=inv(id=0) R1=inv2 R6=ctx(id=0,off=0,imm=0) R7=inv64 R10=fp0,call_-1
+        * >> 10: (bf) r1 = r6
+        * >> 11: (07) r1 += 16
+        * >> 12: (05) goto pc+2
+        * >> 15: (79) r3 = *(u64 *)(r1 +0)
+        * >> dereference of modified ctx ptr R1 off=16 disallowed
+        * > Aha, we at least got a different error message this time.
+        * > And indeed llvm has done that optimisation, rather than the more obvious
+        * > 11: r3 = *(u64 *)(r1 +16)
+        * > because it wants to have lots of reads share a single insn.  You may be able
+        * > to defeat that optimisation by adding compiler barriers, idk.  Maybe someone
+        * > with llvm knowledge can figure out how to stop it (ideally, llvm would know
+        * > when it's generating for bpf backend and not do that).  -O0?  Â¯\_(ツ)_/¯
+        *
+        * The optimization mostly likes below:
+        *
+        *      br1:
+        *      ...
+        *      r1 += 16
+        *      goto merge
+        *      br2:
+        *      ...
+        *      r1 += 20
+        *      goto merge
+        *      merge:
+        *      *(u64 *)(r1 + 0)
+        *
+        * The compiler tries to merge common loads. There is no easy way to
+        * stop this compiler optimization without turning off a lot of other
+        * optimizations. The easiest way is to add barriers:
+        *
+        *       __asm__ __volatile__("": : :"memory")
+        *
+        *       after the ctx memory access to prevent their down stream merging.
+        */
+       switch (augmented_args.args.syscall_nr) {
+       case SYS_OPEN:   filename_arg = (const void *)args->args[0];
+                       __asm__ __volatile__("": : :"memory");
+                        break;
+       case SYS_OPENAT: filename_arg = (const void *)args->args[1];
+                        break;
+       }
+
+       if (filename_arg != NULL) {
+               augmented_args.filename.reserved = 0;
+               augmented_args.filename.size = probe_read_str(&augmented_args.filename.value,
+                                                             sizeof(augmented_args.filename.value),
+                                                             filename_arg);
+               if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) {
+                       len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size;
+                       len &= sizeof(augmented_args.filename.value) - 1;
+               }
+       } else {
+               len = sizeof(augmented_args.args);
+       }
+
+       perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, &augmented_args, len);
+       return 0;
+}
+
+SEC("raw_syscalls:sys_exit")
+int sys_exit(struct syscall_exit_args *args)
+{
+       return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */
+}
+
+license(GPL);
index ac1bcdc17dae7554f51a780b843605c441c6abbf..f7eb63cbbc655bdcebbd710ed38ce39a907db4bc 100644 (file)
@@ -125,7 +125,7 @@ perf_get_timestamp(void)
 }
 
 static int
-debug_cache_init(void)
+create_jit_cache_dir(void)
 {
        char str[32];
        char *base, *p;
@@ -144,8 +144,13 @@ debug_cache_init(void)
 
        strftime(str, sizeof(str), JIT_LANG"-jit-%Y%m%d", &tm);
 
-       snprintf(jit_path, PATH_MAX - 1, "%s/.debug/", base);
-
+       ret = snprintf(jit_path, PATH_MAX, "%s/.debug/", base);
+       if (ret >= PATH_MAX) {
+               warnx("jvmti: cannot generate jit cache dir because %s/.debug/"
+                       " is too long, please check the cwd, JITDUMPDIR, and"
+                       " HOME variables", base);
+               return -1;
+       }
        ret = mkdir(jit_path, 0755);
        if (ret == -1) {
                if (errno != EEXIST) {
@@ -154,20 +159,32 @@ debug_cache_init(void)
                }
        }
 
-       snprintf(jit_path, PATH_MAX - 1, "%s/.debug/jit", base);
+       ret = snprintf(jit_path, PATH_MAX, "%s/.debug/jit", base);
+       if (ret >= PATH_MAX) {
+               warnx("jvmti: cannot generate jit cache dir because"
+                       " %s/.debug/jit is too long, please check the cwd,"
+                       " JITDUMPDIR, and HOME variables", base);
+               return -1;
+       }
        ret = mkdir(jit_path, 0755);
        if (ret == -1) {
                if (errno != EEXIST) {
-                       warn("cannot create jit cache dir %s", jit_path);
+                       warn("jvmti: cannot create jit cache dir %s", jit_path);
                        return -1;
                }
        }
 
-       snprintf(jit_path, PATH_MAX - 1, "%s/.debug/jit/%s.XXXXXXXX", base, str);
-
+       ret = snprintf(jit_path, PATH_MAX, "%s/.debug/jit/%s.XXXXXXXX", base, str);
+       if (ret >= PATH_MAX) {
+               warnx("jvmti: cannot generate jit cache dir because"
+                       " %s/.debug/jit/%s.XXXXXXXX is too long, please check"
+                       " the cwd, JITDUMPDIR, and HOME variables",
+                       base, str);
+               return -1;
+       }
        p = mkdtemp(jit_path);
        if (p != jit_path) {
-               warn("cannot create jit cache dir %s", jit_path);
+               warn("jvmti: cannot create jit cache dir %s", jit_path);
                return -1;
        }
 
@@ -228,7 +245,7 @@ void *jvmti_open(void)
 {
        char dump_path[PATH_MAX];
        struct jitheader header;
-       int fd;
+       int fd, ret;
        FILE *fp;
 
        init_arch_timestamp();
@@ -245,12 +262,22 @@ void *jvmti_open(void)
 
        memset(&header, 0, sizeof(header));
 
-       debug_cache_init();
+       /*
+        * jitdump file dir
+        */
+       if (create_jit_cache_dir() < 0)
+               return NULL;
 
        /*
         * jitdump file name
         */
-       scnprintf(dump_path, PATH_MAX, "%s/jit-%i.dump", jit_path, getpid());
+       ret = snprintf(dump_path, PATH_MAX, "%s/jit-%i.dump", jit_path, getpid());
+       if (ret >= PATH_MAX) {
+               warnx("jvmti: cannot generate jitdump file full path because"
+                       " %s/jit-%i.dump is too long, please check the cwd,"
+                       " JITDUMPDIR, and HOME variables", jit_path, getpid());
+               return NULL;
+       }
 
        fd = open(dump_path, O_CREAT|O_TRUNC|O_RDWR, 0666);
        if (fd == -1)
index 24cb0bd56afa56bb4f0c4d48cefa4f7446681c66..f278ce5ebab76640de4eb61ee8661040d0ac092a 100755 (executable)
@@ -119,6 +119,14 @@ def dsoname(name):
                return "[kernel]"
        return name
 
+def findnth(s, sub, n, offs=0):
+       pos = s.find(sub)
+       if pos < 0:
+               return pos
+       if n <= 1:
+               return offs + pos
+       return findnth(s[pos + 1:], sub, n - 1, offs + pos + 1)
+
 # Percent to one decimal place
 
 def PercentToOneDP(n, d):
@@ -1464,6 +1472,317 @@ class BranchWindow(QMdiSubWindow):
                else:
                        self.find_bar.NotFound()
 
+# Dialog data item converted and validated using a SQL table
+
+class SQLTableDialogDataItem():
+
+       def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
+               self.glb = glb
+               self.label = label
+               self.placeholder_text = placeholder_text
+               self.table_name = table_name
+               self.match_column = match_column
+               self.column_name1 = column_name1
+               self.column_name2 = column_name2
+               self.parent = parent
+
+               self.value = ""
+
+               self.widget = QLineEdit()
+               self.widget.editingFinished.connect(self.Validate)
+               self.widget.textChanged.connect(self.Invalidate)
+               self.red = False
+               self.error = ""
+               self.validated = True
+
+               self.last_id = 0
+               self.first_time = 0
+               self.last_time = 2 ** 64
+               if self.table_name == "<timeranges>":
+                       query = QSqlQuery(self.glb.db)
+                       QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
+                       if query.next():
+                               self.last_id = int(query.value(0))
+                               self.last_time = int(query.value(1))
+                       QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1")
+                       if query.next():
+                               self.first_time = int(query.value(0))
+                       if placeholder_text:
+                               placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)
+
+               if placeholder_text:
+                       self.widget.setPlaceholderText(placeholder_text)
+
+       def ValueToIds(self, value):
+               ids = []
+               query = QSqlQuery(self.glb.db)
+               stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'"
+               ret = query.exec_(stmt)
+               if ret:
+                       while query.next():
+                               ids.append(str(query.value(0)))
+               return ids
+
+       def IdBetween(self, query, lower_id, higher_id, order):
+               QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")
+               if query.next():
+                       return True, int(query.value(0))
+               else:
+                       return False, 0
+
+       def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor):
+               query = QSqlQuery(self.glb.db)
+               while True:
+                       next_id = int((lower_id + higher_id) / 2)
+                       QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
+                       if not query.next():
+                               ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC")
+                               if not ok:
+                                       ok, dbid = self.IdBetween(query, next_id, higher_id, "")
+                                       if not ok:
+                                               return str(higher_id)
+                               next_id = dbid
+                               QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
+                       next_time = int(query.value(0))
+                       if get_floor:
+                               if target_time > next_time:
+                                       lower_id = next_id
+                               else:
+                                       higher_id = next_id
+                               if higher_id <= lower_id + 1:
+                                       return str(higher_id)
+                       else:
+                               if target_time >= next_time:
+                                       lower_id = next_id
+                               else:
+                                       higher_id = next_id
+                               if higher_id <= lower_id + 1:
+                                       return str(lower_id)
+
+       def ConvertRelativeTime(self, val):
+               print "val ", val
+               mult = 1
+               suffix = val[-2:]
+               if suffix == "ms":
+                       mult = 1000000
+               elif suffix == "us":
+                       mult = 1000
+               elif suffix == "ns":
+                       mult = 1
+               else:
+                       return val
+               val = val[:-2].strip()
+               if not self.IsNumber(val):
+                       return val
+               val = int(val) * mult
+               if val >= 0:
+                       val += self.first_time
+               else:
+                       val += self.last_time
+               return str(val)
+
+       def ConvertTimeRange(self, vrange):
+               print "vrange ", vrange
+               if vrange[0] == "":
+                       vrange[0] = str(self.first_time)
+               if vrange[1] == "":
+                       vrange[1] = str(self.last_time)
+               vrange[0] = self.ConvertRelativeTime(vrange[0])
+               vrange[1] = self.ConvertRelativeTime(vrange[1])
+               print "vrange2 ", vrange
+               if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
+                       return False
+               print "ok1"
+               beg_range = max(int(vrange[0]), self.first_time)
+               end_range = min(int(vrange[1]), self.last_time)
+               if beg_range > self.last_time or end_range < self.first_time:
+                       return False
+               print "ok2"
+               vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
+               vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
+               print "vrange3 ", vrange
+               return True
+
+       def AddTimeRange(self, value, ranges):
+               print "value ", value
+               n = value.count("-")
+               if n == 1:
+                       pass
+               elif n == 2:
+                       if value.split("-")[1].strip() == "":
+                               n = 1
+               elif n == 3:
+                       n = 2
+               else:
+                       return False
+               pos = findnth(value, "-", n)
+               vrange = [value[:pos].strip() ,value[pos+1:].strip()]
+               if self.ConvertTimeRange(vrange):
+                       ranges.append(vrange)
+                       return True
+               return False
+
+       def InvalidValue(self, value):
+               self.value = ""
+               palette = QPalette()
+               palette.setColor(QPalette.Text,Qt.red)
+               self.widget.setPalette(palette)
+               self.red = True
+               self.error = self.label + " invalid value '" + value + "'"
+               self.parent.ShowMessage(self.error)
+
+       def IsNumber(self, value):
+               try:
+                       x = int(value)
+               except:
+                       x = 0
+               return str(x) == value
+
+       def Invalidate(self):
+               self.validated = False
+
+       def Validate(self):
+               input_string = self.widget.text()
+               self.validated = True
+               if self.red:
+                       palette = QPalette()
+                       self.widget.setPalette(palette)
+                       self.red = False
+               if not len(input_string.strip()):
+                       self.error = ""
+                       self.value = ""
+                       return
+               if self.table_name == "<timeranges>":
+                       ranges = []
+                       for value in [x.strip() for x in input_string.split(",")]:
+                               if not self.AddTimeRange(value, ranges):
+                                       return self.InvalidValue(value)
+                       ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges]
+                       self.value = " OR ".join(ranges)
+               elif self.table_name == "<ranges>":
+                       singles = []
+                       ranges = []
+                       for value in [x.strip() for x in input_string.split(",")]:
+                               if "-" in value:
+                                       vrange = value.split("-")
+                                       if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
+                                               return self.InvalidValue(value)
+                                       ranges.append(vrange)
+                               else:
+                                       if not self.IsNumber(value):
+                                               return self.InvalidValue(value)
+                                       singles.append(value)
+                       ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges]
+                       if len(singles):
+                               ranges.append(self.column_name1 + " IN (" + ",".join(singles) + ")")
+                       self.value = " OR ".join(ranges)
+               elif self.table_name:
+                       all_ids = []
+                       for value in [x.strip() for x in input_string.split(",")]:
+                               ids = self.ValueToIds(value)
+                               if len(ids):
+                                       all_ids.extend(ids)
+                               else:
+                                       return self.InvalidValue(value)
+                       self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
+                       if self.column_name2:
+                               self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"
+               else:
+                       self.value = input_string.strip()
+               self.error = ""
+               self.parent.ClearMessage()
+
+       def IsValid(self):
+               if not self.validated:
+                       self.Validate()
+               if len(self.error):
+                       self.parent.ShowMessage(self.error)
+                       return False
+               return True
+
+# Selected branch report creation dialog
+
+class SelectedBranchDialog(QDialog):
+
+       def __init__(self, glb, parent=None):
+               super(SelectedBranchDialog, self).__init__(parent)
+
+               self.glb = glb
+
+               self.name = ""
+               self.where_clause = ""
+
+               self.setWindowTitle("Selected Branches")
+               self.setMinimumWidth(600)
+
+               items = (
+                       ("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""),
+                       ("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""),
+                       ("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""),
+                       ("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""),
+                       ("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""),
+                       ("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""),
+                       ("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"),
+                       ("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"),
+                       ("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""),
+                       )
+               self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items]
+
+               self.grid = QGridLayout()
+
+               for row in xrange(len(self.data_items)):
+                       self.grid.addWidget(QLabel(self.data_items[row].label), row, 0)
+                       self.grid.addWidget(self.data_items[row].widget, row, 1)
+
+               self.status = QLabel()
+
+               self.ok_button = QPushButton("Ok", self)
+               self.ok_button.setDefault(True)
+               self.ok_button.released.connect(self.Ok)
+               self.ok_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+
+               self.cancel_button = QPushButton("Cancel", self)
+               self.cancel_button.released.connect(self.reject)
+               self.cancel_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+
+               self.hbox = QHBoxLayout()
+               #self.hbox.addStretch()
+               self.hbox.addWidget(self.status)
+               self.hbox.addWidget(self.ok_button)
+               self.hbox.addWidget(self.cancel_button)
+
+               self.vbox = QVBoxLayout()
+               self.vbox.addLayout(self.grid)
+               self.vbox.addLayout(self.hbox)
+
+               self.setLayout(self.vbox);
+
+       def Ok(self):
+               self.name = self.data_items[0].value
+               if not self.name:
+                       self.ShowMessage("Report name is required")
+                       return
+               for d in self.data_items:
+                       if not d.IsValid():
+                               return
+               for d in self.data_items[1:]:
+                       if len(d.value):
+                               if len(self.where_clause):
+                                       self.where_clause += " AND "
+                               self.where_clause += d.value
+               if len(self.where_clause):
+                       self.where_clause = " AND ( " + self.where_clause + " ) "
+               else:
+                       self.ShowMessage("No selection")
+                       return
+               self.accept()
+
+       def ShowMessage(self, msg):
+               self.status.setText("<font color=#FF0000>" + msg)
+
+       def ClearMessage(self):
+               self.status.setText("")
+
 # Event list
 
 def GetEventList(db):
@@ -1656,7 +1975,7 @@ class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):
        def FindDone(self, row):
                self.find_bar.Idle()
                if row >= 0:
-                       self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
+                       self.view.setCurrentIndex(self.model.mapFromSource(self.data_model.index(row, 0, QModelIndex())))
                else:
                        self.find_bar.NotFound()
 
@@ -1765,6 +2084,149 @@ class WindowMenu():
        def setActiveSubWindow(self, nr):
                self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1])
 
+# Help text
+
+glb_help_text = """
+<h1>Contents</h1>
+<style>
+p.c1 {
+    text-indent: 40px;
+}
+p.c2 {
+    text-indent: 80px;
+}
+}
+</style>
+<p class=c1><a href=#reports>1. Reports</a></p>
+<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p>
+<p class=c2><a href=#allbranches>1.2 All branches</a></p>
+<p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p>
+<p class=c1><a href=#tables>2. Tables</a></p>
+<h1 id=reports>1. Reports</h1>
+<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2>
+The result is a GUI window with a tree representing a context-sensitive
+call-graph. Expanding a couple of levels of the tree and adjusting column
+widths to suit will display something like:
+<pre>
+                                         Call Graph: pt_example
+Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
+v- ls
+    v- 2638:2638
+        v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
+          |- unknown               unknown       1        13198     0.1              1              0.0
+          >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
+          >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
+          v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
+             >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
+             >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
+             >- __libc_csu_init    ls            1        10354     0.1             10              0.0
+             |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
+             v- main               ls            1      8182043    99.6         180254             99.9
+</pre>
+<h3>Points to note:</h3>
+<ul>
+<li>The top level is a command name (comm)</li>
+<li>The next level is a thread (pid:tid)</li>
+<li>Subsequent levels are functions</li>
+<li>'Count' is the number of calls</li>
+<li>'Time' is the elapsed time until the function returns</li>
+<li>Percentages are relative to the level above</li>
+<li>'Branch Count' is the total number of branches for that function and all functions that it calls
+</ul>
+<h3>Find</h3>
+Ctrl-F displays a Find bar which finds function names by either an exact match or a pattern match.
+The pattern matching symbols are ? for any character and * for zero or more characters.
+<h2 id=allbranches>1.2 All branches</h2>
+The All branches report displays all branches in chronological order.
+Not all data is fetched immediately. More records can be fetched using the Fetch bar provided.
+<h3>Disassembly</h3>
+Open a branch to display disassembly. This only works if:
+<ol>
+<li>The disassembler is available. Currently, only Intel XED is supported - see <a href=#xed>Intel XED Setup</a></li>
+<li>The object code is available. Currently, only the perf build ID cache is searched for object code.
+The default directory ~/.debug can be overridden by setting environment variable PERF_BUILDID_DIR.
+One exception is kcore where the DSO long name is used (refer dsos_view on the Tables menu),
+or alternatively, set environment variable PERF_KCORE to the kcore file name.</li>
+</ol>
+<h4 id=xed>Intel XED Setup</h4>
+To use Intel XED, libxed.so must be present.  To build and install libxed.so:
+<pre>
+git clone https://github.com/intelxed/mbuild.git mbuild
+git clone https://github.com/intelxed/xed
+cd xed
+./mfile.py --share
+sudo ./mfile.py --prefix=/usr/local install
+sudo ldconfig
+</pre>
+<h3>Find</h3>
+Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
+Refer to Python documentation for the regular expression syntax.
+All columns are searched, but only currently fetched rows are searched.
+<h2 id=selectedbranches>1.3 Selected branches</h2>
+This is the same as the <a href=#allbranches>All branches</a> report but with the data reduced
+by various selection criteria. A dialog box displays available criteria which are AND'ed together.
+<h3>1.3.1 Time ranges</h3>
+The time ranges hint text shows the total time range. Relative time ranges can also be entered in
+ms, us or ns. Also, negative values are relative to the end of trace.  Examples:
+<pre>
+       81073085947329-81073085958238   From 81073085947329 to 81073085958238
+       100us-200us             From 100us to 200us
+       10ms-                   From 10ms to the end
+       -100ns                  The first 100ns
+       -10ms-                  The last 10ms
+</pre>
+N.B. Due to the granularity of timestamps, there could be no branches in any given time range.
+<h1 id=tables>2. Tables</h1>
+The Tables menu shows all tables and views in the database. Most tables have an associated view
+which displays the information in a more friendly way. Not all data for large tables is fetched
+immediately. More records can be fetched using the Fetch bar provided. Columns can be sorted,
+but that can be slow for large tables.
+<p>There are also tables of database meta-information.
+For SQLite3 databases, the sqlite_master table is included.
+For PostgreSQL databases, information_schema.tables/views/columns are included.
+<h3>Find</h3>
+Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
+Refer to Python documentation for the regular expression syntax.
+All columns are searched, but only currently fetched rows are searched.
+<p>N.B. Results are found in id order, so if the table is re-ordered, find-next and find-previous
+will go to the next/previous result in id order, instead of display order.
+"""
+
+# Help window
+
+class HelpWindow(QMdiSubWindow):
+
+       def __init__(self, glb, parent=None):
+               super(HelpWindow, self).__init__(parent)
+
+               self.text = QTextBrowser()
+               self.text.setHtml(glb_help_text)
+               self.text.setReadOnly(True)
+               self.text.setOpenExternalLinks(True)
+
+               self.setWidget(self.text)
+
+               AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help")
+
+# Main window that only displays the help text
+
+class HelpOnlyWindow(QMainWindow):
+
+       def __init__(self, parent=None):
+               super(HelpOnlyWindow, self).__init__(parent)
+
+               self.setMinimumSize(200, 100)
+               self.resize(800, 600)
+               self.setWindowTitle("Exported SQL Viewer Help")
+               self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
+
+               self.text = QTextBrowser()
+               self.text.setHtml(glb_help_text)
+               self.text.setReadOnly(True)
+               self.text.setOpenExternalLinks(True)
+
+               self.setCentralWidget(self.text)
+
 # Font resize
 
 def ResizeFont(widget, diff):
@@ -1851,6 +2313,9 @@ class MainWindow(QMainWindow):
 
                self.window_menu = WindowMenu(self.mdi_area, menu)
 
+               help_menu = menu.addMenu("&Help")
+               help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
+
        def Find(self):
                win = self.mdi_area.activeSubWindow()
                if win:
@@ -1888,6 +2353,8 @@ class MainWindow(QMainWindow):
                        if event == "branches":
                                label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")"
                                reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda x=dbid: self.NewBranchView(x), self))
+                               label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")"
+                               reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda x=dbid: self.NewSelectedBranchView(x), self))
 
        def TableMenu(self, tables, menu):
                table_menu = menu.addMenu("&Tables")
@@ -1900,9 +2367,18 @@ class MainWindow(QMainWindow):
        def NewBranchView(self, event_id):
                BranchWindow(self.glb, event_id, "", "", self)
 
+       def NewSelectedBranchView(self, event_id):
+               dialog = SelectedBranchDialog(self.glb, self)
+               ret = dialog.exec_()
+               if ret:
+                       BranchWindow(self.glb, event_id, dialog.name, dialog.where_clause, self)
+
        def NewTableView(self, table_name):
                TableWindow(self.glb, table_name, self)
 
+       def Help(self):
+               HelpWindow(self.glb, self)
+
 # XED Disassembler
 
 class xed_state_t(Structure):
@@ -1929,7 +2405,12 @@ class XEDInstruction():
 class LibXED():
 
        def __init__(self):
-               self.libxed = CDLL("libxed.so")
+               try:
+                       self.libxed = CDLL("libxed.so")
+               except:
+                       self.libxed = None
+               if not self.libxed:
+                       self.libxed = CDLL("/usr/local/lib/libxed.so")
 
                self.xed_tables_init = self.libxed.xed_tables_init
                self.xed_tables_init.restype = None
@@ -2097,10 +2578,16 @@ class DBRef():
 
 def Main():
        if (len(sys.argv) < 2):
-               print >> sys.stderr, "Usage is: exported-sql-viewer.py <database name>"
+               print >> sys.stderr, "Usage is: exported-sql-viewer.py {<database name> | --help-only}"
                raise Exception("Too few arguments")
 
        dbname = sys.argv[1]
+       if dbname == "--help-only":
+               app = QApplication(sys.argv)
+               mainwindow = HelpOnlyWindow()
+               mainwindow.show()
+               err = app.exec_()
+               sys.exit(err)
 
        is_sqlite3 = False
        try:
index 8a33ca4f9e1f7feed87159d755ba3b4797a987b6..f0729c454f160bed941b16133b9ac437c973404d 100644 (file)
@@ -37,4 +37,3 @@ sample_freq=0
 sample_period=0
 freq=0
 write_backward=0
-sample_id_all=0
index e88e6f9b1463f0674a0eaf12423b35978e58d8da..668d2a9ef0f4b698231c7ad0388210175f0f8dab 100644 (file)
@@ -1810,3 +1810,30 @@ void perf_evlist__force_leader(struct perf_evlist *evlist)
                leader->forced_leader = true;
        }
 }
+
+struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list,
+                                                struct perf_evsel *evsel)
+{
+       struct perf_evsel *c2, *leader;
+       bool is_open = true;
+
+       leader = evsel->leader;
+       pr_debug("Weak group for %s/%d failed\n",
+                       leader->name, leader->nr_members);
+
+       /*
+        * for_each_group_member doesn't work here because it doesn't
+        * include the first entry.
+        */
+       evlist__for_each_entry(evsel_list, c2) {
+               if (c2 == evsel)
+                       is_open = false;
+               if (c2->leader == leader) {
+                       if (is_open)
+                               perf_evsel__close(c2);
+                       c2->leader = c2;
+                       c2->nr_members = 0;
+               }
+       }
+       return leader;
+}
index dc66436add98a3c795efa3ddf0889f09f1d7abe3..9919eed6d15bc1994844187d9b55e69b746312cc 100644 (file)
@@ -312,4 +312,7 @@ bool perf_evlist__exclude_kernel(struct perf_evlist *evlist);
 
 void perf_evlist__force_leader(struct perf_evlist *evlist);
 
+struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evlist,
+                                                struct perf_evsel *evsel);
+
 #endif /* __PERF_EVLIST_H */
index 6d187059a37360ae669220c913c535b1278d6514..d37bb1566cd9da7eb0875f83dcfa46edce36a552 100644 (file)
@@ -956,7 +956,6 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
                attr->sample_freq    = 0;
                attr->sample_period  = 0;
                attr->write_backward = 0;
-               attr->sample_id_all  = 0;
        }
 
        if (opts->no_samples)
index 58f6a9ceb5909c1007c4e7a95aa92230da6fff41..4503f3ca45ab48d7305260cf36e51800eecaf089 100644 (file)
@@ -1474,6 +1474,8 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
                decoder->have_calc_cyc_to_tsc = false;
                intel_pt_calc_cyc_to_tsc(decoder, true);
        }
+
+       intel_pt_log_to("Setting timestamp", decoder->timestamp);
 }
 
 static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder)
@@ -1514,6 +1516,8 @@ static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder)
                decoder->timestamp = timestamp;
 
        decoder->timestamp_insn_cnt = 0;
+
+       intel_pt_log_to("Setting timestamp", decoder->timestamp);
 }
 
 /* Walk PSB+ packets when already in sync. */
index e02bc7b166a0e48f1cf537606a71ab43875c6de8..5e64da270f97684b7f42c56079a04a2653a1b890 100644 (file)
@@ -31,6 +31,11 @@ static FILE *f;
 static char log_name[MAX_LOG_NAME];
 bool intel_pt_enable_logging;
 
+void *intel_pt_log_fp(void)
+{
+       return f;
+}
+
 void intel_pt_log_enable(void)
 {
        intel_pt_enable_logging = true;
index 45b64f93f358898c6fb8d5caca92b37cd70f2e2e..cc084937f701acfa16bc3eb3623aab7e6ed429d2 100644 (file)
@@ -22,6 +22,7 @@
 
 struct intel_pt_pkt;
 
+void *intel_pt_log_fp(void);
 void intel_pt_log_enable(void);
 void intel_pt_log_disable(void);
 void intel_pt_log_set_name(const char *name);
index 86cc9a64e982773408e2d51cc25a51a82c396ff5..149ff361ca789e460cd896beaa439ff7b225c2a2 100644 (file)
@@ -206,6 +206,16 @@ static void intel_pt_dump_event(struct intel_pt *pt, unsigned char *buf,
        intel_pt_dump(pt, buf, len);
 }
 
+static void intel_pt_log_event(union perf_event *event)
+{
+       FILE *f = intel_pt_log_fp();
+
+       if (!intel_pt_enable_logging || !f)
+               return;
+
+       perf_event__fprintf(event, f);
+}
+
 static int intel_pt_do_fix_overlap(struct intel_pt *pt, struct auxtrace_buffer *a,
                                   struct auxtrace_buffer *b)
 {
@@ -2010,9 +2020,9 @@ static int intel_pt_process_event(struct perf_session *session,
                 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)
                err = intel_pt_context_switch(pt, event, sample);
 
-       intel_pt_log("event %s (%u): cpu %d time %"PRIu64" tsc %#"PRIx64"\n",
-                    perf_event__name(event->header.type), event->header.type,
-                    sample->cpu, sample->time, timestamp);
+       intel_pt_log("event %u: cpu %d time %"PRIu64" tsc %#"PRIx64" ",
+                    event->header.type, sample->cpu, sample->time, timestamp);
+       intel_pt_log_event(event);
 
        return err;
 }
index 7799788f662fdc05765915b383d13085f2a932ac..7e49baad304d78815966a6ac918f472fd817620b 100644 (file)
@@ -773,7 +773,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
 
                if (!is_arm_pmu_core(name)) {
                        pname = pe->pmu ? pe->pmu : "cpu";
-                       if (strncmp(pname, name, strlen(pname)))
+                       if (strcmp(pname, name))
                                continue;
                }
 
index 9527d47a1070ecbabc716273d6e46f34e18c1ca1..01ec04bf91b592e470c26512e744d5e59211a3d4 100644 (file)
@@ -140,8 +140,8 @@ static u32 handle[] = {
        [6] = NFIT_DIMM_HANDLE(1, 0, 0, 0, 1),
 };
 
-static unsigned long dimm_fail_cmd_flags[NUM_DCR];
-static int dimm_fail_cmd_code[NUM_DCR];
+static unsigned long dimm_fail_cmd_flags[ARRAY_SIZE(handle)];
+static int dimm_fail_cmd_code[ARRAY_SIZE(handle)];
 
 static const struct nd_intel_smart smart_def = {
        .flags = ND_INTEL_SMART_HEALTH_VALID
@@ -205,7 +205,7 @@ struct nfit_test {
                unsigned long deadline;
                spinlock_t lock;
        } ars_state;
-       struct device *dimm_dev[NUM_DCR];
+       struct device *dimm_dev[ARRAY_SIZE(handle)];
        struct nd_intel_smart *smart;
        struct nd_intel_smart_threshold *smart_threshold;
        struct badrange badrange;
@@ -2680,7 +2680,7 @@ static int nfit_test_probe(struct platform_device *pdev)
                u32 nfit_handle = __to_nfit_memdev(nfit_mem)->device_handle;
                int i;
 
-               for (i = 0; i < NUM_DCR; i++)
+               for (i = 0; i < ARRAY_SIZE(handle); i++)
                        if (nfit_handle == handle[i])
                                dev_set_drvdata(nfit_test->dimm_dev[i],
                                                nfit_mem);
index 1b0e9e9a2ddce5a3377ded7dad656202586339dc..f2fa101c5a6ac149bd93c4f8140aed76798b8e69 100644 (file)
@@ -47,8 +47,9 @@ static int ok(void)
        return 0;
 }
 
-#define REG_POISON     0x5a5aUL
-#define POISONED_REG(n)        ((REG_POISON << 48) | ((n) << 32) | (REG_POISON << 16) | (n))
+#define REG_POISON     0x5a5a
+#define POISONED_REG(n)        ((((unsigned long)REG_POISON) << 48) | ((n) << 32) | \
+                        (((unsigned long)REG_POISON) << 16) | (n))
 
 static inline void poison_regs(void)
 {
@@ -105,6 +106,20 @@ static void dump_regs(void)
        }
 }
 
+#ifdef _CALL_AIXDESC
+struct opd {
+       unsigned long ip;
+       unsigned long toc;
+       unsigned long env;
+};
+static struct opd bad_opd = {
+       .ip = BAD_NIP,
+};
+#define BAD_FUNC (&bad_opd)
+#else
+#define BAD_FUNC BAD_NIP
+#endif
+
 int test_wild_bctr(void)
 {
        int (*func_ptr)(void);
@@ -133,7 +148,7 @@ int test_wild_bctr(void)
 
                poison_regs();
 
-               func_ptr = (int (*)(void))BAD_NIP;
+               func_ptr = (int (*)(void))BAD_FUNC;
                func_ptr();
 
                FAIL_IF(1); /* we didn't segv? */
index 87a04a8a5945c21222a21c103e5ed88bff0f5c67..7607ba3e3cbe4eba89dfe5a35badae9182b974a9 100755 (executable)
@@ -134,9 +134,9 @@ def exec_cmd(args, pm, stage, command):
     (rawout, serr) = proc.communicate()
 
     if proc.returncode != 0 and len(serr) > 0:
-        foutput = serr.decode("utf-8")
+        foutput = serr.decode("utf-8", errors="ignore")
     else:
-        foutput = rawout.decode("utf-8")
+        foutput = rawout.decode("utf-8", errors="ignore")
 
     proc.stdout.close()
     proc.stderr.close()
@@ -169,6 +169,8 @@ def prepare_env(args, pm, stage, prefix, cmdlist, output = None):
                   file=sys.stderr)
             print("\n{} *** Error message: \"{}\"".format(prefix, foutput),
                   file=sys.stderr)
+            print("returncode {}; expected {}".format(proc.returncode,
+                                                      exit_codes))
             print("\n{} *** Aborting test run.".format(prefix), file=sys.stderr)
             print("\n\n{} *** stdout ***".format(proc.stdout), file=sys.stderr)
             print("\n\n{} *** stderr ***".format(proc.stderr), file=sys.stderr)
@@ -195,12 +197,18 @@ def run_one_test(pm, args, index, tidx):
         print('-----> execute stage')
     pm.call_pre_execute()
     (p, procout) = exec_cmd(args, pm, 'execute', tidx["cmdUnderTest"])
-    exit_code = p.returncode
+    if p:
+        exit_code = p.returncode
+    else:
+        exit_code = None
+
     pm.call_post_execute()
 
-    if (exit_code != int(tidx["expExitCode"])):
+    if (exit_code is None or exit_code != int(tidx["expExitCode"])):
         result = False
-        print("exit:", exit_code, int(tidx["expExitCode"]))
+        print("exit: {!r}".format(exit_code))
+        print("exit: {}".format(int(tidx["expExitCode"])))
+        #print("exit: {!r} {}".format(exit_code, int(tidx["expExitCode"])))
         print(procout)
     else:
         if args.verbose > 0: