android_kernel_motorola_sm6375/mm/ksm.c
Blagovest Kolenichev 441301dd42 Merge android-5.4-stable.45 (a9a13ee) into msm-5.4
* refs/heads/tmp-a9a13ee:
  Linux 5.4.45
  net: smsc911x: Fix runtime PM imbalance on error
  selftests: mlxsw: qos_mc_aware: Specify arping timeout as an integer
  net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x
  net/ethernet/freescale: rework quiesce/activate for ucc_geth
  null_blk: return error for invalid zone size
  s390/mm: fix set_huge_pte_at() for empty ptes
  drm/edid: Add Oculus Rift S to non-desktop list
  net: bmac: Fix read of MAC address from ROM
  x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables
  io_uring: initialize ctx->sqo_wait earlier
  i2c: altera: Fix race between xfer_msg and isr thread
  scsi: pm: Balance pm_only counter of request queue during system resume
  evm: Fix RCU list related warnings
  ARC: [plat-eznps]: Restrict to CONFIG_ISA_ARCOMPACT
  ARC: Fix ICCM & DCCM runtime size checks
  RDMA/qedr: Fix synchronization methods and memory leaks in qedr
  RDMA/qedr: Fix qpids xarray api used
  s390/ftrace: save traced function caller
  ASoC: intel - fix the card names
  spi: dw: use "smp_mb()" to avoid sending spi data error
  powerpc/xmon: Restrict when kernel is locked down
  powerpc/powernv: Avoid re-registration of imc debugfs directory
  scsi: hisi_sas: Check sas_port before using it
  drm/i915: fix port checks for MST support on gen >= 11
  airo: Fix read overflows sending packets
  net: dsa: mt7530: set CPU port to fallback mode
  scsi: ufs: Release clock if DMA map fails
  media: staging: ipu3-imgu: Move alignment attribute to field
  media: Revert "staging: imgu: Address a compiler warning on alignment"
  mmc: fix compilation of user API
  kernel/relay.c: handle alloc_percpu returning NULL in relay_open
  mt76: mt76x02u: Add support for newer versions of the XBox One wifi adapter
  p54usb: add AirVasT USB stick device-id
  HID: i2c-hid: add Schneider SCL142ALM to descriptor override
  HID: multitouch: enable multi-input as a quirk for some devices
  HID: sony: Fix for broken buttons on DS3 USB dongles
  mm: Fix mremap not considering huge pmd devmap
  Revert "cgroup: Add memory barriers to plug cgroup_rstat_updated() race window"
  ANDROID: GKI: Enable SYS_HYPERVISOR
  ANDROID: Update ABI representation
  ANDROID: GKI: disable CONFIG_I2C_CHARDEV
  ANDROID: GKI: remove netfilter apis from supported symbols
  Linux 5.4.44
  perf: Make perf able to build with latest libbfd
  netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build
  netfilter: conntrack: Pass value of ctinfo to __nf_conntrack_update
  netfilter: conntrack: comparison of unsigned in cthelper confirmation
  bonding: Fix reference count leak in bond_sysfs_slave_add.
  net: dsa: declare lockless TX feature for slave ports
  ipv4: nexthop version of fib_info_nh_uses_dev
  nexthop: Expand nexthop_is_multipath in a few places
  nexthops: don't modify published nexthop groups
  nexthops: Move code from remove_nexthop_from_groups to remove_nh_grp_entry
  crypto: chelsio/chtls: properly set tp->lsndtime
  qlcnic: fix missing release in qlcnic_83xx_interrupt_test.
  xsk: Add overflow check for u64 division, stored into u32
  ieee80211: Fix incorrect mask for default PE duration
  bnxt_en: Fix accumulation of bp->net_stats_prev.
  esp6: get the right proto for transport mode in esp6_gso_encap
  netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code
  netfilter: nfnetlink_cthelper: unbreak userspace helper support
  netfilter: conntrack: make conntrack userspace helpers work again
  netfilter: ipset: Fix subcounter update skip
  netfilter: nft_reject_bridge: enable reject with bridge vlan
  ip_vti: receive ipip packet by calling ip_tunnel_rcv
  xfrm: fix error in comment
  xfrm: fix a NULL-ptr deref in xfrm_local_error
  xfrm: fix a warning in xfrm_policy_insert_list
  xfrm interface: fix oops when deleting a x-netns interface
  xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output
  xfrm: remove the xfrm_state_put call becofe going to out_reset
  xfrm: do pskb_pull properly in __xfrm_transport_prep
  xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
  copy_xstate_to_kernel(): don't leave parts of destination uninitialized
  x86/dma: Fix max PFN arithmetic overflow on 32 bit systems
  mac80211: mesh: fix discovery timer re-arming issue / crash
  x86/syscalls: Revert "x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long"
  cfg80211: fix debugfs rename crash
  parisc: Fix kernel panic in mem_init()
  iommu: Fix reference count leak in iommu_group_alloc.
  gpio: fix locking open drain IRQ lines
  Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and REQ_NOWAIT"
  include/asm-generic/topology.h: guard cpumask_of_node() macro argument
  fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
  mm: remove VM_BUG_ON(PageSlab()) from page_mapcount()
  mm,thp: stop leaking unreleased file pages
  IB/ipoib: Fix double free of skb in case of multicast traffic in CM mode
  drm/amd/display: drop cursor position check in atomic test
  RDMA/core: Fix double destruction of uobject
  ceph: flush release queue when handling caps for unknown inode
  libceph: ignore pool overlay and cache logic on redirects
  ALSA: hda/realtek - Add new codec supported for ALC287
  ALSA: usb-audio: Quirks for Gigabyte TRX40 Aorus Master onboard audio
  clk: qcom: gcc: Fix parent for gpll0_out_even
  exec: Always set cap_ambient in cap_bprm_set_creds
  ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC
  ALSA: hda/realtek - Add a model for Thinkpad T570 without DAC workaround
  ALSA: hwdep: fix a left shifting 1 by 31 UB bug
  RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe()
  gpio: bcm-kona: Fix return value of bcm_kona_gpio_probe()
  gpio: pxa: Fix return value of pxa_gpio_probe()
  mmc: block: Fix use-after-free issue for rpmb
  ARM: dts: bcm: HR2: Fix PPI interrupt types
  ARM: dts: bcm2835-rpi-zero-w: Fix led polarity
  ARM: dts/imx6q-bx50v3: Set display interface clock parents
  IB/qib: Call kobject_put() when kobject_init_and_add() fails
  gpu/drm: Ingenic: Fix opaque pointer casted to wrong type
  soc: mediatek: cmdq: return send msg error code
  arm64: dts: mt8173: fix vcodec-enc clock
  gpio: exar: Fix bad handling for ida_simple_get error path
  ARM: uaccess: fix DACR mismatch with nested exceptions
  ARM: uaccess: integrate uaccess_save and uaccess_restore
  ARM: uaccess: consolidate uaccess asm to asm/uaccess-asm.h
  ARM: 8970/1: decompressor: increase tag size
  Input: synaptics-rmi4 - fix error return code in rmi_driver_probe()
  Input: synaptics-rmi4 - really fix attn_data use-after-free
  Input: i8042 - add ThinkPad S230u to i8042 reset list
  Input: dlink-dir685-touchkeys - fix a typo in driver name
  Input: xpad - add custom init packet for Xbox One S controllers
  Input: evdev - call input_flush_device() on release(), not flush()
  Input: usbtouchscreen - add support for BonXeon TP
  drivers: net: hamradio: Fix suspicious RCU usage warning in bpqether.c
  samples: bpf: Fix build error
  csky: Fixup raw_copy_from_user()
  cifs: Fix null pointer check in cifs_read
  hwmon: (nct7904) Fix incorrect range of temperature limit registers
  csky: Fixup remove duplicate irq_disable
  csky: Fixup perf callchain unwind
  csky: Fixup msa highest 3 bits mask
  clk: ti: am33xx: fix RTC clock parent
  riscv: stacktrace: Fix undefined reference to `walk_stackframe'
  IB/i40iw: Remove bogus call to netdev_master_upper_dev_get()
  net: freescale: select CONFIG_FIXED_PHY where needed
  usb: gadget: legacy: fix redundant initialization warnings
  usb: phy: twl6030-usb: Fix a resource leak in an error handling path in 'twl6030_usb_probe()'
  usb: dwc3: pci: Enable extcon driver for Intel Merrifield
  cachefiles: Fix race between read_waiter and read_copier involving op->to_do
  drm/amdgpu: Use GEM obj reference for KFD BOs
  drm/amd/powerplay: perform PG ungate prior to CG ungate
  drm/amdgpu: drop unnecessary cancel_delayed_work_sync on PG ungate
  gfs2: Grab glock reference sooner in gfs2_add_revoke
  gfs2: move privileged user check to gfs2_quota_lock_check
  net: microchip: encx24j600: add missed kthread_stop
  ALSA: usb-audio: add mapping for ASRock TRX40 Creator
  gpio: tegra: mask GPIO IRQs during IRQ shutdown
  ARM: dts: rockchip: fix pinctrl sub nodename for spi in rk322x.dtsi
  ARM: dts: rockchip: swap clock-names of gpu nodes
  arm64: dts: rockchip: swap interrupts interrupt-names rk3399 gpu node
  arm64: dts: rockchip: fix status for &gmac2phy in rk3328-evb.dts
  ARM: dts: rockchip: fix phy nodename for rk3229-xms6
  ARM: dts: rockchip: fix phy nodename for rk3228-evb
  mlxsw: spectrum: Fix use-after-free of split/unsplit/type_set in case reload fails
  net/mlx4_core: fix a memory leak bug.
  net: sun: fix missing release regions in cas_init_one().
  net/tls: free record only on encryption error
  net/tls: fix encryption error checking
  net/mlx5: Annotate mutex destroy for root ns
  net/mlx5: Fix error flow in case of function_setup failure
  net/mlx5e: Update netdev txq on completions during closure
  net/mlx5: Fix memory leak in mlx5_events_init
  net/mlx5e: Fix inner tirs handling
  net/mlx5e: kTLS, Destroy key object after destroying the TIS
  tipc: block BH before using dst_cache
  sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and socket is closed
  sctp: Don't add the shutdown timer if its already been added
  r8152: support additional Microsoft Surface Ethernet Adapter variant
  nexthop: Fix attribute checking for groups
  net/tls: fix race condition causing kernel panic
  net sched: fix reporting the first-time use timestamp
  net: revert "net: get rid of an signed integer overflow in ip_idents_reserve()"
  net: qrtr: Fix passing invalid reference to qrtr_local_enqueue()
  net: nlmsg_cancel() if put fails for nhmsg
  net: mvpp2: fix RX hashing for non-10G ports
  net/mlx5: Add command entry handling completion
  net: ipip: fix wrong address family in init error path
  net: inet_csk: Fix so_reuseport bind-address cache in tb->fast*
  __netif_receive_skb_core: pass skb by reference
  net: ethernet: ti: cpsw: fix ASSERT_RTNL() warning during suspend
  net: dsa: mt7530: fix roaming from DSA user ports
  net: don't return invalid table id error when we fall back to PF_UNSPEC
  dpaa_eth: fix usage as DSA master, try 3
  ax25: fix setsockopt(SO_BINDTODEVICE)
  ANDROID: GKI: enable CONFIG_USB_DUMMY_HCD
  FROMGIT: USB: dummy-hcd: use configurable endpoint naming scheme
  ANDROID: GKI: enable a bunch of HID config options =y
  UPSTREAM: usb: raw-gadget: fix null-ptr-deref when reenabling endpoints
  UPSTREAM: usb: raw-gadget: documentation updates
  UPSTREAM: usb: raw-gadget: support stalling/halting/wedging endpoints
  UPSTREAM: usb: raw-gadget: fix gadget endpoint selection
  UPSTREAM: usb: raw-gadget: improve uapi headers comments
  UPSTREAM: usb: raw-gadget: fix return value of ep read ioctls
  UPSTREAM: usb: raw-gadget: fix raw_event_queue_fetch locking
  UPSTREAM: usb: raw-gadget: Fix copy_to/from_user() checks
  ANDROID: GKI: update abi definitions after enabling PCIEPORTBUS
  Revert "ANDROID: gki_defconfig: Drop CONFIG_PCIEPORTBUS"
  ANDROID: net: bpf: permit redirect from ingress L3 to egress L2 devices at near max mtu
  ANDROID: GKI: update abi definitions now that sdcardfs is gone
  Revert "ANDROID: sdcardfs: Enable modular sdcardfs"
  ANDROID: remove sdcardfs-needed exports from whitelist
  Revert "ANDROID: vfs: Add setattr2 for filesystems with per mount permissions"
  Revert "ANDROID: vfs: Add permission2 for filesystems with per mount permissions"
  Revert "ANDROID: vfs: add d_canonical_path for stacked filesystem support"
  Revert "ANDROID: fs: Restore vfs_path_lookup() export"
  ANDROID: sdcardfs: remove sdcardfs from system
  FROMGIT: driver core: Update device link status correctly for SYNC_STATE_ONLY links
  UPSTREAM: driver core: Fix handling of SYNC_STATE_ONLY + STATELESS device links
  UPSTREAM: driver core: Fix SYNC_STATE_ONLY device link implementation
  Revert "ANDROID: Incremental fs: Avoid continually recalculating hashes"
  ANDROID: remove unused variable
  Linux 5.4.43
  sched/fair: Fix enqueue_task_fair() warning some more
  sched/fair: Fix reordering of enqueue/dequeue_task_fair()
  sched/fair: Reorder enqueue/dequeue_task_fair path
  tpm: check event log version before reading final events
  rxrpc: Fix ack discard
  rxrpc: Trace discarded ACKs
  iio: adc: stm32-dfsdm: fix device used to request dma
  iio: adc: stm32-dfsdm: Use dma_request_chan() instead dma_request_slave_channel()
  iio: adc: stm32-adc: fix device used to request dma
  iio: adc: stm32-adc: Use dma_request_chan() instead dma_request_slave_channel()
  x86/unwind/orc: Fix unwind_get_return_address_ptr() for inactive tasks
  flow_dissector: Drop BPF flow dissector prog ref on netns cleanup
  s390/kexec_file: fix initrd location for kdump kernel
  rxrpc: Fix a memory leak in rxkad_verify_response()
  rxrpc: Fix the excessive initial retransmission timeout
  kasan: disable branch tracing for core runtime
  rapidio: fix an error in get_user_pages_fast() error handling
  device-dax: don't leak kernel memory to user space after unloading kmem
  s390/kaslr: add support for R_390_JMP_SLOT relocation type
  s390/pci: Fix s390_mmio_read/write with MIO
  ipack: tpci200: fix error return code in tpci200_register()
  mei: release me_cl object reference
  tty: serial: add missing spin_lock_init for SiFive serial console
  misc: rtsx: Add short delay after exit from ASPM
  iio: adc: ti-ads8344: Fix channel selection
  iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()'
  iio: sca3000: Remove an erroneous 'get_device()'
  staging: greybus: Fix uninitialized scalar variable
  staging: kpc2000: fix error return code in kp2000_pcie_probe()
  staging: iio: ad2s1210: Fix SPI reading
  media: fdp1: Fix R-Car M3-N naming in debug message
  Revert "gfs2: Don't demote a glock until its revokes are written"
  kbuild: Remove debug info from kallsyms linking
  bpf: Avoid setting bpf insns pages read-only when prog is jited
  powerpc/64s: Disable STRICT_KERNEL_RWX
  powerpc: Remove STRICT_KERNEL_RWX incompatibility with RELOCATABLE
  drm/i915: Propagate error from completed fences
  drm/i915/gvt: Init DPLL/DDI vreg for virtual display instead of inheritance.
  vsprintf: don't obfuscate NULL and error pointers
  dmaengine: owl: Use correct lock in owl_dma_get_pchan()
  dmaengine: dmatest: Restore default for channel
  drm/etnaviv: Fix a leak in submit_pin_objects()
  dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()'
  apparmor: Fix aa_label refcnt leak in policy_update
  apparmor: fix potential label refcnt leak in aa_change_profile
  apparmor: Fix use-after-free in aa_audit_rule_init
  drm/etnaviv: fix perfmon domain interation
  arm64: Fix PTRACE_SYSEMU semantics
  scsi: target: Put lun_ref at end of tmr processing
  scsi: qla2xxx: Do not log message when reading port speed via sysfs
  ALSA: hda/realtek - Add more fixup entries for Clevo machines
  ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Xtreme
  ALSA: pcm: fix incorrect hw_base increase
  ALSA: iec1712: Initialize STDSP24 properly when using the model=staudio option
  KVM: x86: Fix pkru save/restore when guest CR4.PKE=0, move it to x86.c
  ALSA: hda/realtek: Enable headset mic of ASUS UX581LV with ALC295
  ALSA: hda/realtek - Enable headset mic of ASUS UX550GE with ALC295
  ALSA: hda/realtek - Enable headset mic of ASUS GL503VM with ALC295
  ALSA: hda/realtek: Add quirk for Samsung Notebook
  ALSA: hda/realtek - Add HP new mute led supported for ALC236
  ALSA: hda/realtek - Add supported new mute Led for HP
  ALSA: hda: Manage concurrent reg access more properly
  ALSA: hda: patch_realtek: fix empty macro usage in if block
  ALSA: hda - constify and cleanup static NodeID tables
  scripts/gdb: repair rb_first() and rb_last()
  ARM: futex: Address build warning
  KVM: selftests: Fix build for evmcs.h
  drm/amd/display: Prevent dpcd reads with passive dongles
  iommu/amd: Call domain_flush_complete() in update_domain()
  platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA
  USB: core: Fix misleading driver bug report
  stmmac: fix pointer check after utilization in stmmac_interrupt
  ceph: fix double unlock in handle_cap_export()
  HID: quirks: Add HID_QUIRK_NO_INIT_REPORTS quirk for Dell K12A keyboard-dock
  gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp()
  x86/apic: Move TSC deadline timer debug printk
  ftrace/selftest: make unresolved cases cause failure if --fail-unresolved set
  ibmvnic: Skip fatal error reset after passive init
  x86/mm/cpa: Flush direct map alias during cpa
  HID: i2c-hid: reset Synaptics SYNA2393 on resume
  scsi: ibmvscsi: Fix WARN_ON during event pool release
  net/ena: Fix build warning in ena_xdp_set()
  component: Silence bind error on -EPROBE_DEFER
  aquantia: Fix the media type of AQC100 ethernet controller in the driver
  vhost/vsock: fix packet delivery order to monitoring devices
  configfs: fix config_item refcnt leak in configfs_rmdir()
  scsi: qla2xxx: Delete all sessions before unregister local nvme port
  scsi: qla2xxx: Fix hang when issuing nvme disconnect-all in NPIV
  HID: alps: ALPS_1657 is too specific; use U1_UNICORN_LEGACY instead
  HID: alps: Add AUI1657 device ID
  HID: multitouch: add eGalaxTouch P80H84 support
  gcc-common.h: Update for GCC 10
  net: drop_monitor: use IS_REACHABLE() to guard net_dm_hw_report()
  kbuild: avoid concurrency issue in parallel building dtbs and dtbs_check
  mtd: Fix mtd not registered due to nvmem name collision
  afs: Don't unlock fetched data pages until the op completes successfully
  ubi: Fix seq_file usage in detailed_erase_block_info debugfs file
  i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()'
  evm: Fix a small race in init_desc()
  iommu/amd: Fix over-read of ACPI UID from IVRS table
  i2c: fix missing pm_runtime_put_sync in i2c_device_probe
  ubifs: remove broken lazytime support
  fix multiplication overflow in copy_fdtable()
  mtd: spinand: Propagate ECC information to the MTD structure
  ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactive
  ubifs: fix wrong use of crypto_shash_descsize()
  ima: Fix return value of ima_write_policy()
  evm: Check also if *tfm is an error pointer in init_desc()
  ima: Set file->f_mode instead of file->f_flags in ima_calc_file_hash()
  KVM: SVM: Fix potential memory leak in svm_cpu_init()
  i2c: dev: Fix the race between the release of i2c_dev and cdev
  ANDROID: scsi: ufs: Handle clocks when lrbp fails
  ANDROID: ABI/Whitelist: add erofs whitelist to unisoc whitelist
  ANDROID: GKI: Update abi for 5.4.42 update
  UPSTREAM: serial: samsung: 32-bit access for TX/RX hold registers
  BACKPORT: serial: samsung: dt-bindings: Add reg-io-width compatible
  UPSTREAM: serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg
  ANDROID: fscrypt: handle direct I/O with IV_INO_LBLK_32
  BACKPORT: FROMLIST: fscrypt: add support for IV_INO_LBLK_32 policies
  Linux 5.4.42
  bpf: Test_progs, fix test_get_stack_rawtp_err.c build
  selftest/bpf: fix backported test_select_reuseport selftest changes
  libbpf: Extract and generalize CPU mask parsing logic
  Makefile: disallow data races on gcc-10 as well
  KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce
  bpf: Fix sk_psock refcnt leak when receiving message
  SUNRPC: Revert 241b1f419f ("SUNRPC: Remove xdr_buf_trim()")
  ARM: dts: r8a7740: Add missing extal2 to CPG node
  arm64: dts: renesas: r8a77980: Fix IPMMU VIP[01] nodes
  ARM: dts: r8a73a4: Add missing CMT1 interrupts
  arm64: dts: imx8mn: Change SDMA1 ahb clock for imx8mn
  arm64: dts: rockchip: Rename dwc3 device nodes on rk3399 to make dtc happy
  arm64: dts: rockchip: Replace RK805 PMIC node name with "pmic" on rk3328 boards
  arm64: dts: meson-g12-common: fix dwc2 clock names
  arm64: dts: meson-g12b-khadas-vim3: add missing frddr_a status property
  clk: Unlink clock if failed to prepare or enable
  Revert "ALSA: hda/realtek: Fix pop noise on ALC225"
  usb: gadget: legacy: fix error return code in cdc_bind()
  usb: gadget: legacy: fix error return code in gncm_bind()
  usb: gadget: audio: Fix a missing error return value in audio_bind()
  usb: gadget: net2272: Fix a memory leak in an error handling path in 'net2272_plat_probe()'
  fanotify: fix merging marks masks with FAN_ONDIR
  dwc3: Remove check for HWO flag in dwc3_gadget_ep_reclaim_trb_sg()
  clk: rockchip: fix incorrect configuration of rk3228 aclk_gpu* clocks
  exec: Move would_dump into flush_old_exec
  x86/unwind/orc: Fix error handling in __unwind_start()
  x86: Fix early boot crash on gcc-10, third try
  cifs: fix leaked reference on requeued write
  powerpc/32s: Fix build failure with CONFIG_PPC_KUAP_DEBUG
  drm/amd/display: add basic atomic check for cursor plane
  ARM: dts: imx6dl-yapp4: Fix Ursa board Ethernet connection
  ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries
  ARM: dts: dra7: Fix bus_dma_limit for PCIe
  Make the "Reducing compressed framebufer size" message be DRM_INFO_ONCE()
  usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list
  USB: gadget: fix illegal array access in binding with UDC
  usb: cdns3: gadget: prev_req->trb is NULL for ep0
  usb: host: xhci-plat: keep runtime active when removing host
  usb: core: hub: limit HUB_QUIRK_DISABLE_AUTOSUSPEND to USB5534B
  ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset
  ALSA: rawmidi: Fix racy buffer resize under concurrent accesses
  ALSA: hda/realtek - Add COEF workaround for ASUS ZenBook UX431DA
  ALSA: hda/realtek - Limit int mic boost for Thinkpad T530
  USB: usbfs: fix mmap dma mismatch
  usb: usbfs: correct kernel->user page attribute mismatch
  gcc-10: avoid shadowing standard library 'free()' in crypto
  gcc-10: mark more functions __init to avoid section mismatch warnings
  gcc-10 warnings: fix low-hanging fruit
  gcc-10: disable 'restrict' warning for now
  gcc-10: disable 'stringop-overflow' warning for now
  gcc-10: disable 'array-bounds' warning for now
  gcc-10: disable 'zero-length-bounds' warning for now
  Stop the ad-hoc games with -Wno-maybe-initialized
  net/rds: Use ERR_PTR for rds_message_alloc_sgs()
  pnp: Use list_for_each_entry() instead of open coding
  NFSv3: fix rpc receive buffer size for MOUNT call
  mm, memcg: fix inconsistent oom event behavior
  s390/ism: fix error return code in ism_probe()
  hwmon: (da9052) Synchronize access with mfd
  RDMA/iw_cxgb4: Fix incorrect function parameters
  RDMA/core: Fix double put of resource
  IB/core: Fix potential NULL pointer dereference in pkey cache
  IB/mlx4: Test return value of calls to ib_get_cached_pkey
  RDMA/rxe: Always return ERR_PTR from rxe_create_mmap_info()
  netfilter: nft_set_rbtree: Add missing expired checks
  netfilter: nft_set_rbtree: Introduce and use nft_rbtree_interval_start()
  SUNRPC: Signalled ASYNC tasks need to exit
  nfs: fix NULL deference in nfs4_get_valid_delegation
  arm64: fix the flush_icache_range arguments in machine_kexec
  drm/i915/gvt: Fix kernel oops for 3-level ppgtt guest
  netfilter: conntrack: avoid gcc-10 zero-length-bounds warning
  NFSv4: Fix fscache cookie aux_data to ensure change_attr is included
  nfs: fscache: use timespec64 in inode auxdata
  NFS: Fix fscache super_cookie index_key from changing after umount
  drm/amdgpu: force fbdev into vram
  fork: prevent accidental access to clone3 features
  gfs2: More gfs2_find_jhead fixes
  mmc: block: Fix request completion in the CQE timeout path
  mmc: core: Fix recursive locking issue in CQE recovery path
  mmc: core: Check request type before completing the request
  mmc: sdhci-pci-gli: Fix can not access GL9750 after reboot from Windows 10
  mmc: alcor: Fix a resource leak in the error path for ->probe()
  bpf, sockmap: bpf_tcp_ingress needs to subtract bytes from sg.size
  bpf, sockmap: msg_pop_data can incorrecty set an sge length
  drm/i915: Don't enable WaIncreaseLatencyIPCEnabled when IPC is disabled
  i40iw: Fix error handling in i40iw_manage_arp_cache()
  ALSA: firewire-lib: fix 'function sizeof not defined' error of tracepoints format
  bpf: Fix error return code in map_lookup_and_delete_elem()
  pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler
  pinctrl: qcom: fix wrong write in update_dual_edge
  pinctrl: baytrail: Enable pin configuration setting for GPIO chip
  pinctrl: sunrisepoint: Fix PAD lock register offset for SPT-H
  ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake()
  IB/hfi1: Fix another case where pq is left on waitlist
  mmc: sdhci-pci-gli: Fix no irq handler from suspend
  gfs2: Another gfs2_walk_metadata fix
  ALSA: hda/realtek - Fix S3 pop noise on Dell Wyse
  ipc/util.c: sysvipc_find_ipc() incorrectly updates position index
  drm/amdgpu: invalidate L2 before SDMA IBs (v2)
  drm/amdgpu: simplify padding calculations (v2)
  drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper()
  drm/amd/display: Update downspread percent to match spreadsheet for DCN2.1
  drm/amd/display: check if REFCLK_CNTL register is present
  drm/amd/powerplay: avoid using pm_en before it is initialized revised
  ALSA: hda/hdmi: fix race in monitor detection during probe
  cpufreq: intel_pstate: Only mention the BIOS disabling turbo mode once
  selftests/ftrace: Check the first record for kprobe_args_type.tc
  dmaengine: mmp_tdma: Reset channel error on release
  dmaengine: mmp_tdma: Do not ignore slave config validation errors
  dmaengine: pch_dma.c: Avoid data race between probe and irq handler
  riscv: fix vdso build with lld
  umh: fix memory leak on execve failure
  r8169: re-establish support for RTL8401 chip version
  nfp: abm: fix error return code in nfp_abm_vnic_alloc()
  net: tcp: fix rx timestamp behavior for tcp_recvmsg
  netprio_cgroup: Fix unlimited memory leak of v2 cgroups
  net: ipv4: really enforce backoff for redirects
  net: dsa: loop: Add module soft dependency
  hinic: fix a bug of ndo_stop
  dpaa2-eth: prevent array underflow in update_cls_rule()
  virtio_net: fix lockdep warning on 32 bit
  tcp: fix SO_RCVLOWAT hangs with fat skbs
  tcp: fix error recovery in tcp_zerocopy_receive()
  Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu"
  pppoe: only process PADT targeted at local interfaces
  net: stmmac: fix num_por initialization
  net: phy: fix aneg restart in phy_ethtool_set_eee
  netlabel: cope with NULL catmap
  net: fix a potential recursive NETDEV_FEAT_CHANGE
  dpaa2-eth: properly handle buffer size restrictions
  mmc: sdhci-acpi: Add SDHCI_QUIRK2_BROKEN_64_BIT_DMA for AMDI0040
  selftests/bpf: fix goto cleanup label not defined
  scsi: sg: add sg_remove_request in sg_write
  net_sched: fix tcm_parent in tc filter dump
  sun6i: dsi: fix gcc-4.8
  virtio-blk: handle block_device_operations callbacks after hot unplug
  drop_monitor: work around gcc-10 stringop-overflow warning
  ftrace/selftests: workaround cgroup RT scheduling issues
  net: moxa: Fix a potential double 'free_irq()'
  net/sonic: Fix a resource leak in an error handling path in 'jazz_sonic_probe()'
  SUNRPC: Fix GSS privacy computation of auth->au_ralign
  SUNRPC: Add "@len" parameter to gss_unwrap()
  gpio: pca953x: Fix pca953x_gpio_set_config
  KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read
  net: phy: microchip_t1: add lan87xx_phy_init to initialize the lan87xx phy.
  shmem: fix possible deadlocks on shmlock_user_lock
  net: dsa: Do not make user port errors fatal
  f2fs: flush dirty meta pages when flushing them
  f2fs: fix checkpoint=disable:%u%%
  f2fs: rework filename handling
  f2fs: split f2fs_d_compare() from f2fs_match_name()
  f2fs: don't leak filename in f2fs_try_convert_inline_dir()
  ANDROID: clang: update to 11.0.1
  FROMLIST: x86_64: fix jiffies ODR violation
  ANDROID: ABI/Whitelist: add ufs whitelist to unisoc whitelist
  ANDROID: GKI: Enable net testing options
  ANDROID: fscrypt: set dun_bytes more precisely
  ANDROID: dm-default-key: set dun_bytes more precisely
  ANDROID: block: backport the ability to specify max_dun_bytes
  ANDROID: Incremental fs: wake up log pollers less often
  ANDROID: Incremental fs: Fix scheduling while atomic error
  ANDROID: Incremental fs: Avoid continually recalculating hashes
  ANDROID: export: Disable symbol trimming on modules
  ANDROID: ABI/Whitelist: add the symbol sdhci_request_atomic to unisoc whitelist
  FROMGIT: media: uapi: h264: Add new profile and levels
  FROMGIT: media: v4l2-ctrl: Add H264 profile and levels
  ANDROID: GKI: abi update due to mmc patches merged
  FROMGIT: mmc: host: sdhci-sprd: Implement the request_atomic() API
  FROMGIT: mmc: host: sdhci: Implement the request_atomic() API
  FROMGIT: mmc: host: Introduce the request_atomic() for the host
  FROMGIT: mmc: sdhci: Reduce maximum time under spinlock in sdhci_send_command()
  FROMGIT: mmc: sdhci: Tidy sdhci_request() a bit
  FROMGIT: mmc: sdhci: Remove unneeded forward declaration of sdhci_finish_data()
  FROMGIT: mmc: sdhci: Stop exporting sdhci_send_command()
  FROMGIT: mmc: sdhci: Add helpers for the auto-CMD23 flag
  FROMGIT: mmc: sdhci-sprd: Drop redundant cap flags
  ANDROID: GKI: update abi definition due to 5.4.41 merge
  Linux 5.4.41
  fanotify: merge duplicate events on parent and child
  fsnotify: replace inode pointer with an object id
  bdi: add a ->dev_name field to struct backing_dev_info
  bdi: move bdi_dev_name out of line
  mm, memcg: fix error return value of mem_cgroup_css_alloc()
  scripts/decodecode: fix trapping instruction formatting
  iommu/virtio: Reverse arguments to list_add
  objtool: Fix stack offset tracking for indirect CFAs
  netfilter: nf_osf: avoid passing pointer to local var
  netfilter: nat: never update the UDP checksum when it's 0
  arch/x86/kvm/svm/sev.c: change flag passed to GUP fast in sev_pin_memory()
  KVM: x86: Fixes posted interrupt check for IRQs delivery modes
  x86/unwind/orc: Fix premature unwind stoppage due to IRET frames
  x86/unwind/orc: Fix error path for bad ORC entry type
  x86/unwind/orc: Prevent unwinding before ORC initialization
  x86/unwind/orc: Don't skip the first frame for inactive tasks
  x86/entry/64: Fix unwind hints in rewind_stack_do_exit()
  x86/entry/64: Fix unwind hints in kernel exit path
  x86/entry/64: Fix unwind hints in register clearing code
  batman-adv: Fix refcnt leak in batadv_v_ogm_process
  batman-adv: Fix refcnt leak in batadv_store_throughput_override
  batman-adv: Fix refcnt leak in batadv_show_throughput_override
  batman-adv: fix batadv_nc_random_weight_tq
  iocost: protect iocg->abs_vdebt with iocg->waitq.lock
  riscv: set max_pfn to the PFN of the last page
  coredump: fix crash when umh is disabled
  staging: gasket: Check the return value of gasket_get_bar_index()
  ceph: demote quotarealm lookup warning to a debug message
  ceph: fix endianness bug when handling MDS session feature bits
  mm: limit boost_watermark on small zones
  mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous()
  eventpoll: fix missing wakeup for ovflist in ep_poll_callback
  epoll: atomically remove wait entry on wake up
  ipc/mqueue.c: change __do_notify() to bypass check_kill_permission()
  drm: ingenic-drm: add MODULE_DEVICE_TABLE
  arm64: hugetlb: avoid potential NULL dereference
  KVM: arm64: Fix 32bit PC wrap-around
  KVM: arm: vgic: Fix limit condition when writing to GICD_I[CS]ACTIVER
  KVM: VMX: Explicitly clear RFLAGS.CF and RFLAGS.ZF in VM-Exit RSB path
  KVM: s390: Remove false WARN_ON_ONCE for the PQAP instruction
  crypto: arch/nhpoly1305 - process in explicit 4k chunks
  tracing: Add a vmalloc_sync_mappings() for safe measure
  USB: serial: garmin_gps: add sanity checking for data length
  usb: chipidea: msm: Ensure proper controller reset using role switch API
  USB: uas: add quirk for LaCie 2Big Quadra
  HID: wacom: Report 2nd-gen Intuos Pro S center button status over BT
  HID: usbhid: Fix race between usbhid_close() and usbhid_stop()
  Revert "HID: wacom: generic: read the number of expected touches on a per collection basis"
  sctp: Fix bundling of SHUTDOWN with COOKIE-ACK
  HID: wacom: Read HID_DG_CONTACTMAX directly for non-generic devices
  net: mvpp2: cls: Prevent buffer overflow in mvpp2_ethtool_cls_rule_del()
  net: mvpp2: prevent buffer overflow in mvpp22_rss_ctx()
  net/mlx5: Fix command entry leak in Internal Error State
  net/mlx5: Fix forced completion access non initialized command entry
  net/mlx5: DR, On creation set CQ's arm_db member to right value
  bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features().
  bnxt_en: Return error when allocating zero size context memory.
  bnxt_en: Improve AER slot reset.
  bnxt_en: Reduce BNXT_MSIX_VEC_MAX value to supported CQs per PF.
  bnxt_en: Fix VF anti-spoof filter setup.
  tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040
  tipc: fix partial topology connection closure
  sch_sfq: validate silly quantum values
  sch_choke: avoid potential panic in choke_reset()
  nfp: abm: fix a memory leak bug
  net: usb: qmi_wwan: add support for DW5816e
  net/tls: Fix sk_psock refcnt leak when in tls_data_ready()
  net/tls: Fix sk_psock refcnt leak in bpf_exec_tx_verdict()
  net: tc35815: Fix phydev supported/advertising mask
  net: stricter validation of untrusted gso packets
  net_sched: sch_skbprio: add message validation to skbprio_change()
  net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc()
  net: macsec: preserve ingress frame ordering
  net: macb: fix an issue about leak related system resources
  net: dsa: Do not leave DSA master with NULL netdev_ops
  neigh: send protocol value in neighbor create notification
  mlxsw: spectrum_acl_tcam: Position vchunk in a vregion list properly
  ipv6: Use global sernum for dst validation with nexthop objects
  fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks
  dp83640: reverse arguments to list_add_tail
  devlink: fix return value after hitting end in region read
  tty: xilinx_uartps: Fix missing id assignment to the console
  vt: fix unicode console freeing with a common interface
  drm/amdgpu: drop redundant cg/pg ungate on runpm enter
  drm/amdgpu: move kfd suspend after ip_suspend_phase1
  net: macb: Fix runtime PM refcounting
  tracing/kprobes: Fix a double initialization typo
  nvme: fix possible hang when ns scanning fails during error recovery
  nvme: refactor nvme_identify_ns_descs error handling
  USB: serial: qcserial: Add DW5816e support
  ANDROID: GKI: enable CONFIG_IRQ_TIME_ACCOUNTING
  ANDROID: GKI: Enable CONFIG_STATIC_USERMODEHELPER
  ANDROID: dm-default-key: Update key size for wrapped keys
  ANDROID: GKI: x86: Drop CONFIG_DEVPORT
  Linux 5.4.40
  PM / devfreq: Add missing locking while setting suspend_freq
  udp: document udp_rcv_segment special case for looped packets
  tools headers UAPI: Sync copy of arm64's asm/unistd.h with the kernel sources
  Revert "drm/amd/display: setting the DIG_MODE to the correct value."
  mm/mremap: Add comment explaining the untagging behaviour of mremap()
  libbpf: Fix readelf output parsing for Fedora
  cgroup, netclassid: remove double cond_resched
  mac80211: add ieee80211_is_any_nullfunc()
  ACPI: PM: s2idle: Fix comment in acpi_s2idle_prepare_late()
  platform/x86: GPD pocket fan: Fix error message when temp-limits are out of range
  x86/kvm: fix a missing-prototypes "vmread_error"
  ALSA: hda: Match both PCI ID and SSID for driver blacklist
  hexagon: define ioremap_uc
  hexagon: clean up ioremap
  mfd: intel-lpss: Use devm_ioremap_uc for MMIO
  lib: devres: add a helper function for ioremap_uc
  Revert "software node: Simplify software_node_release() function"
  drm/amdgpu: Fix oops when pp_funcs is unset in ACPI event
  sctp: Fix SHUTDOWN CTSN Ack in the peer restart case
  drm/i915: Extend WaDisableDARBFClkGating to icl,ehl,tgl
  net: systemport: suppress warnings on failed Rx SKB allocations
  net: bcmgenet: suppress warnings on failed Rx SKB allocations
  mac80211: sta_info: Add lockdep condition for RCU list usage
  lib/mpi: Fix building for powerpc with clang
  tracing: Fix memory leaks in trace_events_hist.c
  cifs: do not share tcons with DFS
  scripts/config: allow colons in option strings for sed
  cifs: protect updating server->dstaddr with a spinlock
  ASoC: rsnd: Fix "status check failed" spam for multi-SSI
  ASoC: rsnd: Don't treat master SSI in multi SSI setup as parent
  net: stmmac: Fix sub-second increment
  net: stmmac: fix enabling socfpga's ptp_ref_clock
  wimax/i2400m: Fix potential urb refcnt leak
  drm/amdgpu: Correctly initialize thermal controller for GPUs with Powerplay table v0 (e.g Hawaii)
  remoteproc: qcom_q6v5_mss: fix a bug in q6v5_probe()
  ASoC: codecs: hdac_hdmi: Fix incorrect use of list_for_each_entry
  ASoC: rsnd: Fix HDMI channel mapping for multi-SSI mode
  ASoC: rsnd: Fix parent SSI start/stop in multi-SSI mode
  usb: dwc3: gadget: Properly set maxpacket limit
  ASoC: topology: Fix endianness issue
  ASoC: sgtl5000: Fix VAG power-on handling
  selftests/ipc: Fix test failure seen after initial test run
  ASoC: topology: Check return value of soc_tplg_dai_config
  ASoC: topology: Check return value of pcm_new_ver
  ASoC: topology: Check soc_tplg_add_route return value
  ASoC: topology: Check return value of soc_tplg_*_create
  ASoC: topology: Check return value of soc_tplg_create_tlv
  drm/bridge: analogix_dp: Split bind() into probe() and real bind()
  vhost: vsock: kick send_pkt worker once device is started
  ANDROID: GKI: update abi definition due to FAIR_GROUP_SCHED removal
  ANDROID: GKI: Remove FAIR_GROUP_SCHED
  ANDROID: Drop ABI monitoring from KASAN build config
  ANDROID: Enforce KMI stability
  Linux 5.4.39
  selinux: properly handle multiple messages in selinux_netlink_send()
  arm64: vdso: Add -fasynchronous-unwind-tables to cflags
  dmaengine: dmatest: Fix process hang when reading 'wait' parameter
  dmaengine: dmatest: Fix iteration non-stop logic
  nfs: Fix potential posix_acl refcnt leak in nfs3_set_acl
  nvme: prevent double free in nvme_alloc_ns() error handling
  Fix use after free in get_tree_bdev()
  ALSA: opti9xx: shut up gcc-10 range warning
  i2c: aspeed: Avoid i2c interrupt status clear race condition.
  iommu/amd: Fix legacy interrupt remapping for x2APIC-enabled system
  scsi: target/iblock: fix WRITE SAME zeroing
  iommu/qcom: Fix local_base status check
  vfio/type1: Fix VA->PA translation for PFNMAP VMAs in vaddr_get_pfn()
  vfio: avoid possible overflow in vfio_iommu_type1_pin_pages
  i2c: iproc: generate stop event for slave writes
  RDMA/cm: Fix an error check in cm_alloc_id_priv()
  RDMA/cm: Fix ordering of xa_alloc_cyclic() in ib_create_cm_id()
  RDMA/core: Fix race between destroy and release FD object
  RDMA/core: Prevent mixed use of FDs between shared ufiles
  RDMA/siw: Fix potential siw_mem refcnt leak in siw_fastreg_mr()
  RDMA/mlx4: Initialize ib_spec on the stack
  RDMA/mlx5: Set GRH fields in query QP on RoCE
  scsi: qla2xxx: check UNLOADING before posting async work
  scsi: qla2xxx: set UNLOADING before waiting for session deletion
  ARM: dts: imx6qdl-sr-som-ti: indicate powering off wifi is safe
  dm multipath: use updated MPATHF_QUEUE_IO on mapping for bio-based mpath
  dm writecache: fix data corruption when reloading the target
  dm verity fec: fix hash block number in verity_fec_decode
  PM: hibernate: Freeze kernel threads in software_resume()
  PM: ACPI: Output correct message on target power state
  IB/rdmavt: Always return ERR_PTR from rvt_create_mmap_info()
  dlmfs_file_write(): fix the bogosity in handling non-zero *ppos
  Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM
  i2c: amd-mp2-pci: Fix Oops in amd_mp2_pci_init() error handling
  ALSA: pcm: oss: Place the plugin buffer overflow checks correctly
  ALSA: line6: Fix POD HD500 audio playback
  ALSA: hda/hdmi: fix without unlocked before return
  ALSA: usb-audio: Correct a typo of NuPrime DAC-10 USB ID
  ALSA: hda/realtek - Two front mics on a Lenovo ThinkCenter
  crypto: caam - fix the address of the last entry of S/G
  mmc: meson-mx-sdio: remove the broken ->card_busy() op
  mmc: meson-mx-sdio: Set MMC_CAP_WAIT_WHILE_BUSY
  mmc: sdhci-msm: Enable host capabilities pertains to R1b response
  mmc: sdhci-pci: Fix eMMC driver strength for BYT-based controllers
  mmc: sdhci-xenon: fix annoying 1.8V regulator warning
  mmc: cqhci: Avoid false "cqhci: CQE stuck on" by not open-coding timeout loop
  btrfs: transaction: Avoid deadlock due to bad initialization timing of fs_info::journal_info
  btrfs: fix partial loss of prealloc extent past i_size after fsync
  btrfs: fix block group leak when removing fails
  btrfs: fix transaction leak in btrfs_recover_relocation
  NFSv4.1: fix handling of backchannel binding in BIND_CONN_TO_SESSION
  drm/qxl: qxl_release use after free
  drm/qxl: qxl_release leak in qxl_hw_surface_alloc()
  drm/qxl: qxl_release leak in qxl_draw_dirty_fb()
  drm/amd/display: Fix green screen issue after suspend
  drm/edid: Fix off-by-one in DispID DTD pixel clock
  dma-buf: Fix SET_NAME ioctl uapi
  ANDROID: Rename build.config.gki.arch_kasan
  ANDROID: Incremental fs: Fix issues with very large files
  ANDROID: Correct build.config branch name
  FROMGIT: f2fs: fix missing check for f2fs_unlock_op
  ANDROID: Fix build.config.gki-debug
  UPSTREAM: vdso: Fix clocksource.h macro detection
  Linux 5.4.38
  Revert "ASoC: meson: axg-card: fix codec-to-codec link setup"
  ANDROID: GKI: update abi definition due to added padding
  ANDROID: GKI: user_namespace.h: add Android ABI padding to a structure
  ANDROID: GKI: timer.h: add Android ABI padding to a structure
  ANDROID: GKI: quota.h: add Android ABI padding to some structures
  ANDROID: GKI: mmu_notifier.h: add Android ABI padding to some structures
  ANDROID: GKI: mm.h: add Android ABI padding to a structure
  ANDROID: GKI: kobject.h: add Android ABI padding to some structures
  ANDROID: GKI: kernfs.h: add Android ABI padding to some structures
  ANDROID: GKI: irqdomain.h: add Android ABI padding to a structure
  ANDROID: GKI: ioport.h: add Android ABI padding to a structure
  ANDROID: GKI: iomap.h: add Android ABI padding to a structure
  ANDROID: GKI: hrtimer.h: add Android ABI padding to a structure
  ANDROID: GKI: genhd.h: add Android ABI padding to some structures
  ANDROID: GKI: ethtool.h: add Android ABI padding to a structure
  ANDROID: GKI: dma-mapping.h: add Android ABI padding to a structure
  ANDROID: GKI: sched: add Android ABI padding to some structures
  ANDROID: GKI: networking: add Android ABI padding to a lot of networking structures
  ANDROID: GKI: blk_types.h: add Android ABI padding to a structure
  ANDROID: GKI: scsi.h: add Android ABI padding to a structure
  ANDROID: GKI: pci: add Android ABI padding to some structures
  ANDROID: GKI: update abi definition due to 5.4.37 merge
  Linux 5.4.37
  ASoC: stm32: spdifrx: fix regmap status check
  ASoC: soc-core: disable route checks for legacy devices
  ext4: check for non-zero journal inum in ext4_calculate_overhead
  qed: Fix use after free in qed_chain_free
  net: use indirect call wrappers for skb_copy_datagram_iter()
  Crypto: chelsio - Fixes a hang issue during driver registration
  qed: Fix race condition between scheduling and destroying the slowpath workqueue
  taprio: do not use BIT() in TCA_TAPRIO_ATTR_FLAG_* definitions
  hwmon: (jc42) Fix name to have no illegal characters
  blk-mq: Put driver tag in blk_mq_dispatch_rq_list() when no budget
  ext4: convert BUG_ON's to WARN_ON's in mballoc.c
  ext4: increase wait time needed before reuse of deleted inode numbers
  ext4: use matching invalidatepage in ext4_writepage
  arm64: Delete the space separator in __emit_inst
  mac80211: fix channel switch trigger from unknown mesh peer
  net: stmmac: socfpga: Allow all RGMII modes
  ALSA: hda: call runtime_allow() for all hda controllers
  xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status
  objtool: Support Clang non-section symbols in ORC dump
  objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings
  scsi: target: tcmu: reset_ring should reset TCMU_DEV_BIT_BROKEN
  scsi: target: fix PR IN / READ FULL STATUS for FC
  ALSA: hda: Explicitly permit using autosuspend if runtime PM is supported
  ALSA: hda: Keep the controller initialization even if no codecs found
  ALSA: hda: Release resources at error in delayed probe
  xfs: fix partially uninitialized structure in xfs_reflink_remap_extent
  afs: Fix length of dump of bad YFSFetchStatus record
  signal: check sig before setting info in kill_pid_usb_asyncio
  x86: hyperv: report value of misc_features
  net: fec: set GPR bit on suspend by DT configuration.
  libbpf: Initialize *nl_pid so gcc 10 is happy
  bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B
  xfs: clear PF_MEMALLOC before exiting xfsaild thread
  mm: shmem: disable interrupt when acquiring info->lock in userfaultfd_copy path
  bpf, x86_32: Fix logic error in BPF_LDX zero-extension
  bpf, x86_32: Fix clobbering of dst for BPF_JSET
  bpf, x86_32: Fix incorrect encoding in BPF_LDX zero-extension
  um: ensure `make ARCH=um mrproper` removes arch/$(SUBARCH)/include/generated/
  blk-iocost: Fix error on iocost_ioc_vrate_adj
  PM: sleep: core: Switch back to async_schedule_dev()
  netfilter: nat: fix error handling upon registering inet hook
  perf/core: fix parent pid/tid in task exit events
  sched/core: Fix reset-on-fork from RT with uclamp
  net/mlx5: Fix failing fw tracer allocation on s390
  s390/pci: do not set affinity for floating irqs
  cpumap: Avoid warning when CONFIG_DEBUG_PER_CPU_MAPS is enabled
  ARM: dts: bcm283x: Disable dsi0 node
  PCI: Move Apex Edge TPU class quirk to fix BAR assignment
  PCI: Add ACS quirk for Zhaoxin Root/Downstream Ports
  PCI: Add Zhaoxin Vendor ID
  PCI: Unify ACS quirk desired vs provided checking
  PCI: Make ACS quirk implementations more uniform
  PCI: Add ACS quirk for Zhaoxin multi-function devices
  PCI: Avoid ASMedia XHCI USB PME# from D0 defect
  net/mlx5e: Get the latest values from counters in switchdev mode
  net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ overruns
  svcrdma: Fix leak of svc_rdma_recv_ctxt objects
  svcrdma: Fix trace point use-after-free race
  xfs: acquire superblock freeze protection on eofblocks scans
  net/cxgb4: Check the return from t4_query_params properly
  rxrpc: Fix DATA Tx to disable nofrag for UDP on AF_INET6 socket
  i2c: altera: use proper variable to hold errno
  bpf: Forbid XADD on spilled pointers for unprivileged users
  nfsd: memory corruption in nfsd4_lock()
  drivers: soc: xilinx: fix firmware driver Kconfig dependency
  ASoC: wm8960: Fix wrong clock after suspend & resume
  ASoC: meson: axg-card: fix codec-to-codec link setup
  ASoC: tas571x: disable regulators on failed probe
  ASoC: q6dsp6: q6afe-dai: add missing channels to MI2S DAIs
  s390/ftrace: fix potential crashes when switching tracers
  counter: 104-quad-8: Add lock guards - generic interface
  propagate_one(): mnt_set_mountpoint() needs mount_lock
  iio:ad7797: Use correct attribute_group
  afs: Fix to actually set AFS_SERVER_FL_HAVE_EPOCH
  afs: Make record checking use TASK_UNINTERRUPTIBLE when appropriate
  usb: gadget: udc: atmel: Fix vbus disconnect handling
  usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete
  kbuild: fix DT binding schema rule again to avoid needless rebuilds
  usb: dwc3: gadget: Do link recovery for SS and SSP
  ASoC: stm32: sai: fix sai probe
  printk: queue wake_up_klogd irq_work only if per-CPU areas are ready
  ubifs: Fix ubifs_tnc_lookup() usage in do_kill_orphans()
  remoteproc: Fix wrong rvring index computation
  ANDROID: Update ABI representation after enabling CONFIG_HID_BATTERY_STRENGTH
  ANDROID: GKI: enable CONFIG_HID_BATTERY_STRENGTH
  ANDROID: Update ABI representation after adding exynos whitelist
  ANDROID: Add abi_gki_aarch64_exynos_whitelist
  ANDROID: build.config.gki.aarch64: Enable WHITELIST_STRICT_MODE
  ANDROID: abi_gki_aarch64_sunxi_whitelist: remove stale symbols
  ANDROID: abi_gki_aarch64_unisoc_whitelist: remove stale symbols
  ANDROID: abi_gki_aarch64_qcom_whitelist: Sync with android-5.4
  ANDROID: abi_gki_aarch64_hikey960_whitelist: remove stale symbols
  ANDROID: Incremental fs: Add setattr call
  ANDROID: GKI: enable CONFIG_RTC_SYSTOHC on x86
  ANDROID: drivers: gpu: drm: fix export symbol type
  ANDROID: driver: gpu: drm: fix export symbol types
  ANDROID: drm: kirin: fix export symbol type
  ANDROID: iommu: fix export symbol type
  ANDROID: ion: fix export symbol type
  ANDROID: mm/memory.c: fix export symbol type
  ANDROID: sdcardfs: fix export symbol type
  ANDROID: SoC: core: fix export symbol type
  ANDROID: ufshcd-crypto: fix export symbol type
  ANDROID: GKI: update abi and cf/gf whitelists
  ANDROID: GKI: enable CONFIG_RTC_SYSTOHC
  ANDROID: virt_wifi: fix export symbol types
  ANDROID: vfs: fix export symbol type
  ANDROID: vfs: fix export symbol types
  ANDROID: fscrypt: fix export symbol type
  ANDROID: cfi: fix export symbol types
  ANDROID: bpf: fix export symbol type
  Linux 5.4.36
  s390/mm: fix page table upgrade vs 2ndary address mode accesses
  compat: ARM64: always include asm-generic/compat.h
  powerpc/mm: Fix CONFIG_PPC_KUAP_DEBUG on PPC32
  powerpc/kuap: PPC_KUAP_DEBUG should depend on PPC_KUAP
  Revert "serial: uartps: Register own uart console and driver structures"
  Revert "serial: uartps: Move Port ID to device data structure"
  Revert "serial: uartps: Change uart ID port allocation"
  Revert "serial: uartps: Do not allow use aliases >= MAX_UART_INSTANCES"
  Revert "serial: uartps: Fix error path when alloc failed"
  Revert "serial: uartps: Use the same dynamic major number for all ports"
  Revert "serial: uartps: Fix uartps_major handling"
  serial: sh-sci: Make sure status register SCxSR is read in correct sequence
  xhci: Don't clear hub TT buffer on ep0 protocol stall
  xhci: prevent bus suspend if a roothub port detected a over-current condition
  xhci: Fix handling halted endpoint even if endpoint ring appears empty
  usb: typec: altmode: Fix typec_altmode_get_partner sometimes returning an invalid pointer
  usb: typec: tcpm: Ignore CC and vbus changes in PORT_RESET change
  usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset()
  usb: dwc3: gadget: Fix request completion check
  fpga: dfl: pci: fix return value of cci_pci_sriov_configure
  UAS: fix deadlock in error handling and PM flushing work
  UAS: no use logging any details in case of ENODEV
  cdc-acm: introduce a cool down
  cdc-acm: close race betrween suspend() and acm_softint
  staging: vt6656: Power save stop wake_up_count wrap around.
  staging: vt6656: Fix pairwise key entry save.
  staging: vt6656: Fix drivers TBTT timing counter.
  staging: vt6656: Fix calling conditions of vnt_set_bss_mode
  staging: vt6656: Don't set RCR_MULTICAST or RCR_BROADCAST by default.
  vt: don't use kmalloc() for the unicode screen buffer
  vt: don't hardcode the mem allocation upper bound
  staging: comedi: Fix comedi_device refcnt leak in comedi_open
  staging: comedi: dt2815: fix writing hi byte of analog output
  powerpc/setup_64: Set cache-line-size based on cache-block-size
  ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y
  cifs: fix uninitialised lease_key in open_shroot()
  iwlwifi: mvm: fix inactive TID removal return value usage
  iwlwifi: mvm: Do not declare support for ACK Enabled Aggregation
  iwlwifi: mvm: limit maximum queue appropriately
  iwlwifi: mvm: beacon statistics shouldn't go backwards
  iwlwifi: pcie: actually release queue memory in TVQM
  SUNRPC: Fix backchannel RPC soft lockups
  mac80211: populate debugfs only after cfg80211 init
  ASoC: dapm: fixup dapm kcontrol widget
  audit: check the length of userspace generated audit records
  signal: Avoid corrupting si_pid and si_uid in do_notify_parent
  usb-storage: Add unusual_devs entry for JMicron JMS566
  tty: rocket, avoid OOB access
  tty: hvc: fix buffer overflow during hvc_alloc().
  KVM: VMX: Enable machine check support for 32bit targets
  KVM: Check validity of resolved slot when searching memslots
  KVM: s390: Return last valid slot if approx index is out-of-bounds
  tpm: ibmvtpm: retry on H_CLOSED in tpm_ibmvtpm_send()
  tpm: fix wrong return value in tpm_pcr_extend
  tpm/tpm_tis: Free IRQ if probing fails
  ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
  ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif
  ALSA: hda/hdmi: Add module option to disable audio component binding
  ALSA: hda/realtek - Add new codec supported for ALC245
  ALSA: hda/realtek - Fix unexpected init_amp override
  ALSA: usx2y: Fix potential NULL dereference
  tools/vm: fix cross-compile build
  mm/ksm: fix NULL pointer dereference when KSM zero page is enabled
  mm/hugetlb: fix a addressing exception caused by huge_pte_offset
  coredump: fix null pointer dereference on coredump
  staging: gasket: Fix incongruency in handling of sysfs entries creation
  vmalloc: fix remap_vmalloc_range() bounds checks
  tty: serial: owl: add "much needed" clk_prepare_enable()
  USB: hub: Revert commit bd0e6c9614 ("usb: hub: try old enumeration scheme first for high speed devices")
  USB: hub: Fix handling of connect changes during sleep
  USB: core: Fix free-while-in-use bug in the USB S-Glibrary
  USB: early: Handle AMD's spec-compliant identifiers, too
  USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 RGB RAPIDFIRE
  USB: sisusbvga: Change port variable from signed to unsigned
  iio: xilinx-xadc: Make sure not exceed maximum samplerate
  iio: xilinx-xadc: Fix sequencer configuration for aux channels in simultaneous mode
  iio: xilinx-xadc: Fix clearing interrupt when enabling trigger
  iio: xilinx-xadc: Fix ADC-B powerdown
  iio: adc: ti-ads8344: properly byte swap value
  iio: adc: stm32-adc: fix sleep in atomic context
  iio: st_sensors: rely on odr mask to know if odr can be set
  iio: core: remove extra semi-colon from devm_iio_device_register() macro
  ALSA: usb-audio: Add connector notifier delegation
  ALSA: usb-audio: Add static mapping table for ALC1220-VB-based mobos
  ALSA: hda: Remove ASUS ROG Zenith from the blacklist
  KEYS: Avoid false positive ENOMEM error on key read
  vrf: Check skb for XFRM_TRANSFORMED flag
  xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish
  geneve: use the correct nlattr array in NL_SET_ERR_MSG_ATTR
  vxlan: use the correct nlattr array in NL_SET_ERR_MSG_ATTR
  net: dsa: b53: b53_arl_rw_op() needs to select IVL or SVL
  net: dsa: b53: Rework ARL bin logic
  net: dsa: b53: Fix ARL register definitions
  net: dsa: b53: Fix valid setting for MDB entries
  net: dsa: b53: Lookup VID in ARL searches when VLAN is enabled
  vrf: Fix IPv6 with qdisc and xfrm
  team: fix hang in team_mode_get()
  tcp: cache line align MAX_TCP_HEADER
  selftests: Fix suppress test in fib_tests.sh
  sched: etf: do not assume all sockets are full blown
  net/x25: Fix x25_neigh refcnt leak when receiving frame
  net: stmmac: dwmac-meson8b: Add missing boundary to RGMII TX clock array
  net: openvswitch: ovs_ct_exit to be done under ovs_lock
  net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node
  net/mlx4_en: avoid indirect call in TX completion
  net: bcmgenet: correct per TX/RX ring statistics
  mlxsw: Fix some IS_ERR() vs NULL bugs
  macvlan: fix null dereference in macvlan_device_event()
  macsec: avoid to set wrong mtu
  ipv6: fix restrict IPV6_ADDRFORM operation
  ipv4: Update fib_select_default to handle nexthop objects
  cxgb4: fix large delays in PTP synchronization
  cxgb4: fix adapter crash due to wrong MC size
  PCI/PM: Add missing link delays required by the PCIe spec
  PCI/ASPM: Allow re-enabling Clock PM
  scsi: smartpqi: fix problem with unique ID for physical device
  scsi: smartpqi: fix call trace in device discovery
  scsi: smartpqi: fix controller lockup observed during force reboot
  virtio-blk: improve virtqueue error to BLK_STS
  tracing/selftests: Turn off timeout setting
  ASoC: SOF: trace: fix unconditional free in trace release
  PCI: pciehp: Prevent deadlock on disconnect
  libbpf: Fix readelf output parsing on powerpc with recent binutils
  PCI/PM: Add pcie_wait_for_link_delay()
  drm/amd/display: Not doing optimize bandwidth if flip pending.
  xhci: Finetune host initiated USB3 rootport link suspend and resume
  xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0
  xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
  ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk
  ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet
  drm/amd/display: Calculate scaling ratios on every medium/full update
  perf/core: Disable page faults when getting phys address
  pwm: bcm2835: Dynamically allocate base
  pwm: renesas-tpu: Fix late Runtime PM enablement
  nvme: fix compat address handling in several ioctls
  powerpc/pseries: Fix MCE handling on pseries
  Revert "powerpc/64: irq_work avoid interrupt when called with hardware irqs enabled"
  loop: Better discard support for block devices
  s390/cio: avoid duplicated 'ADD' uevents
  s390/cio: generate delayed uevent for vfio-ccw subchannels
  lib/raid6/test: fix build on distros whose /bin/sh is not bash
  kconfig: qconf: Fix a few alignment issues
  ipc/util.c: sysvipc_find_ipc() should increase position index
  selftests: kmod: fix handling test numbers above 9
  kernel/gcov/fs.c: gcov_seq_next() should increase position index
  dma-direct: fix data truncation in dma_direct_get_required_mask()
  drm/amd/display: Update stream adjust in dc_stream_adjust_vmin_vmax
  nvme: fix deadlock caused by ANA update wrong locking
  ASoC: Intel: atom: Take the drv->lock mutex before calling sst_send_slot_map()
  tools/test/nvdimm: Fix out of tree build
  scsi: iscsi: Report unbind session event when the target has been removed
  nvme-tcp: fix possible crash in write_zeroes processing
  pwm: rcar: Fix late Runtime PM enablement
  ceph: don't skip updating wanted caps when cap is stale
  ceph: return ceph_mdsc_do_request() errors from __get_parent()
  scsi: libfc: If PRLI rejected, move rport to PLOGI state
  scsi: lpfc: Fix crash in target side cable pulls hitting WAIT_FOR_UNREG
  scsi: lpfc: Fix crash after handling a pci error
  scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
  watchdog: reset last_hw_keepalive time at start
  tools/testing/nvdimm: Fix compilation failure without CONFIG_DEV_DAX_PMEM_COMPAT
  arm64: Silence clang warning on mismatched value/register sizes
  arm64: compat: Workaround Neoverse-N1 #1542419 for compat user-space
  arm64: Fake the IminLine size on systems affected by Neoverse-N1 #1542419
  arm64: errata: Hide CTR_EL0.DIC on systems affected by Neoverse-N1 #1542419
  net, ip_tunnel: fix interface lookup with no key
  f2fs: fix to avoid memory leakage in f2fs_listxattr
  ext4: fix extent_status fragmentation for plain files
  ANDROID: GKI: Update abi and cf/gf whitelists
  ANDROID: ABI/Whitelist: update pcie whitelist to unisoc whitelist
  ANDROID: GKI: Update ABI for DRM core changes
  ANDROID: add compat cross compiler
  UPSTREAM: arm64: vdso32: Enable Clang Compilation
  BACKPORT: lib/vdso: Enable common headers
  BACKPORT: arm: vdso: Enable arm to use common headers
  BACKPORT: x86/vdso: Enable x86 to use common headers
  UPSTREAM: arm64: vdso32: Include common headers in the vdso library
  UPSTREAM: arm64: vdso: Include common headers in the vdso library
  UPSTREAM: arm64: Introduce asm/vdso/processor.h
  UPSTREAM: arm64: vdso32: Code clean up
  UPSTREAM: linux/elfnote.h: Replace elf.h with UAPI equivalent
  UPSTREAM: scripts: Fix the inclusion order in modpost
  UPSTREAM: common: Introduce processor.h
  UPSTREAM: linux/ktime.h: Extract common header for vDSO
  UPSTREAM: linux/jiffies.h: Extract common header for vDSO
  UPSTREAM: linux/time64.h: Extract common header for vDSO
  BACKPORT: linux/time32.h: Extract common header for vDSO
  BACKPORT: linux/time.h: Extract common header for vDSO
  UPSTREAM: linux/math64.h: Extract common header for vDSO
  BACKPORT: linux/clocksource.h: Extract common header for vDSO
  BACKPORT: arm64: Introduce asm/vdso/clocksource.h
  BACKPORT: arm: Introduce asm/vdso/clocksource.h
  BACKPORT: x86: Introduce asm/vdso/clocksource.h
  UPSTREAM: linux/limits.h: Extract common header for vDSO
  UPSTREAM: linux/bits.h: Extract common header for vDSO
  UPSTREAM: linux/const.h: Extract common header for vDSO
  BACKPORT: lib/vdso: Allow the high resolution parts to be compiled out
  BACKPORT: lib/vdso: Only read hrtimer_res when needed in __cvdso_clock_getres()
  UPSTREAM: lib/vdso: Mark do_hres() and do_coarse() as __always_inline
  UPSTREAM: lib/vdso: Avoid duplication in __cvdso_clock_getres()
  UPSTREAM: lib/vdso: Let do_coarse() return 0 to simplify the callsite
  UPSTREAM: lib/vdso: Remove checks on return value for 32 bit vDSO
  UPSTREAM: lib/vdso: Build 32 bit specific functions in the right context
  UPSTREAM: lib/vdso: Make __cvdso_clock_getres() static
  UPSTREAM: arm64: compat: vdso: Expose BUILD_VDSO32
  ANDROID: GKI: Enable GENERIC_IRQ_CHIP
  ANDROID: ABI/Whitelist: update unisoc Whitelist after CONFIG_PPP =m
  ANDROID: ABI/Whitelist: update for allwinner.
  ANDROID: gki_defconfig: enable CONFIG_PM_DEVFREQ_EVENT.
  ANDROID: Incremental fs: Use simple compression in log buffer
  ANDROID: dm-bow: Fix not to skip trim at framented range
  ANDROID: Remove VLA from uid_sys_stats.c
  ANDROID: ABI/Whitelist: add net whitelist to unisoc Whitelist
  f2fs: fix missing check for f2fs_unlock_op
  ANDROID: gki_defconfig: enable CONFIG_MMC_CRYPTO
  ANDROID: Add padding for crypto related structs in UFS and MMC
  ANDROID: mmc: MMC crypto API
  ANDROID: GKI: USB: Add vendor specified variables to hc_driver
  ANDROID: hikey960_gki.fragment enable CONFIG_SDCARD_FS=m
  ANDROID: GKI: update abi.xml due to additional Android ABI padding
  ANDROID: GKI: elevator: add Android ABI padding to some structures
  ANDROID: GKI: dentry: add Android ABI padding to some structures
  ANDROID: GKI: bio: add Android ABI padding to some structures
  ANDROID: GKI: scsi: add Android ABI padding to some structures
  ANDROID: GKI: ufs: add Android ABI padding to some structures
  ANDROID: sdcardfs: fix export symbol types
  Linux 5.4.35
  bpf, test_verifier: switch bpf_get_stack's 0 s> r8 test
  bpf: Test_progs, add test to catch retval refine error handling
  bpf: Test_verifier, bpf_get_stack return value add <0
  bpf: fix buggy r0 retval refinement for tracing helpers
  KEYS: Don't write out to userspace while holding key semaphore
  mtd: phram: fix a double free issue in error path
  mtd: lpddr: Fix a double free in probe()
  docs: Fix path to MTD command line partition parser
  mtd: spinand: Explicitly use MTD_OPS_RAW to write the bad block marker to OOB
  mtd: rawnand: free the nand_device object
  locktorture: Print ratio of acquisitions, not failures
  tty: evh_bytechan: Fix out of bounds accesses
  fbmem: Adjust indentation in fb_prepare_logo and fb_blank
  iio: si1133: read 24-bit signed integer for measurement
  ARM: dts: sunxi: Fix DE2 clocks register range
  fbdev: potential information leak in do_fb_ioctl()
  dma-debug: fix displaying of dma allocation type
  net: dsa: bcm_sf2: Fix overflow checks
  drm/nouveau/gr/gp107,gp108: implement workaround for HW hanging during init
  f2fs: fix to wait all node page writeback
  iommu/amd: Fix the configuration of GCR3 table root pointer
  libnvdimm: Out of bounds read in __nd_ioctl()
  power: supply: axp288_fuel_gauge: Broaden vendor check for Intel Compute Sticks.
  csky: Fixup init_fpu compile warning with __init
  sunrpc: Fix gss_unwrap_resp_integ() again
  ext2: fix debug reference to ext2_xattr_cache
  iommu/vt-d: Fix page request descriptor size
  iommu/vt-d: Silence RCU-list debugging warning in dmar_find_atsr()
  ext2: fix empty body warnings when -Wextra is used
  SUNRPC: fix krb5p mount to provide large enough buffer in rq_rcvsize
  iommu/vt-d: Fix mm reference leak
  iommu/virtio: Fix freeing of incomplete domains
  drm/vc4: Fix HDMI mode validation
  um: falloc.h needs to be directly included for older libc
  ACPICA: Fixes for acpiExec namespace init file
  f2fs: fix NULL pointer dereference in f2fs_write_begin()
  csky: Fixup get wrong psr value from phyical reg
  NFS: Fix memory leaks in nfs_pageio_stop_mirroring()
  drm/amdkfd: kfree the wrong pointer
  csky: Fixup cpu speculative execution to IO area
  x86: ACPI: fix CPU hotplug deadlock
  leds: core: Fix warning message when init_data
  drm/nouveau: workaround runpm fail by disabling PCI power management on certain intel bridges
  KVM: s390: vsie: Fix possible race when shadowing region 3 tables
  compiler.h: fix error in BUILD_BUG_ON() reporting
  percpu_counter: fix a data race at vm_committed_as
  include/linux/swapops.h: correct guards for non_swap_entry()
  drm/nouveau/svm: fix vma range check for migration
  drm/nouveau/svm: check for SVM initialized before migrating
  mm/hugetlb: fix build failure with HUGETLB_PAGE but not HUGEBTLBFS
  cifs: Allocate encryption header through kmalloc
  um: ubd: Prevent buffer overrun on command completion
  ext4: do not commit super on read-only bdev
  s390/cpum_sf: Fix wrong page count in error message
  powerpc/maple: Fix declaration made after definition
  powerpc/prom_init: Pass the "os-term" message to hypervisor
  btrfs: add RCU locks around block group initialization
  hibernate: Allow uswsusp to write to swap
  s390/cpuinfo: fix wrong output when CPU0 is offline
  f2fs: Add a new CP flag to help fsck fix resize SPO issues
  f2fs: Fix mount failure due to SPO after a successful online resize FS
  NFS: direct.c: Fix memory leak of dreq when nfs_get_lock_context fails
  phy: uniphier-usb3ss: Add Pro5 support
  f2fs: fix to show norecovery mount option
  KVM: PPC: Book3S HV: Fix H_CEDE return code for nested guests
  ARM: dts: rockchip: fix lvds-encoder ports subnode for rk3188-bqedison2qc
  NFSv4.2: error out when relink swapfile
  NFSv4/pnfs: Return valid stateids in nfs_layout_find_inode_by_stateid()
  NFS: alloc_nfs_open_context() must use the file cred when available
  rtc: 88pm860x: fix possible race condition
  dma-coherent: fix integer overflow in the reserved-memory dma allocation
  soc: imx: gpc: fix power up sequencing
  arm64: dts: clearfog-gt-8k: set gigabit PHY reset deassert delay
  arm64: tegra: Fix Tegra194 PCIe compatible string
  arm64: tegra: Add PCIe endpoint controllers nodes for Tegra194
  clk: tegra: Fix Tegra PMC clock out parents
  power: supply: bq27xxx_battery: Silence deferred-probe error
  arm64: dts: allwinner: a64: Fix display clock register range
  ARM: dts: rockchip: fix vqmmc-supply property name for rk3188-bqedison2qc
  f2fs: fix the panic in do_checkpoint()
  net/mlx5e: Enforce setting of a single FEC mode
  clk: at91: usb: continue if clk_hw_round_rate() return zero
  clk: Don't cache errors from clk_ops::get_phase()
  drm/ttm: flush the fence on the bo after we individualize the reservation object
  x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump
  rbd: call rbd_dev_unprobe() after unwatching and flushing notifies
  rbd: avoid a deadlock on header_rwsem when flushing notifies
  block, bfq: invoke flush_idle_tree after reparent_active_queues in pd_offline
  block, bfq: make reparent_leaf_entity actually work only on leaf entities
  block, bfq: turn put_queue into release_process_ref in __bfq_bic_change_cgroup
  afs: Fix race between post-modification dir edit and readdir/d_revalidate
  afs: Fix afs_d_validate() to set the right directory version
  afs: Fix rename operation status delivery
  afs: Fix decoding of inline abort codes from version 1 status records
  afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus()
  x86/Hyper-V: Report crash data in die() when panic_on_oops is set
  x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not set
  x86/Hyper-V: Report crash register data or kmsg before running crash kernel
  x86/Hyper-V: Trigger crash enlightenment only once during system crash.
  x86/Hyper-V: Unload vmbus channel in hv panic callback
  of: overlay: kmemleak in dup_and_fixup_symbol_prop()
  of: unittest: kmemleak in of_unittest_overlay_high_level()
  of: unittest: kmemleak in of_unittest_platform_populate()
  of: unittest: kmemleak on changeset destroy
  xsk: Add missing check on user supplied headroom size
  ALSA: hda: Don't release card at firmware loading error
  irqchip/mbigen: Free msi_desc on device teardown
  netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type
  kbuild, btf: Fix dependencies for DEBUG_INFO_BTF
  ARM: dts: imx6: Use gpc for FEC interrupt controller to fix wake on LAN.
  ALSA: hda: Honor PM disablement in PM freeze and thaw_noirq ops
  scsi: sg: add sg_remove_request in sg_common_write
  objtool: Fix switch table detection in .text.unlikely
  arm, bpf: Fix offset overflow for BPF_MEM BPF_DW
  arm, bpf: Fix bugs with ALU64 {RSH, ARSH} BPF_K shift by 0
  xsk: Fix out of boundary write in __xsk_rcv_memcpy
  watchdog: sp805: fix restart handler
  ext4: use non-movable memory for superblock readahead
  ANDROID: ABI/Whitelist: update unisoc Whitelist to latest
  ANDROID: iommu: Kconfig: Make ARM_SMMU depend on QCOM_SCM || !QCOM_SCM
  ANDROID: GKI: enable CONFIG_DYNAMIC_DEBUG_CORE
  FROMLIST: BACKPORT: dynamic_debug: Add an option to enable dynamic debug for modules only
  ANDROID: init: GKI: enable hidden configs for GPU
  FROMLIST: clocksource/drivers/sprd: Add module support to Spreadtrum timer
  FROMLIST: drivers/clocksource/timer-of: Remove __init markings
  UPSTREAM: gpu/trace: add a gpu total memory usage tracepoint
  Linux 5.4.34
  x86/microcode/AMD: Increase microcode PATCH_MAX_SIZE
  scsi: target: fix hang when multiple threads try to destroy the same iscsi session
  scsi: target: remove boilerplate code
  x86/resctrl: Fix invalid attempt at removing the default resource group
  x86/resctrl: Preserve CDP enable over CPU hotplug
  irqchip/ti-sci-inta: Fix processing of masked irqs
  ext4: do not zeroout extents beyond i_disksize
  i2c: designware: platdrv: Remove DPM_FLAG_SMART_SUSPEND flag on BYT and CHT
  drm/amdgpu: fix the hw hang during perform system reboot and reset
  drm/amd/powerplay: force the trim of the mclk dpm_levels if OD is enabled
  net/mlx5e: Use preactivate hook to set the indirection table
  net/mlx5e: Rename hw_modify to preactivate
  net/mlx5e: Encapsulate updating netdev queues into a function
  mac80211_hwsim: Use kstrndup() in place of kasprintf()
  mac80211: fix race in ieee80211_register_hw()
  nl80211: fix NL80211_ATTR_FTM_RESPONDER policy
  btrfs: check commit root generation in should_ignore_root
  tracing: Fix the race between registering 'snapshot' event trigger and triggering 'snapshot' operation
  keys: Fix proc_keys_next to increase position index
  arm64: vdso: don't free unallocated pages
  ALSA: usb-audio: Check mapping at creating connector controls, too
  ALSA: usb-audio: Don't create jack controls for PCM terminals
  ALSA: usb-audio: Don't override ignore_ctl_error value from the map
  ALSA: usb-audio: Filter error from connector kctl ops, too
  ALSA: hda/realtek - Enable the headset mic on Asus FX505DT
  ASoC: Intel: mrfld: return error codes when an error occurs
  ASoC: Intel: mrfld: fix incorrect check on p->sink
  usb: dwc3: gadget: Don't clear flags before transfer ended
  arm64: dts: librem5-devkit: add a vbus supply to usb0
  ARM: dts: imx7-colibri: fix muxing of usbc_det pin
  clk: at91: usb: use proper usbs_mask
  clk: at91: sam9x60: fix usb clock parents
  ext4: fix incorrect inodes per group in error message
  ext4: fix incorrect group count in ext4_fill_super error message
  net/bpfilter: remove superfluous testing message
  pwm: pca9685: Fix PWM/GPIO inter-operation
  perf report: Fix no branch type statistics report issue
  acpi/nfit: improve bounds checking for 'func'
  jbd2: improve comments about freeing data buffers whose page mapping is NULL
  platform/chrome: cros_ec_rpmsg: Fix race with host event
  scsi: ufs: Fix ufshcd_hold() caused scheduling while atomic
  ovl: fix value of i_ino for lower hardlink corner case
  Revert "ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add()"
  net: stmmac: dwmac-sunxi: Provide TX and RX fifo sizes
  net/mlx5e: Fix pfnum in devlink port attribute
  net/mlx5e: Fix nest_level for vlan pop action
  net/mlx5e: Add missing release firmware call
  net/mlx5: Fix frequent ioread PCI access during recovery
  net: ethernet: mediatek: move mt7623 settings out off the mt7530
  net: dsa: mt7530: move mt7623 settings out off the mt7530
  net: tun: record RX queue in skb before do_xdp_generic()
  net: revert default NAPI poll timeout to 2 jiffies
  net: qrtr: send msgs from local of same id as broadcast
  net: phy: micrel: use genphy_read_status for KSZ9131
  net: ipv6: do not consider routes via gateways for anycast address check
  net: ipv4: devinet: Fix crash when add/del multicast IP with autojoin
  net: dsa: mt7530: fix tagged frames pass-through in VLAN-unaware mode
  l2tp: Allow management of tunnels and session in user namespace
  hsr: check protocol version in hsr_newlink()
  amd-xgbe: Use __napi_schedule() in BH context
  ANDROID: Add C protos for dma_buf/drm_prime get_uuid
  f2fs: fix quota_sync failure due to f2fs_lock_op
  f2fs: support read iostat
  f2fs: Fix the accounting of dcc->undiscard_blks
  f2fs: fix to handle error path of f2fs_ra_meta_pages()
  f2fs: report the discard cmd errors properly
  f2fs: fix long latency due to discard during umount
  f2fs: add tracepoint for f2fs iostat
  f2fs: introduce sysfs/data_io_flag to attach REQ_META/FUA
  ANDROID: GKI: update abi for 5.4.33 changes
  Linux 5.4.33
  scsi: lpfc: fix inlining of lpfc_sli4_cleanup_poll_list()
  ASoC: stm32: sai: Add missing cleanup
  efi/x86: Fix the deletion of variables in mixed mode
  mfd: dln2: Fix sanity checking for endpoints
  bpf: Fix tnum constraints for 32-bit comparisons
  mmc: sdhci: Refactor sdhci_set_timeout()
  mmc: sdhci: Convert sdhci_set_timeout_irq() to non-static
  powerpc/kasan: Fix kasan_remap_early_shadow_ro()
  drm/i915/icl+: Don't enable DDI IO power on a TypeC port in TBT mode
  drm/amdgpu: fix gfx hang during suspend with video playback (v2)
  drm/dp_mst: Fix clearing payload state on topology disable
  Revert "drm/dp_mst: Remove VCPI while disabling topology mgr"
  scsi: lpfc: Fix broken Credit Recovery after driver load
  scsi: lpfc: Fix configuration of BB credit recovery in service parameters
  scsi: lpfc: Fix Fabric hostname registration if system hostname changes
  scsi: lpfc: Add registration for CPU Offline/Online events
  dm clone: Add missing casts to prevent overflows and data corruption
  dm clone: Fix handling of partial region discards
  dm clone: replace spin_lock_irqsave with spin_lock_irq
  dm zoned: remove duplicate nr_rnd_zones increase in dmz_init_zone()
  arm64: Always force a branch protection mode when the compiler has one
  powerpc: Make setjmp/longjmp signature standard
  scsi: mpt3sas: Fix kernel panic observed on soft HBA unplug
  powerpc/64: Prevent stack protection in early boot
  powerpc/kprobes: Ignore traps that happened in real mode
  powerpc/xive: Fix xmon support on the PowerNV platform
  powerpc/64: Setup a paca before parsing device tree etc.
  powerpc/xive: Use XIVE_BAD_IRQ instead of zero to catch non configured IPIs
  powerpc/hash64/devmap: Use H_PAGE_THP_HUGE when setting up huge devmap PTE entries
  powerpc/fsl_booke: Avoid creating duplicate tlb1 entry
  powerpc/64/tm: Don't let userspace set regs->trap via sigreturn
  xen/blkfront: fix memory allocation flags in blkfront_setup_indirect()
  ipmi: fix hung processes in __get_guid()
  libata: Return correct status in sata_pmp_eh_recover_pm() when ATA_DFLAG_DETACH is set
  hfsplus: fix crash and filesystem corruption when deleting files
  cpufreq: powernv: Fix use-after-free
  kmod: make request_module() return an error when autoloading is disabled
  clk: ingenic/TCU: Fix round_rate returning error
  clk: ingenic/jz4770: Exit with error if CGU init failed
  ftrace/kprobe: Show the maxactive number on kprobe_events
  Input: i8042 - add Acer Aspire 5738z to nomux list
  s390/diag: fix display of diagnose call statistics
  perf tools: Support Python 3.8+ in Makefile
  ocfs2: no need try to truncate file beyond i_size
  fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once()
  ext4: fix a data race at inode->i_blocks
  NFS: Fix a page leak in nfs_destroy_unlinked_subrequests()
  NFS: Fix use-after-free issues in nfs_pageio_add_request()
  nfsd: fsnotify on rmdir under nfsd/clients/
  powerpc/pseries: Avoid NULL pointer dereference when drmem is unavailable
  drm/amdgpu: unify fw_write_wait for new gfx9 asics
  drm/amdgpu/powerplay: using the FCLK DPM table to set the MCLK
  drm: Remove PageReserved manipulation from drm_pci_alloc
  drm/etnaviv: rework perfmon query infrastructure
  drm/i915/gem: Flush all the reloc_gpu batch
  vfio: platform: Switch to platform_get_irq_optional()
  selftests/powerpc: Add tlbie_test in .gitignore
  selftests/vm: fix map_hugetlb length used for testing read and write
  selftests: vm: drop dependencies on page flags from mlock2 tests
  arm64: armv8_deprecated: Fix undef_hook mask for thumb setend
  arm64: dts: ti: k3-am65: Add clocks to dwc3 nodes
  ARM: dts: exynos: Fix polarity of the LCD SPI bus on UniversalC210 board
  scsi: lpfc: Fix lpfc_io_buf resource leak in lpfc_get_scsi_buf_s4 error path
  scsi: ufs: fix Auto-Hibern8 error detection
  scsi: zfcp: fix missing erp_lock in port recovery trigger for point-to-point
  crypto: ccree - dec auth tag size from cryptlen map
  crypto: ccree - only try to map auth tag if needed
  crypto: ccree - protect against empty or NULL scatterlists
  crypto: caam - update xts sector size for large input length
  crypto: caam/qi2 - fix chacha20 data size error
  xarray: Fix early termination of xas_for_each_marked
  XArray: Fix xas_pause for large multi-index entries
  dm clone metadata: Fix return type of dm_clone_nr_of_hydrated_regions()
  dm clone: Add overflow check for number of regions
  dm verity fec: fix memory leak in verity_fec_dtr
  dm integrity: fix a crash with unusually large tag size
  dm writecache: add cond_resched to avoid CPU hangs
  mm, memcg: do not high throttle allocators based on wraparound
  arm64: dts: allwinner: h5: Fix PMU compatible
  sched/core: Remove duplicate assignment in sched_tick_remote()
  arm64: dts: allwinner: h6: Fix PMU compatible
  net: qualcomm: rmnet: Allow configuration updates to existing devices
  tools: gpio: Fix out-of-tree build regression
  powerpc/pseries: Drop pointless static qualifier in vpa_debugfs_init()
  mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions
  io_uring: honor original task RLIMIT_FSIZE
  erofs: correct the remaining shrink objects
  crypto: mxs-dcp - fix scatterlist linearization for hash
  crypto: rng - Fix a refcounting bug in crypto_rng_reset()
  remoteproc: Fix NULL pointer dereference in rproc_virtio_notify
  remoteproc: qcom_q6v5_mss: Reload the mba region on coredump
  remoteproc: qcom_q6v5_mss: Don't reassign mpss region on shutdown
  btrfs: use nofs allocations for running delayed items
  btrfs: fix missing semaphore unlock in btrfs_sync_file
  btrfs: unset reloc control if we fail to recover
  btrfs: fix missing file extent item for hole after ranged fsync
  btrfs: drop block from cache on error in relocation
  btrfs: set update the uuid generation as soon as possible
  btrfs: reloc: clean dirty subvols if we fail to start a transaction
  Btrfs: fix crash during unmount due to race with delayed inode workers
  btrfs: Don't submit any btree write bio if the fs has errors
  mtd: spinand: Do not erase the block before writing a bad block marker
  mtd: spinand: Stop using spinand->oobbuf for buffering bad block markers
  CIFS: Fix bug which the return value by asynchronous read is error
  smb3: fix performance regression with setting mtime
  KVM: VMX: fix crash cleanup when KVM wasn't used
  KVM: VMX: Add a trampoline to fix VMREAD error handling
  KVM: x86: Gracefully handle __vmalloc() failure during VM allocation
  KVM: VMX: Always VMCLEAR in-use VMCSes during crash with kexec support
  KVM: x86: Allocate new rmap and large page tracking when moving memslot
  KVM: s390: vsie: Fix delivery of addressing exceptions
  KVM: s390: vsie: Fix region 1 ASCE sanity shadow address checks
  KVM: nVMX: Properly handle userspace interrupt window request
  platform/x86: asus-wmi: Support laptops where the first battery is named BATT
  x86/entry/32: Add missing ASM_CLAC to general_protection entry
  x86/tsc_msr: Make MSR derived TSC frequency more accurate
  x86/tsc_msr: Fix MSR_FSB_FREQ mask for Cherry Trail devices
  x86/tsc_msr: Use named struct initializers
  signal: Extend exec_id to 64bits
  ath9k: Handle txpower changes even when TPC is disabled
  PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there
  PM / Domains: Allow no domain-idle-states DT property in genpd when parsing
  MIPS: OCTEON: irq: Fix potential NULL pointer dereference
  MIPS/tlbex: Fix LDDIR usage in setup_pw() for Loongson-3
  pstore: pstore_ftrace_seq_next should increase position index
  io_uring: remove bogus RLIMIT_NOFILE check in file registration
  irqchip/versatile-fpga: Apply clear-mask earlier
  genirq/debugfs: Add missing sanity checks to interrupt injection
  cpu/hotplug: Ignore pm_wakeup_pending() for disable_nonboot_cpus()
  KEYS: reaching the keys quotas correctly
  tpm: tpm2_bios_measurements_next should increase position index
  tpm: tpm1_bios_measurements_next should increase position index
  tpm: Don't make log failures fatal
  sched/fair: Fix enqueue_task_fair warning
  PCI: endpoint: Fix for concurrent memory allocation in OB address region
  PCI: qcom: Fix the fixup of PCI_VENDOR_ID_QCOM
  PCI: Add boot interrupt quirk mechanism for Xeon chipsets
  PCI/ASPM: Clear the correct bits when enabling L1 substates
  PCI: pciehp: Fix indefinite wait on sysfs requests
  efi/x86: Add TPM related EFI tables to unencrypted mapping checks
  nvme-fc: Revert "add module to ops template to allow module references"
  nvmet-tcp: fix maxh2cdata icresp parameter
  thermal: devfreq_cooling: inline all stubs for CONFIG_DEVFREQ_THERMAL=n
  ACPI: PM: s2idle: Refine active GPEs check
  ACPICA: Allow acpi_any_gpe_status_set() to skip one GPE
  acpi/x86: ignore unspecified bit positions in the ACPI global lock field
  seccomp: Add missing compat_ioctl for notify
  media: ti-vpe: cal: fix a kernel oops when unloading module
  media: ti-vpe: cal: fix disable_irqs to only the intended target
  media: hantro: Read be32 words starting at every fourth byte
  media: venus: firmware: Ignore secure call error on first resume
  ALSA: hda/realtek - Add quirk for MSI GL63
  ALSA: hda/realtek - Add quirk for Lenovo Carbon X1 8th gen
  ALSA: hda/realtek - Remove now-unnecessary XPS 13 headphone noise fixups
  ALSA: hda/realtek - Set principled PC Beep configuration for ALC256
  ALSA: doc: Document PC Beep Hidden Register on Realtek ALC256
  ALSA: hda/realtek - a fake key event is triggered by running shutup
  ALSA: hda/realtek: Enable mute LED on an HP system
  ALSA: pcm: oss: Fix regression by buffer overflow fix
  ALSA: ice1724: Fix invalid access for enumerated ctl items
  ALSA: hda: Fix potential access overflow in beep helper
  ALSA: hda: Add driver blacklist
  ALSA: usb-audio: Add mixer workaround for TRX40 and co
  usb: gadget: composite: Inform controller driver of self-powered
  usb: gadget: f_fs: Fix use after free issue as part of queue failure
  ASoC: topology: use name_prefix for new kcontrol
  ASoC: dpcm: allow start or stop during pause for backend
  ASoC: dapm: connect virtual mux with default value
  ASoC: fix regwmask
  btrfs: track reloc roots based on their commit root bytenr
  btrfs: restart relocate_tree_blocks properly
  btrfs: remove a BUG_ON() from merge_reloc_roots()
  btrfs: qgroup: ensure qgroup_rescan_running is only set when the worker is at least queued
  block, bfq: fix use-after-free in bfq_idle_slice_timer_body
  locking/lockdep: Avoid recursion in lockdep_count_{for,back}ward_deps()
  spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion
  firmware: fix a double abort case with fw_load_sysfs_fallback
  md: check arrays is suspended in mddev_detach before call quiesce operations
  irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency
  usb: dwc3: core: add support for disabling SS instances in park mode
  media: i2c: ov5695: Fix power on and off sequences
  block: Fix use-after-free issue accessing struct io_cq
  genirq/irqdomain: Check pointer in irq_domain_alloc_irqs_hierarchy()
  efi/x86: Ignore the memory attributes table on i386
  x86/boot: Use unsigned comparison for addresses
  cpufreq: imx6q: fix error handling
  gfs2: Don't demote a glock until its revokes are written
  gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty
  pstore/platform: fix potential mem leak if pstore_init_fs failed
  libata: Remove extra scsi_host_put() in ata_scsi_add_hosts()
  media: i2c: video-i2c: fix build errors due to 'imply hwmon'
  block, bfq: move forward the getting of an extra ref in bfq_bfqq_move
  PCI/switchtec: Fix init_completion race condition with poll_wait()
  selftests/x86/ptrace_syscall_32: Fix no-vDSO segfault
  sched: Avoid scale real weight down to zero
  media: allegro: fix type of gop_length in channel_create message
  time/sched_clock: Expire timer in hardirq context
  irqchip/versatile-fpga: Handle chained IRQs properly
  debugfs: Check module state before warning in {full/open}_proxy_open()
  block: keep bdi->io_pages in sync with max_sectors_kb for stacked devices
  dma-mapping: Fix dma_pgprot() for unencrypted coherent pages
  x86: Don't let pgprot_modify() change the page encryption bit
  ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add()
  xhci: bail out early if driver can't accress host in resume
  media: imx: imx7-media-csi: Fix video field handling
  media: imx: imx7_mipi_csis: Power off the source when stopping streaming
  null_blk: fix spurious IO errors after failed past-wp access
  null_blk: Handle null_add_dev() failures properly
  null_blk: Fix the null_add_dev() error path
  firmware: arm_sdei: fix double-lock on hibernate with shared events
  media: venus: hfi_parser: Ignore HEVC encoding for V1
  staging: wilc1000: avoid double unlocking of 'wilc->hif_cs' mutex
  cpufreq: imx6q: Fixes unwanted cpu overclocking on i.MX6ULL
  media: rc: add keymap for Videostrong KII Pro
  i2c: pca-platform: Use platform_irq_get_optional
  i2c: st: fix missing struct parameter description
  qlcnic: Fix bad kzalloc null test
  cfg80211: Do not warn on same channel at the end of CSA
  drm/scheduler: fix rare NULL ptr race
  cxgb4/ptp: pass the sign of offset delta in FW CMD
  selftests/net: add definition for SOL_DCCP to fix compilation errors for old libc
  hinic: fix wrong value of MIN_SKB_LEN
  hinic: fix wrong para of wait_for_completion_timeout
  hinic: fix out-of-order excution in arm cpu
  hinic: fix the bug of clearing event queue
  hinic: fix a bug of waitting for IO stopped
  net: vxge: fix wrong __VA_ARGS__ usage
  net: stmmac: platform: Fix misleading interrupt error msg
  rxrpc: Fix call interruptibility handling
  rxrpc: Abstract out the calculation of whether there's Tx space
  soc: fsl: dpio: register dpio irq handlers after dpio create
  Input: tm2-touchkey - add support for Coreriver TC360 variant
  iwlwifi: mvm: Fix rate scale NSS configuration
  bpf: Fix deadlock with rq_lock in bpf_send_signal()
  ARM: dts: Fix dm814x Ethernet by changing to use rgmii-id mode
  bus: sunxi-rsb: Return correct data when mixing 16-bit and 8-bit reads
  ARM: dts: sun8i-a83t-tbs-a711: HM5065 doesn't like such a high voltage
  ANDROID: GKI: ABI update for dma-buf/DRM get_uuid change
  ANDROID: ABI/Whitelist: update for db845c after changing drivers to modules.
  ANDROID: Switch CONFIG_QCOM_PDC CONFIG_QCOM_SCM and CONFIG_ARM_SMMU to be loaded as modules
  ANDROID: firmware: QCOM_SCM: Allow qcom_scm driver to be loadable as a permenent module
  ANDROID: irqchip: Allow QCOM_PDC to be loadable as a perment module
  ANDROID: irq: irqchip: Export irq_chip_retrigger_hierarchy and irq_chip_set_vcpu_affinity_parent
  ANDROID: irq: irqdomain: Export irq_domain_update_bus_token
  ANDROID: GKI: Add DRM_TTM config to GKI
  FROMLIST: drm/prime: add support for virtio exported objects
  FROMLIST: dma-buf: add support for virtio exported objects
  ANDROID: Incremental fs: Fix create_file performance
  UPSTREAM: Merge remote-tracking branch 'aosp/upstream-f2fs-stable-linux-5.4.y' into android-5.4 (v5.7-rc1)
  ANDROID: fix allmodconfig build to use the right toolchain
  ANDROID: Incremental fs: Fix compound page usercopy crash
  ANDROID: Incremental fs: Clean up incfs_test build process
  ANDROID: Incremental fs: make remount log buffer change atomic
  ANDROID: Incremental fs: Optimize get_filled_block
  ANDROID: Incremental fs: Fix mislabeled __user ptrs
  ANDROID: Incremental fs: Use 64-bit int for file_size when writing hash blocks
  ubifs: wire up FS_IOC_GET_ENCRYPTION_NONCE
  f2fs: wire up FS_IOC_GET_ENCRYPTION_NONCE
  ext4: wire up FS_IOC_GET_ENCRYPTION_NONCE
  fscrypt: add FS_IOC_GET_ENCRYPTION_NONCE ioctl
  f2fs: keep inline_data when compression conversion
  f2fs: fix to disable compression on directory
  f2fs: add missing CONFIG_F2FS_FS_COMPRESSION
  f2fs: switch discard_policy.timeout to bool type
  f2fs: fix to verify tpage before releasing in f2fs_free_dic()
  f2fs: show compression in statx
  f2fs: clean up dic->tpages assignment
  f2fs: compress: support zstd compress algorithm
  f2fs: compress: add .{init,destroy}_decompress_ctx callback
  f2fs: compress: fix to call missing destroy_compress_ctx()
  f2fs: change default compression algorithm
  f2fs: clean up {cic,dic}.ref handling
  f2fs: fix to use f2fs_readpage_limit() in f2fs_read_multi_pages()
  f2fs: xattr.h: Make stub helpers inline
  f2fs: fix to avoid double unlock
  f2fs: fix potential .flags overflow on 32bit architecture
  f2fs: fix NULL pointer dereference in f2fs_verity_work()
  f2fs: fix to clear PG_error if fsverity failed
  f2fs: don't call fscrypt_get_encryption_info() explicitly in f2fs_tmpfile()
  f2fs: don't trigger data flush in foreground operation
  f2fs: fix NULL pointer dereference in f2fs_write_begin()
  f2fs: clean up f2fs_may_encrypt()
  f2fs: fix to avoid potential deadlock
  f2fs: don't change inode status under page lock
  f2fs: fix potential deadlock on compressed quota file
  f2fs: delete DIO read lock
  f2fs: don't mark compressed inode dirty during f2fs_iget()
  f2fs: fix to account compressed blocks in f2fs_compressed_blocks()
  f2fs: xattr.h: Replace zero-length array with flexible-array member
  f2fs: fix to update f2fs_super_block fields under sb_lock
  f2fs: Add a new CP flag to help fsck fix resize SPO issues
  f2fs: Fix mount failure due to SPO after a successful online resize FS
  f2fs: use kmem_cache pool during inline xattr lookups
  f2fs: skip migration only when BG_GC is called
  f2fs: fix to show tracepoint correctly
  f2fs: avoid __GFP_NOFAIL in f2fs_bio_alloc
  f2fs: introduce F2FS_IOC_GET_COMPRESS_BLOCKS
  f2fs: fix to avoid triggering IO in write path
  f2fs: add prefix for f2fs slab cache name
  f2fs: introduce DEFAULT_IO_TIMEOUT
  f2fs: skip GC when section is full
  f2fs: add migration count iff migration happens
  f2fs: clean up bggc mount option
  f2fs: clean up lfs/adaptive mount option
  f2fs: fix to show norecovery mount option
  f2fs: clean up parameter of macro XATTR_SIZE()
  f2fs: clean up codes with {f2fs_,}data_blkaddr()
  f2fs: show mounted time
  f2fs: Use scnprintf() for avoiding potential buffer overflow
  f2fs: allow to clear F2FS_COMPR_FL flag
  f2fs: fix to check dirty pages during compressed inode conversion
  f2fs: fix to account compressed inode correctly
  f2fs: fix wrong check on F2FS_IOC_FSSETXATTR
  f2fs: fix to avoid use-after-free in f2fs_write_multi_pages()
  f2fs: fix to avoid using uninitialized variable
  f2fs: fix inconsistent comments
  f2fs: remove i_sem lock coverage in f2fs_setxattr()
  f2fs: cover last_disk_size update with spinlock
  f2fs: fix to check i_compr_blocks correctly
  f2fs: fix to avoid potential deadlock
  f2fs: add missing function name in kernel message
  f2fs: recycle unused compress_data.chksum feild
  f2fs: fix to avoid NULL pointer dereference
  f2fs: fix leaking uninitialized memory in compressed clusters
  f2fs: fix the panic in do_checkpoint()
  f2fs: fix to wait all node page writeback
  mm/swapfile.c: move inode_lock out of claim_swapfile
  fscrypt: don't evict dirty inodes after removing key

Conflicts:
	Documentation/devicetree/bindings
	Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
	Documentation/devicetree/bindings/serial/samsung_uart.txt
	abi_gki_aarch64_qcom_whitelist
	build.config.common
	drivers/firmware/Kconfig
	drivers/firmware/Makefile
	drivers/firmware/qcom_scm.c
	drivers/gpu/Makefile
	drivers/irqchip/qcom-pdc.c
	drivers/md/dm-default-key.c
	drivers/mmc/core/Kconfig
	drivers/mmc/host/sdhci-msm.c
	drivers/pci/pci-driver.c
	drivers/usb/dwc3/gadget.c
	include/linux/dma-mapping.h
	include/linux/mmc/host.h
	init/Kconfig.gki
	kernel/dma/mapping.c
	kernel/sched/core.c
	kernel/sched/fair.c
	lib/Kconfig.debug
	net/qrtr/qrtr.c

Change-Id: I4db80470ba7be66c94cb7345f292bfa1e095723d
Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
2020-07-09 17:51:24 -07:00

3225 lines
89 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Memory merging support.
*
* This code enables dynamic sharing of identical pages found in different
* memory areas, even if they are not shared by fork()
*
* Copyright (C) 2008-2009 Red Hat, Inc.
* Authors:
* Izik Eidus
* Andrea Arcangeli
* Chris Wright
* Hugh Dickins
*/
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/mman.h>
#include <linux/sched.h>
#include <linux/sched/mm.h>
#include <linux/sched/coredump.h>
#include <linux/rwsem.h>
#include <linux/pagemap.h>
#include <linux/rmap.h>
#include <linux/spinlock.h>
#include <linux/xxhash.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
#include <linux/memory.h>
#include <linux/mmu_notifier.h>
#include <linux/swap.h>
#include <linux/ksm.h>
#include <linux/hashtable.h>
#include <linux/freezer.h>
#include <linux/oom.h>
#include <linux/numa.h>
#include <asm/tlbflush.h>
#include "internal.h"
#ifdef CONFIG_NUMA
#define NUMA(x) (x)
#define DO_NUMA(x) do { (x); } while (0)
#else
#define NUMA(x) (0)
#define DO_NUMA(x) do { } while (0)
#endif
/**
* DOC: Overview
*
* A few notes about the KSM scanning process,
* to make it easier to understand the data structures below:
*
* In order to reduce excessive scanning, KSM sorts the memory pages by their
* contents into a data structure that holds pointers to the pages' locations.
*
* Since the contents of the pages may change at any moment, KSM cannot just
* insert the pages into a normal sorted tree and expect it to find anything.
* Therefore KSM uses two data structures - the stable and the unstable tree.
*
* The stable tree holds pointers to all the merged pages (ksm pages), sorted
* by their contents. Because each such page is write-protected, searching on
* this tree is fully assured to be working (except when pages are unmapped),
* and therefore this tree is called the stable tree.
*
* The stable tree node includes information required for reverse
* mapping from a KSM page to virtual addresses that map this page.
*
* In order to avoid large latencies of the rmap walks on KSM pages,
* KSM maintains two types of nodes in the stable tree:
*
* * the regular nodes that keep the reverse mapping structures in a
* linked list
* * the "chains" that link nodes ("dups") that represent the same
* write protected memory content, but each "dup" corresponds to a
* different KSM page copy of that content
*
* Internally, the regular nodes, "dups" and "chains" are represented
* using the same :c:type:`struct stable_node` structure.
*
* In addition to the stable tree, KSM uses a second data structure called the
* unstable tree: this tree holds pointers to pages which have been found to
* be "unchanged for a period of time". The unstable tree sorts these pages
* by their contents, but since they are not write-protected, KSM cannot rely
* upon the unstable tree to work correctly - the unstable tree is liable to
* be corrupted as its contents are modified, and so it is called unstable.
*
* KSM solves this problem by several techniques:
*
* 1) The unstable tree is flushed every time KSM completes scanning all
* memory areas, and then the tree is rebuilt again from the beginning.
* 2) KSM will only insert into the unstable tree, pages whose hash value
* has not changed since the previous scan of all memory areas.
* 3) The unstable tree is a RedBlack Tree - so its balancing is based on the
* colors of the nodes and not on their contents, assuring that even when
* the tree gets "corrupted" it won't get out of balance, so scanning time
* remains the same (also, searching and inserting nodes in an rbtree uses
* the same algorithm, so we have no overhead when we flush and rebuild).
* 4) KSM never flushes the stable tree, which means that even if it were to
* take 10 attempts to find a page in the unstable tree, once it is found,
* it is secured in the stable tree. (When we scan a new page, we first
* compare it against the stable tree, and then against the unstable tree.)
*
* If the merge_across_nodes tunable is unset, then KSM maintains multiple
* stable trees and multiple unstable trees: one of each for each NUMA node.
*/
/**
* struct mm_slot - ksm information per mm that is being scanned
* @link: link to the mm_slots hash list
* @mm_list: link into the mm_slots list, rooted in ksm_mm_head
* @rmap_list: head for this mm_slot's singly-linked list of rmap_items
* @mm: the mm that this information is valid for
*/
struct mm_slot {
struct hlist_node link;
struct list_head mm_list;
struct rmap_item *rmap_list;
struct mm_struct *mm;
};
/**
* struct ksm_scan - cursor for scanning
* @mm_slot: the current mm_slot we are scanning
* @address: the next address inside that to be scanned
* @rmap_list: link to the next rmap to be scanned in the rmap_list
* @seqnr: count of completed full scans (needed when removing unstable node)
*
* There is only the one ksm_scan instance of this cursor structure.
*/
struct ksm_scan {
struct mm_slot *mm_slot;
unsigned long address;
struct rmap_item **rmap_list;
unsigned long seqnr;
};
/**
* struct stable_node - node of the stable rbtree
* @node: rb node of this ksm page in the stable tree
* @head: (overlaying parent) &migrate_nodes indicates temporarily on that list
* @hlist_dup: linked into the stable_node->hlist with a stable_node chain
* @list: linked into migrate_nodes, pending placement in the proper node tree
* @hlist: hlist head of rmap_items using this ksm page
* @kpfn: page frame number of this ksm page (perhaps temporarily on wrong nid)
* @chain_prune_time: time of the last full garbage collection
* @rmap_hlist_len: number of rmap_item entries in hlist or STABLE_NODE_CHAIN
* @nid: NUMA node id of stable tree in which linked (may not match kpfn)
*/
struct stable_node {
union {
struct rb_node node; /* when node of stable tree */
struct { /* when listed for migration */
struct list_head *head;
struct {
struct hlist_node hlist_dup;
struct list_head list;
};
};
};
struct hlist_head hlist;
union {
unsigned long kpfn;
unsigned long chain_prune_time;
};
/*
* STABLE_NODE_CHAIN can be any negative number in
* rmap_hlist_len negative range, but better not -1 to be able
* to reliably detect underflows.
*/
#define STABLE_NODE_CHAIN -1024
int rmap_hlist_len;
#ifdef CONFIG_NUMA
int nid;
#endif
};
/**
* struct rmap_item - reverse mapping item for virtual addresses
* @rmap_list: next rmap_item in mm_slot's singly-linked rmap_list
* @anon_vma: pointer to anon_vma for this mm,address, when in stable tree
* @nid: NUMA node id of unstable tree in which linked (may not match page)
* @mm: the memory structure this rmap_item is pointing into
* @address: the virtual address this rmap_item tracks (+ flags in low bits)
* @oldchecksum: previous checksum of the page at that virtual address
* @node: rb node of this rmap_item in the unstable tree
* @head: pointer to stable_node heading this list in the stable tree
* @hlist: link into hlist of rmap_items hanging off that stable_node
*/
struct rmap_item {
struct rmap_item *rmap_list;
union {
struct anon_vma *anon_vma; /* when stable */
#ifdef CONFIG_NUMA
int nid; /* when node of unstable tree */
#endif
};
struct mm_struct *mm;
unsigned long address; /* + low bits used for flags below */
unsigned int oldchecksum; /* when unstable */
union {
struct rb_node node; /* when node of unstable tree */
struct { /* when listed from stable tree */
struct stable_node *head;
struct hlist_node hlist;
};
};
};
#define SEQNR_MASK 0x0ff /* low bits of unstable tree seqnr */
#define UNSTABLE_FLAG 0x100 /* is a node of the unstable tree */
#define STABLE_FLAG 0x200 /* is listed from the stable tree */
#define KSM_FLAG_MASK (SEQNR_MASK|UNSTABLE_FLAG|STABLE_FLAG)
/* to mask all the flags */
/* The stable and unstable tree heads */
static struct rb_root one_stable_tree[1] = { RB_ROOT };
static struct rb_root one_unstable_tree[1] = { RB_ROOT };
static struct rb_root *root_stable_tree = one_stable_tree;
static struct rb_root *root_unstable_tree = one_unstable_tree;
/* Recently migrated nodes of stable tree, pending proper placement */
static LIST_HEAD(migrate_nodes);
#define STABLE_NODE_DUP_HEAD ((struct list_head *)&migrate_nodes.prev)
#define MM_SLOTS_HASH_BITS 10
static DEFINE_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
static struct mm_slot ksm_mm_head = {
.mm_list = LIST_HEAD_INIT(ksm_mm_head.mm_list),
};
static struct ksm_scan ksm_scan = {
.mm_slot = &ksm_mm_head,
};
static struct kmem_cache *rmap_item_cache;
static struct kmem_cache *stable_node_cache;
static struct kmem_cache *mm_slot_cache;
/* The number of nodes in the stable tree */
static unsigned long ksm_pages_shared;
/* The number of page slots additionally sharing those nodes */
static unsigned long ksm_pages_sharing;
/* The number of nodes in the unstable tree */
static unsigned long ksm_pages_unshared;
/* The number of rmap_items in use: to calculate pages_volatile */
static unsigned long ksm_rmap_items;
/* The number of stable_node chains */
static unsigned long ksm_stable_node_chains;
/* The number of stable_node dups linked to the stable_node chains */
static unsigned long ksm_stable_node_dups;
/* Delay in pruning stale stable_node_dups in the stable_node_chains */
static int ksm_stable_node_chains_prune_millisecs = 2000;
/* Maximum number of page slots sharing a stable node */
static int ksm_max_page_sharing = 256;
/* Number of pages ksmd should scan in one batch */
static unsigned int ksm_thread_pages_to_scan = 100;
/* Milliseconds ksmd should sleep between batches */
static unsigned int ksm_thread_sleep_millisecs = 20;
/* Checksum of an empty (zeroed) page */
static unsigned int zero_checksum __read_mostly;
/* Whether to merge empty (zeroed) pages with actual zero pages */
static bool ksm_use_zero_pages __read_mostly;
#ifdef CONFIG_NUMA
/* Zeroed when merging across nodes is not allowed */
static unsigned int ksm_merge_across_nodes = 1;
static int ksm_nr_node_ids = 1;
#else
#define ksm_merge_across_nodes 1U
#define ksm_nr_node_ids 1
#endif
#define KSM_RUN_STOP 0
#define KSM_RUN_MERGE 1
#define KSM_RUN_UNMERGE 2
#define KSM_RUN_OFFLINE 4
static unsigned long ksm_run = KSM_RUN_STOP;
static void wait_while_offlining(void);
static DECLARE_WAIT_QUEUE_HEAD(ksm_thread_wait);
static DECLARE_WAIT_QUEUE_HEAD(ksm_iter_wait);
static DEFINE_MUTEX(ksm_thread_mutex);
static DEFINE_SPINLOCK(ksm_mmlist_lock);
#define KSM_KMEM_CACHE(__struct, __flags) kmem_cache_create("ksm_"#__struct,\
sizeof(struct __struct), __alignof__(struct __struct),\
(__flags), NULL)
static int __init ksm_slab_init(void)
{
rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0);
if (!rmap_item_cache)
goto out;
stable_node_cache = KSM_KMEM_CACHE(stable_node, 0);
if (!stable_node_cache)
goto out_free1;
mm_slot_cache = KSM_KMEM_CACHE(mm_slot, 0);
if (!mm_slot_cache)
goto out_free2;
return 0;
out_free2:
kmem_cache_destroy(stable_node_cache);
out_free1:
kmem_cache_destroy(rmap_item_cache);
out:
return -ENOMEM;
}
static void __init ksm_slab_free(void)
{
kmem_cache_destroy(mm_slot_cache);
kmem_cache_destroy(stable_node_cache);
kmem_cache_destroy(rmap_item_cache);
mm_slot_cache = NULL;
}
static __always_inline bool is_stable_node_chain(struct stable_node *chain)
{
return chain->rmap_hlist_len == STABLE_NODE_CHAIN;
}
static __always_inline bool is_stable_node_dup(struct stable_node *dup)
{
return dup->head == STABLE_NODE_DUP_HEAD;
}
static inline void stable_node_chain_add_dup(struct stable_node *dup,
struct stable_node *chain)
{
VM_BUG_ON(is_stable_node_dup(dup));
dup->head = STABLE_NODE_DUP_HEAD;
VM_BUG_ON(!is_stable_node_chain(chain));
hlist_add_head(&dup->hlist_dup, &chain->hlist);
ksm_stable_node_dups++;
}
static inline void __stable_node_dup_del(struct stable_node *dup)
{
VM_BUG_ON(!is_stable_node_dup(dup));
hlist_del(&dup->hlist_dup);
ksm_stable_node_dups--;
}
static inline void stable_node_dup_del(struct stable_node *dup)
{
VM_BUG_ON(is_stable_node_chain(dup));
if (is_stable_node_dup(dup))
__stable_node_dup_del(dup);
else
rb_erase(&dup->node, root_stable_tree + NUMA(dup->nid));
#ifdef CONFIG_DEBUG_VM
dup->head = NULL;
#endif
}
static inline struct rmap_item *alloc_rmap_item(void)
{
struct rmap_item *rmap_item;
rmap_item = kmem_cache_zalloc(rmap_item_cache, GFP_KERNEL |
__GFP_NORETRY | __GFP_NOWARN);
if (rmap_item)
ksm_rmap_items++;
return rmap_item;
}
static inline void free_rmap_item(struct rmap_item *rmap_item)
{
ksm_rmap_items--;
rmap_item->mm = NULL; /* debug safety */
kmem_cache_free(rmap_item_cache, rmap_item);
}
static inline struct stable_node *alloc_stable_node(void)
{
/*
* The allocation can take too long with GFP_KERNEL when memory is under
* pressure, which may lead to hung task warnings. Adding __GFP_HIGH
* grants access to memory reserves, helping to avoid this problem.
*/
return kmem_cache_alloc(stable_node_cache, GFP_KERNEL | __GFP_HIGH);
}
static inline void free_stable_node(struct stable_node *stable_node)
{
VM_BUG_ON(stable_node->rmap_hlist_len &&
!is_stable_node_chain(stable_node));
kmem_cache_free(stable_node_cache, stable_node);
}
static inline struct mm_slot *alloc_mm_slot(void)
{
if (!mm_slot_cache) /* initialization failed */
return NULL;
return kmem_cache_zalloc(mm_slot_cache, GFP_KERNEL);
}
static inline void free_mm_slot(struct mm_slot *mm_slot)
{
kmem_cache_free(mm_slot_cache, mm_slot);
}
static struct mm_slot *get_mm_slot(struct mm_struct *mm)
{
struct mm_slot *slot;
hash_for_each_possible(mm_slots_hash, slot, link, (unsigned long)mm)
if (slot->mm == mm)
return slot;
return NULL;
}
static void insert_to_mm_slots_hash(struct mm_struct *mm,
struct mm_slot *mm_slot)
{
mm_slot->mm = mm;
hash_add(mm_slots_hash, &mm_slot->link, (unsigned long)mm);
}
/*
* ksmd, and unmerge_and_remove_all_rmap_items(), must not touch an mm's
* page tables after it has passed through ksm_exit() - which, if necessary,
* takes mmap_sem briefly to serialize against them. ksm_exit() does not set
* a special flag: they can just back out as soon as mm_users goes to zero.
* ksm_test_exit() is used throughout to make this test for exit: in some
* places for correctness, in some places just to avoid unnecessary work.
*/
static inline bool ksm_test_exit(struct mm_struct *mm)
{
return atomic_read(&mm->mm_users) == 0;
}
/*
* We use break_ksm to break COW on a ksm page: it's a stripped down
*
* if (get_user_pages(addr, 1, 1, 1, &page, NULL) == 1)
* put_page(page);
*
* but taking great care only to touch a ksm page, in a VM_MERGEABLE vma,
* in case the application has unmapped and remapped mm,addr meanwhile.
* Could a ksm page appear anywhere else? Actually yes, in a VM_PFNMAP
* mmap of /dev/mem or /dev/kmem, where we would not want to touch it.
*
* FAULT_FLAG/FOLL_REMOTE are because we do this outside the context
* of the process that owns 'vma'. We also do not want to enforce
* protection keys here anyway.
*/
static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
{
struct page *page;
vm_fault_t ret = 0;
do {
cond_resched();
page = follow_page(vma, addr,
FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE);
if (IS_ERR_OR_NULL(page))
break;
if (PageKsm(page))
ret = handle_mm_fault(vma, addr,
FAULT_FLAG_WRITE | FAULT_FLAG_REMOTE);
else
ret = VM_FAULT_WRITE;
put_page(page);
} while (!(ret & (VM_FAULT_WRITE | VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV | VM_FAULT_OOM)));
/*
* We must loop because handle_mm_fault() may back out if there's
* any difficulty e.g. if pte accessed bit gets updated concurrently.
*
* VM_FAULT_WRITE is what we have been hoping for: it indicates that
* COW has been broken, even if the vma does not permit VM_WRITE;
* but note that a concurrent fault might break PageKsm for us.
*
* VM_FAULT_SIGBUS could occur if we race with truncation of the
* backing file, which also invalidates anonymous pages: that's
* okay, that truncation will have unmapped the PageKsm for us.
*
* VM_FAULT_OOM: at the time of writing (late July 2009), setting
* aside mem_cgroup limits, VM_FAULT_OOM would only be set if the
* current task has TIF_MEMDIE set, and will be OOM killed on return
* to user; and ksmd, having no mm, would never be chosen for that.
*
* But if the mm is in a limited mem_cgroup, then the fault may fail
* with VM_FAULT_OOM even if the current task is not TIF_MEMDIE; and
* even ksmd can fail in this way - though it's usually breaking ksm
* just to undo a merge it made a moment before, so unlikely to oom.
*
* That's a pity: we might therefore have more kernel pages allocated
* than we're counting as nodes in the stable tree; but ksm_do_scan
* will retry to break_cow on each pass, so should recover the page
* in due course. The important thing is to not let VM_MERGEABLE
* be cleared while any such pages might remain in the area.
*/
return (ret & VM_FAULT_OOM) ? -ENOMEM : 0;
}
static struct vm_area_struct *find_mergeable_vma(struct mm_struct *mm,
unsigned long addr)
{
struct vm_area_struct *vma;
if (ksm_test_exit(mm))
return NULL;
vma = find_vma(mm, addr);
if (!vma || vma->vm_start > addr)
return NULL;
if (!(vma->vm_flags & VM_MERGEABLE) || !vma->anon_vma)
return NULL;
return vma;
}
static void break_cow(struct rmap_item *rmap_item)
{
struct mm_struct *mm = rmap_item->mm;
unsigned long addr = rmap_item->address;
struct vm_area_struct *vma;
/*
* It is not an accident that whenever we want to break COW
* to undo, we also need to drop a reference to the anon_vma.
*/
put_anon_vma(rmap_item->anon_vma);
down_read(&mm->mmap_sem);
vma = find_mergeable_vma(mm, addr);
if (vma)
break_ksm(vma, addr);
up_read(&mm->mmap_sem);
}
static struct page *get_mergeable_page(struct rmap_item *rmap_item)
{
struct mm_struct *mm = rmap_item->mm;
unsigned long addr = rmap_item->address;
struct vm_area_struct *vma;
struct page *page;
down_read(&mm->mmap_sem);
vma = find_mergeable_vma(mm, addr);
if (!vma)
goto out;
page = follow_page(vma, addr, FOLL_GET);
if (IS_ERR_OR_NULL(page))
goto out;
if (PageAnon(page)) {
flush_anon_page(vma, page, addr);
flush_dcache_page(page);
} else {
put_page(page);
out:
page = NULL;
}
up_read(&mm->mmap_sem);
return page;
}
/*
* This helper is used for getting right index into array of tree roots.
* When merge_across_nodes knob is set to 1, there are only two rb-trees for
* stable and unstable pages from all nodes with roots in index 0. Otherwise,
* every node has its own stable and unstable tree.
*/
static inline int get_kpfn_nid(unsigned long kpfn)
{
return ksm_merge_across_nodes ? 0 : NUMA(pfn_to_nid(kpfn));
}
static struct stable_node *alloc_stable_node_chain(struct stable_node *dup,
struct rb_root *root)
{
struct stable_node *chain = alloc_stable_node();
VM_BUG_ON(is_stable_node_chain(dup));
if (likely(chain)) {
INIT_HLIST_HEAD(&chain->hlist);
chain->chain_prune_time = jiffies;
chain->rmap_hlist_len = STABLE_NODE_CHAIN;
#if defined (CONFIG_DEBUG_VM) && defined(CONFIG_NUMA)
chain->nid = NUMA_NO_NODE; /* debug */
#endif
ksm_stable_node_chains++;
/*
* Put the stable node chain in the first dimension of
* the stable tree and at the same time remove the old
* stable node.
*/
rb_replace_node(&dup->node, &chain->node, root);
/*
* Move the old stable node to the second dimension
* queued in the hlist_dup. The invariant is that all
* dup stable_nodes in the chain->hlist point to pages
* that are wrprotected and have the exact same
* content.
*/
stable_node_chain_add_dup(dup, chain);
}
return chain;
}
static inline void free_stable_node_chain(struct stable_node *chain,
struct rb_root *root)
{
rb_erase(&chain->node, root);
free_stable_node(chain);
ksm_stable_node_chains--;
}
static void remove_node_from_stable_tree(struct stable_node *stable_node)
{
struct rmap_item *rmap_item;
/* check it's not STABLE_NODE_CHAIN or negative */
BUG_ON(stable_node->rmap_hlist_len < 0);
hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
if (rmap_item->hlist.next)
ksm_pages_sharing--;
else
ksm_pages_shared--;
VM_BUG_ON(stable_node->rmap_hlist_len <= 0);
stable_node->rmap_hlist_len--;
put_anon_vma(rmap_item->anon_vma);
rmap_item->address &= PAGE_MASK;
cond_resched();
}
/*
* We need the second aligned pointer of the migrate_nodes
* list_head to stay clear from the rb_parent_color union
* (aligned and different than any node) and also different
* from &migrate_nodes. This will verify that future list.h changes
* don't break STABLE_NODE_DUP_HEAD. Only recent gcc can handle it.
*/
#if defined(GCC_VERSION) && GCC_VERSION >= 40903
BUILD_BUG_ON(STABLE_NODE_DUP_HEAD <= &migrate_nodes);
BUILD_BUG_ON(STABLE_NODE_DUP_HEAD >= &migrate_nodes + 1);
#endif
if (stable_node->head == &migrate_nodes)
list_del(&stable_node->list);
else
stable_node_dup_del(stable_node);
free_stable_node(stable_node);
}
enum get_ksm_page_flags {
GET_KSM_PAGE_NOLOCK,
GET_KSM_PAGE_LOCK,
GET_KSM_PAGE_TRYLOCK
};
/*
* get_ksm_page: checks if the page indicated by the stable node
* is still its ksm page, despite having held no reference to it.
* In which case we can trust the content of the page, and it
* returns the gotten page; but if the page has now been zapped,
* remove the stale node from the stable tree and return NULL.
* But beware, the stable node's page might be being migrated.
*
* You would expect the stable_node to hold a reference to the ksm page.
* But if it increments the page's count, swapping out has to wait for
* ksmd to come around again before it can free the page, which may take
* seconds or even minutes: much too unresponsive. So instead we use a
* "keyhole reference": access to the ksm page from the stable node peeps
* out through its keyhole to see if that page still holds the right key,
* pointing back to this stable node. This relies on freeing a PageAnon
* page to reset its page->mapping to NULL, and relies on no other use of
* a page to put something that might look like our key in page->mapping.
* is on its way to being freed; but it is an anomaly to bear in mind.
*/
static struct page *get_ksm_page(struct stable_node *stable_node,
enum get_ksm_page_flags flags)
{
struct page *page;
void *expected_mapping;
unsigned long kpfn;
expected_mapping = (void *)((unsigned long)stable_node |
PAGE_MAPPING_KSM);
again:
kpfn = READ_ONCE(stable_node->kpfn); /* Address dependency. */
page = pfn_to_page(kpfn);
if (READ_ONCE(page->mapping) != expected_mapping)
goto stale;
/*
* We cannot do anything with the page while its refcount is 0.
* Usually 0 means free, or tail of a higher-order page: in which
* case this node is no longer referenced, and should be freed;
* however, it might mean that the page is under page_ref_freeze().
* The __remove_mapping() case is easy, again the node is now stale;
* the same is in reuse_ksm_page() case; but if page is swapcache
* in migrate_page_move_mapping(), it might still be our page,
* in which case it's essential to keep the node.
*/
while (!get_page_unless_zero(page)) {
/*
* Another check for page->mapping != expected_mapping would
* work here too. We have chosen the !PageSwapCache test to
* optimize the common case, when the page is or is about to
* be freed: PageSwapCache is cleared (under spin_lock_irq)
* in the ref_freeze section of __remove_mapping(); but Anon
* page->mapping reset to NULL later, in free_pages_prepare().
*/
if (!PageSwapCache(page))
goto stale;
cpu_relax();
}
if (READ_ONCE(page->mapping) != expected_mapping) {
put_page(page);
goto stale;
}
if (flags == GET_KSM_PAGE_TRYLOCK) {
if (!trylock_page(page)) {
put_page(page);
return ERR_PTR(-EBUSY);
}
} else if (flags == GET_KSM_PAGE_LOCK)
lock_page(page);
if (flags != GET_KSM_PAGE_NOLOCK) {
if (READ_ONCE(page->mapping) != expected_mapping) {
unlock_page(page);
put_page(page);
goto stale;
}
}
return page;
stale:
/*
* We come here from above when page->mapping or !PageSwapCache
* suggests that the node is stale; but it might be under migration.
* We need smp_rmb(), matching the smp_wmb() in ksm_migrate_page(),
* before checking whether node->kpfn has been changed.
*/
smp_rmb();
if (READ_ONCE(stable_node->kpfn) != kpfn)
goto again;
remove_node_from_stable_tree(stable_node);
return NULL;
}
/*
* Removing rmap_item from stable or unstable tree.
* This function will clean the information from the stable/unstable tree.
*/
static void remove_rmap_item_from_tree(struct rmap_item *rmap_item)
{
if (rmap_item->address & STABLE_FLAG) {
struct stable_node *stable_node;
struct page *page;
stable_node = rmap_item->head;
page = get_ksm_page(stable_node, GET_KSM_PAGE_LOCK);
if (!page)
goto out;
hlist_del(&rmap_item->hlist);
unlock_page(page);
put_page(page);
if (!hlist_empty(&stable_node->hlist))
ksm_pages_sharing--;
else
ksm_pages_shared--;
VM_BUG_ON(stable_node->rmap_hlist_len <= 0);
stable_node->rmap_hlist_len--;
put_anon_vma(rmap_item->anon_vma);
rmap_item->address &= PAGE_MASK;
} else if (rmap_item->address & UNSTABLE_FLAG) {
unsigned char age;
/*
* Usually ksmd can and must skip the rb_erase, because
* root_unstable_tree was already reset to RB_ROOT.
* But be careful when an mm is exiting: do the rb_erase
* if this rmap_item was inserted by this scan, rather
* than left over from before.
*/
age = (unsigned char)(ksm_scan.seqnr - rmap_item->address);
BUG_ON(age > 1);
if (!age)
rb_erase(&rmap_item->node,
root_unstable_tree + NUMA(rmap_item->nid));
ksm_pages_unshared--;
rmap_item->address &= PAGE_MASK;
}
out:
cond_resched(); /* we're called from many long loops */
}
static void remove_trailing_rmap_items(struct mm_slot *mm_slot,
struct rmap_item **rmap_list)
{
while (*rmap_list) {
struct rmap_item *rmap_item = *rmap_list;
*rmap_list = rmap_item->rmap_list;
remove_rmap_item_from_tree(rmap_item);
free_rmap_item(rmap_item);
}
}
/*
* Though it's very tempting to unmerge rmap_items from stable tree rather
* than check every pte of a given vma, the locking doesn't quite work for
* that - an rmap_item is assigned to the stable tree after inserting ksm
* page and upping mmap_sem. Nor does it fit with the way we skip dup'ing
* rmap_items from parent to child at fork time (so as not to waste time
* if exit comes before the next scan reaches it).
*
* Similarly, although we'd like to remove rmap_items (so updating counts
* and freeing memory) when unmerging an area, it's easier to leave that
* to the next pass of ksmd - consider, for example, how ksmd might be
* in cmp_and_merge_page on one of the rmap_items we would be removing.
*/
static int unmerge_ksm_pages(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
unsigned long addr;
int err = 0;
for (addr = start; addr < end && !err; addr += PAGE_SIZE) {
if (ksm_test_exit(vma->vm_mm))
break;
if (signal_pending(current))
err = -ERESTARTSYS;
else
err = break_ksm(vma, addr);
}
return err;
}
static inline struct stable_node *page_stable_node(struct page *page)
{
return PageKsm(page) ? page_rmapping(page) : NULL;
}
static inline void set_page_stable_node(struct page *page,
struct stable_node *stable_node)
{
page->mapping = (void *)((unsigned long)stable_node | PAGE_MAPPING_KSM);
}
#ifdef CONFIG_SYSFS
/*
* Only called through the sysfs control interface:
*/
static int remove_stable_node(struct stable_node *stable_node)
{
struct page *page;
int err;
page = get_ksm_page(stable_node, GET_KSM_PAGE_LOCK);
if (!page) {
/*
* get_ksm_page did remove_node_from_stable_tree itself.
*/
return 0;
}
/*
* Page could be still mapped if this races with __mmput() running in
* between ksm_exit() and exit_mmap(). Just refuse to let
* merge_across_nodes/max_page_sharing be switched.
*/
err = -EBUSY;
if (!page_mapped(page)) {
/*
* The stable node did not yet appear stale to get_ksm_page(),
* since that allows for an unmapped ksm page to be recognized
* right up until it is freed; but the node is safe to remove.
* This page might be in a pagevec waiting to be freed,
* or it might be PageSwapCache (perhaps under writeback),
* or it might have been removed from swapcache a moment ago.
*/
set_page_stable_node(page, NULL);
remove_node_from_stable_tree(stable_node);
err = 0;
}
unlock_page(page);
put_page(page);
return err;
}
static int remove_stable_node_chain(struct stable_node *stable_node,
struct rb_root *root)
{
struct stable_node *dup;
struct hlist_node *hlist_safe;
if (!is_stable_node_chain(stable_node)) {
VM_BUG_ON(is_stable_node_dup(stable_node));
if (remove_stable_node(stable_node))
return true;
else
return false;
}
hlist_for_each_entry_safe(dup, hlist_safe,
&stable_node->hlist, hlist_dup) {
VM_BUG_ON(!is_stable_node_dup(dup));
if (remove_stable_node(dup))
return true;
}
BUG_ON(!hlist_empty(&stable_node->hlist));
free_stable_node_chain(stable_node, root);
return false;
}
static int remove_all_stable_nodes(void)
{
struct stable_node *stable_node, *next;
int nid;
int err = 0;
for (nid = 0; nid < ksm_nr_node_ids; nid++) {
while (root_stable_tree[nid].rb_node) {
stable_node = rb_entry(root_stable_tree[nid].rb_node,
struct stable_node, node);
if (remove_stable_node_chain(stable_node,
root_stable_tree + nid)) {
err = -EBUSY;
break; /* proceed to next nid */
}
cond_resched();
}
}
list_for_each_entry_safe(stable_node, next, &migrate_nodes, list) {
if (remove_stable_node(stable_node))
err = -EBUSY;
cond_resched();
}
return err;
}
static int unmerge_and_remove_all_rmap_items(void)
{
struct mm_slot *mm_slot;
struct mm_struct *mm;
struct vm_area_struct *vma;
int err = 0;
spin_lock(&ksm_mmlist_lock);
ksm_scan.mm_slot = list_entry(ksm_mm_head.mm_list.next,
struct mm_slot, mm_list);
spin_unlock(&ksm_mmlist_lock);
for (mm_slot = ksm_scan.mm_slot;
mm_slot != &ksm_mm_head; mm_slot = ksm_scan.mm_slot) {
mm = mm_slot->mm;
down_read(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (ksm_test_exit(mm))
break;
if (!(vma->vm_flags & VM_MERGEABLE) || !vma->anon_vma)
continue;
err = unmerge_ksm_pages(vma,
vma->vm_start, vma->vm_end);
if (err)
goto error;
}
remove_trailing_rmap_items(mm_slot, &mm_slot->rmap_list);
up_read(&mm->mmap_sem);
spin_lock(&ksm_mmlist_lock);
ksm_scan.mm_slot = list_entry(mm_slot->mm_list.next,
struct mm_slot, mm_list);
if (ksm_test_exit(mm)) {
hash_del(&mm_slot->link);
list_del(&mm_slot->mm_list);
spin_unlock(&ksm_mmlist_lock);
free_mm_slot(mm_slot);
clear_bit(MMF_VM_MERGEABLE, &mm->flags);
mmdrop(mm);
} else
spin_unlock(&ksm_mmlist_lock);
}
/* Clean up stable nodes, but don't worry if some are still busy */
remove_all_stable_nodes();
ksm_scan.seqnr = 0;
return 0;
error:
up_read(&mm->mmap_sem);
spin_lock(&ksm_mmlist_lock);
ksm_scan.mm_slot = &ksm_mm_head;
spin_unlock(&ksm_mmlist_lock);
return err;
}
#endif /* CONFIG_SYSFS */
static u32 calc_checksum(struct page *page)
{
u32 checksum;
void *addr = kmap_atomic(page);
checksum = xxhash(addr, PAGE_SIZE, 0);
kunmap_atomic(addr);
return checksum;
}
static int write_protect_page(struct vm_area_struct *vma, struct page *page,
pte_t *orig_pte)
{
struct mm_struct *mm = vma->vm_mm;
struct page_vma_mapped_walk pvmw = {
.page = page,
.vma = vma,
};
int swapped;
int err = -EFAULT;
struct mmu_notifier_range range;
pvmw.address = page_address_in_vma(page, vma);
if (pvmw.address == -EFAULT)
goto out;
BUG_ON(PageTransCompound(page));
mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm,
pvmw.address,
pvmw.address + PAGE_SIZE);
mmu_notifier_invalidate_range_start(&range);
if (!page_vma_mapped_walk(&pvmw))
goto out_mn;
if (WARN_ONCE(!pvmw.pte, "Unexpected PMD mapping?"))
goto out_unlock;
if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) ||
(pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) ||
mm_tlb_flush_pending(mm)) {
pte_t entry;
swapped = PageSwapCache(page);
flush_cache_page(vma, pvmw.address, page_to_pfn(page));
/*
* Ok this is tricky, when get_user_pages_fast() run it doesn't
* take any lock, therefore the check that we are going to make
* with the pagecount against the mapcount is racey and
* O_DIRECT can happen right after the check.
* So we clear the pte and flush the tlb before the check
* this assure us that no O_DIRECT can happen after the check
* or in the middle of the check.
*
* No need to notify as we are downgrading page table to read
* only not changing it to point to a new page.
*
* See Documentation/vm/mmu_notifier.rst
*/
entry = ptep_clear_flush(vma, pvmw.address, pvmw.pte);
/*
* Check that no O_DIRECT or similar I/O is in progress on the
* page
*/
if (page_mapcount(page) + 1 + swapped != page_count(page)) {
set_pte_at(mm, pvmw.address, pvmw.pte, entry);
goto out_unlock;
}
if (pte_dirty(entry))
set_page_dirty(page);
if (pte_protnone(entry))
entry = pte_mkclean(pte_clear_savedwrite(entry));
else
entry = pte_mkclean(pte_wrprotect(entry));
set_pte_at_notify(mm, pvmw.address, pvmw.pte, entry);
}
*orig_pte = *pvmw.pte;
err = 0;
out_unlock:
page_vma_mapped_walk_done(&pvmw);
out_mn:
mmu_notifier_invalidate_range_end(&range);
out:
return err;
}
/**
* replace_page - replace page in vma by new ksm page
* @vma: vma that holds the pte pointing to page
* @page: the page we are replacing by kpage
* @kpage: the ksm page we replace page by
* @orig_pte: the original value of the pte
*
* Returns 0 on success, -EFAULT on failure.
*/
static int replace_page(struct vm_area_struct *vma, struct page *page,
struct page *kpage, pte_t orig_pte)
{
struct mm_struct *mm = vma->vm_mm;
pmd_t *pmd;
pte_t *ptep;
pte_t newpte;
spinlock_t *ptl;
unsigned long addr;
int err = -EFAULT;
struct mmu_notifier_range range;
addr = page_address_in_vma(page, vma);
if (addr == -EFAULT)
goto out;
pmd = mm_find_pmd(mm, addr);
if (!pmd)
goto out;
mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, mm, addr,
addr + PAGE_SIZE);
mmu_notifier_invalidate_range_start(&range);
ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
if (!pte_same(*ptep, orig_pte)) {
pte_unmap_unlock(ptep, ptl);
goto out_mn;
}
/*
* No need to check ksm_use_zero_pages here: we can only have a
* zero_page here if ksm_use_zero_pages was enabled alreaady.
*/
if (!is_zero_pfn(page_to_pfn(kpage))) {
get_page(kpage);
page_add_anon_rmap(kpage, vma, addr, false);
newpte = mk_pte(kpage, vma->vm_page_prot);
} else {
newpte = pte_mkspecial(pfn_pte(page_to_pfn(kpage),
vma->vm_page_prot));
/*
* We're replacing an anonymous page with a zero page, which is
* not anonymous. We need to do proper accounting otherwise we
* will get wrong values in /proc, and a BUG message in dmesg
* when tearing down the mm.
*/
dec_mm_counter(mm, MM_ANONPAGES);
}
flush_cache_page(vma, addr, pte_pfn(*ptep));
/*
* No need to notify as we are replacing a read only page with another
* read only page with the same content.
*
* See Documentation/vm/mmu_notifier.rst
*/
ptep_clear_flush(vma, addr, ptep);
set_pte_at_notify(mm, addr, ptep, newpte);
page_remove_rmap(page, false);
if (!page_mapped(page))
try_to_free_swap(page);
put_page(page);
pte_unmap_unlock(ptep, ptl);
err = 0;
out_mn:
mmu_notifier_invalidate_range_end(&range);
out:
return err;
}
/*
* try_to_merge_one_page - take two pages and merge them into one
* @vma: the vma that holds the pte pointing to page
* @page: the PageAnon page that we want to replace with kpage
* @kpage: the PageKsm page that we want to map instead of page,
* or NULL the first time when we want to use page as kpage.
*
* This function returns 0 if the pages were merged, -EFAULT otherwise.
*/
static int try_to_merge_one_page(struct vm_area_struct *vma,
struct page *page, struct page *kpage)
{
pte_t orig_pte = __pte(0);
int err = -EFAULT;
if (page == kpage) /* ksm page forked */
return 0;
if (!PageAnon(page))
goto out;
/*
* We need the page lock to read a stable PageSwapCache in
* write_protect_page(). We use trylock_page() instead of
* lock_page() because we don't want to wait here - we
* prefer to continue scanning and merging different pages,
* then come back to this page when it is unlocked.
*/
if (!trylock_page(page))
goto out;
if (PageTransCompound(page)) {
if (split_huge_page(page))
goto out_unlock;
}
/*
* If this anonymous page is mapped only here, its pte may need
* to be write-protected. If it's mapped elsewhere, all of its
* ptes are necessarily already write-protected. But in either
* case, we need to lock and check page_count is not raised.
*/
if (write_protect_page(vma, page, &orig_pte) == 0) {
if (!kpage) {
/*
* While we hold page lock, upgrade page from
* PageAnon+anon_vma to PageKsm+NULL stable_node:
* stable_tree_insert() will update stable_node.
*/
set_page_stable_node(page, NULL);
mark_page_accessed(page);
/*
* Page reclaim just frees a clean page with no dirty
* ptes: make sure that the ksm page would be swapped.
*/
if (!PageDirty(page))
SetPageDirty(page);
err = 0;
} else if (pages_identical(page, kpage))
err = replace_page(vma, page, kpage, orig_pte);
}
if ((vma->vm_flags & VM_LOCKED) && kpage && !err) {
munlock_vma_page(page);
if (!PageMlocked(kpage)) {
unlock_page(page);
lock_page(kpage);
mlock_vma_page(kpage);
page = kpage; /* for final unlock */
}
}
out_unlock:
unlock_page(page);
out:
return err;
}
/*
* try_to_merge_with_ksm_page - like try_to_merge_two_pages,
* but no new kernel page is allocated: kpage must already be a ksm page.
*
* This function returns 0 if the pages were merged, -EFAULT otherwise.
*/
static int try_to_merge_with_ksm_page(struct rmap_item *rmap_item,
struct page *page, struct page *kpage)
{
struct mm_struct *mm = rmap_item->mm;
struct vm_area_struct *vma;
int err = -EFAULT;
down_read(&mm->mmap_sem);
vma = find_mergeable_vma(mm, rmap_item->address);
if (!vma)
goto out;
err = try_to_merge_one_page(vma, page, kpage);
if (err)
goto out;
/* Unstable nid is in union with stable anon_vma: remove first */
remove_rmap_item_from_tree(rmap_item);
/* Must get reference to anon_vma while still holding mmap_sem */
rmap_item->anon_vma = vma->anon_vma;
get_anon_vma(vma->anon_vma);
out:
up_read(&mm->mmap_sem);
return err;
}
/*
* try_to_merge_two_pages - take two identical pages and prepare them
* to be merged into one page.
*
* This function returns the kpage if we successfully merged two identical
* pages into one ksm page, NULL otherwise.
*
* Note that this function upgrades page to ksm page: if one of the pages
* is already a ksm page, try_to_merge_with_ksm_page should be used.
*/
static struct page *try_to_merge_two_pages(struct rmap_item *rmap_item,
struct page *page,
struct rmap_item *tree_rmap_item,
struct page *tree_page)
{
int err;
err = try_to_merge_with_ksm_page(rmap_item, page, NULL);
if (!err) {
err = try_to_merge_with_ksm_page(tree_rmap_item,
tree_page, page);
/*
* If that fails, we have a ksm page with only one pte
* pointing to it: so break it.
*/
if (err)
break_cow(rmap_item);
}
return err ? NULL : page;
}
static __always_inline
bool __is_page_sharing_candidate(struct stable_node *stable_node, int offset)
{
VM_BUG_ON(stable_node->rmap_hlist_len < 0);
/*
* Check that at least one mapping still exists, otherwise
* there's no much point to merge and share with this
* stable_node, as the underlying tree_page of the other
* sharer is going to be freed soon.
*/
return stable_node->rmap_hlist_len &&
stable_node->rmap_hlist_len + offset < ksm_max_page_sharing;
}
static __always_inline
bool is_page_sharing_candidate(struct stable_node *stable_node)
{
return __is_page_sharing_candidate(stable_node, 0);
}
static struct page *stable_node_dup(struct stable_node **_stable_node_dup,
struct stable_node **_stable_node,
struct rb_root *root,
bool prune_stale_stable_nodes)
{
struct stable_node *dup, *found = NULL, *stable_node = *_stable_node;
struct hlist_node *hlist_safe;
struct page *_tree_page, *tree_page = NULL;
int nr = 0;
int found_rmap_hlist_len;
if (!prune_stale_stable_nodes ||
time_before(jiffies, stable_node->chain_prune_time +
msecs_to_jiffies(
ksm_stable_node_chains_prune_millisecs)))
prune_stale_stable_nodes = false;
else
stable_node->chain_prune_time = jiffies;
hlist_for_each_entry_safe(dup, hlist_safe,
&stable_node->hlist, hlist_dup) {
cond_resched();
/*
* We must walk all stable_node_dup to prune the stale
* stable nodes during lookup.
*
* get_ksm_page can drop the nodes from the
* stable_node->hlist if they point to freed pages
* (that's why we do a _safe walk). The "dup"
* stable_node parameter itself will be freed from
* under us if it returns NULL.
*/
_tree_page = get_ksm_page(dup, GET_KSM_PAGE_NOLOCK);
if (!_tree_page)
continue;
nr += 1;
if (is_page_sharing_candidate(dup)) {
if (!found ||
dup->rmap_hlist_len > found_rmap_hlist_len) {
if (found)
put_page(tree_page);
found = dup;
found_rmap_hlist_len = found->rmap_hlist_len;
tree_page = _tree_page;
/* skip put_page for found dup */
if (!prune_stale_stable_nodes)
break;
continue;
}
}
put_page(_tree_page);
}
if (found) {
/*
* nr is counting all dups in the chain only if
* prune_stale_stable_nodes is true, otherwise we may
* break the loop at nr == 1 even if there are
* multiple entries.
*/
if (prune_stale_stable_nodes && nr == 1) {
/*
* If there's not just one entry it would
* corrupt memory, better BUG_ON. In KSM
* context with no lock held it's not even
* fatal.
*/
BUG_ON(stable_node->hlist.first->next);
/*
* There's just one entry and it is below the
* deduplication limit so drop the chain.
*/
rb_replace_node(&stable_node->node, &found->node,
root);
free_stable_node(stable_node);
ksm_stable_node_chains--;
ksm_stable_node_dups--;
/*
* NOTE: the caller depends on the stable_node
* to be equal to stable_node_dup if the chain
* was collapsed.
*/
*_stable_node = found;
/*
* Just for robustneess as stable_node is
* otherwise left as a stable pointer, the
* compiler shall optimize it away at build
* time.
*/
stable_node = NULL;
} else if (stable_node->hlist.first != &found->hlist_dup &&
__is_page_sharing_candidate(found, 1)) {
/*
* If the found stable_node dup can accept one
* more future merge (in addition to the one
* that is underway) and is not at the head of
* the chain, put it there so next search will
* be quicker in the !prune_stale_stable_nodes
* case.
*
* NOTE: it would be inaccurate to use nr > 1
* instead of checking the hlist.first pointer
* directly, because in the
* prune_stale_stable_nodes case "nr" isn't
* the position of the found dup in the chain,
* but the total number of dups in the chain.
*/
hlist_del(&found->hlist_dup);
hlist_add_head(&found->hlist_dup,
&stable_node->hlist);
}
}
*_stable_node_dup = found;
return tree_page;
}
static struct stable_node *stable_node_dup_any(struct stable_node *stable_node,
struct rb_root *root)
{
if (!is_stable_node_chain(stable_node))
return stable_node;
if (hlist_empty(&stable_node->hlist)) {
free_stable_node_chain(stable_node, root);
return NULL;
}
return hlist_entry(stable_node->hlist.first,
typeof(*stable_node), hlist_dup);
}
/*
* Like for get_ksm_page, this function can free the *_stable_node and
* *_stable_node_dup if the returned tree_page is NULL.
*
* It can also free and overwrite *_stable_node with the found
* stable_node_dup if the chain is collapsed (in which case
* *_stable_node will be equal to *_stable_node_dup like if the chain
* never existed). It's up to the caller to verify tree_page is not
* NULL before dereferencing *_stable_node or *_stable_node_dup.
*
* *_stable_node_dup is really a second output parameter of this
* function and will be overwritten in all cases, the caller doesn't
* need to initialize it.
*/
static struct page *__stable_node_chain(struct stable_node **_stable_node_dup,
struct stable_node **_stable_node,
struct rb_root *root,
bool prune_stale_stable_nodes)
{
struct stable_node *stable_node = *_stable_node;
if (!is_stable_node_chain(stable_node)) {
if (is_page_sharing_candidate(stable_node)) {
*_stable_node_dup = stable_node;
return get_ksm_page(stable_node, GET_KSM_PAGE_NOLOCK);
}
/*
* _stable_node_dup set to NULL means the stable_node
* reached the ksm_max_page_sharing limit.
*/
*_stable_node_dup = NULL;
return NULL;
}
return stable_node_dup(_stable_node_dup, _stable_node, root,
prune_stale_stable_nodes);
}
static __always_inline struct page *chain_prune(struct stable_node **s_n_d,
struct stable_node **s_n,
struct rb_root *root)
{
return __stable_node_chain(s_n_d, s_n, root, true);
}
static __always_inline struct page *chain(struct stable_node **s_n_d,
struct stable_node *s_n,
struct rb_root *root)
{
struct stable_node *old_stable_node = s_n;
struct page *tree_page;
tree_page = __stable_node_chain(s_n_d, &s_n, root, false);
/* not pruning dups so s_n cannot have changed */
VM_BUG_ON(s_n != old_stable_node);
return tree_page;
}
/*
* stable_tree_search - search for page inside the stable tree
*
* This function checks if there is a page inside the stable tree
* with identical content to the page that we are scanning right now.
*
* This function returns the stable tree node of identical content if found,
* NULL otherwise.
*/
static struct page *stable_tree_search(struct page *page)
{
int nid;
struct rb_root *root;
struct rb_node **new;
struct rb_node *parent;
struct stable_node *stable_node, *stable_node_dup, *stable_node_any;
struct stable_node *page_node;
page_node = page_stable_node(page);
if (page_node && page_node->head != &migrate_nodes) {
/* ksm page forked */
get_page(page);
return page;
}
nid = get_kpfn_nid(page_to_pfn(page));
root = root_stable_tree + nid;
again:
new = &root->rb_node;
parent = NULL;
while (*new) {
struct page *tree_page;
int ret;
cond_resched();
stable_node = rb_entry(*new, struct stable_node, node);
stable_node_any = NULL;
tree_page = chain_prune(&stable_node_dup, &stable_node, root);
/*
* NOTE: stable_node may have been freed by
* chain_prune() if the returned stable_node_dup is
* not NULL. stable_node_dup may have been inserted in
* the rbtree instead as a regular stable_node (in
* order to collapse the stable_node chain if a single
* stable_node dup was found in it). In such case the
* stable_node is overwritten by the calleee to point
* to the stable_node_dup that was collapsed in the
* stable rbtree and stable_node will be equal to
* stable_node_dup like if the chain never existed.
*/
if (!stable_node_dup) {
/*
* Either all stable_node dups were full in
* this stable_node chain, or this chain was
* empty and should be rb_erased.
*/
stable_node_any = stable_node_dup_any(stable_node,
root);
if (!stable_node_any) {
/* rb_erase just run */
goto again;
}
/*
* Take any of the stable_node dups page of
* this stable_node chain to let the tree walk
* continue. All KSM pages belonging to the
* stable_node dups in a stable_node chain
* have the same content and they're
* wrprotected at all times. Any will work
* fine to continue the walk.
*/
tree_page = get_ksm_page(stable_node_any,
GET_KSM_PAGE_NOLOCK);
}
VM_BUG_ON(!stable_node_dup ^ !!stable_node_any);
if (!tree_page) {
/*
* If we walked over a stale stable_node,
* get_ksm_page() will call rb_erase() and it
* may rebalance the tree from under us. So
* restart the search from scratch. Returning
* NULL would be safe too, but we'd generate
* false negative insertions just because some
* stable_node was stale.
*/
goto again;
}
ret = memcmp_pages(page, tree_page);
put_page(tree_page);
parent = *new;
if (ret < 0)
new = &parent->rb_left;
else if (ret > 0)
new = &parent->rb_right;
else {
if (page_node) {
VM_BUG_ON(page_node->head != &migrate_nodes);
/*
* Test if the migrated page should be merged
* into a stable node dup. If the mapcount is
* 1 we can migrate it with another KSM page
* without adding it to the chain.
*/
if (page_mapcount(page) > 1)
goto chain_append;
}
if (!stable_node_dup) {
/*
* If the stable_node is a chain and
* we got a payload match in memcmp
* but we cannot merge the scanned
* page in any of the existing
* stable_node dups because they're
* all full, we need to wait the
* scanned page to find itself a match
* in the unstable tree to create a
* brand new KSM page to add later to
* the dups of this stable_node.
*/
return NULL;
}
/*
* Lock and unlock the stable_node's page (which
* might already have been migrated) so that page
* migration is sure to notice its raised count.
* It would be more elegant to return stable_node
* than kpage, but that involves more changes.
*/
tree_page = get_ksm_page(stable_node_dup,
GET_KSM_PAGE_TRYLOCK);
if (PTR_ERR(tree_page) == -EBUSY)
return ERR_PTR(-EBUSY);
if (unlikely(!tree_page))
/*
* The tree may have been rebalanced,
* so re-evaluate parent and new.
*/
goto again;
unlock_page(tree_page);
if (get_kpfn_nid(stable_node_dup->kpfn) !=
NUMA(stable_node_dup->nid)) {
put_page(tree_page);
goto replace;
}
return tree_page;
}
}
if (!page_node)
return NULL;
list_del(&page_node->list);
DO_NUMA(page_node->nid = nid);
rb_link_node(&page_node->node, parent, new);
rb_insert_color(&page_node->node, root);
out:
if (is_page_sharing_candidate(page_node)) {
get_page(page);
return page;
} else
return NULL;
replace:
/*
* If stable_node was a chain and chain_prune collapsed it,
* stable_node has been updated to be the new regular
* stable_node. A collapse of the chain is indistinguishable
* from the case there was no chain in the stable
* rbtree. Otherwise stable_node is the chain and
* stable_node_dup is the dup to replace.
*/
if (stable_node_dup == stable_node) {
VM_BUG_ON(is_stable_node_chain(stable_node_dup));
VM_BUG_ON(is_stable_node_dup(stable_node_dup));
/* there is no chain */
if (page_node) {
VM_BUG_ON(page_node->head != &migrate_nodes);
list_del(&page_node->list);
DO_NUMA(page_node->nid = nid);
rb_replace_node(&stable_node_dup->node,
&page_node->node,
root);
if (is_page_sharing_candidate(page_node))
get_page(page);
else
page = NULL;
} else {
rb_erase(&stable_node_dup->node, root);
page = NULL;
}
} else {
VM_BUG_ON(!is_stable_node_chain(stable_node));
__stable_node_dup_del(stable_node_dup);
if (page_node) {
VM_BUG_ON(page_node->head != &migrate_nodes);
list_del(&page_node->list);
DO_NUMA(page_node->nid = nid);
stable_node_chain_add_dup(page_node, stable_node);
if (is_page_sharing_candidate(page_node))
get_page(page);
else
page = NULL;
} else {
page = NULL;
}
}
stable_node_dup->head = &migrate_nodes;
list_add(&stable_node_dup->list, stable_node_dup->head);
return page;
chain_append:
/* stable_node_dup could be null if it reached the limit */
if (!stable_node_dup)
stable_node_dup = stable_node_any;
/*
* If stable_node was a chain and chain_prune collapsed it,
* stable_node has been updated to be the new regular
* stable_node. A collapse of the chain is indistinguishable
* from the case there was no chain in the stable
* rbtree. Otherwise stable_node is the chain and
* stable_node_dup is the dup to replace.
*/
if (stable_node_dup == stable_node) {
VM_BUG_ON(is_stable_node_chain(stable_node_dup));
VM_BUG_ON(is_stable_node_dup(stable_node_dup));
/* chain is missing so create it */
stable_node = alloc_stable_node_chain(stable_node_dup,
root);
if (!stable_node)
return NULL;
}
/*
* Add this stable_node dup that was
* migrated to the stable_node chain
* of the current nid for this page
* content.
*/
VM_BUG_ON(!is_stable_node_chain(stable_node));
VM_BUG_ON(!is_stable_node_dup(stable_node_dup));
VM_BUG_ON(page_node->head != &migrate_nodes);
list_del(&page_node->list);
DO_NUMA(page_node->nid = nid);
stable_node_chain_add_dup(page_node, stable_node);
goto out;
}
/*
* stable_tree_insert - insert stable tree node pointing to new ksm page
* into the stable tree.
*
* This function returns the stable tree node just allocated on success,
* NULL otherwise.
*/
static struct stable_node *stable_tree_insert(struct page *kpage)
{
int nid;
unsigned long kpfn;
struct rb_root *root;
struct rb_node **new;
struct rb_node *parent;
struct stable_node *stable_node, *stable_node_dup, *stable_node_any;
bool need_chain = false;
kpfn = page_to_pfn(kpage);
nid = get_kpfn_nid(kpfn);
root = root_stable_tree + nid;
again:
parent = NULL;
new = &root->rb_node;
while (*new) {
struct page *tree_page;
int ret;
cond_resched();
stable_node = rb_entry(*new, struct stable_node, node);
stable_node_any = NULL;
tree_page = chain(&stable_node_dup, stable_node, root);
if (!stable_node_dup) {
/*
* Either all stable_node dups were full in
* this stable_node chain, or this chain was
* empty and should be rb_erased.
*/
stable_node_any = stable_node_dup_any(stable_node,
root);
if (!stable_node_any) {
/* rb_erase just run */
goto again;
}
/*
* Take any of the stable_node dups page of
* this stable_node chain to let the tree walk
* continue. All KSM pages belonging to the
* stable_node dups in a stable_node chain
* have the same content and they're
* wrprotected at all times. Any will work
* fine to continue the walk.
*/
tree_page = get_ksm_page(stable_node_any,
GET_KSM_PAGE_NOLOCK);
}
VM_BUG_ON(!stable_node_dup ^ !!stable_node_any);
if (!tree_page) {
/*
* If we walked over a stale stable_node,
* get_ksm_page() will call rb_erase() and it
* may rebalance the tree from under us. So
* restart the search from scratch. Returning
* NULL would be safe too, but we'd generate
* false negative insertions just because some
* stable_node was stale.
*/
goto again;
}
ret = memcmp_pages(kpage, tree_page);
put_page(tree_page);
parent = *new;
if (ret < 0)
new = &parent->rb_left;
else if (ret > 0)
new = &parent->rb_right;
else {
need_chain = true;
break;
}
}
stable_node_dup = alloc_stable_node();
if (!stable_node_dup)
return NULL;
INIT_HLIST_HEAD(&stable_node_dup->hlist);
stable_node_dup->kpfn = kpfn;
set_page_stable_node(kpage, stable_node_dup);
stable_node_dup->rmap_hlist_len = 0;
DO_NUMA(stable_node_dup->nid = nid);
if (!need_chain) {
rb_link_node(&stable_node_dup->node, parent, new);
rb_insert_color(&stable_node_dup->node, root);
} else {
if (!is_stable_node_chain(stable_node)) {
struct stable_node *orig = stable_node;
/* chain is missing so create it */
stable_node = alloc_stable_node_chain(orig, root);
if (!stable_node) {
free_stable_node(stable_node_dup);
return NULL;
}
}
stable_node_chain_add_dup(stable_node_dup, stable_node);
}
return stable_node_dup;
}
/*
* unstable_tree_search_insert - search for identical page,
* else insert rmap_item into the unstable tree.
*
* This function searches for a page in the unstable tree identical to the
* page currently being scanned; and if no identical page is found in the
* tree, we insert rmap_item as a new object into the unstable tree.
*
* This function returns pointer to rmap_item found to be identical
* to the currently scanned page, NULL otherwise.
*
* This function does both searching and inserting, because they share
* the same walking algorithm in an rbtree.
*/
static
struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item,
struct page *page,
struct page **tree_pagep)
{
struct rb_node **new;
struct rb_root *root;
struct rb_node *parent = NULL;
int nid;
nid = get_kpfn_nid(page_to_pfn(page));
root = root_unstable_tree + nid;
new = &root->rb_node;
while (*new) {
struct rmap_item *tree_rmap_item;
struct page *tree_page;
int ret;
cond_resched();
tree_rmap_item = rb_entry(*new, struct rmap_item, node);
tree_page = get_mergeable_page(tree_rmap_item);
if (!tree_page)
return NULL;
/*
* Don't substitute a ksm page for a forked page.
*/
if (page == tree_page) {
put_page(tree_page);
return NULL;
}
ret = memcmp_pages(page, tree_page);
parent = *new;
if (ret < 0) {
put_page(tree_page);
new = &parent->rb_left;
} else if (ret > 0) {
put_page(tree_page);
new = &parent->rb_right;
} else if (!ksm_merge_across_nodes &&
page_to_nid(tree_page) != nid) {
/*
* If tree_page has been migrated to another NUMA node,
* it will be flushed out and put in the right unstable
* tree next time: only merge with it when across_nodes.
*/
put_page(tree_page);
return NULL;
} else {
*tree_pagep = tree_page;
return tree_rmap_item;
}
}
rmap_item->address |= UNSTABLE_FLAG;
rmap_item->address |= (ksm_scan.seqnr & SEQNR_MASK);
DO_NUMA(rmap_item->nid = nid);
rb_link_node(&rmap_item->node, parent, new);
rb_insert_color(&rmap_item->node, root);
ksm_pages_unshared++;
return NULL;
}
/*
* stable_tree_append - add another rmap_item to the linked list of
* rmap_items hanging off a given node of the stable tree, all sharing
* the same ksm page.
*/
static void stable_tree_append(struct rmap_item *rmap_item,
struct stable_node *stable_node,
bool max_page_sharing_bypass)
{
/*
* rmap won't find this mapping if we don't insert the
* rmap_item in the right stable_node
* duplicate. page_migration could break later if rmap breaks,
* so we can as well crash here. We really need to check for
* rmap_hlist_len == STABLE_NODE_CHAIN, but we can as well check
* for other negative values as an undeflow if detected here
* for the first time (and not when decreasing rmap_hlist_len)
* would be sign of memory corruption in the stable_node.
*/
BUG_ON(stable_node->rmap_hlist_len < 0);
stable_node->rmap_hlist_len++;
if (!max_page_sharing_bypass)
/* possibly non fatal but unexpected overflow, only warn */
WARN_ON_ONCE(stable_node->rmap_hlist_len >
ksm_max_page_sharing);
rmap_item->head = stable_node;
rmap_item->address |= STABLE_FLAG;
hlist_add_head(&rmap_item->hlist, &stable_node->hlist);
if (rmap_item->hlist.next)
ksm_pages_sharing++;
else
ksm_pages_shared++;
}
/*
* cmp_and_merge_page - first see if page can be merged into the stable tree;
* if not, compare checksum to previous and if it's the same, see if page can
* be inserted into the unstable tree, or merged with a page already there and
* both transferred to the stable tree.
*
* @page: the page that we are searching identical page to.
* @rmap_item: the reverse mapping into the virtual address of this page
*/
static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
{
struct mm_struct *mm = rmap_item->mm;
struct rmap_item *tree_rmap_item;
struct page *tree_page = NULL;
struct stable_node *stable_node;
struct page *kpage;
unsigned int checksum;
int err;
bool max_page_sharing_bypass = false;
stable_node = page_stable_node(page);
if (stable_node) {
if (stable_node->head != &migrate_nodes &&
get_kpfn_nid(READ_ONCE(stable_node->kpfn)) !=
NUMA(stable_node->nid)) {
stable_node_dup_del(stable_node);
stable_node->head = &migrate_nodes;
list_add(&stable_node->list, stable_node->head);
}
if (stable_node->head != &migrate_nodes &&
rmap_item->head == stable_node)
return;
/*
* If it's a KSM fork, allow it to go over the sharing limit
* without warnings.
*/
if (!is_page_sharing_candidate(stable_node))
max_page_sharing_bypass = true;
}
/* We first start with searching the page inside the stable tree */
kpage = stable_tree_search(page);
if (kpage == page && rmap_item->head == stable_node) {
put_page(kpage);
return;
}
remove_rmap_item_from_tree(rmap_item);
if (kpage) {
if (PTR_ERR(kpage) == -EBUSY)
return;
err = try_to_merge_with_ksm_page(rmap_item, page, kpage);
if (!err) {
/*
* The page was successfully merged:
* add its rmap_item to the stable tree.
*/
lock_page(kpage);
stable_tree_append(rmap_item, page_stable_node(kpage),
max_page_sharing_bypass);
unlock_page(kpage);
}
put_page(kpage);
return;
}
/*
* If the hash value of the page has changed from the last time
* we calculated it, this page is changing frequently: therefore we
* don't want to insert it in the unstable tree, and we don't want
* to waste our time searching for something identical to it there.
*/
checksum = calc_checksum(page);
if (rmap_item->oldchecksum != checksum) {
rmap_item->oldchecksum = checksum;
return;
}
/*
* Same checksum as an empty page. We attempt to merge it with the
* appropriate zero page if the user enabled this via sysfs.
*/
if (ksm_use_zero_pages && (checksum == zero_checksum)) {
struct vm_area_struct *vma;
down_read(&mm->mmap_sem);
vma = find_mergeable_vma(mm, rmap_item->address);
if (vma) {
err = try_to_merge_one_page(vma, page,
ZERO_PAGE(rmap_item->address));
} else {
/*
* If the vma is out of date, we do not need to
* continue.
*/
err = 0;
}
up_read(&mm->mmap_sem);
/*
* In case of failure, the page was not really empty, so we
* need to continue. Otherwise we're done.
*/
if (!err)
return;
}
tree_rmap_item =
unstable_tree_search_insert(rmap_item, page, &tree_page);
if (tree_rmap_item) {
bool split;
kpage = try_to_merge_two_pages(rmap_item, page,
tree_rmap_item, tree_page);
/*
* If both pages we tried to merge belong to the same compound
* page, then we actually ended up increasing the reference
* count of the same compound page twice, and split_huge_page
* failed.
* Here we set a flag if that happened, and we use it later to
* try split_huge_page again. Since we call put_page right
* afterwards, the reference count will be correct and
* split_huge_page should succeed.
*/
split = PageTransCompound(page)
&& compound_head(page) == compound_head(tree_page);
put_page(tree_page);
if (kpage) {
/*
* The pages were successfully merged: insert new
* node in the stable tree and add both rmap_items.
*/
lock_page(kpage);
stable_node = stable_tree_insert(kpage);
if (stable_node) {
stable_tree_append(tree_rmap_item, stable_node,
false);
stable_tree_append(rmap_item, stable_node,
false);
}
unlock_page(kpage);
/*
* If we fail to insert the page into the stable tree,
* we will have 2 virtual addresses that are pointing
* to a ksm page left outside the stable tree,
* in which case we need to break_cow on both.
*/
if (!stable_node) {
break_cow(tree_rmap_item);
break_cow(rmap_item);
}
} else if (split) {
/*
* We are here if we tried to merge two pages and
* failed because they both belonged to the same
* compound page. We will split the page now, but no
* merging will take place.
* We do not want to add the cost of a full lock; if
* the page is locked, it is better to skip it and
* perhaps try again later.
*/
if (!trylock_page(page))
return;
split_huge_page(page);
unlock_page(page);
}
}
}
static struct rmap_item *get_next_rmap_item(struct mm_slot *mm_slot,
struct rmap_item **rmap_list,
unsigned long addr)
{
struct rmap_item *rmap_item;
while (*rmap_list) {
rmap_item = *rmap_list;
if ((rmap_item->address & PAGE_MASK) == addr)
return rmap_item;
if (rmap_item->address > addr)
break;
*rmap_list = rmap_item->rmap_list;
remove_rmap_item_from_tree(rmap_item);
free_rmap_item(rmap_item);
}
rmap_item = alloc_rmap_item();
if (rmap_item) {
/* It has already been zeroed */
rmap_item->mm = mm_slot->mm;
rmap_item->address = addr;
rmap_item->rmap_list = *rmap_list;
*rmap_list = rmap_item;
}
return rmap_item;
}
static struct rmap_item *scan_get_next_rmap_item(struct page **page)
{
struct mm_struct *mm;
struct mm_slot *slot;
struct vm_area_struct *vma;
struct rmap_item *rmap_item;
int nid;
if (list_empty(&ksm_mm_head.mm_list))
return NULL;
slot = ksm_scan.mm_slot;
if (slot == &ksm_mm_head) {
/*
* A number of pages can hang around indefinitely on per-cpu
* pagevecs, raised page count preventing write_protect_page
* from merging them. Though it doesn't really matter much,
* it is puzzling to see some stuck in pages_volatile until
* other activity jostles them out, and they also prevented
* LTP's KSM test from succeeding deterministically; so drain
* them here (here rather than on entry to ksm_do_scan(),
* so we don't IPI too often when pages_to_scan is set low).
*/
lru_add_drain_all();
/*
* Whereas stale stable_nodes on the stable_tree itself
* get pruned in the regular course of stable_tree_search(),
* those moved out to the migrate_nodes list can accumulate:
* so prune them once before each full scan.
*/
if (!ksm_merge_across_nodes) {
struct stable_node *stable_node, *next;
struct page *page;
list_for_each_entry_safe(stable_node, next,
&migrate_nodes, list) {
page = get_ksm_page(stable_node,
GET_KSM_PAGE_NOLOCK);
if (page)
put_page(page);
cond_resched();
}
}
for (nid = 0; nid < ksm_nr_node_ids; nid++)
root_unstable_tree[nid] = RB_ROOT;
spin_lock(&ksm_mmlist_lock);
slot = list_entry(slot->mm_list.next, struct mm_slot, mm_list);
ksm_scan.mm_slot = slot;
spin_unlock(&ksm_mmlist_lock);
/*
* Although we tested list_empty() above, a racing __ksm_exit
* of the last mm on the list may have removed it since then.
*/
if (slot == &ksm_mm_head)
return NULL;
next_mm:
ksm_scan.address = 0;
ksm_scan.rmap_list = &slot->rmap_list;
}
mm = slot->mm;
down_read(&mm->mmap_sem);
if (ksm_test_exit(mm))
vma = NULL;
else
vma = find_vma(mm, ksm_scan.address);
for (; vma; vma = vma->vm_next) {
if (!(vma->vm_flags & VM_MERGEABLE))
continue;
if (ksm_scan.address < vma->vm_start)
ksm_scan.address = vma->vm_start;
if (!vma->anon_vma)
ksm_scan.address = vma->vm_end;
while (ksm_scan.address < vma->vm_end) {
if (ksm_test_exit(mm))
break;
*page = follow_page(vma, ksm_scan.address, FOLL_GET);
if (IS_ERR_OR_NULL(*page)) {
ksm_scan.address += PAGE_SIZE;
cond_resched();
continue;
}
if (PageAnon(*page)) {
flush_anon_page(vma, *page, ksm_scan.address);
flush_dcache_page(*page);
rmap_item = get_next_rmap_item(slot,
ksm_scan.rmap_list, ksm_scan.address);
if (rmap_item) {
ksm_scan.rmap_list =
&rmap_item->rmap_list;
ksm_scan.address += PAGE_SIZE;
} else
put_page(*page);
up_read(&mm->mmap_sem);
return rmap_item;
}
put_page(*page);
ksm_scan.address += PAGE_SIZE;
cond_resched();
}
}
if (ksm_test_exit(mm)) {
ksm_scan.address = 0;
ksm_scan.rmap_list = &slot->rmap_list;
}
/*
* Nuke all the rmap_items that are above this current rmap:
* because there were no VM_MERGEABLE vmas with such addresses.
*/
remove_trailing_rmap_items(slot, ksm_scan.rmap_list);
spin_lock(&ksm_mmlist_lock);
ksm_scan.mm_slot = list_entry(slot->mm_list.next,
struct mm_slot, mm_list);
if (ksm_scan.address == 0) {
/*
* We've completed a full scan of all vmas, holding mmap_sem
* throughout, and found no VM_MERGEABLE: so do the same as
* __ksm_exit does to remove this mm from all our lists now.
* This applies either when cleaning up after __ksm_exit
* (but beware: we can reach here even before __ksm_exit),
* or when all VM_MERGEABLE areas have been unmapped (and
* mmap_sem then protects against race with MADV_MERGEABLE).
*/
hash_del(&slot->link);
list_del(&slot->mm_list);
spin_unlock(&ksm_mmlist_lock);
free_mm_slot(slot);
clear_bit(MMF_VM_MERGEABLE, &mm->flags);
up_read(&mm->mmap_sem);
mmdrop(mm);
} else {
up_read(&mm->mmap_sem);
/*
* up_read(&mm->mmap_sem) first because after
* spin_unlock(&ksm_mmlist_lock) run, the "mm" may
* already have been freed under us by __ksm_exit()
* because the "mm_slot" is still hashed and
* ksm_scan.mm_slot doesn't point to it anymore.
*/
spin_unlock(&ksm_mmlist_lock);
}
/* Repeat until we've completed scanning the whole list */
slot = ksm_scan.mm_slot;
if (slot != &ksm_mm_head)
goto next_mm;
ksm_scan.seqnr++;
return NULL;
}
/**
* ksm_do_scan - the ksm scanner main worker function.
* @scan_npages: number of pages we want to scan before we return.
*/
static void ksm_do_scan(unsigned int scan_npages)
{
struct rmap_item *rmap_item;
struct page *uninitialized_var(page);
while (scan_npages-- && likely(!freezing(current))) {
cond_resched();
rmap_item = scan_get_next_rmap_item(&page);
if (!rmap_item)
return;
cmp_and_merge_page(page, rmap_item);
put_page(page);
}
}
static int ksmd_should_run(void)
{
return (ksm_run & KSM_RUN_MERGE) && !list_empty(&ksm_mm_head.mm_list);
}
static int ksm_scan_thread(void *nothing)
{
unsigned int sleep_ms;
set_freezable();
set_user_nice(current, 5);
while (!kthread_should_stop()) {
mutex_lock(&ksm_thread_mutex);
wait_while_offlining();
if (ksmd_should_run())
ksm_do_scan(ksm_thread_pages_to_scan);
mutex_unlock(&ksm_thread_mutex);
try_to_freeze();
if (ksmd_should_run()) {
sleep_ms = READ_ONCE(ksm_thread_sleep_millisecs);
wait_event_interruptible_timeout(ksm_iter_wait,
sleep_ms != READ_ONCE(ksm_thread_sleep_millisecs),
msecs_to_jiffies(sleep_ms));
} else {
wait_event_freezable(ksm_thread_wait,
ksmd_should_run() || kthread_should_stop());
}
}
return 0;
}
int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
unsigned long end, int advice, unsigned long *vm_flags)
{
struct mm_struct *mm = vma->vm_mm;
int err;
switch (advice) {
case MADV_MERGEABLE:
/*
* Be somewhat over-protective for now!
*/
if (*vm_flags & (VM_MERGEABLE | VM_SHARED | VM_MAYSHARE |
VM_PFNMAP | VM_IO | VM_DONTEXPAND |
VM_HUGETLB | VM_MIXEDMAP))
return 0; /* just ignore the advice */
if (vma_is_dax(vma))
return 0;
#ifdef VM_SAO
if (*vm_flags & VM_SAO)
return 0;
#endif
#ifdef VM_SPARC_ADI
if (*vm_flags & VM_SPARC_ADI)
return 0;
#endif
if (!test_bit(MMF_VM_MERGEABLE, &mm->flags)) {
err = __ksm_enter(mm);
if (err)
return err;
}
*vm_flags |= VM_MERGEABLE;
break;
case MADV_UNMERGEABLE:
if (!(*vm_flags & VM_MERGEABLE))
return 0; /* just ignore the advice */
if (vma->anon_vma) {
err = unmerge_ksm_pages(vma, start, end);
if (err)
return err;
}
*vm_flags &= ~VM_MERGEABLE;
break;
}
return 0;
}
int __ksm_enter(struct mm_struct *mm)
{
struct mm_slot *mm_slot;
int needs_wakeup;
mm_slot = alloc_mm_slot();
if (!mm_slot)
return -ENOMEM;
/* Check ksm_run too? Would need tighter locking */
needs_wakeup = list_empty(&ksm_mm_head.mm_list);
spin_lock(&ksm_mmlist_lock);
insert_to_mm_slots_hash(mm, mm_slot);
/*
* When KSM_RUN_MERGE (or KSM_RUN_STOP),
* insert just behind the scanning cursor, to let the area settle
* down a little; when fork is followed by immediate exec, we don't
* want ksmd to waste time setting up and tearing down an rmap_list.
*
* But when KSM_RUN_UNMERGE, it's important to insert ahead of its
* scanning cursor, otherwise KSM pages in newly forked mms will be
* missed: then we might as well insert at the end of the list.
*/
if (ksm_run & KSM_RUN_UNMERGE)
list_add_tail(&mm_slot->mm_list, &ksm_mm_head.mm_list);
else
list_add_tail(&mm_slot->mm_list, &ksm_scan.mm_slot->mm_list);
spin_unlock(&ksm_mmlist_lock);
set_bit(MMF_VM_MERGEABLE, &mm->flags);
mmgrab(mm);
if (needs_wakeup)
wake_up_interruptible(&ksm_thread_wait);
return 0;
}
void __ksm_exit(struct mm_struct *mm)
{
struct mm_slot *mm_slot;
int easy_to_free = 0;
/*
* This process is exiting: if it's straightforward (as is the
* case when ksmd was never running), free mm_slot immediately.
* But if it's at the cursor or has rmap_items linked to it, use
* mmap_sem to synchronize with any break_cows before pagetables
* are freed, and leave the mm_slot on the list for ksmd to free.
* Beware: ksm may already have noticed it exiting and freed the slot.
*/
spin_lock(&ksm_mmlist_lock);
mm_slot = get_mm_slot(mm);
if (mm_slot && ksm_scan.mm_slot != mm_slot) {
if (!mm_slot->rmap_list) {
hash_del(&mm_slot->link);
list_del(&mm_slot->mm_list);
easy_to_free = 1;
} else {
list_move(&mm_slot->mm_list,
&ksm_scan.mm_slot->mm_list);
}
}
spin_unlock(&ksm_mmlist_lock);
if (easy_to_free) {
free_mm_slot(mm_slot);
clear_bit(MMF_VM_MERGEABLE, &mm->flags);
mmdrop(mm);
} else if (mm_slot) {
down_write(&mm->mmap_sem);
up_write(&mm->mmap_sem);
}
}
struct page *ksm_might_need_to_copy(struct page *page,
struct vm_area_struct *vma, unsigned long address)
{
struct anon_vma *anon_vma = page_anon_vma(page);
struct page *new_page;
if (PageKsm(page)) {
if (page_stable_node(page) &&
!(ksm_run & KSM_RUN_UNMERGE))
return page; /* no need to copy it */
} else if (!anon_vma) {
return page; /* no need to copy it */
} else if (anon_vma->root == vma->anon_vma->root &&
page->index == linear_page_index(vma, address)) {
return page; /* still no need to copy it */
}
if (!PageUptodate(page))
return page; /* let do_swap_page report the error */
new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
if (new_page) {
copy_user_highpage(new_page, page, address, vma);
SetPageDirty(new_page);
__SetPageUptodate(new_page);
__SetPageLocked(new_page);
}
return new_page;
}
void rmap_walk_ksm(struct page *page, struct rmap_walk_control *rwc)
{
struct stable_node *stable_node;
struct rmap_item *rmap_item;
int search_new_forks = 0;
VM_BUG_ON_PAGE(!PageKsm(page), page);
/*
* Rely on the page lock to protect against concurrent modifications
* to that page's node of the stable tree.
*/
VM_BUG_ON_PAGE(!PageLocked(page), page);
stable_node = page_stable_node(page);
if (!stable_node)
return;
again:
hlist_for_each_entry(rmap_item, &stable_node->hlist, hlist) {
struct anon_vma *anon_vma = rmap_item->anon_vma;
struct anon_vma_chain *vmac;
struct vm_area_struct *vma;
cond_resched();
anon_vma_lock_read(anon_vma);
anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
0, ULONG_MAX) {
unsigned long addr;
cond_resched();
vma = vmac->vma;
/* Ignore the stable/unstable/sqnr flags */
addr = rmap_item->address & ~KSM_FLAG_MASK;
if (addr < vma->vm_start || addr >= vma->vm_end)
continue;
/*
* Initially we examine only the vma which covers this
* rmap_item; but later, if there is still work to do,
* we examine covering vmas in other mms: in case they
* were forked from the original since ksmd passed.
*/
if ((rmap_item->mm == vma->vm_mm) == search_new_forks)
continue;
if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg))
continue;
if (!rwc->rmap_one(page, vma, addr, rwc->arg)) {
anon_vma_unlock_read(anon_vma);
return;
}
if (rwc->done && rwc->done(page)) {
anon_vma_unlock_read(anon_vma);
return;
}
}
anon_vma_unlock_read(anon_vma);
}
if (!search_new_forks++)
goto again;
}
bool reuse_ksm_page(struct page *page,
struct vm_area_struct *vma,
unsigned long address)
{
#ifdef CONFIG_DEBUG_VM
if (WARN_ON(is_zero_pfn(page_to_pfn(page))) ||
WARN_ON(!page_mapped(page)) ||
WARN_ON(!PageLocked(page))) {
dump_page(page, "reuse_ksm_page");
return false;
}
#endif
if (PageSwapCache(page) || !page_stable_node(page))
return false;
/* Prohibit parallel get_ksm_page() */
if (!page_ref_freeze(page, 1))
return false;
page_move_anon_rmap(page, vma);
page->index = linear_page_index(vma, address);
page_ref_unfreeze(page, 1);
return true;
}
#ifdef CONFIG_MIGRATION
void ksm_migrate_page(struct page *newpage, struct page *oldpage)
{
struct stable_node *stable_node;
VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage);
VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
VM_BUG_ON_PAGE(newpage->mapping != oldpage->mapping, newpage);
stable_node = page_stable_node(newpage);
if (stable_node) {
VM_BUG_ON_PAGE(stable_node->kpfn != page_to_pfn(oldpage), oldpage);
stable_node->kpfn = page_to_pfn(newpage);
/*
* newpage->mapping was set in advance; now we need smp_wmb()
* to make sure that the new stable_node->kpfn is visible
* to get_ksm_page() before it can see that oldpage->mapping
* has gone stale (or that PageSwapCache has been cleared).
*/
smp_wmb();
set_page_stable_node(oldpage, NULL);
}
}
#endif /* CONFIG_MIGRATION */
#ifdef CONFIG_MEMORY_HOTREMOVE
static void wait_while_offlining(void)
{
while (ksm_run & KSM_RUN_OFFLINE) {
mutex_unlock(&ksm_thread_mutex);
wait_on_bit(&ksm_run, ilog2(KSM_RUN_OFFLINE),
TASK_UNINTERRUPTIBLE);
mutex_lock(&ksm_thread_mutex);
}
}
static bool stable_node_dup_remove_range(struct stable_node *stable_node,
unsigned long start_pfn,
unsigned long end_pfn)
{
if (stable_node->kpfn >= start_pfn &&
stable_node->kpfn < end_pfn) {
/*
* Don't get_ksm_page, page has already gone:
* which is why we keep kpfn instead of page*
*/
remove_node_from_stable_tree(stable_node);
return true;
}
return false;
}
static bool stable_node_chain_remove_range(struct stable_node *stable_node,
unsigned long start_pfn,
unsigned long end_pfn,
struct rb_root *root)
{
struct stable_node *dup;
struct hlist_node *hlist_safe;
if (!is_stable_node_chain(stable_node)) {
VM_BUG_ON(is_stable_node_dup(stable_node));
return stable_node_dup_remove_range(stable_node, start_pfn,
end_pfn);
}
hlist_for_each_entry_safe(dup, hlist_safe,
&stable_node->hlist, hlist_dup) {
VM_BUG_ON(!is_stable_node_dup(dup));
stable_node_dup_remove_range(dup, start_pfn, end_pfn);
}
if (hlist_empty(&stable_node->hlist)) {
free_stable_node_chain(stable_node, root);
return true; /* notify caller that tree was rebalanced */
} else
return false;
}
static void ksm_check_stable_tree(unsigned long start_pfn,
unsigned long end_pfn)
{
struct stable_node *stable_node, *next;
struct rb_node *node;
int nid;
for (nid = 0; nid < ksm_nr_node_ids; nid++) {
node = rb_first(root_stable_tree + nid);
while (node) {
stable_node = rb_entry(node, struct stable_node, node);
if (stable_node_chain_remove_range(stable_node,
start_pfn, end_pfn,
root_stable_tree +
nid))
node = rb_first(root_stable_tree + nid);
else
node = rb_next(node);
cond_resched();
}
}
list_for_each_entry_safe(stable_node, next, &migrate_nodes, list) {
if (stable_node->kpfn >= start_pfn &&
stable_node->kpfn < end_pfn)
remove_node_from_stable_tree(stable_node);
cond_resched();
}
}
static int ksm_memory_callback(struct notifier_block *self,
unsigned long action, void *arg)
{
struct memory_notify *mn = arg;
switch (action) {
case MEM_GOING_OFFLINE:
/*
* Prevent ksm_do_scan(), unmerge_and_remove_all_rmap_items()
* and remove_all_stable_nodes() while memory is going offline:
* it is unsafe for them to touch the stable tree at this time.
* But unmerge_ksm_pages(), rmap lookups and other entry points
* which do not need the ksm_thread_mutex are all safe.
*/
mutex_lock(&ksm_thread_mutex);
ksm_run |= KSM_RUN_OFFLINE;
mutex_unlock(&ksm_thread_mutex);
break;
case MEM_OFFLINE:
/*
* Most of the work is done by page migration; but there might
* be a few stable_nodes left over, still pointing to struct
* pages which have been offlined: prune those from the tree,
* otherwise get_ksm_page() might later try to access a
* non-existent struct page.
*/
ksm_check_stable_tree(mn->start_pfn,
mn->start_pfn + mn->nr_pages);
/* fallthrough */
case MEM_CANCEL_OFFLINE:
mutex_lock(&ksm_thread_mutex);
ksm_run &= ~KSM_RUN_OFFLINE;
mutex_unlock(&ksm_thread_mutex);
smp_mb(); /* wake_up_bit advises this */
wake_up_bit(&ksm_run, ilog2(KSM_RUN_OFFLINE));
break;
}
return NOTIFY_OK;
}
#else
static void wait_while_offlining(void)
{
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
#ifdef CONFIG_SYSFS
/*
* This all compiles without CONFIG_SYSFS, but is a waste of space.
*/
#define KSM_ATTR_RO(_name) \
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
#define KSM_ATTR(_name) \
static struct kobj_attribute _name##_attr = \
__ATTR(_name, 0644, _name##_show, _name##_store)
static ssize_t sleep_millisecs_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", ksm_thread_sleep_millisecs);
}
static ssize_t sleep_millisecs_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned long msecs;
int err;
err = kstrtoul(buf, 10, &msecs);
if (err || msecs > UINT_MAX)
return -EINVAL;
ksm_thread_sleep_millisecs = msecs;
wake_up_interruptible(&ksm_iter_wait);
return count;
}
KSM_ATTR(sleep_millisecs);
static ssize_t pages_to_scan_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", ksm_thread_pages_to_scan);
}
static ssize_t pages_to_scan_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err;
unsigned long nr_pages;
err = kstrtoul(buf, 10, &nr_pages);
if (err || nr_pages > UINT_MAX)
return -EINVAL;
ksm_thread_pages_to_scan = nr_pages;
return count;
}
KSM_ATTR(pages_to_scan);
static ssize_t run_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
return sprintf(buf, "%lu\n", ksm_run);
}
static ssize_t run_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err;
unsigned long flags;
err = kstrtoul(buf, 10, &flags);
if (err || flags > UINT_MAX)
return -EINVAL;
if (flags > KSM_RUN_UNMERGE)
return -EINVAL;
/*
* KSM_RUN_MERGE sets ksmd running, and 0 stops it running.
* KSM_RUN_UNMERGE stops it running and unmerges all rmap_items,
* breaking COW to free the pages_shared (but leaves mm_slots
* on the list for when ksmd may be set running again).
*/
mutex_lock(&ksm_thread_mutex);
wait_while_offlining();
if (ksm_run != flags) {
ksm_run = flags;
if (flags & KSM_RUN_UNMERGE) {
set_current_oom_origin();
err = unmerge_and_remove_all_rmap_items();
clear_current_oom_origin();
if (err) {
ksm_run = KSM_RUN_STOP;
count = err;
}
}
}
mutex_unlock(&ksm_thread_mutex);
if (flags & KSM_RUN_MERGE)
wake_up_interruptible(&ksm_thread_wait);
return count;
}
KSM_ATTR(run);
#ifdef CONFIG_NUMA
static ssize_t merge_across_nodes_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", ksm_merge_across_nodes);
}
static ssize_t merge_across_nodes_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err;
unsigned long knob;
err = kstrtoul(buf, 10, &knob);
if (err)
return err;
if (knob > 1)
return -EINVAL;
mutex_lock(&ksm_thread_mutex);
wait_while_offlining();
if (ksm_merge_across_nodes != knob) {
if (ksm_pages_shared || remove_all_stable_nodes())
err = -EBUSY;
else if (root_stable_tree == one_stable_tree) {
struct rb_root *buf;
/*
* This is the first time that we switch away from the
* default of merging across nodes: must now allocate
* a buffer to hold as many roots as may be needed.
* Allocate stable and unstable together:
* MAXSMP NODES_SHIFT 10 will use 16kB.
*/
buf = kcalloc(nr_node_ids + nr_node_ids, sizeof(*buf),
GFP_KERNEL);
/* Let us assume that RB_ROOT is NULL is zero */
if (!buf)
err = -ENOMEM;
else {
root_stable_tree = buf;
root_unstable_tree = buf + nr_node_ids;
/* Stable tree is empty but not the unstable */
root_unstable_tree[0] = one_unstable_tree[0];
}
}
if (!err) {
ksm_merge_across_nodes = knob;
ksm_nr_node_ids = knob ? 1 : nr_node_ids;
}
}
mutex_unlock(&ksm_thread_mutex);
return err ? err : count;
}
KSM_ATTR(merge_across_nodes);
#endif
static ssize_t use_zero_pages_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", ksm_use_zero_pages);
}
static ssize_t use_zero_pages_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err;
bool value;
err = kstrtobool(buf, &value);
if (err)
return -EINVAL;
ksm_use_zero_pages = value;
return count;
}
KSM_ATTR(use_zero_pages);
static ssize_t max_page_sharing_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", ksm_max_page_sharing);
}
static ssize_t max_page_sharing_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err;
int knob;
err = kstrtoint(buf, 10, &knob);
if (err)
return err;
/*
* When a KSM page is created it is shared by 2 mappings. This
* being a signed comparison, it implicitly verifies it's not
* negative.
*/
if (knob < 2)
return -EINVAL;
if (READ_ONCE(ksm_max_page_sharing) == knob)
return count;
mutex_lock(&ksm_thread_mutex);
wait_while_offlining();
if (ksm_max_page_sharing != knob) {
if (ksm_pages_shared || remove_all_stable_nodes())
err = -EBUSY;
else
ksm_max_page_sharing = knob;
}
mutex_unlock(&ksm_thread_mutex);
return err ? err : count;
}
KSM_ATTR(max_page_sharing);
static ssize_t pages_shared_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_pages_shared);
}
KSM_ATTR_RO(pages_shared);
static ssize_t pages_sharing_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_pages_sharing);
}
KSM_ATTR_RO(pages_sharing);
static ssize_t pages_unshared_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_pages_unshared);
}
KSM_ATTR_RO(pages_unshared);
static ssize_t pages_volatile_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
long ksm_pages_volatile;
ksm_pages_volatile = ksm_rmap_items - ksm_pages_shared
- ksm_pages_sharing - ksm_pages_unshared;
/*
* It was not worth any locking to calculate that statistic,
* but it might therefore sometimes be negative: conceal that.
*/
if (ksm_pages_volatile < 0)
ksm_pages_volatile = 0;
return sprintf(buf, "%ld\n", ksm_pages_volatile);
}
KSM_ATTR_RO(pages_volatile);
static ssize_t stable_node_dups_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_stable_node_dups);
}
KSM_ATTR_RO(stable_node_dups);
static ssize_t stable_node_chains_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_stable_node_chains);
}
KSM_ATTR_RO(stable_node_chains);
static ssize_t
stable_node_chains_prune_millisecs_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
return sprintf(buf, "%u\n", ksm_stable_node_chains_prune_millisecs);
}
static ssize_t
stable_node_chains_prune_millisecs_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned long msecs;
int err;
err = kstrtoul(buf, 10, &msecs);
if (err || msecs > UINT_MAX)
return -EINVAL;
ksm_stable_node_chains_prune_millisecs = msecs;
return count;
}
KSM_ATTR(stable_node_chains_prune_millisecs);
static ssize_t full_scans_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", ksm_scan.seqnr);
}
KSM_ATTR_RO(full_scans);
static struct attribute *ksm_attrs[] = {
&sleep_millisecs_attr.attr,
&pages_to_scan_attr.attr,
&run_attr.attr,
&pages_shared_attr.attr,
&pages_sharing_attr.attr,
&pages_unshared_attr.attr,
&pages_volatile_attr.attr,
&full_scans_attr.attr,
#ifdef CONFIG_NUMA
&merge_across_nodes_attr.attr,
#endif
&max_page_sharing_attr.attr,
&stable_node_chains_attr.attr,
&stable_node_dups_attr.attr,
&stable_node_chains_prune_millisecs_attr.attr,
&use_zero_pages_attr.attr,
NULL,
};
static const struct attribute_group ksm_attr_group = {
.attrs = ksm_attrs,
.name = "ksm",
};
#endif /* CONFIG_SYSFS */
static int __init ksm_init(void)
{
struct task_struct *ksm_thread;
int err;
/* The correct value depends on page size and endianness */
zero_checksum = calc_checksum(ZERO_PAGE(0));
/* Default to false for backwards compatibility */
ksm_use_zero_pages = false;
err = ksm_slab_init();
if (err)
goto out;
ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd");
if (IS_ERR(ksm_thread)) {
pr_err("ksm: creating kthread failed\n");
err = PTR_ERR(ksm_thread);
goto out_free;
}
#ifdef CONFIG_SYSFS
err = sysfs_create_group(mm_kobj, &ksm_attr_group);
if (err) {
pr_err("ksm: register sysfs failed\n");
kthread_stop(ksm_thread);
goto out_free;
}
#else
ksm_run = KSM_RUN_MERGE; /* no way for user to start it */
#endif /* CONFIG_SYSFS */
#ifdef CONFIG_MEMORY_HOTREMOVE
/* There is no significance to this priority 100 */
hotplug_memory_notifier(ksm_memory_callback, 100);
#endif
return 0;
out_free:
ksm_slab_free();
out:
return err;
}
subsys_initcall(ksm_init);