mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
remotes/origin/tmp-387dbb9:
reverting enum-conversion, Handle CPU state and all USB patches
ANDROID: bpf: do not fail to load if log is full
ANDROID: fix kernelci compressed kernel linking
ANDROID: GKI: Update symbol list for Zebra
UPSTREAM: posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del()
Linux 5.4.295
scsi: qedf: Use designated initializer for struct qed_fcoe_cb_ops
arm64/ptrace: Fix stack-out-of-bounds read in regs_get_kernel_stack_nth()
perf: Fix sample vs do_exit()
s390/pci: Fix __pcilg_mio_inuser() inline assembly
rtc: test: Fix invalid format specifier.
jbd2: fix data-race and null-ptr-deref in jbd2_journal_dirty_metadata()
mm/huge_memory: fix dereferencing invalid pmd migration entry
rtc: Make rtc_time64_to_tm() support dates before 1970
rtc: Improve performance of rtc_time64_to_tm(). Add tests.
xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create
posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del()
ARM: dts: am335x-bone-common: Increase MDIO reset deassert delay to 50ms
ARM: dts: am335x-bone-common: Increase MDIO reset deassert time
ARM: dts: am335x-bone-common: Add GPIO PHY reset on revision C3 board
net: atm: fix /proc/net/atm/lec handling
net: atm: add lec_mutex
calipso: Fix null-ptr-deref in calipso_req_{set,del}attr().
tipc: fix null-ptr-deref when acquiring remote ip of ethernet bearer
tcp: fix tcp_packet_delayed() for tcp_is_non_sack_preventing_reopen() behavior
atm: atmtcp: Free invalid length skb in atmtcp_c_send().
mpls: Use rcu_dereference_rtnl() in mpls_route_input_rcu().
wifi: carl9170: do not ping device which has failed to load firmware
aoe: clean device rq_list in aoedev_downdev()
hwmon: (occ) fix unaligned accesses
drm/nouveau/bl: increase buffer size to avoid truncate warning
erofs: remove unused trace event erofs_destroy_inode
ALSA: hda/realtek: enable headset mic on Latitude 5420 Rugged
ALSA: hda/intel: Add Thinkpad E15 to PM deny list
Input: sparcspkr - avoid unannotated fall-through
HID: usbhid: Eliminate recurrent out-of-bounds bug in usbhid_parse()
atm: Revert atm_account_tx() if copy_from_iter_full() fails.
selinux: fix selinux_xfrm_alloc_user() to set correct ctx_len
scsi: s390: zfcp: Ensure synchronous unit_add
scsi: storvsc: Increase the timeouts to storvsc_timeout
jffs2: check jffs2_prealloc_raw_node_refs() result in few other places
jffs2: check that raw node were preallocated before writing summary
drivers/rapidio/rio_cm.c: prevent possible heap overwrite
Revert "x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2" on v6.6 and older
powerpc/eeh: Fix missing PE bridge reconfiguration during VFIO EEH recovery
platform/x86: dell_rbu: Stop overwriting data buffer
platform: Add Surface platform directory
Revert "bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first"
tee: Prevent size calculation wraparound on 32-bit kernels
ARM: OMAP2+: Fix l4ls clk domain handling in STANDBY
bus: fsl-mc: increase MC_CMD_COMPLETION_TIMEOUT_MS value
watchdog: da9052_wdt: respect TWDMIN
i40e: fix MMIO write access to an invalid page in i40e_clear_hw
sock: Correct error checking condition for (assign|release)_proto_idx()
scsi: lpfc: Use memcpy() for BIOS version
vxlan: Do not treat dst cache initialization errors as fatal
clk: rockchip: rk3036: mark ddrphy as critical
wifi: mac80211: do not offer a mesh path if forwarding is disabled
net: mlx4: add SOF_TIMESTAMPING_TX_SOFTWARE flag when getting ts info
pinctrl: armada-37xx: propagate error from armada_37xx_gpio_get()
pinctrl: armada-37xx: propagate error from armada_37xx_pmx_gpio_set_direction()
pinctrl: armada-37xx: propagate error from armada_37xx_gpio_get_direction()
pinctrl: armada-37xx: propagate error from armada_37xx_pmx_set_by_name()
ipv4/route: Use this_cpu_inc() for stats on PREEMPT_RT
tcp: fix initial tp->rcvq_space.space value for passive TS enabled flows
tcp: always seek for minimal rtt in tcp_rcv_rtt_update()
net: dlink: add synchronization for stats update
sctp: Do not wake readers in __sctp_write_space()
emulex/benet: correct command version selection in be_cmd_get_stats()
i2c: designware: Invoke runtime suspend on quick slave re-registration
net: macb: Check return value of dma_set_mask_and_coherent()
cpufreq: Force sync policy boost with global boost on sysfs update
nios2: force update_mmu_cache on spurious tlb-permission--related pagefaults
media: platform: exynos4-is: Add hardware sync wait to fimc_is_hw_change_mode()
media: tc358743: ignore video while HPD is low
drm/amdkfd: Set SDMA_RLCx_IB_CNTL/SWITCH_INSIDE_IB
jfs: Fix null-ptr-deref in jfs_ioc_trim
drm/amdgpu/gfx9: fix CSIB handling
drm/amdgpu/gfx8: fix CSIB handling
jfs: fix array-index-out-of-bounds read in add_missing_indices
drm/amdgpu/gfx7: fix CSIB handling
drm/amdgpu/gfx10: fix CSIB handling
drm/msm/a6xx: Increase HFI response timeout
drm/amd/display: Add NULL pointer checks in dm_force_atomic_commit()
media: uapi: v4l: Fix V4L2_TYPE_IS_OUTPUT condition
drm/msm/hdmi: add runtime PM calls to DDC transfer function
drm/bridge: analogix_dp: Add irq flag IRQF_NO_AUTOEN instead of calling disable_irq()
sunrpc: update nextcheck time when adding new cache entries
drm/amdgpu/gfx6: fix CSIB handling
ACPI: battery: negate current when discharging
PM: runtime: fix denying of auto suspend in pm_suspend_timer_fn()
power: supply: bq27xxx: Retrieve again when busy
ACPICA: fix acpi parse and parseext cache leaks
ACPICA: Avoid sequence overread in call to strncmp()
ACPICA: fix acpi operand cache leak in dswstate.c
iio: adc: ad7606_spi: fix reg write value mask
PCI: Fix lock symmetry in pci_slot_unlock()
PCI: Add ACS quirk for Loongson PCIe
uio_hv_generic: Use correct size for interrupt and monitor pages
regulator: max14577: Add error check for max14577_read_reg()
mips: Add -std= flag specified in KBUILD_CFLAGS to vdso CFLAGS
staging: iio: ad5933: Correct settling cycles encoding per datasheet
net: ch9200: fix uninitialised access during mii_nway_restart
ftrace: Fix UAF when lookup kallsym after ftrace disabled
dm-mirror: fix a tiny race condition
mtd: nand: sunxi: Add randomizer configuration before randomizer enable
mtd: rawnand: sunxi: Add randomizer configuration in sunxi_nfc_hw_ecc_write_chunk
mm: fix ratelimit_pages update error in dirty_ratio_handler()
ipc: fix to protect IPCS lookups using RCU
parisc: fix building with gcc-15
vgacon: Add check for vc_origin address range in vgacon_scroll()
fbdev: Fix fb_set_var to prevent null-ptr-deref in fb_videomode_to_var
EDAC/altera: Use correct write width with the INTTEST register
NFC: nci: uart: Set tty->disc_data only in success path
f2fs: prevent kernel warning due to negative i_nlink from corrupted image
Input: ims-pcu - check record size in ims_pcu_flash_firmware()
ext4: fix calculation of credits for extent tree modification
ext4: inline: fix len overflow in ext4_prepare_inline_data
bus: fsl-mc: do not add a device-link for the UAPI used DPMCP device
ata: pata_via: Force PIO for ATAPI devices on VT6415/VT6330
ARM: 9447/1: arm/memremap: fix arch_memremap_can_ram_remap()
media: v4l2-dev: fix error handling in __video_register_device()
media: gspca: Add error handling for stv06xx_read_sensor()
wifi: rtlwifi: disable ASPM for RTL8723BE with subsystem ID 11ad:1723
nfsd: nfsd4_spo_must_allow() must check this is a v4 compound request
wifi: p54: prevent buffer-overflow in p54_rx_eeprom_readback()
gfs2: move msleep to sleepable context
configfs: Do not override creating attribute file failure in populate_attrs()
net: usb: aqc111: debug info before sanitation
calipso: unlock rcu before returning -EAFNOSUPPORT
xen/arm: call uaccess_ttbr0_enable for dm_op hypercall
usb: Flush altsetting 0 endpoints before reinitializating them after reset.
fs/filesystems: Fix potential unsigned integer underflow in fs_name()
net/mdiobus: Fix potential out-of-bounds read/write access
drm/amd/display: Do not add '-mhard-float' to dcn2{1,0}_resource.o for clang
drm/amd/display: Do not add '-mhard-float' to dml_ccflags for clang
MIPS: Move '-Wa,-msoft-float' check from as-option to cc-option
x86/boot/compressed: prefer cc-option for CFLAGS additions
net: mdio: C22 is now optional, EOPNOTSUPP if not provided
net_sched: tbf: fix a race in tbf_change()
net_sched: red: fix a race in __red_change()
net_sched: prio: fix a race in prio_tune()
net/mlx5: Fix return value when searching for existing flow group
net/mlx5: Wait for inactive autogroups
i40e: retry VFLR handling if there is ongoing VF reset
i40e: return false from i40e_reset_vf if reset is in progress
net_sched: sch_sfq: fix a potential crash on gso_skb handling
scsi: iscsi: Fix incorrect error path labels for flashnode operations
NFSD: Fix NFSv3 SETATTR/CREATE's handling of large file sizes
NFSD: Fix ia_size underflow
Input: synaptics-rmi - fix crash with unsupported versions of F34
Input: synaptics-rmi4 - convert to use sysfs_emit() APIs
pmdomain: core: Fix error checking in genpd_dev_pm_attach_by_id()
do_change_type(): refuse to operate on unmounted/not ours mounts
PM: sleep: Fix power.is_suspended cleanup for direct-complete devices
ice: create new Tx scheduler nodes for new queues only
Bluetooth: L2CAP: Fix not responding with L2CAP_CR_LE_ENCRYPTION
net/mlx4_en: Prevent potential integer overflow calculating Hz
vt: remove VT_RESIZE and VT_RESIZEX from vt_compat_ioctl()
serial: Fix potential null-ptr-deref in mlb_usio_probe()
usb: renesas_usbhs: Reorder clock handling and power management in probe
rtc: Fix offset calculation for .start_secs < 0
rtc: sh: assign correct interrupts with DT
perf record: Fix incorrect --user-regs comments
perf tests switch-tracking: Fix timestamp comparison
mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
mfd: exynos-lpass: Avoid calling exynos_lpass_disable() twice in exynos_lpass_remove()
rpmsg: qcom_smd: Fix uninitialized return variable in __qcom_smd_send()
perf scripts python: exported-sql-viewer.py: Fix pattern matching with Python 3
perf ui browser hists: Set actions->thread before calling do_zoom_thread()
fbdev: core: fbcvt: avoid division by 0 in fb_cvt_hperiod()
soc: aspeed: Add NULL check in aspeed_lpc_enable_snoop()
soc: aspeed: lpc: Fix impossible judgment condition
arm64: dts: rockchip: disable unrouted USB controllers and PHY on RK3399 Puma with Haikou
ARM: dts: qcom: apq8064 merge hw splinlock into corresponding syscon device
bus: fsl-mc: fix double-free on mc_dev
nilfs2: do not propagate ENOENT error from nilfs_btree_propagate()
nilfs2: add pointer check for nilfs_direct_propagate()
Squashfs: check return result of sb_min_blocksize
ARM: dts: at91: at91sam9263: fix NAND chip selects
ARM: dts: at91: usb_a9263: fix GPIO for Dataflash chip select
f2fs: fix to correct check conditions in f2fs_cross_rename
f2fs: use d_inode(dentry) cleanup dentry->d_inode
calipso: Don't call calipso functions for AF_INET sk.
net: lan743x: rename lan743x_reset_phy to lan743x_hw_reset_phy
net: usb: aqc111: fix error handling of usbnet read calls
netfilter: nf_tables: nft_fib_ipv6: fix VRF ipv4/ipv6 result discrepancy
wifi: ath9k_htc: Abort software beacon handling if disabled
bpf: Fix WARN() in get_bpf_raw_tp_regs
pinctrl: at91: Fix possible out-of-boundary access
ktls, sockmap: Fix missing uncharge operation
netfilter: bridge: Move specific fragmented packet to slow_path instead of dropping it
f2fs: clean up w/ fscrypt_is_bounce_page()
RDMA/hns: Include hnae3.h in hns_roce_hw_v2.h
wifi: rtw88: do not ignore hardware read error during DPK
net: ncsi: Fix GCPS 64-bit member variables
f2fs: fix to do sanity check on sbi->total_valid_block_count
drm/tegra: rgb: Fix the unbound reference count
drm/vkms: Adjust vkms_state->active_planes allocation type
drm: rcar-du: Fix memory leak in rcar_du_vsps_init()
selftests/seccomp: fix syscall_restart test for arm compat
firmware: psci: Fix refcount leak in psci_dt_init
m68k: mac: Fix macintosh_config for Mac II
drm/vmwgfx: Add seqno waiter for sync_files
spi: sh-msiof: Fix maximum DMA transfer size
ACPI: OSI: Stop advertising support for "3.0 _SCP Extensions"
x86/mtrr: Check if fixed-range MTRRs exist in mtrr_save_fixed_ranges()
PM: wakeup: Delete space in the end of string shown by pm_show_wakelocks()
EDAC/skx_common: Fix general protection fault
crypto: marvell/cesa - Avoid empty transfer descriptor
crypto: marvell/cesa - Handle zero-length skcipher requests
x86/cpu: Sanitize CPUID(0x80000000) output
perf/core: Fix broken throttling when max_samples_per_tick=1
gfs2: gfs2_create_inode error handling fix
netfilter: nft_socket: fix sk refcount leaks
thunderbolt: Do not double dequeue a configuration request
usb: usbtmc: Fix timeout value in get_stb
usb: storage: Ignore UAS driver for SanDisk 3.2 Gen2 storage device
usb: quirks: Add NO_LPM quirk for SanDisk Extreme 55AE
pinctrl: armada-37xx: set GPIO output value before setting direction
pinctrl: armada-37xx: use correct OUTPUT_VAL register for GPIOs > 31
tracing: Fix compilation warning on arm32
BACKPORT: binder: Create safe versions of binder log files
UPSTREAM: binder: Refactor binder_node print synchronization
Revert "coredump: hand a pidfd to the usermode coredump helper"
Linux 5.4.294
xen/swiotlb: relax alignment requirements
platform/x86: thinkpad_acpi: Ignore battery threshold change event notification
platform/x86: fujitsu-laptop: Support Lifebook S2110 hotkeys
spi: spi-sun4i: fix early activation
um: let 'make clean' properly clean underlying SUBARCH as well
platform/x86: thinkpad_acpi: Support also NEC Lavie X1475JAS
nfs: don't share pNFS DS connections between net namespaces
HID: quirks: Add ADATA XPG alpha wireless mouse support
coredump: hand a pidfd to the usermode coredump helper
fork: use pidfd_prepare()
pid: add pidfd_prepare()
pidfd: check pid has attached task in fdinfo
coredump: fix error handling for replace_fd()
net_sched: hfsc: Address reentrant enqueue adding class to eltree twice
smb: client: Reset all search buffer pointers when releasing buffer
smb: client: Fix use-after-free in cifs_fill_dirent
drm/i915/gvt: fix unterminated-string-initialization warning
netfilter: nf_tables: do not defer rule destruction via call_rcu
netfilter: nf_tables: wait for rcu grace period on net_device removal
netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
kbuild: Disable -Wdefault-const-init-unsafe
spi: spi-fsl-dspi: restrict register range for regmap access
mm/page_alloc.c: avoid infinite retries caused by cpuset race
memcg: always call cond_resched() after fn()
drm/edid: fixed the bug that hdr metadata was not reset
llc: fix data loss when reading from a socket in llc_ui_recvmsg()
ALSA: pcm: Fix race of buffer access at PCM OSS layer
can: bcm: add missing rcu read protection for procfs content
can: bcm: add locking for bcm_op runtime updates
crypto: algif_hash - fix double free in hash_accept
sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()
net: dwmac-sun8i: Use parsed internal PHY address instead of 1
bridge: netfilter: Fix forwarding of fragmented packets
xfrm: Sanitize marks before insert
__legitimize_mnt(): check for MNT_SYNC_UMOUNT should be under mount_lock
xenbus: Allow PVH dom0 a non-local xenstore
btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref
nvmet-tcp: don't restore null sk_state_change
ASoC: Intel: bytcr_rt5640: Add DMI quirk for Acer Aspire SW3-013
pinctrl: meson: define the pull up/down resistor value as 60 kOhm
drm: Add valid clones check
drm/atomic: clarify the rules around drm_atomic_state->allow_modeset
regulator: ad5398: Add device tree support
wifi: rtw88: Don't use static local variable in rtw8822b_set_tx_power_index_by_rate
bpftool: Fix readlink usage in get_fd_type
HID: usbkbd: Fix the bit shift number for LED_KANA
scsi: st: Restore some drive settings after reset
scsi: lpfc: Handle duplicate D_IDs in ndlp search-by D_ID routine
rcu: fix header guard for rcu_all_qs()
rcu: handle quiescent states for PREEMPT_RCU=n, PREEMPT_COUNT=y
vxlan: Annotate FDB data races
hwmon: (xgene-hwmon) use appropriate type for the latency value
ip: fib_rules: Fetch net from fib_rule in fib[46]_rule_configure().
net/mlx5e: reduce rep rxq depth to 256 for ECPF
net/mlx5e: set the tx_queue_len for pfifo_fast
net/mlx5: Extend Ethtool loopback selftest to support non-linear SKB
phy: core: don't require set_mode() callback for phy_get_mode() to work
net/mlx4_core: Avoid impossible mlx4_db_alloc() order value
smack: recognize ipv4 CIPSO w/o categories
pinctrl: devicetree: do not goto err when probing hogs in pinctrl_dt_to_map
ASoC: ops: Enforce platform maximum on initial value
net/mlx5: Apply rate-limiting to high temperature warning
net/mlx5: Modify LSB bitmask in temperature event to include only the first bit
ACPI: HED: Always initialize before evged
PCI: Fix old_size lower bound in calculate_iosize() too
EDAC/ie31200: work around false positive build warning
net: pktgen: fix access outside of user given buffer in pktgen_thread_write()
wifi: rtw88: Fix rtw_init_ht_cap() for RTL8814AU
scsi: mpt3sas: Send a diag reset if target reset fails
MIPS: pm-cps: Use per-CPU variables as per-CPU, not per-core
MIPS: Use arch specific syscall name match function
cpuidle: menu: Avoid discarding useful information
x86/nmi: Add an emergency handler in nmi_desc & use it in nmi_shootdown_cpus()
bonding: report duplicate MAC address in all situations
net: xgene-v2: remove incorrect ACPI_PTR annotation
drm/amdkfd: KFD release_work possible circular locking
net/mlx5: Avoid report two health errors on same syndrome
fpga: altera-cvp: Increase credit timeout
drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence
hwmon: (gpio-fan) Add missing mutex locks
x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2
net: pktgen: fix mpls maximum labels list parsing
pinctrl: bcm281xx: Use "unsigned int" instead of bare "unsigned"
media: cx231xx: set device_caps for 417
orangefs: Do not truncate file size
dm cache: prevent BUG_ON by blocking retries on failed device resumes
media: c8sectpfe: Call of_node_put(i2c_bus) only once in c8sectpfe_probe()
ARM: tegra: Switch DSI-B clock parent to PLLD on Tegra114
ieee802154: ca8210: Use proper setters and getters for bitwise types
rtc: ds1307: stop disabling alarms on probe
powerpc/prom_init: Fixup missing #size-cells on PowerBook6,7
mmc: sdhci: Disable SD card clock before changing parameters
netfilter: conntrack: Bound nf_conntrack sysctl writes
posix-timers: Add cond_resched() to posix_timer_add() search loop
xen: Add support for XenServer 6.1 platform device
dm: restrict dm device size to 2^63-512 bytes
kbuild: fix argument parsing in scripts/config
scsi: st: ERASE does not change tape location
scsi: st: Tighten the page format heuristics with MODE SELECT
ext4: reorder capability check last
um: Update min_low_pfn to match changes in uml_reserved
um: Store full CSGSFS and SS register from mcontext
btrfs: send: return -ENAMETOOLONG when attempting a path that is too long
btrfs: avoid linker error in btrfs_find_create_tree_block()
i2c: pxa: fix call balance of i2c->clk handling routines
mmc: host: Wait for Vdd to settle on card power off
libnvdimm/labels: Fix divide error in nd_label_data_init()
pNFS/flexfiles: Report ENETDOWN as a connection error
tools/build: Don't pass test log files to linker
dql: Fix dql->limit value when reset.
SUNRPC: rpc_clnt_set_transport() must not change the autobind setting
NFSv4: Treat ENETUNREACH errors as fatal for state recovery
fbdev: core: tileblit: Implement missing margin clearing for tileblit
fbdev: fsl-diu-fb: add missing device_remove_file()
mailbox: use error ret code of of_parse_phandle_with_args()
kconfig: merge_config: use an empty file as initfile
cgroup: Fix compilation issue due to cgroup_mutex not being exported
dma-mapping: avoid potential unused data compilation warning
scsi: target: iscsi: Fix timeout on deleted connection
openvswitch: Fix unsafe attribute parsing in output_userspace()
Input: synaptics - enable InterTouch on TUXEDO InfinityBook Pro 14 v5
Input: synaptics - enable SMBus for HP Elitebook 850 G1
clocksource/i8253: Use raw_spinlock_irqsave() in clockevent_i8253_disable()
phy: renesas: rcar-gen3-usb2: Set timing registers only once
phy: Fix error handling in tegra_xusb_port_init
ALSA: es1968: Add error handling for snd_pcm_hw_constraint_pow2()
ACPI: PPTT: Fix processor subtable walk
dmaengine: Revert "dmaengine: dmatest: Fix dmatest waiting less when interrupted"
NFSv4/pnfs: Reset the layout state after a layoutreturn
NFSv4/pnfs: pnfs_set_layout_stateid() should update the layout cred
qlcnic: fix memory leak in qlcnic_sriov_channel_cfg_cmd()
ALSA: sh: SND_AICA should depend on SH_DMA_API
net: dsa: sja1105: discard incoming frames in BR_STATE_LISTENING
spi: loopback-test: Do not split 1024-byte hexdumps
nfs: handle failure of nfs_get_lock_context in unlock path
RDMA/rxe: Fix slab-use-after-free Read in rxe_queue_cleanup bug
iio: chemical: sps30: use aligned_s64 for timestamp
iio: adc: ad7768-1: Fix insufficient alignment of timestamp.
staging: axis-fifo: Correct handling of tx_fifo_depth for size validation
staging: axis-fifo: avoid parsing ignored device tree properties
staging: axis-fifo: Remove hardware resets for user errors
staging: axis-fifo: replace spinlock with mutex
platform/x86: asus-wmi: Fix wlan_ctrl_by_user detection
do_umount(): add missing barrier before refcount checks in sync case
nvme: unblock ctrl state transition for firmware update
MIPS: Fix MAX_REG_OFFSET
iio: adc: dln2: Use aligned_s64 for timestamp
types: Complement the aligned types with signed 64-bit one
usb: usbtmc: Fix erroneous generic_read ioctl return
usb: usbtmc: Fix erroneous wait_srq ioctl return
usb: usbtmc: Fix erroneous get_stb ioctl error returns
USB: usbtmc: use interruptible sleep in usbtmc_read
usb: typec: ucsi: displayport: Fix NULL pointer access
usb: typec: tcpm: delay SNK_TRY_WAIT_DEBOUNCE to SRC_TRYWAIT transition
ocfs2: stop quota recovery before disabling quotas
ocfs2: implement handshaking with ocfs2 recovery thread
ocfs2: switch osb->disable_recovery to enum
module: ensure that kobject_put() is safe for module type kobjects
xenbus: Use kref to track req lifetime
usb: uhci-platform: Make the clock really optional
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_tagged_fifo
iio: imu: st_lsm6dsx: fix possible lockup in st_lsm6dsx_read_fifo
iio: adis16201: Correct inclinometer channel resolution
iio: adc: ad7606: fix serial register access
staging: iio: adc: ad7816: Correct conditional logic for store mode
Input: synaptics - enable InterTouch on Dell Precision M3800
Input: synaptics - enable InterTouch on Dynabook Portege X30L-G
Input: synaptics - enable InterTouch on Dynabook Portege X30-D
net: dsa: b53: fix learning on VLAN unaware bridges
netfilter: ipset: fix region locking in hash types
sch_htb: make htb_deactivate() idempotent
scsi: target: Fix WRITE_SAME No Data Buffer crash
dm: fix copying after src array boundaries
iommu/amd: Fix potential buffer overflow in parse_ivrs_acpihid
arm64: dts: rockchip: fix iface clock-name on px30 iommus
usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling
usb: chipidea: ci_hdrc_imx: use dev_err_probe()
usb: chipidea: imx: refine the error handling for hsic
usb: chipidea: imx: change hsic power regulator as optional
irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()
irqchip/gic-v2m: Mark a few functions __init
irqchip/gic-v2m: Add const to of_device_id
sch_htb: make htb_qlen_notify() idempotent
of: module: add buffer overflow check in of_modalias()
PCI: imx6: Skip controller_id generation logic for i.MX7D
net: fec: ERR007885 Workaround for conventional TX
net: lan743x: Fix memleak issue when GSO enabled
lan743x: fix endianness when accessing descriptors
lan743x: remove redundant initialization of variable current_head_index
nvme-tcp: fix premature queue removal and I/O failover
net: dlink: Correct endianness handling of led_mode
net_sched: qfq: Fix double list add in class with netem as child qdisc
net_sched: hfsc: Fix a UAF vulnerability in class with netem as child qdisc
net_sched: drr: Fix double list add in class with netem as child qdisc
net/mlx5: E-Switch, Initialize MAC Address for Default GID
tracing: Fix oob write in trace_seq_to_buffer()
dm: always update the array size in realloc_argv on success
dm-integrity: fix a warning on invalid table line
wifi: brcm80211: fmac: Add error handling for brcmf_usb_dl_writeimage()
amd-xgbe: Fix to ensure dependent features are toggled with RX checksum offload
parisc: Fix double SIGFPE crash
i2c: imx-lpi2c: Fix clock count when probe defers
EDAC/altera: Set DDR and SDMMC interrupt mask before registration
EDAC/altera: Test the correct error reg offset
ANDROID: binder: fix minimum node priority comparison
ANDROID: 16K: Remove ELF padding entry from map_file ranges
Linux 5.4.293
MIPS: cm: Fix warning if MIPS_CM is disabled
crypto: atmel-sha204a - Set hwrng quality to lowest possible
comedi: jr3_pci: Fix synchronous deletion of timer
md/raid1: Add check for missing source disk in process_checks()
scsi: pm80xx: Set phy_attached to zero when device is gone
x86/bugs: Don't fill RSB on VMEXIT with eIBRS+retpoline
ACPI PPTT: Fix coding mistakes in a couple of sizeof() calls
selftests: ublk: fix test_stripe_04
udmabuf: fix a buf size overflow issue during udmabuf creation
KVM: s390: Don't use %pK through tracepoints
sched/isolation: Make CONFIG_CPU_ISOLATION depend on CONFIG_SMP
ntb: reduce stack usage in idt_scan_mws
qibfs: fix _another_ leak
usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev()
dmaengine: dmatest: Fix dmatest waiting less when interrupted
usb: host: max3421-hcd: Add missing spi_device_id table
parisc: PDT: Fix missing prototype warning
clk: check for disabled clock-provider in of_clk_get_hw_from_clkspec()
crypto: null - Use spin lock instead of mutex
MIPS: cm: Detect CM quirks from device tree
USB: VLI disk crashes if LPM is used
usb: quirks: Add delay init quirk for SanDisk 3.2Gen1 Flash Drive
usb: quirks: add DELAY_INIT quirk for Silicon Motion Flash Drive
usb: dwc3: gadget: check that event count does not exceed event buffer length
USB: OHCI: Add quirk for LS7A OHCI controller (rev 0x02)
usb: cdns3: Fix deadlock when using NCM gadget
USB: serial: simple: add OWON HDS200 series oscilloscope support
USB: serial: option: add Sierra Wireless EM9291
USB: serial: ftdi_sio: add support for Abacus Electrics Optical Probe
serial: sifive: lock port in startup()/shutdown() callbacks
USB: storage: quirk for ADATA Portable HDD CH94
mcb: fix a double free bug in chameleon_parse_gdd()
virtio_console: fix missing byte order handling for cols and rows
net_sched: hfsc: Fix a potential UAF in hfsc_dequeue() too
net_sched: hfsc: Fix a UAF vulnerability in class handling
tipc: fix NULL pointer dereference in tipc_mon_reinit_self()
net: phy: leds: fix memory leak
cpufreq: scpi: Fix null-ptr-deref in scpi_cpufreq_get_rate()
drm/amd/pm: Prevent division by zero
misc: pci_endpoint_test: Fix displaying 'irq_type' after 'request_irq' error
misc: pci_endpoint_test: Use INTX instead of LEGACY
PCI: Rename PCI_IRQ_LEGACY to PCI_IRQ_INTX
iio: adc: ad7768-1: Fix conversion result sign
iio: adc: ad7768-1: Move setting of val a bit later to avoid unnecessary return value check
net: dsa: mv88e6xxx: fix VTU methods for 6320 family
media: vim2m: print device name after registering device
ext4: fix OOB read when checking dotdot dir
ext4: optimize __ext4_check_dir_entry()
ext4: don't over-report free space or inodes in statvfs
ext4: code cleanup for ext4_statfs_project()
ext4: simplify checking quota limits in ext4_statfs()
platform/x86: ISST: Correct command storage data length
MIPS: ds1287: Match ds1287_set_base_clock() function types
MIPS: cevt-ds1287: Add missing ds1287.h include
MIPS: dec: Declare which_prom() as static
virtio-net: Add validation for used length
RDMA/srpt: Support specifying the srpt_service_guid parameter
openvswitch: fix lockup on tx to unregistering netdev with carrier
net: openvswitch: fix race on port output
mmc: cqhci: Fix checking of CQHCI_HALT state
nvmet-fc: Remove unused functions
usb: dwc3: support continuous runtime PM with dual role
misc: pci_endpoint_test: Fix 'irq_type' to convey the correct type
misc: pci_endpoint_test: Avoid issue of interrupts remaining after request_irq error
tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink().
powerpc/prom_init: Use -ffreestanding to avoid a reference to bcmp
kbuild: Add '-fno-builtin-wcslen'
cpufreq: Reference count policy in cpufreq_update_limits()
drm/sti: remove duplicate object names
drm/nouveau: prime: fix ttm_bo_delayed_delete oops
drm/repaper: fix integer overflows in repeat functions
module: sign with sha512 instead of sha1 by default
perf/x86/intel/uncore: Fix the scale of IIO free running counters on SNR
perf/x86/intel: Allow to update user space GPRs from PEBS records
virtiofs: add filesystem context source name check
riscv: Avoid fortify warning in syscall_get_arguments()
isofs: Prevent the use of too small fid
i2c: cros-ec-tunnel: defer probe if parent EC is not present
hfs/hfsplus: fix slab-out-of-bounds in hfs_bnode_read_key
btrfs: correctly escape subvol in btrfs_show_options()
nfs: add missing selections of CONFIG_CRC32
nfs: move nfs_fhandle_hash to common include file
NFSD: Constify @fh argument of knfsd_fh_hash()
asus-laptop: Fix an uninitialized variable
writeback: fix false warning in inode_to_wb()
net: b53: enable BPDU reception for management port
net: openvswitch: fix nested key length validation in the set() action
Revert "wifi: mac80211: Update skb's control block key in ieee80211_tx_dequeue()"
Bluetooth: btrtl: Prevent potential NULL dereference
Bluetooth: hci_event: Fix sending MGMT_EV_DEVICE_FOUND for invalid address
RDMA/usnic: Fix passing zero to PTR_ERR in usnic_ib_pci_probe()
scsi: iscsi: Fix missing scsi_host_put() in error path
wifi: wl1251: fix memory leak in wl1251_tx_work
wifi: mac80211: Purge vif txq in ieee80211_do_stop()
wifi: mac80211: Update skb's control block key in ieee80211_tx_dequeue()
wifi: at76c50x: fix use after free access in at76_disconnect
HSI: ssi_protocol: Fix use after free vulnerability in ssi_protocol Driver Due to Race Condition
pwm: mediatek: always use bus clock for PWM on MT7622
Bluetooth: hci_uart: Fix another race during initialization
x86/e820: Fix handling of subpage regions when calculating nosave ranges in e820__register_nosave_regions()
PCI: Fix reference leak in pci_alloc_child_bus()
of/irq: Fix device node refcount leakages in of_irq_init()
of/irq: Fix device node refcount leakage in API irq_of_parse_and_map()
of/irq: Fix device node refcount leakages in of_irq_count()
ntb: use 64-bit arithmetic for the MSI doorbell mask
gpio: zynq: Fix wakeup source leaks on device unbind
ftrace: Add cond_resched() to ftrace_graph_set_hash()
dm-integrity: set ti->error on memory allocation failure
crypto: ccp - Fix check for the primary ASP device
thermal/drivers/rockchip: Add missing rk3328 mapping entry
sctp: detect and prevent references to a freed transport in sendmsg
mm: add missing release barrier on PGDAT_RECLAIM_LOCKED unlock
sparc/mm: disable preemption in lazy mmu mode
arm64: dts: mediatek: mt8173: Fix disp-pwm compatible string
mtd: rawnand: Add status chack in r852_ready()
mtd: inftlcore: Add error check for inftl_read_oob()
lib: scatterlist: fix sg_split_phys to preserve original scatterlist offsets
locking/lockdep: Decrease nr_unused_locks if lock unused in zap_class()
jbd2: remove wrong sb->s_sequence check
i3c: Add NULL pointer check in i3c_master_queue_ibi()
ext4: fix off-by-one error in do_split
wifi: mac80211: fix integer overflow in hwmp_route_info_get()
net: dsa: mv88e6xxx: workaround RGMII transmit delay erratum for 6320 family
media: venus: hfi_parser: add check to avoid out of bound access
media: i2c: ov7251: Introduce 1 ms delay between regulators and en GPIO
media: i2c: ov7251: Set enable GPIO low in probe
media: v4l2-dv-timings: prevent possible overflow in v4l2_detect_gtf()
media: streamzap: prevent processing IR data on URB failure
mtd: rawnand: brcmnand: fix PM resume warning
arm64: cputype: Add MIDR_CORTEX_A76AE
xenfs/xensyms: respect hypervisor's "next" indication
media: siano: Fix error handling in smsdvb_module_init()
media: venus: hfi: add check to handle incorrect queue size
media: venus: hfi: add a check to handle OOB in sfr region
media: i2c: adv748x: Fix test pattern selection mask
ext4: don't treat fhandle lookup of ea_inode as FS corruption
ext4: reject casefold inode flag without casefold feature
bpf: support SKF_NET_OFF and SKF_LL_OFF on skb frags
bpf: Add endian modifiers to fix endian warnings
pwm: fsl-ftm: Handle clk_get_rate() returning 0
pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config()
pwm: mediatek: Always use bus clock
fbdev: omapfb: Add 'plane' value check
drm/mediatek: mtk_dpi: Explicitly manage TVD clock in power on/off
drm/amdkfd: Fix pqm_destroy_queue race with GPU reset
drm/amdkfd: clamp queue size to minimum
drm: panel-orientation-quirks: Add new quirk for GPD Win 2
drm: panel-orientation-quirks: Add support for AYANEO 2S
drm: allow encoder mode_set even when connectors change for crtc
Bluetooth: hci_uart: fix race during initialization
tracing: fix return value in __ftrace_event_enable_disable for TRACE_REG_UNREGISTER
net: vlan: don't propagate flags on open
wifi: mt76: mt76x2u: add TP-Link TL-WDN6200 ID to device table
scsi: st: Fix array overflow in st_setup()
ext4: ignore xattrs past end
ext4: protect ext4_release_dquot against freezing
ahci: add PCI ID for Marvell 88SE9215 SATA Controller
ata: libata-eh: Do not use ATAPI DMA for a device limited to PIO mode
jfs: add sanity check for agwidth in dbMount
jfs: Prevent copying of nlink with value 0 from disk inode
fs/jfs: Prevent integer overflow in AG size calculation
fs/jfs: cast inactags to s64 to prevent potential overflow
page_pool: avoid infinite loop to schedule delayed worker
ALSA: usb-audio: Fix CME quirk for UF series keyboards
ALSA: hda: intel: Fix Optimus when GPU has no sound
HID: pidff: Fix null pointer dereference in pidff_find_fields
HID: pidff: Do not send effect envelope if it's empty
HID: pidff: Convert infinite length from Linux API to PID standard
xen/mcelog: Add __nonstring annotations for unterminated strings
perf: arm_pmu: Don't disable counter in armpmu_add()
x86/cpu: Don't clear X86_FEATURE_LAHF_LM flag in init_amd_k8() on AMD when running in a virtual machine
pm: cpupower: bench: Prevent NULL dereference on malloc failure
net: ppp: Add bound checking for skb data on ppp_sync_txmung
ata: sata_sx4: Add error handling in pdc20621_i2c_read()
ata: sata_sx4: Drop pointless VPRINTK() calls and convert the remaining ones
tipc: fix memory leak in tipc_link_xmit
ata: pata_pxa: Fix potential NULL pointer dereference in pxa_ata_probe()
UPSTREAM: net_sched: Prevent creation of classes with TC_H_ROOT
Linux 5.4.292
jfs: add index corruption check to DT_GETPAGE()
jfs: fix slab-out-of-bounds read in ea_get()
tracing: Fix use-after-free in print_graph_function_flags during tracer switching
mmc: sdhci-pxav3: set NEED_RSP_BUSY capability
ACPI: resource: Skip IRQ override on ASUS Vivobook 14 X1404VAP
x86/mm: Fix flush_tlb_range() when used for zapping normal PMDs
x86/tsc: Always save/restore TSC sched_clock() on suspend/resume
ntb_perf: Delete duplicate dmaengine_unmap_put() call in perf_copy_chunk()
can: flexcan: only change CAN state when link up in system PM
arcnet: Add NULL check in com20020pci_probe()
net: dsa: mv88e6xxx: propperly shutdown PPU re-enable timer on destroy
ipv6: fix omitted netlink attributes when using RTEXT_FILTER_SKIP_STATS
vsock: avoid timeout during connect() if the socket is closing
net_sched: skbprio: Remove overly strict queue assertions
netlabel: Fix NULL pointer exception caused by CALIPSO on IPv4 sockets
ntb: intel: Fix using link status DB's
ntb_hw_switchtec: Fix shift-out-of-bounds in switchtec_ntb_mw_set_trans
spufs: fix a leak in spufs_create_context()
spufs: fix a leak on spufs_new_file() failure
hwmon: (nct6775-core) Fix out of bounds access for NCT679{8,9}
can: statistics: use atomic access in hot path
locking/semaphore: Use wake_q to wake up processes outside lock critical section
sched/deadline: Use online cpus for validating runtime
affs: don't write overlarge OFS data block size fields
affs: generate OFS sequence numbers starting at 1
wifi: iwlwifi: fw: allocate chained SG tables for dump
sched/smt: Always inline sched_smt_active()
octeontx2-af: Fix mbox INTR handler when num VFs > 64
ring-buffer: Fix bytes_dropped calculation issue
objtool, media: dib8000: Prevent divide-by-zero in dib8000_set_dds()
fs/procfs: fix the comment above proc_pid_wchan()
perf python: Check if there is space to copy all the event
perf python: Decrement the refcount of just created event on failure
perf python: Fixup description of sample.id event member
ocfs2: validate l_tree_depth to avoid out-of-bounds access
kexec: initialize ELF lowest address to ULONG_MAX
perf units: Fix insufficient array space
iio: accel: mma8452: Ensure error return on failure to matching oversampling ratio
coresight: catu: Fix number of pages while using 64k pages
isofs: fix KMSAN uninit-value bug in do_isofs_readdir()
x86/dumpstack: Fix inaccurate unwinding from exception stacks due to misplaced assignment
mfd: sm501: Switch to BIT() to mitigate integer overflows
RDMA/mlx5: Fix mlx5_poll_one() cur_qp update flow
power: supply: max77693: Fix wrong conversion of charge input threshold value
x86/entry: Fix ORC unwinder for PUSH_REGS with save_ret=1
clk: amlogic: g12a: fix mmc A peripheral clock
clk: amlogic: gxbb: drop non existing 32k clock parent
clk: amlogic: g12b: fix cluster A parent data
IB/mad: Check available slots before posting receive WRs
clk: rockchip: rk3328: fix wrong clk_ref_usb3otg parent
pinctrl: renesas: rza2: Fix missing of_node_put() call
lib: 842: Improve error handling in sw842_compress()
bpf: Use preempt_count() directly in bpf_send_signal_common()
clk: amlogic: gxbb: drop incorrect flag on 32k clock
fbdev: sm501fb: Add some geometry checks.
mdacon: rework dependency list
fbdev: au1100fb: Move a variable assignment behind a null pointer check
PCI: pciehp: Don't enable HPIE when resuming in poll mode
PCI: Remove stray put_device() in pci_register_host_bridge()
PCI/portdrv: Only disable pciehp interrupts early when needed
PCI/ASPM: Fix link state exit during switch upstream function removal
drm/mediatek: mtk_hdmi: Fix typo for aud_sampe_size member
ALSA: hda/realtek: Always honor no_shutup_pins
perf/ring_buffer: Allow the EPOLLRDNORM flag for poll
lockdep: Don't disable interrupts on RT in disable_irq_nosync_lockdep.*()
PM: sleep: Fix handling devices with direct_complete set on errors
thermal: int340x: Add NULL check for adev
EDAC/ie31200: Fix the error path order of ie31200_init()
EDAC/ie31200: Fix the DIMM size mask for several SoCs
EDAC/ie31200: Fix the size of EDAC_MC_LAYER_CHIP_SELECT layer
selinux: Chain up tool resolving errors in install_policy.sh
x86/platform: Only allow CONFIG_EISA for 32-bit
x86/fpu: Avoid copying dynamic FP state from init_task in arch_dup_task_struct()
cpufreq: governor: Fix negative 'idle_time' handling in dbs_update()
x86/mm/pat: cpa-test: fix length for CPA_ARRAY test
serial: 8250_dma: terminate correct DMA in tx_dma_flush()
memstick: rtsx_usb_ms: Fix slab-use-after-free in rtsx_usb_ms_drv_remove
net: usb: usbnet: restore usb%d name exception for local mac addresses
net: usb: qmi_wwan: add Telit Cinterion FE990B composition
net: usb: qmi_wwan: add Telit Cinterion FN990B composition
tty: serial: 8250: Add some more device IDs
counter: stm32-lptimer-cnt: fix error handling when enabling
netfilter: socket: Lookup orig tuple for IPv6 SNAT
ARM: Remove address checking for MMUless devices
ARM: 9351/1: fault: Add "cut here" line for prefetch aborts
ARM: 9350/1: fault: Implement copy_from_kernel_nofault_allowed()
atm: Fix NULL pointer dereference
HID: hid-plantronics: Add mic mute mapping and generalize quirks
ALSA: usb-audio: Add quirk for Plantronics headsets to fix control names
drm/radeon: fix uninitialized size issue in radeon_vce_cs_parse()
batman-adv: Ignore own maximum aggregation size during RX
ARM: shmobile: smp: Enforce shmobile_smp_* alignment
mmc: atmel-mci: Add missing clk_disable_unprepare()
drm/v3d: Don't run jobs that have errors flagged in its fence
i2c: omap: fix IRQ storms
net/neighbor: add missing policy for NDTPA_QUEUE_LENBYTES
net: atm: fix use after free in lec_send()
ipv6: Set errno after ip_fib_metrics_init() in ip6_route_info_create().
ipv6: Fix memleak of nhc_pcpu_rth_output in fib_check_nh_v6_gw().
Bluetooth: Fix error code in chan_alloc_skb_cb()
RDMA/hns: Fix wrong value of max_sge_rd
RDMA/bnxt_re: Avoid clearing VLAN_ID mask in modify qp path
xfrm_output: Force software GSO only in tunnel mode
firmware: imx-scu: fix OF node leak in .probe()
i2c: sis630: Fix an error handling path in sis630_probe()
i2c: ali15x3: Fix an error handling path in ali15x3_probe()
i2c: ali1535: Fix an error handling path in ali1535_probe()
ASoC: codecs: wm0010: Fix error handling path in wm0010_spi_probe()
drm/gma500: Add NULL check for pci_gfx_root in mid_get_vbt_data()
qlcnic: fix memory leak issues in qlcnic_sriov_common.c
drm/amd/display: Assign normalized_pix_clk when color depth = 14
drm/atomic: Filter out redundant DPMS calls
x86/microcode/AMD: Fix out-of-bounds on systems with CPU-less NUMA nodes
USB: serial: option: match on interface class for Telit FN990B
USB: serial: option: fix Telit Cinterion FE990A name
USB: serial: option: add Telit Cinterion FE990B compositions
USB: serial: ftdi_sio: add support for Altera USB Blaster 3
block: fix 'kmem_cache of name 'bio-108' already exists'
drm/nouveau: Do not override forced connector status
x86/irq: Define trace events conditionally
fuse: don't truncate cached, mutated symlink
nvme: only allow entering LIVE from CONNECTING state
sctp: Fix undefined behavior in left shift operation
nvmet-rdma: recheck queue state is LIVE in state lock in recv done
ASoC: rsnd: don't indicate warning on rsnd_kctrl_accept_runtime()
s390/cio: Fix CHPID "configure" attribute caching
HID: ignore non-functional sensor in HP 5MP Camera
HID: intel-ish-hid: fix the length of MNG_SYNC_FW_CLOCK in doorbell
ACPI: resource: IRQ override for Eluktronics MECH-17
scsi: qla1280: Fix kernel oops when debug level > 2
iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic()
powercap: call put_device() on an error path in powercap_register_control_type()
hrtimers: Mark is_migration_base() with __always_inline
nvme-fc: go straight to connecting state when initializing
net/mlx5e: Prevent bridge link show failure for non-eswitch-allowed devices
netfilter: nft_exthdr: fix offset with ipv4_find_option()
net_sched: Prevent creation of classes with TC_H_ROOT
ipvs: prevent integer overflow in do_ip_vs_get_ctl()
netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple in insert_tree()
Drivers: hv: vmbus: Don't release fb_mmio resource in vmbus_free_mmio()
drivers/hv: Replace binary semaphore with mutex
netpoll: hold rcu read lock in __netpoll_send_skb()
netpoll: netpoll_send_skb() returns transmit status
netpoll: move netpoll_send_skb() out of line
netpoll: remove dev argument from netpoll_send_skb_on_dev()
netpoll: Fix use correct return type for ndo_start_xmit()
pinctrl: bcm281xx: Fix incorrect regmap max_registers value
sctp: sysctl: auth_enable: avoid using current->nsproxy
sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy
Revert "sctp: sysctl: auth_enable: avoid using current->nsproxy"
Revert "sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy"
sched/isolation: Prevent boot crash when the boot CPU is nohz_full
clockevents/drivers/i8253: Fix stop sequence for timer 0
vlan: fix memory leak in vlan_newlink()
UPSTREAM: net: sched: Disallow replacing of child qdisc from one parent to another
UPSTREAM: pfifo_tail_enqueue: Drop new packet when sch->limit == 0
Revert "tasklet: Introduce new initialization API"
Revert "net: usb: rtl8150: use new tasklet API"
Revert "net: usb: rtl8150: enable basic endpoint checking"
Revert "usb: xhci: Add timeout argument in address_device USB HCD callback"
Revert "usb: xhci: Fix NULL pointer dereference on certain command aborts"
Linux 5.4.291
eeprom: digsy_mtc: Make GPIO lookup table match the device
slimbus: messaging: Free transaction ID in delayed interrupt scenario
intel_th: pci: Add Panther Lake-P/U support
intel_th: pci: Add Panther Lake-H support
intel_th: pci: Add Arrow Lake support
Squashfs: check the inode number is not the invalid value of zero
xhci: pci: Fix indentation in the PCI device ID definitions
usb: gadget: Check bmAttributes only if configuration is valid
usb: gadget: Fix setting self-powered state on suspend
usb: gadget: Set self-powered based on MaxPower and bmAttributes
usb: typec: tcpci_rt1711h: Unmask alert interrupts to fix functionality
usb: typec: ucsi: increase timeout for PPM reset operations
usb: atm: cxacru: fix a flaw in existing endpoint checks
usb: renesas_usbhs: Flush the notify_hotplug_work
usb: quirks: Add DELAY_INIT and NO_LPM for Prolific Mass Storage Card Reader
usb: renesas_usbhs: Use devm_usb_get_phy()
usb: renesas_usbhs: Call clk_put()
Revert "drivers/card_reader/rtsx_usb: Restore interrupt based detection"
gpio: rcar: Fix missing of_node_put() call
net: ipv6: fix missing dst ref drop in ila lwtunnel
net: ipv6: fix dst ref loop in ila lwtunnel
net-timestamp: support TCP GSO case for a few missing flags
vlan: enforce underlying device type
ppp: Fix KMSAN uninit-value warning with bpf
be2net: fix sleeping while atomic bugs in be_ndo_bridge_getlink
drm/sched: Fix preprocessor guard
hwmon: fix a NULL vs IS_ERR_OR_NULL() check in xgene_hwmon_probe()
llc: do not use skb_get() before dev_queue_xmit()
hwmon: (ad7314) Validate leading zero bits and return error
hwmon: (ntc_thermistor) Fix the ncpXXxh103 sensor table
hwmon: (pmbus) Initialise page count in pmbus_identify()
caif_virtio: fix wrong pointer check in cfv_probe()
net: gso: fix ownership in __udp_gso_segment
HID: intel-ish-hid: Fix use-after-free issue in ishtp_hid_remove()
HID: google: fix unused variable warning under !CONFIG_ACPI
wifi: iwlwifi: limit printed string from FW file
mm/page_alloc: fix uninitialized variable
rapidio: fix an API misues when rio_add_net() fails
rapidio: add check for rio_add_net() in rio_scan_alloc_net()
wifi: nl80211: reject cooked mode if it is set along with other flags
wifi: cfg80211: regulatory: improve invalid hints checking
x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63
x86/cpu: Validate CPUID leaf 0x2 EDX output
x86/cacheinfo: Validate CPUID leaf 0x2 EDX output
platform/x86: thinkpad_acpi: Add battery quirk for ThinkPad X131e
drm/radeon: Fix rs400_gpu_init for ATI mobility radeon Xpress 200M
ALSA: hda/realtek: update ALC222 depop optimize
ALSA: hda: intel: Add Dell ALC3271 to power_save denylist
HID: appleir: Fix potential NULL dereference at raw event handle
Revert "of: reserved-memory: Fix using wrong number of cells to get property 'alignment'"
drm/amdgpu: disable BAR resize on Dell G5 SE
drm/amdgpu: Check extended configuration space register when system uses large bar
drm/amdgpu: skip BAR resizing if the bios already did it
acct: perform last write from workqueue
kernel/acct.c: use dedicated helper to access rlimit values
kernel/acct.c: use #elif instead of #end and #elif
drop_monitor: fix incorrect initialization order
pfifo_tail_enqueue: Drop new packet when sch->limit == 0
sched/core: Prevent rescheduling when interrupts are disabled
phy: exynos5-usbdrd: fix MPLL_MULTIPLIER and SSC_REFCLKSEL masks in refclk
phy: tegra: xusb: reset VBUS & ID OVERRIDE
usbnet: gl620a: fix endpoint checking in genelink_bind()
perf/core: Fix low freq setting via IOC_PERIOD
ftrace: Avoid potential division by zero in function_stat_show()
x86/CPU: Fix warm boot hang regression on AMD SC1100 SoC systems
net: mvpp2: cls: Fixed Non IP flow, with vlan tag flow defination.
ipvs: Always clear ipvs_property flag in skb_scrub_packet()
ASoC: es8328: fix route from DAC to output
net: cadence: macb: Synchronize stats calculations
net: loopback: Avoid sending IP packets without an Ethernet header
sunrpc: suppress warnings for unused procfs functions
batman-adv: Drop unmanaged ELP metric worker
batman-adv: Ignore neighbor throughput metrics in error case
acct: block access to kernel internal filesystems
ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED
nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
tee: optee: Fix supplicant wait loop
power: supply: da9150-fg: fix potential overflow
flow_dissector: Fix port range key handling in BPF conversion
flow_dissector: Fix handling of mixed port and port-range keys
net: extract port range fields from fl_flow_key
geneve: Suppress list corruption splat in geneve_destroy_tunnels().
gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
geneve: Fix use-after-free in geneve_find_dev().
powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC
ALSA: hda/realtek: Fixup ALC225 depop procedure
ALSA: hda/realtek - Add type for ALC287
powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline
powerpc/64s/mm: Move __real_pte stubs into hash-4k.h
USB: gadget: f_midi: f_midi_complete to call queue_work
usb/gadget: f_midi: Replace tasklet with work
usb/gadget: f_midi: convert tasklets to use new tasklet_setup() API
usb: dwc3: Fix timeout issue during controller enter/exit from halt state
usb: dwc3: Increase DWC3 controller halt timeout
memcg: fix soft lockup in the OOM process
mm: update mark_victim tracepoints fields
crypto: testmgr - some more fixes to RSA test vectors
crypto: testmgr - populate RSA CRT parameters in RSA test vectors
crypto: testmgr - fix version number of RSA tests
crypto: testmgr - Fix wrong test case of RSA
crypto: testmgr - fix wrong key length for pkcs1pad
driver core: bus: Fix double free in driver API bus_register()
scsi: storvsc: Set correct data length for sending SCSI command without payload
vlan: move dev_put into vlan_dev_uninit
vlan: introduce vlan_dev_free_egress_priority
ima: Fix use-after-free on a dentry's dname.name
pps: Fix a use-after-free
btrfs: avoid monopolizing a core when activating a swap file
Revert "btrfs: avoid monopolizing a core when activating a swap file"
x86/i8253: Disable PIT timer 0 when not in use
parport_pc: add support for ASIX AX99100
serial: 8250_pci: add support for ASIX AX99100
can: ems_pci: move ASIX AX99100 ids to pci_ids.h
nilfs2: protect access to buffers with no active references
nilfs2: do not force clear folio if buffer is referenced
nilfs2: do not output warnings when clearing dirty buffers
alpha: replace hardcoded stack offsets with autogenerated ones
ndisc: extend RCU protection in ndisc_send_skb()
openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
arp: use RCU protection in arp_xmit()
neighbour: use RCU protection in __neigh_notify()
neighbour: delete redundant judgment statements
ndisc: use RCU protection in ndisc_alloc_skb()
ipv6: use RCU protection in ip6_default_advmss()
ipv4: use RCU protection in inet_select_addr()
ipv4: use RCU protection in rt_is_expired()
net: add dev_net_rcu() helper
net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu()
regmap-irq: Add missing kfree()
partitions: mac: fix handling of bogus partition table
gpio: stmpe: Check return value of stmpe_reg_read in stmpe_gpio_irq_sync_unlock
alpha: align stack for page fault and user unaligned trap handlers
serial: 8250: Fix fifo underflow on flush
alpha: make stack 16-byte aligned (most cases)
can: j1939: j1939_sk_send_loop(): fix unable to send messages with data length zero
can: c_can: fix unbalanced runtime PM disable in error path
USB: serial: option: drop MeiG Smart defines
USB: serial: option: fix Telit Cinterion FN990A name
USB: serial: option: add Telit Cinterion FN990B compositions
USB: serial: option: add MeiG Smart SLM828
usb: cdc-acm: Fix handling of oversized fragments
usb: cdc-acm: Check control transfer buffer size before access
USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk
USB: hub: Ignore non-compliant devices with too many configs or interfaces
usb: gadget: f_midi: fix MIDI Streaming descriptor lengths
USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone
USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist
USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI
usb: dwc2: gadget: remove of_node reference upon udc_stop
usb: gadget: udc: renesas_usb3: Fix compiler warning
usb: roles: set switch registered flag early on
batman-adv: fix panic during interface removal
ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V
orangefs: fix a oob in orangefs_debug_write
Grab mm lock before grabbing pt lock
vfio/pci: Enable iowrite64 and ioread64 for vfio pci
media: cxd2841er: fix 64-bit division on gcc-9
x86/xen: allow larger contiguous memory regions in PV guests
xen: remove a confusing comment on auto-translated guest I/O
gpio: bcm-kona: Add missing newline to dev_err format string
gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ
gpio: bcm-kona: Fix GPIO lock/unlock for banks above bank 0
arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array
team: better TEAM_OPTION_TYPE_STRING validation
vrf: use RCU protection in l3mdev_l3_out()
ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu()
HID: multitouch: Add NULL check in mt_input_configured
ocfs2: check dir i_size in ocfs2_find_entry
MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
ptp: Ensure info->enable callback is always set
net/ncsi: wait for the last response to Deselect Package before configuring channel
misc: fastrpc: Fix registered buffer page address
mtd: onenand: Fix uninitialized retlen in do_otp_read()
NFC: nci: Add bounds checking in nci_hci_create_pipe()
nilfs2: fix possible int overflows in nilfs_fiemap()
ocfs2: handle a symlink read error correctly
ocfs2: fix incorrect CPU endianness conversion causing mount failure
vfio/platform: check the bounds of read/write syscalls
nvmem: core: improve range check for nvmem_cell_write()
crypto: qce - unregister previously registered algos in error path
crypto: qce - fix goto jump in error path
media: uvcvideo: Remove redundant NULL assignment
media: uvcvideo: Fix event flags in uvc_ctrl_send_events
media: ov5640: fix get_light_freq on auto
soc: qcom: smem_state: fix missing of_node_put in error path
kbuild: Move -Wenum-enum-conversion to W=2
powerpc/pseries/eeh: Fix get PE state translation
serial: sh-sci: Do not probe the serial port if its slot in sci_ports[] is in use
serial: sh-sci: Drop __initdata macro for port_cfg
soc: qcom: socinfo: Avoid out of bounds read of serial number
usb: gadget: f_tcm: Don't prepare BOT write request twice
usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint
usb: gadget: f_tcm: Decrement command ref count on cleanup
usb: gadget: f_tcm: Translate error to sense
wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize()
HID: hid-sensor-hub: don't use stale platform-data on remove
of: reserved-memory: Fix using wrong number of cells to get property 'alignment'
of: Fix of_find_node_opts_by_path() handling of alias+path+options
of: Correct child specifier used as input of the 2nd nexus node
perf bench: Fix undefined behavior in cmpworker()
clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate
clk: qcom: clk-alpha-pll: fix alpha mode configuration
Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc
drm/komeda: Add check for komeda_get_layer_fourcc_list()
KVM: s390: vsie: fix some corner-cases when grabbing vsie pages
KVM: Explicitly verify target vCPU is online in kvm_get_vcpu()
arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
binfmt_flat: Fix integer overflow bug on 32 bit systems
m68k: vga: Fix I/O defines
s390/futex: Fix FUTEX_OP_ANDN implementation
leds: lp8860: Write full EEPROM, not only half of it
cpufreq: s3c64xx: Fix compilation warning
tun: revert fix group permission check
netem: Update sch->q.qlen before qdisc_tree_reduce_backlog()
net: rose: lock the socket in rose_bind()
udp: gso: do not drop small packets when PMTU reduces
tg3: Disable tg3 PCIe AER on system reboot
gpu: drm_dp_cec: fix broken CEC adapter properties check
firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry
nvme: handle connectivity loss in nvme_set_queue_count
usb: xhci: Fix NULL pointer dereference on certain command aborts
usb: xhci: Add timeout argument in address_device USB HCD callback
net: usb: rtl8150: enable basic endpoint checking
net: usb: rtl8150: use new tasklet API
tasklet: Introduce new initialization API
kbuild: userprogs: use correct lld when linking through clang
sched: sch_cake: add bounds checks to host bulk flow fairness counts
media: uvcvideo: Remove dangling pointers
media: uvcvideo: Only save async fh if success
nilfs2: handle errors that nilfs_prepare_chunk() may return
nilfs2: eliminate staggered calls to kunmap in nilfs_rename
nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link
spi-mxs: Fix chipselect glitch
x86/mm: Don't disable PCID when INVLPG has been fixed by microcode
APEI: GHES: Have GHES honor the panic= setting
HID: Wacom: Add PCI Wacom device support
mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id
tomoyo: don't emit warning in tomoyo_write_control()
wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy()
mmc: core: Respect quirk_max_rate for non-UHS SDIO card
tun: fix group permission check
printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX
x86/amd_nb: Restrict init function to AMD-based systems
sched: Don't try to catch up excess steal time.
btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling
btrfs: fix use-after-free when attempting to join an aborted transaction
btrfs: output the reason for open_ctree() failure
usb: gadget: f_tcm: Don't free command immediately
media: uvcvideo: Fix double free in error path
HID: core: Fix assumption that Resolution Multipliers must be in Logical Collections
usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to PD_T_SENDER_RESPONSE
drivers/card_reader/rtsx_usb: Restore interrupt based detection
ktest.pl: Check kernelrelease return in get_version
NFSD: Reset cb_seq_status after NFS4ERR_DELAY
hexagon: Fix unbalanced spinlock in die()
hexagon: fix using plain integer as NULL pointer warning in cmpxchg
genksyms: fix memory leak when the same symbol is read from *.symref file
genksyms: fix memory leak when the same symbol is added from source
net: sh_eth: Fix missing rtnl lock in suspend/resume path
vsock: Allow retrying on connect() failure
perf trace: Fix runtime error of index out of bounds
net: davicom: fix UAF in dm9000_drv_remove
net: rose: fix timer races against user threads
PM: hibernate: Add error handling for syscore_suspend()
ipmr: do not call mr_mfc_uses_dev() for unres entries
net: fec: implement TSO descriptor cleanup
ubifs: skip dumping tnc tree when zroot is null
rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read
dmaengine: ti: edma: fix OF node reference leaks in edma_driver
module: Extend the preempt disabled section in dereference_symbol_descriptor().
ocfs2: mark dquot as inactive if failed to start trans while releasing dquot
scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails
scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1
staging: media: imx: fix OF node leak in imx_media_add_of_subdevs()
media: uvcvideo: Propagate buf->error to userspace
media: camif-core: Add check for clk_enable()
media: mipi-csis: Add check for clk_enable()
PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy()
media: lmedm04: Handle errors for lme2510_int_read
media: lmedm04: Use GFP_KERNEL for URB allocation/submission.
media: rc: iguanair: handle timeouts
fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device()
ARM: dts: mediatek: mt7623: fix IR nodename
arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
rdma/cxgb4: Prevent potential integer overflow on 32bit
RDMA/mlx4: Avoid false error about access to uninitialized gids array
bpf: Send signals asynchronously if !preemptible
perf report: Fix misleading help message about --demangle
perf top: Don't complain about lack of vmlinux when not resolving some kernel samples
padata: fix sysfs store callback check
ktest.pl: Remove unused declarations in run_bisect_test function
perf header: Fix one memory leakage in process_bpf_prog_info()
perf header: Fix one memory leakage in process_bpf_btf()
ASoC: sun4i-spdif: Add clock multiplier settings
tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind
net: sched: Disallow replacing of child qdisc from one parent to another
net/mlxfw: Drop hard coded max FW flash image size
net: let net.core.dev_weight always be non-zero
clk: analogbits: Fix incorrect calculation of vco rate delta
selftests: harness: fix printing of mismatch values in __EXPECT()
selftests/harness: Display signed values correctly
wifi: wlcore: fix unbalanced pm_runtime calls
regulator: of: Implement the unwind path of of_regulator_match()
team: prevent adding a device which is already a team device lower
cpupower: fix TSC MHz calculation
wifi: rtlwifi: pci: wait for firmware loading before releasing memory
wifi: rtlwifi: fix memory leaks and invalid access at probe error path
wifi: rtlwifi: remove unused check_buddy_priv
wifi: rtlwifi: remove unused dualmac control leftovers
wifi: rtlwifi: remove unused timer and related code
rtlwifi: replace usage of found with dedicated list iterator variable
dt-bindings: mmc: controller: clarify the address-cells description
wifi: rtlwifi: usb: fix workqueue leak when probe fails
wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last step
rtlwifi: rtl8192se Rename RT_TRACE to rtl_dbg
wifi: rtlwifi: do not complete firmware loading needlessly
ipmi: ipmb: Add check devm_kasprintf() returned value
drm/amdgpu: Fix potential NULL pointer dereference in atomctrl_get_smc_sclk_range_table
drm/etnaviv: Fix page property being used for non writecombine buffers
partitions: ldm: remove the initial kernel-doc notation
nbd: don't allow reconnect after disconnect
afs: Fix directory format encoding struct
overflow: Allow mixed type arguments
overflow: Correct check_shl_overflow() comment
overflow: Add __must_check attribute to check_*() helpers
udf: Fix use of check_add_overflow() with mixed type arguments
perf cs-etm: Add missing variable in cs_etm__process_queues()
UPSTREAM: f2fs: compress: don't allow unaligned truncation on released compress inode
UPSTREAM: net: core: reject skb_copy(_expand) for fraglist GSO skbs
UPSTREAM: udp: prevent local UDP tunnel packets from being GROed
UPSTREAM: udp: do not transition UDP GRO fraglist partial checksums to unnecessary
UPSTREAM: udp: do not accept non-tunnel GSO skbs landing in a tunnel
UPSTREAM: binder: Return EFAULT if we fail BINDER_ENABLE_ONEWAY_SPAM_DETECTION
ANDROID: ABI: Cuttlefish Symbol update
Revert "net: net_namespace: Optimize the code"
Revert "net: add exit_batch_rtnl() method"
Revert "gtp: use exit_batch_rtnl() method"
Revert "gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp()."
Revert "gtp: Destroy device along with udp socket's netns dismantle."
ANDROID: gki - change networking configuration
Linux 5.4.290
Partial revert of xhci: use pm_ptr() instead #ifdef for CONFIG_PM conditionals
xhci: use pm_ptr() instead of #ifdef for CONFIG_PM conditionals
drm/v3d: Assign job pointer to NULL before signaling the fence
Input: xpad - add support for wooting two he (arm)
Input: xpad - add unofficial Xbox 360 wireless receiver clone
Input: atkbd - map F23 key to support default copilot shortcut
Revert "usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null"
USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb()
ext4: fix slab-use-after-free in ext4_split_extent_at()
ext4: avoid ext4_error()'s caused by ENOMEM in the truncate path
vfio/platform: check the bounds of read/write syscalls
net/xen-netback: prevent UAF in xenvif_flush_hash()
net: xen-netback: hash.c: Use built-in RCU list checking
signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die
m68k: Add missing mmap_read_lock() to sys_cacheflush()
m68k: Update ->thread.esp0 before calling syscall_trace() in ret_from_signal
gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag
irqchip/sunxi-nmi: Add missing SKIP_WAKE flag
scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request
ASoC: wm8994: Add depends on MFD core
net: fix data-races around sk->sk_forward_alloc
scsi: sg: Fix slab-use-after-free read in sg_release()
ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev()
hrtimers: Handle CPU state correctly on hotplug
irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
fs/proc: fix softlockup in __read_vmcore (part 2)
net: ethernet: xgbe: re-add aneg to supported features in PHY quirks
nvmet: propagate npwg topology
poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll()
kheaders: Ignore silly-rename files
hfs: Sanity check the root record
mac802154: check local interfaces before deleting sdata list
i2c: mux: demux-pinctrl: check initial mux selection, too
drm/v3d: Ensure job pointer is set to NULL after job completion
nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
gtp: Destroy device along with udp socket's netns dismantle.
gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
gtp: use exit_batch_rtnl() method
net: add exit_batch_rtnl() method
net: net_namespace: Optimize the code
net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
sctp: sysctl: rto_min/max: avoid using current->nsproxy
ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv
ocfs2: correct return value of ocfs2_local_free_info()
phy: core: Fix that API devm_of_phy_provider_unregister() fails to unregister the phy provider
phy: core: fix code style in devm_of_phy_provider_unregister
arm64: dts: rockchip: add hevc power domain clock to rk3328
arm64: dts: rockchip: add #power-domain-cells to power domain nodes
arm64: dts: rockchip: fix pd_tcpc0 and pd_tcpc1 node position on rk3399
arm64: dts: rockchip: fix defines in pd_vio node for rk3399
iio: inkern: call iio_device_put() only on mapped devices
iio: adc: at91: call input_free_device() on allocated iio_dev
iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep()
iio: gyro: fxas21002c: Fix missing data update in trigger handler
iio: adc: ti-ads8688: fix information leak in triggered buffer
iio: imu: kmx61: fix information leak in triggered buffer
iio: light: vcnl4035: fix information leak in triggered buffer
iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered buffer
iio: pressure: zpa2326: fix information leak in triggered buffer
usb: gadget: f_fs: Remove WARN_ON in functionfs_bind
usb: fix reference leak in usb_new_device()
USB: core: Disable LPM only for non-suspended ports
USB: usblp: return error when setting unsupported protocol
usb: gadget: u_serial: Disable ep before setting port to null to fix the crash caused by port being null
USB: serial: cp210x: add Phoenix Contact UPS Device
usb-storage: Add max sectors quirk for Nokia 208
staging: iio: ad9832: Correct phase range check
staging: iio: ad9834: Correct phase range check
USB: serial: option: add Neoway N723-EA support
USB: serial: option: add MeiG Smart SRM815
drm/amd/display: increase MAX_SURFACES to the value supported by hw
ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[]
ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[]
drm/amd/display: Add check for granularity in dml ceil/floor helpers
sctp: sysctl: auth_enable: avoid using current->nsproxy
sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy
dm thin: make get_first_thin use rcu-safe list first function
tls: Fix tls_sw_sendmsg error handling
net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute
tcp/dccp: allow a connection when sk_max_ack_backlog is zero
tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog
net: 802: LLC+SNAP OID:PID lookup on start of skb data
ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe()
dm array: fix cursor index when skipping across block boundaries
dm array: fix unreleased btree blocks on closing a faulty array cursor
dm array: fix releasing a faulty array block twice in dm_array_cursor_end
jbd2: flush filesystem device before updating tail sequence
ANDROID: kernelci build-break for 64-bit riscv clang builds (5.4 only)
Revert "BACKPORT: RISC-V: Stop relying on GCC's register allocator's hueristics"
Revert "ANDROID: declare sp_in_global outside of CONFIG_FRAME_POINTER".
Conflicts:
Makefile
arch/arm64/include/asm/cputype.h
drivers/clk/qcom/clk-alpha-pll.c
drivers/platform/Kconfig
drivers/platform/Makefile
drivers/soc/qcom/socinfo.c
include/linux/pid.h
mm/oom_kill.c
Change-Id: I5ab3bedbb68119a9e80e5d5eca28a8a819798b17
Signed-off-by: kamasali Satyanarayan <quic_kamasali@quicinc.com>
2232 lines
56 KiB
C
2232 lines
56 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2001 Jens Axboe <axboe@kernel.dk>
|
|
*/
|
|
#include <linux/mm.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/bio.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/uio.h>
|
|
#include <linux/iocontext.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/export.h>
|
|
#include <linux/mempool.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/cgroup.h>
|
|
#include <linux/blk-cgroup.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/blk-crypto.h>
|
|
|
|
#include <trace/events/block.h>
|
|
#include "blk.h"
|
|
#include "blk-rq-qos.h"
|
|
|
|
/*
|
|
* Test patch to inline a certain number of bi_io_vec's inside the bio
|
|
* itself, to shrink a bio data allocation from two mempool calls to one
|
|
*/
|
|
#define BIO_INLINE_VECS 4
|
|
|
|
/*
|
|
* if you change this list, also change bvec_alloc or things will
|
|
* break badly! cannot be bigger than what you can fit into an
|
|
* unsigned short
|
|
*/
|
|
#define BV(x, n) { .nr_vecs = x, .name = "biovec-"#n }
|
|
static struct biovec_slab bvec_slabs[BVEC_POOL_NR] __read_mostly = {
|
|
BV(1, 1), BV(4, 4), BV(16, 16), BV(64, 64), BV(128, 128), BV(BIO_MAX_PAGES, max),
|
|
};
|
|
#undef BV
|
|
|
|
/*
|
|
* fs_bio_set is the bio_set containing bio and iovec memory pools used by
|
|
* IO code that does not need private memory pools.
|
|
*/
|
|
struct bio_set fs_bio_set;
|
|
EXPORT_SYMBOL(fs_bio_set);
|
|
|
|
/*
|
|
* Our slab pool management
|
|
*/
|
|
struct bio_slab {
|
|
struct kmem_cache *slab;
|
|
unsigned int slab_ref;
|
|
unsigned int slab_size;
|
|
char name[12];
|
|
};
|
|
static DEFINE_MUTEX(bio_slab_lock);
|
|
static struct bio_slab *bio_slabs;
|
|
static unsigned int bio_slab_nr, bio_slab_max;
|
|
|
|
static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
|
|
{
|
|
unsigned int sz = sizeof(struct bio) + extra_size;
|
|
struct kmem_cache *slab = NULL;
|
|
struct bio_slab *bslab, *new_bio_slabs;
|
|
unsigned int new_bio_slab_max;
|
|
unsigned int i, entry = -1;
|
|
|
|
mutex_lock(&bio_slab_lock);
|
|
|
|
i = 0;
|
|
while (i < bio_slab_nr) {
|
|
bslab = &bio_slabs[i];
|
|
|
|
if (!bslab->slab && entry == -1)
|
|
entry = i;
|
|
else if (bslab->slab_size == sz) {
|
|
slab = bslab->slab;
|
|
bslab->slab_ref++;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
if (slab)
|
|
goto out_unlock;
|
|
|
|
if (bio_slab_nr == bio_slab_max && entry == -1) {
|
|
new_bio_slab_max = bio_slab_max << 1;
|
|
new_bio_slabs = krealloc(bio_slabs,
|
|
new_bio_slab_max * sizeof(struct bio_slab),
|
|
GFP_KERNEL);
|
|
if (!new_bio_slabs)
|
|
goto out_unlock;
|
|
bio_slab_max = new_bio_slab_max;
|
|
bio_slabs = new_bio_slabs;
|
|
}
|
|
if (entry == -1)
|
|
entry = bio_slab_nr++;
|
|
|
|
bslab = &bio_slabs[entry];
|
|
|
|
snprintf(bslab->name, sizeof(bslab->name), "bio-%d", entry);
|
|
slab = kmem_cache_create(bslab->name, sz, ARCH_KMALLOC_MINALIGN,
|
|
SLAB_HWCACHE_ALIGN, NULL);
|
|
if (!slab)
|
|
goto out_unlock;
|
|
|
|
bslab->slab = slab;
|
|
bslab->slab_ref = 1;
|
|
bslab->slab_size = sz;
|
|
out_unlock:
|
|
mutex_unlock(&bio_slab_lock);
|
|
return slab;
|
|
}
|
|
|
|
static void bio_put_slab(struct bio_set *bs)
|
|
{
|
|
struct bio_slab *bslab = NULL;
|
|
unsigned int i;
|
|
|
|
mutex_lock(&bio_slab_lock);
|
|
|
|
for (i = 0; i < bio_slab_nr; i++) {
|
|
if (bs->bio_slab == bio_slabs[i].slab) {
|
|
bslab = &bio_slabs[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (WARN(!bslab, KERN_ERR "bio: unable to find slab!\n"))
|
|
goto out;
|
|
|
|
WARN_ON(!bslab->slab_ref);
|
|
|
|
if (--bslab->slab_ref)
|
|
goto out;
|
|
|
|
kmem_cache_destroy(bslab->slab);
|
|
bslab->slab = NULL;
|
|
|
|
out:
|
|
mutex_unlock(&bio_slab_lock);
|
|
}
|
|
|
|
unsigned int bvec_nr_vecs(unsigned short idx)
|
|
{
|
|
return bvec_slabs[--idx].nr_vecs;
|
|
}
|
|
|
|
void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned int idx)
|
|
{
|
|
if (!idx)
|
|
return;
|
|
idx--;
|
|
|
|
BIO_BUG_ON(idx >= BVEC_POOL_NR);
|
|
|
|
if (idx == BVEC_POOL_MAX) {
|
|
mempool_free(bv, pool);
|
|
} else {
|
|
struct biovec_slab *bvs = bvec_slabs + idx;
|
|
|
|
kmem_cache_free(bvs->slab, bv);
|
|
}
|
|
}
|
|
|
|
struct bio_vec *bvec_alloc(gfp_t gfp_mask, int nr, unsigned long *idx,
|
|
mempool_t *pool)
|
|
{
|
|
struct bio_vec *bvl;
|
|
|
|
/*
|
|
* see comment near bvec_array define!
|
|
*/
|
|
switch (nr) {
|
|
case 1:
|
|
*idx = 0;
|
|
break;
|
|
case 2 ... 4:
|
|
*idx = 1;
|
|
break;
|
|
case 5 ... 16:
|
|
*idx = 2;
|
|
break;
|
|
case 17 ... 64:
|
|
*idx = 3;
|
|
break;
|
|
case 65 ... 128:
|
|
*idx = 4;
|
|
break;
|
|
case 129 ... BIO_MAX_PAGES:
|
|
*idx = 5;
|
|
break;
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* idx now points to the pool we want to allocate from. only the
|
|
* 1-vec entry pool is mempool backed.
|
|
*/
|
|
if (*idx == BVEC_POOL_MAX) {
|
|
fallback:
|
|
bvl = mempool_alloc(pool, gfp_mask);
|
|
} else {
|
|
struct biovec_slab *bvs = bvec_slabs + *idx;
|
|
gfp_t __gfp_mask = gfp_mask & ~(__GFP_DIRECT_RECLAIM | __GFP_IO);
|
|
|
|
/*
|
|
* Make this allocation restricted and don't dump info on
|
|
* allocation failures, since we'll fallback to the mempool
|
|
* in case of failure.
|
|
*/
|
|
__gfp_mask |= __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN;
|
|
|
|
/*
|
|
* Try a slab allocation. If this fails and __GFP_DIRECT_RECLAIM
|
|
* is set, retry with the 1-entry mempool
|
|
*/
|
|
bvl = kmem_cache_alloc(bvs->slab, __gfp_mask);
|
|
if (unlikely(!bvl && (gfp_mask & __GFP_DIRECT_RECLAIM))) {
|
|
*idx = BVEC_POOL_MAX;
|
|
goto fallback;
|
|
}
|
|
}
|
|
|
|
(*idx)++;
|
|
return bvl;
|
|
}
|
|
|
|
void bio_uninit(struct bio *bio)
|
|
{
|
|
bio_disassociate_blkg(bio);
|
|
|
|
bio_crypt_free_ctx(bio);
|
|
|
|
if (bio_integrity(bio))
|
|
bio_integrity_free(bio);
|
|
}
|
|
EXPORT_SYMBOL(bio_uninit);
|
|
|
|
static void bio_free(struct bio *bio)
|
|
{
|
|
struct bio_set *bs = bio->bi_pool;
|
|
void *p;
|
|
|
|
bio_uninit(bio);
|
|
|
|
if (bs) {
|
|
bvec_free(&bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
|
|
|
|
/*
|
|
* If we have front padding, adjust the bio pointer before freeing
|
|
*/
|
|
p = bio;
|
|
p -= bs->front_pad;
|
|
|
|
mempool_free(p, &bs->bio_pool);
|
|
} else {
|
|
/* Bio was allocated by bio_kmalloc() */
|
|
kfree(bio);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Users of this function have their own bio allocation. Subsequently,
|
|
* they must remember to pair any call to bio_init() with bio_uninit()
|
|
* when IO has completed, or when the bio is released.
|
|
*/
|
|
void bio_init(struct bio *bio, struct bio_vec *table,
|
|
unsigned short max_vecs)
|
|
{
|
|
memset(bio, 0, sizeof(*bio));
|
|
atomic_set(&bio->__bi_remaining, 1);
|
|
atomic_set(&bio->__bi_cnt, 1);
|
|
|
|
bio->bi_io_vec = table;
|
|
bio->bi_max_vecs = max_vecs;
|
|
}
|
|
EXPORT_SYMBOL(bio_init);
|
|
|
|
/**
|
|
* bio_reset - reinitialize a bio
|
|
* @bio: bio to reset
|
|
*
|
|
* Description:
|
|
* After calling bio_reset(), @bio will be in the same state as a freshly
|
|
* allocated bio returned bio bio_alloc_bioset() - the only fields that are
|
|
* preserved are the ones that are initialized by bio_alloc_bioset(). See
|
|
* comment in struct bio.
|
|
*/
|
|
void bio_reset(struct bio *bio)
|
|
{
|
|
unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);
|
|
|
|
bio_uninit(bio);
|
|
|
|
memset(bio, 0, BIO_RESET_BYTES);
|
|
bio->bi_flags = flags;
|
|
atomic_set(&bio->__bi_remaining, 1);
|
|
}
|
|
EXPORT_SYMBOL(bio_reset);
|
|
|
|
static struct bio *__bio_chain_endio(struct bio *bio)
|
|
{
|
|
struct bio *parent = bio->bi_private;
|
|
|
|
if (bio->bi_status && !parent->bi_status)
|
|
parent->bi_status = bio->bi_status;
|
|
bio_put(bio);
|
|
return parent;
|
|
}
|
|
|
|
static void bio_chain_endio(struct bio *bio)
|
|
{
|
|
bio_endio(__bio_chain_endio(bio));
|
|
}
|
|
|
|
/**
|
|
* bio_chain - chain bio completions
|
|
* @bio: the target bio
|
|
* @parent: the @bio's parent bio
|
|
*
|
|
* The caller won't have a bi_end_io called when @bio completes - instead,
|
|
* @parent's bi_end_io won't be called until both @parent and @bio have
|
|
* completed; the chained bio will also be freed when it completes.
|
|
*
|
|
* The caller must not set bi_private or bi_end_io in @bio.
|
|
*/
|
|
void bio_chain(struct bio *bio, struct bio *parent)
|
|
{
|
|
BUG_ON(bio->bi_private || bio->bi_end_io);
|
|
|
|
bio->bi_private = parent;
|
|
bio->bi_end_io = bio_chain_endio;
|
|
bio_inc_remaining(parent);
|
|
}
|
|
EXPORT_SYMBOL(bio_chain);
|
|
|
|
static void bio_alloc_rescue(struct work_struct *work)
|
|
{
|
|
struct bio_set *bs = container_of(work, struct bio_set, rescue_work);
|
|
struct bio *bio;
|
|
|
|
while (1) {
|
|
spin_lock(&bs->rescue_lock);
|
|
bio = bio_list_pop(&bs->rescue_list);
|
|
spin_unlock(&bs->rescue_lock);
|
|
|
|
if (!bio)
|
|
break;
|
|
|
|
generic_make_request(bio);
|
|
}
|
|
}
|
|
|
|
static void punt_bios_to_rescuer(struct bio_set *bs)
|
|
{
|
|
struct bio_list punt, nopunt;
|
|
struct bio *bio;
|
|
|
|
if (WARN_ON_ONCE(!bs->rescue_workqueue))
|
|
return;
|
|
/*
|
|
* In order to guarantee forward progress we must punt only bios that
|
|
* were allocated from this bio_set; otherwise, if there was a bio on
|
|
* there for a stacking driver higher up in the stack, processing it
|
|
* could require allocating bios from this bio_set, and doing that from
|
|
* our own rescuer would be bad.
|
|
*
|
|
* Since bio lists are singly linked, pop them all instead of trying to
|
|
* remove from the middle of the list:
|
|
*/
|
|
|
|
bio_list_init(&punt);
|
|
bio_list_init(&nopunt);
|
|
|
|
while ((bio = bio_list_pop(¤t->bio_list[0])))
|
|
bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio);
|
|
current->bio_list[0] = nopunt;
|
|
|
|
bio_list_init(&nopunt);
|
|
while ((bio = bio_list_pop(¤t->bio_list[1])))
|
|
bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio);
|
|
current->bio_list[1] = nopunt;
|
|
|
|
spin_lock(&bs->rescue_lock);
|
|
bio_list_merge(&bs->rescue_list, &punt);
|
|
spin_unlock(&bs->rescue_lock);
|
|
|
|
queue_work(bs->rescue_workqueue, &bs->rescue_work);
|
|
}
|
|
|
|
/**
|
|
* bio_alloc_bioset - allocate a bio for I/O
|
|
* @gfp_mask: the GFP_* mask given to the slab allocator
|
|
* @nr_iovecs: number of iovecs to pre-allocate
|
|
* @bs: the bio_set to allocate from.
|
|
*
|
|
* Description:
|
|
* If @bs is NULL, uses kmalloc() to allocate the bio; else the allocation is
|
|
* backed by the @bs's mempool.
|
|
*
|
|
* When @bs is not NULL, if %__GFP_DIRECT_RECLAIM is set then bio_alloc will
|
|
* always be able to allocate a bio. This is due to the mempool guarantees.
|
|
* To make this work, callers must never allocate more than 1 bio at a time
|
|
* from this pool. Callers that need to allocate more than 1 bio must always
|
|
* submit the previously allocated bio for IO before attempting to allocate
|
|
* a new one. Failure to do so can cause deadlocks under memory pressure.
|
|
*
|
|
* Note that when running under generic_make_request() (i.e. any block
|
|
* driver), bios are not submitted until after you return - see the code in
|
|
* generic_make_request() that converts recursion into iteration, to prevent
|
|
* stack overflows.
|
|
*
|
|
* This would normally mean allocating multiple bios under
|
|
* generic_make_request() would be susceptible to deadlocks, but we have
|
|
* deadlock avoidance code that resubmits any blocked bios from a rescuer
|
|
* thread.
|
|
*
|
|
* However, we do not guarantee forward progress for allocations from other
|
|
* mempools. Doing multiple allocations from the same mempool under
|
|
* generic_make_request() should be avoided - instead, use bio_set's front_pad
|
|
* for per bio allocations.
|
|
*
|
|
* RETURNS:
|
|
* Pointer to new bio on success, NULL on failure.
|
|
*/
|
|
struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs,
|
|
struct bio_set *bs)
|
|
{
|
|
gfp_t saved_gfp = gfp_mask;
|
|
unsigned front_pad;
|
|
unsigned inline_vecs;
|
|
struct bio_vec *bvl = NULL;
|
|
struct bio *bio;
|
|
void *p;
|
|
|
|
if (!bs) {
|
|
if (nr_iovecs > UIO_MAXIOV)
|
|
return NULL;
|
|
|
|
p = kmalloc(sizeof(struct bio) +
|
|
nr_iovecs * sizeof(struct bio_vec),
|
|
gfp_mask);
|
|
front_pad = 0;
|
|
inline_vecs = nr_iovecs;
|
|
} else {
|
|
/* should not use nobvec bioset for nr_iovecs > 0 */
|
|
if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) &&
|
|
nr_iovecs > 0))
|
|
return NULL;
|
|
/*
|
|
* generic_make_request() converts recursion to iteration; this
|
|
* means if we're running beneath it, any bios we allocate and
|
|
* submit will not be submitted (and thus freed) until after we
|
|
* return.
|
|
*
|
|
* This exposes us to a potential deadlock if we allocate
|
|
* multiple bios from the same bio_set() while running
|
|
* underneath generic_make_request(). If we were to allocate
|
|
* multiple bios (say a stacking block driver that was splitting
|
|
* bios), we would deadlock if we exhausted the mempool's
|
|
* reserve.
|
|
*
|
|
* We solve this, and guarantee forward progress, with a rescuer
|
|
* workqueue per bio_set. If we go to allocate and there are
|
|
* bios on current->bio_list, we first try the allocation
|
|
* without __GFP_DIRECT_RECLAIM; if that fails, we punt those
|
|
* bios we would be blocking to the rescuer workqueue before
|
|
* we retry with the original gfp_flags.
|
|
*/
|
|
|
|
if (current->bio_list &&
|
|
(!bio_list_empty(¤t->bio_list[0]) ||
|
|
!bio_list_empty(¤t->bio_list[1])) &&
|
|
bs->rescue_workqueue)
|
|
gfp_mask &= ~__GFP_DIRECT_RECLAIM;
|
|
|
|
p = mempool_alloc(&bs->bio_pool, gfp_mask);
|
|
if (!p && gfp_mask != saved_gfp) {
|
|
punt_bios_to_rescuer(bs);
|
|
gfp_mask = saved_gfp;
|
|
p = mempool_alloc(&bs->bio_pool, gfp_mask);
|
|
}
|
|
|
|
front_pad = bs->front_pad;
|
|
inline_vecs = BIO_INLINE_VECS;
|
|
}
|
|
|
|
if (unlikely(!p))
|
|
return NULL;
|
|
|
|
bio = p + front_pad;
|
|
bio_init(bio, NULL, 0);
|
|
|
|
if (nr_iovecs > inline_vecs) {
|
|
unsigned long idx = 0;
|
|
|
|
bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, &bs->bvec_pool);
|
|
if (!bvl && gfp_mask != saved_gfp) {
|
|
punt_bios_to_rescuer(bs);
|
|
gfp_mask = saved_gfp;
|
|
bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx, &bs->bvec_pool);
|
|
}
|
|
|
|
if (unlikely(!bvl))
|
|
goto err_free;
|
|
|
|
bio->bi_flags |= idx << BVEC_POOL_OFFSET;
|
|
} else if (nr_iovecs) {
|
|
bvl = bio->bi_inline_vecs;
|
|
}
|
|
|
|
bio->bi_pool = bs;
|
|
bio->bi_max_vecs = nr_iovecs;
|
|
bio->bi_io_vec = bvl;
|
|
return bio;
|
|
|
|
err_free:
|
|
mempool_free(p, &bs->bio_pool);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(bio_alloc_bioset);
|
|
|
|
void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start)
|
|
{
|
|
unsigned long flags;
|
|
struct bio_vec bv;
|
|
struct bvec_iter iter;
|
|
|
|
__bio_for_each_segment(bv, bio, iter, start) {
|
|
char *data = bvec_kmap_irq(&bv, &flags);
|
|
memset(data, 0, bv.bv_len);
|
|
flush_dcache_page(bv.bv_page);
|
|
bvec_kunmap_irq(data, &flags);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(zero_fill_bio_iter);
|
|
|
|
/**
|
|
* bio_truncate - truncate the bio to small size of @new_size
|
|
* @bio: the bio to be truncated
|
|
* @new_size: new size for truncating the bio
|
|
*
|
|
* Description:
|
|
* Truncate the bio to new size of @new_size. If bio_op(bio) is
|
|
* REQ_OP_READ, zero the truncated part. This function should only
|
|
* be used for handling corner cases, such as bio eod.
|
|
*/
|
|
void bio_truncate(struct bio *bio, unsigned new_size)
|
|
{
|
|
struct bio_vec bv;
|
|
struct bvec_iter iter;
|
|
unsigned int done = 0;
|
|
bool truncated = false;
|
|
|
|
if (new_size >= bio->bi_iter.bi_size)
|
|
return;
|
|
|
|
if (bio_op(bio) != REQ_OP_READ)
|
|
goto exit;
|
|
|
|
bio_for_each_segment(bv, bio, iter) {
|
|
if (done + bv.bv_len > new_size) {
|
|
unsigned offset;
|
|
|
|
if (!truncated)
|
|
offset = new_size - done;
|
|
else
|
|
offset = 0;
|
|
zero_user(bv.bv_page, bv.bv_offset + offset,
|
|
bv.bv_len - offset);
|
|
truncated = true;
|
|
}
|
|
done += bv.bv_len;
|
|
}
|
|
|
|
exit:
|
|
/*
|
|
* Don't touch bvec table here and make it really immutable, since
|
|
* fs bio user has to retrieve all pages via bio_for_each_segment_all
|
|
* in its .end_bio() callback.
|
|
*
|
|
* It is enough to truncate bio by updating .bi_size since we can make
|
|
* correct bvec with the updated .bi_size for drivers.
|
|
*/
|
|
bio->bi_iter.bi_size = new_size;
|
|
}
|
|
|
|
/**
|
|
* bio_put - release a reference to a bio
|
|
* @bio: bio to release reference to
|
|
*
|
|
* Description:
|
|
* Put a reference to a &struct bio, either one you have gotten with
|
|
* bio_alloc, bio_get or bio_clone_*. The last put of a bio will free it.
|
|
**/
|
|
void bio_put(struct bio *bio)
|
|
{
|
|
if (!bio_flagged(bio, BIO_REFFED))
|
|
bio_free(bio);
|
|
else {
|
|
BIO_BUG_ON(!atomic_read(&bio->__bi_cnt));
|
|
|
|
/*
|
|
* last put frees it
|
|
*/
|
|
if (atomic_dec_and_test(&bio->__bi_cnt))
|
|
bio_free(bio);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(bio_put);
|
|
|
|
/**
|
|
* __bio_clone_fast - clone a bio that shares the original bio's biovec
|
|
* @bio: destination bio
|
|
* @bio_src: bio to clone
|
|
*
|
|
* Clone a &bio. Caller will own the returned bio, but not
|
|
* the actual data it points to. Reference count of returned
|
|
* bio will be one.
|
|
*
|
|
* Caller must ensure that @bio_src is not freed before @bio.
|
|
*/
|
|
void __bio_clone_fast(struct bio *bio, struct bio *bio_src)
|
|
{
|
|
BUG_ON(bio->bi_pool && BVEC_POOL_IDX(bio));
|
|
|
|
/*
|
|
* most users will be overriding ->bi_disk with a new target,
|
|
* so we don't set nor calculate new physical/hw segment counts here
|
|
*/
|
|
bio->bi_disk = bio_src->bi_disk;
|
|
bio->bi_partno = bio_src->bi_partno;
|
|
bio_set_flag(bio, BIO_CLONED);
|
|
if (bio_flagged(bio_src, BIO_THROTTLED))
|
|
bio_set_flag(bio, BIO_THROTTLED);
|
|
bio->bi_opf = bio_src->bi_opf;
|
|
bio->bi_ioprio = bio_src->bi_ioprio;
|
|
bio->bi_write_hint = bio_src->bi_write_hint;
|
|
bio->bi_iter = bio_src->bi_iter;
|
|
bio->bi_io_vec = bio_src->bi_io_vec;
|
|
|
|
bio_clone_blkg_association(bio, bio_src);
|
|
blkcg_bio_issue_init(bio);
|
|
}
|
|
EXPORT_SYMBOL(__bio_clone_fast);
|
|
|
|
/**
|
|
* bio_clone_fast - clone a bio that shares the original bio's biovec
|
|
* @bio: bio to clone
|
|
* @gfp_mask: allocation priority
|
|
* @bs: bio_set to allocate from
|
|
*
|
|
* Like __bio_clone_fast, only also allocates the returned bio
|
|
*/
|
|
struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
|
|
{
|
|
struct bio *b;
|
|
|
|
b = bio_alloc_bioset(gfp_mask, 0, bs);
|
|
if (!b)
|
|
return NULL;
|
|
|
|
__bio_clone_fast(b, bio);
|
|
|
|
bio_crypt_clone(b, bio, gfp_mask);
|
|
|
|
if (bio_integrity(bio) &&
|
|
bio_integrity_clone(b, bio, gfp_mask) < 0) {
|
|
bio_put(b);
|
|
return NULL;
|
|
}
|
|
|
|
return b;
|
|
}
|
|
EXPORT_SYMBOL(bio_clone_fast);
|
|
|
|
static inline bool page_is_mergeable(const struct bio_vec *bv,
|
|
struct page *page, unsigned int len, unsigned int off,
|
|
bool *same_page)
|
|
{
|
|
size_t bv_end = bv->bv_offset + bv->bv_len;
|
|
phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + bv_end - 1;
|
|
phys_addr_t page_addr = page_to_phys(page);
|
|
|
|
if (vec_end_addr + 1 != page_addr + off)
|
|
return false;
|
|
if (xen_domain() && !xen_biovec_phys_mergeable(bv, page))
|
|
return false;
|
|
|
|
*same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
|
|
if (*same_page)
|
|
return true;
|
|
return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
|
|
}
|
|
|
|
static bool bio_try_merge_pc_page(struct request_queue *q, struct bio *bio,
|
|
struct page *page, unsigned len, unsigned offset,
|
|
bool *same_page)
|
|
{
|
|
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
|
|
unsigned long mask = queue_segment_boundary(q);
|
|
phys_addr_t addr1 = page_to_phys(bv->bv_page) + bv->bv_offset;
|
|
phys_addr_t addr2 = page_to_phys(page) + offset + len - 1;
|
|
|
|
if ((addr1 | mask) != (addr2 | mask))
|
|
return false;
|
|
if (len > queue_max_segment_size(q) - bv->bv_len)
|
|
return false;
|
|
return __bio_try_merge_page(bio, page, len, offset, same_page);
|
|
}
|
|
|
|
/**
|
|
* __bio_add_pc_page - attempt to add page to passthrough bio
|
|
* @q: the target queue
|
|
* @bio: destination bio
|
|
* @page: page to add
|
|
* @len: vec entry length
|
|
* @offset: vec entry offset
|
|
* @same_page: return if the merge happen inside the same page
|
|
*
|
|
* Attempt to add a page to the bio_vec maplist. This can fail for a
|
|
* number of reasons, such as the bio being full or target block device
|
|
* limitations. The target block device must allow bio's up to PAGE_SIZE,
|
|
* so it is always possible to add a single page to an empty bio.
|
|
*
|
|
* This should only be used by passthrough bios.
|
|
*/
|
|
static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
|
|
struct page *page, unsigned int len, unsigned int offset,
|
|
bool *same_page)
|
|
{
|
|
struct bio_vec *bvec;
|
|
|
|
/*
|
|
* cloned bio must not modify vec list
|
|
*/
|
|
if (unlikely(bio_flagged(bio, BIO_CLONED)))
|
|
return 0;
|
|
|
|
if (((bio->bi_iter.bi_size + len) >> 9) > queue_max_hw_sectors(q))
|
|
return 0;
|
|
|
|
if (bio->bi_vcnt > 0) {
|
|
if (bio_try_merge_pc_page(q, bio, page, len, offset, same_page))
|
|
return len;
|
|
|
|
/*
|
|
* If the queue doesn't support SG gaps and adding this segment
|
|
* would create a gap, disallow it.
|
|
*/
|
|
bvec = &bio->bi_io_vec[bio->bi_vcnt - 1];
|
|
if (bvec_gap_to_prev(q, bvec, offset))
|
|
return 0;
|
|
}
|
|
|
|
if (bio_full(bio, len))
|
|
return 0;
|
|
|
|
if (bio->bi_vcnt >= queue_max_segments(q))
|
|
return 0;
|
|
|
|
bvec = &bio->bi_io_vec[bio->bi_vcnt];
|
|
bvec->bv_page = page;
|
|
bvec->bv_len = len;
|
|
bvec->bv_offset = offset;
|
|
bio->bi_vcnt++;
|
|
bio->bi_iter.bi_size += len;
|
|
return len;
|
|
}
|
|
|
|
int bio_add_pc_page(struct request_queue *q, struct bio *bio,
|
|
struct page *page, unsigned int len, unsigned int offset)
|
|
{
|
|
bool same_page = false;
|
|
return __bio_add_pc_page(q, bio, page, len, offset, &same_page);
|
|
}
|
|
EXPORT_SYMBOL(bio_add_pc_page);
|
|
|
|
/**
|
|
* __bio_try_merge_page - try appending data to an existing bvec.
|
|
* @bio: destination bio
|
|
* @page: start page to add
|
|
* @len: length of the data to add
|
|
* @off: offset of the data relative to @page
|
|
* @same_page: return if the segment has been merged inside the same page
|
|
*
|
|
* Try to add the data at @page + @off to the last bvec of @bio. This is a
|
|
* a useful optimisation for file systems with a block size smaller than the
|
|
* page size.
|
|
*
|
|
* Warn if (@len, @off) crosses pages in case that @same_page is true.
|
|
*
|
|
* Return %true on success or %false on failure.
|
|
*/
|
|
bool __bio_try_merge_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int off, bool *same_page)
|
|
{
|
|
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
|
|
return false;
|
|
|
|
if (bio->bi_vcnt > 0) {
|
|
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
|
|
|
|
if (page == bv->bv_page && off == bv->bv_offset + bv->bv_len) {
|
|
*same_page = true;
|
|
bv->bv_len += len;
|
|
bio->bi_iter.bi_size += len;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
EXPORT_SYMBOL_GPL(__bio_try_merge_page);
|
|
|
|
/**
|
|
* __bio_add_page - add page(s) to a bio in a new segment
|
|
* @bio: destination bio
|
|
* @page: start page to add
|
|
* @len: length of the data to add, may cross pages
|
|
* @off: offset of the data relative to @page, may cross pages
|
|
*
|
|
* Add the data at @page + @off to @bio as a new bvec. The caller must ensure
|
|
* that @bio has space for another bvec.
|
|
*/
|
|
void __bio_add_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int off)
|
|
{
|
|
struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt];
|
|
|
|
WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
|
|
WARN_ON_ONCE(bio_full(bio, len));
|
|
|
|
bv->bv_page = page;
|
|
bv->bv_offset = off;
|
|
bv->bv_len = len;
|
|
|
|
bio->bi_iter.bi_size += len;
|
|
bio->bi_vcnt++;
|
|
|
|
if (!bio_flagged(bio, BIO_WORKINGSET) && unlikely(PageWorkingset(page)))
|
|
bio_set_flag(bio, BIO_WORKINGSET);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__bio_add_page);
|
|
|
|
/**
|
|
* bio_add_page - attempt to add page(s) to bio
|
|
* @bio: destination bio
|
|
* @page: start page to add
|
|
* @len: vec entry length, may cross pages
|
|
* @offset: vec entry offset relative to @page, may cross pages
|
|
*
|
|
* Attempt to add page(s) to the bio_vec maplist. This will only fail
|
|
* if either bio->bi_vcnt == bio->bi_max_vecs or it's a cloned bio.
|
|
*/
|
|
int bio_add_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int offset)
|
|
{
|
|
bool same_page = false;
|
|
|
|
if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
|
|
if (bio_full(bio, len))
|
|
return 0;
|
|
__bio_add_page(bio, page, len, offset);
|
|
}
|
|
return len;
|
|
}
|
|
EXPORT_SYMBOL(bio_add_page);
|
|
|
|
void bio_release_pages(struct bio *bio, bool mark_dirty)
|
|
{
|
|
struct bvec_iter_all iter_all;
|
|
struct bio_vec *bvec;
|
|
|
|
if (bio_flagged(bio, BIO_NO_PAGE_REF))
|
|
return;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
if (mark_dirty)
|
|
set_page_dirty_lock(bvec->bv_page);
|
|
put_page(bvec->bv_page);
|
|
}
|
|
}
|
|
|
|
static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter)
|
|
{
|
|
const struct bio_vec *bv = iter->bvec;
|
|
unsigned int len;
|
|
size_t size;
|
|
|
|
if (WARN_ON_ONCE(iter->iov_offset > bv->bv_len))
|
|
return -EINVAL;
|
|
|
|
len = min_t(size_t, bv->bv_len - iter->iov_offset, iter->count);
|
|
size = bio_add_page(bio, bv->bv_page, len,
|
|
bv->bv_offset + iter->iov_offset);
|
|
if (unlikely(size != len))
|
|
return -EINVAL;
|
|
iov_iter_advance(iter, size);
|
|
return 0;
|
|
}
|
|
|
|
#define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *))
|
|
|
|
/**
|
|
* __bio_iov_iter_get_pages - pin user or kernel pages and add them to a bio
|
|
* @bio: bio to add pages to
|
|
* @iter: iov iterator describing the region to be mapped
|
|
*
|
|
* Pins pages from *iter and appends them to @bio's bvec array. The
|
|
* pages will have to be released using put_page() when done.
|
|
* For multi-segment *iter, this function only adds pages from the
|
|
* the next non-empty segment of the iov iterator.
|
|
*/
|
|
static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
|
|
{
|
|
unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt;
|
|
unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
|
|
struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
|
|
struct page **pages = (struct page **)bv;
|
|
bool same_page = false;
|
|
ssize_t size, left;
|
|
unsigned len, i;
|
|
size_t offset;
|
|
|
|
/*
|
|
* Move page array up in the allocated memory for the bio vecs as far as
|
|
* possible so that we can start filling biovecs from the beginning
|
|
* without overwriting the temporary page array.
|
|
*/
|
|
BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
|
|
pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
|
|
|
|
size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset);
|
|
if (unlikely(size <= 0))
|
|
return size ? size : -EFAULT;
|
|
|
|
for (left = size, i = 0; left > 0; left -= len, i++) {
|
|
struct page *page = pages[i];
|
|
|
|
len = min_t(size_t, PAGE_SIZE - offset, left);
|
|
|
|
if (__bio_try_merge_page(bio, page, len, offset, &same_page)) {
|
|
if (same_page)
|
|
put_page(page);
|
|
} else {
|
|
if (WARN_ON_ONCE(bio_full(bio, len)))
|
|
return -EINVAL;
|
|
__bio_add_page(bio, page, len, offset);
|
|
}
|
|
offset = 0;
|
|
}
|
|
|
|
iov_iter_advance(iter, size);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* bio_iov_iter_get_pages - add user or kernel pages to a bio
|
|
* @bio: bio to add pages to
|
|
* @iter: iov iterator describing the region to be added
|
|
*
|
|
* This takes either an iterator pointing to user memory, or one pointing to
|
|
* kernel pages (BVEC iterator). If we're adding user pages, we pin them and
|
|
* map them into the kernel. On IO completion, the caller should put those
|
|
* pages. If we're adding kernel pages, and the caller told us it's safe to
|
|
* do so, we just have to add the pages to the bio directly. We don't grab an
|
|
* extra reference to those pages (the user should already have that), and we
|
|
* don't put the page on IO completion. The caller needs to check if the bio is
|
|
* flagged BIO_NO_PAGE_REF on IO completion. If it isn't, then pages should be
|
|
* released.
|
|
*
|
|
* The function tries, but does not guarantee, to pin as many pages as
|
|
* fit into the bio, or are requested in *iter, whatever is smaller. If
|
|
* MM encounters an error pinning the requested pages, it stops. Error
|
|
* is returned only if 0 pages could be pinned.
|
|
*/
|
|
int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
|
|
{
|
|
const bool is_bvec = iov_iter_is_bvec(iter);
|
|
int ret;
|
|
|
|
if (WARN_ON_ONCE(bio->bi_vcnt))
|
|
return -EINVAL;
|
|
|
|
do {
|
|
if (is_bvec)
|
|
ret = __bio_iov_bvec_add_pages(bio, iter);
|
|
else
|
|
ret = __bio_iov_iter_get_pages(bio, iter);
|
|
} while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
|
|
|
|
if (is_bvec)
|
|
bio_set_flag(bio, BIO_NO_PAGE_REF);
|
|
return bio->bi_vcnt ? 0 : ret;
|
|
}
|
|
|
|
static void submit_bio_wait_endio(struct bio *bio)
|
|
{
|
|
complete(bio->bi_private);
|
|
}
|
|
|
|
/**
|
|
* submit_bio_wait - submit a bio, and wait until it completes
|
|
* @bio: The &struct bio which describes the I/O
|
|
*
|
|
* Simple wrapper around submit_bio(). Returns 0 on success, or the error from
|
|
* bio_endio() on failure.
|
|
*
|
|
* WARNING: Unlike to how submit_bio() is usually used, this function does not
|
|
* result in bio reference to be consumed. The caller must drop the reference
|
|
* on his own.
|
|
*/
|
|
int submit_bio_wait(struct bio *bio)
|
|
{
|
|
DECLARE_COMPLETION_ONSTACK_MAP(done, bio->bi_disk->lockdep_map);
|
|
|
|
bio->bi_private = &done;
|
|
bio->bi_end_io = submit_bio_wait_endio;
|
|
bio->bi_opf |= REQ_SYNC;
|
|
submit_bio(bio);
|
|
wait_for_completion_io(&done);
|
|
|
|
return blk_status_to_errno(bio->bi_status);
|
|
}
|
|
EXPORT_SYMBOL(submit_bio_wait);
|
|
|
|
/**
|
|
* bio_advance - increment/complete a bio by some number of bytes
|
|
* @bio: bio to advance
|
|
* @bytes: number of bytes to complete
|
|
*
|
|
* This updates bi_sector, bi_size and bi_idx; if the number of bytes to
|
|
* complete doesn't align with a bvec boundary, then bv_len and bv_offset will
|
|
* be updated on the last bvec as well.
|
|
*
|
|
* @bio will then represent the remaining, uncompleted portion of the io.
|
|
*/
|
|
void bio_advance(struct bio *bio, unsigned bytes)
|
|
{
|
|
if (bio_integrity(bio))
|
|
bio_integrity_advance(bio, bytes);
|
|
|
|
bio_crypt_advance(bio, bytes);
|
|
bio_advance_iter(bio, &bio->bi_iter, bytes);
|
|
}
|
|
EXPORT_SYMBOL(bio_advance);
|
|
|
|
void bio_copy_data_iter(struct bio *dst, struct bvec_iter *dst_iter,
|
|
struct bio *src, struct bvec_iter *src_iter)
|
|
{
|
|
struct bio_vec src_bv, dst_bv;
|
|
void *src_p, *dst_p;
|
|
unsigned bytes;
|
|
|
|
while (src_iter->bi_size && dst_iter->bi_size) {
|
|
src_bv = bio_iter_iovec(src, *src_iter);
|
|
dst_bv = bio_iter_iovec(dst, *dst_iter);
|
|
|
|
bytes = min(src_bv.bv_len, dst_bv.bv_len);
|
|
|
|
src_p = kmap_atomic(src_bv.bv_page);
|
|
dst_p = kmap_atomic(dst_bv.bv_page);
|
|
|
|
memcpy(dst_p + dst_bv.bv_offset,
|
|
src_p + src_bv.bv_offset,
|
|
bytes);
|
|
|
|
kunmap_atomic(dst_p);
|
|
kunmap_atomic(src_p);
|
|
|
|
flush_dcache_page(dst_bv.bv_page);
|
|
|
|
bio_advance_iter(src, src_iter, bytes);
|
|
bio_advance_iter(dst, dst_iter, bytes);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(bio_copy_data_iter);
|
|
|
|
/**
|
|
* bio_copy_data - copy contents of data buffers from one bio to another
|
|
* @src: source bio
|
|
* @dst: destination bio
|
|
*
|
|
* Stops when it reaches the end of either @src or @dst - that is, copies
|
|
* min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of bios).
|
|
*/
|
|
void bio_copy_data(struct bio *dst, struct bio *src)
|
|
{
|
|
struct bvec_iter src_iter = src->bi_iter;
|
|
struct bvec_iter dst_iter = dst->bi_iter;
|
|
|
|
bio_copy_data_iter(dst, &dst_iter, src, &src_iter);
|
|
}
|
|
EXPORT_SYMBOL(bio_copy_data);
|
|
|
|
/**
|
|
* bio_list_copy_data - copy contents of data buffers from one chain of bios to
|
|
* another
|
|
* @src: source bio list
|
|
* @dst: destination bio list
|
|
*
|
|
* Stops when it reaches the end of either the @src list or @dst list - that is,
|
|
* copies min(src->bi_size, dst->bi_size) bytes (or the equivalent for lists of
|
|
* bios).
|
|
*/
|
|
void bio_list_copy_data(struct bio *dst, struct bio *src)
|
|
{
|
|
struct bvec_iter src_iter = src->bi_iter;
|
|
struct bvec_iter dst_iter = dst->bi_iter;
|
|
|
|
while (1) {
|
|
if (!src_iter.bi_size) {
|
|
src = src->bi_next;
|
|
if (!src)
|
|
break;
|
|
|
|
src_iter = src->bi_iter;
|
|
}
|
|
|
|
if (!dst_iter.bi_size) {
|
|
dst = dst->bi_next;
|
|
if (!dst)
|
|
break;
|
|
|
|
dst_iter = dst->bi_iter;
|
|
}
|
|
|
|
bio_copy_data_iter(dst, &dst_iter, src, &src_iter);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(bio_list_copy_data);
|
|
|
|
struct bio_map_data {
|
|
int is_our_pages;
|
|
struct iov_iter iter;
|
|
struct iovec iov[];
|
|
};
|
|
|
|
static struct bio_map_data *bio_alloc_map_data(struct iov_iter *data,
|
|
gfp_t gfp_mask)
|
|
{
|
|
struct bio_map_data *bmd;
|
|
if (data->nr_segs > UIO_MAXIOV)
|
|
return NULL;
|
|
|
|
bmd = kmalloc(struct_size(bmd, iov, data->nr_segs), gfp_mask);
|
|
if (!bmd)
|
|
return NULL;
|
|
memcpy(bmd->iov, data->iov, sizeof(struct iovec) * data->nr_segs);
|
|
bmd->iter = *data;
|
|
bmd->iter.iov = bmd->iov;
|
|
return bmd;
|
|
}
|
|
|
|
/**
|
|
* bio_copy_from_iter - copy all pages from iov_iter to bio
|
|
* @bio: The &struct bio which describes the I/O as destination
|
|
* @iter: iov_iter as source
|
|
*
|
|
* Copy all pages from iov_iter to bio.
|
|
* Returns 0 on success, or error on failure.
|
|
*/
|
|
static int bio_copy_from_iter(struct bio *bio, struct iov_iter *iter)
|
|
{
|
|
struct bio_vec *bvec;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
ssize_t ret;
|
|
|
|
ret = copy_page_from_iter(bvec->bv_page,
|
|
bvec->bv_offset,
|
|
bvec->bv_len,
|
|
iter);
|
|
|
|
if (!iov_iter_count(iter))
|
|
break;
|
|
|
|
if (ret < bvec->bv_len)
|
|
return -EFAULT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* bio_copy_to_iter - copy all pages from bio to iov_iter
|
|
* @bio: The &struct bio which describes the I/O as source
|
|
* @iter: iov_iter as destination
|
|
*
|
|
* Copy all pages from bio to iov_iter.
|
|
* Returns 0 on success, or error on failure.
|
|
*/
|
|
static int bio_copy_to_iter(struct bio *bio, struct iov_iter iter)
|
|
{
|
|
struct bio_vec *bvec;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
ssize_t ret;
|
|
|
|
ret = copy_page_to_iter(bvec->bv_page,
|
|
bvec->bv_offset,
|
|
bvec->bv_len,
|
|
&iter);
|
|
|
|
if (!iov_iter_count(&iter))
|
|
break;
|
|
|
|
if (ret < bvec->bv_len)
|
|
return -EFAULT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void bio_free_pages(struct bio *bio)
|
|
{
|
|
struct bio_vec *bvec;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all)
|
|
__free_page(bvec->bv_page);
|
|
}
|
|
EXPORT_SYMBOL(bio_free_pages);
|
|
|
|
/**
|
|
* bio_uncopy_user - finish previously mapped bio
|
|
* @bio: bio being terminated
|
|
*
|
|
* Free pages allocated from bio_copy_user_iov() and write back data
|
|
* to user space in case of a read.
|
|
*/
|
|
int bio_uncopy_user(struct bio *bio)
|
|
{
|
|
struct bio_map_data *bmd = bio->bi_private;
|
|
int ret = 0;
|
|
|
|
if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
|
|
/*
|
|
* if we're in a workqueue, the request is orphaned, so
|
|
* don't copy into a random user address space, just free
|
|
* and return -EINTR so user space doesn't expect any data.
|
|
*/
|
|
if (!current->mm)
|
|
ret = -EINTR;
|
|
else if (bio_data_dir(bio) == READ)
|
|
ret = bio_copy_to_iter(bio, bmd->iter);
|
|
if (bmd->is_our_pages)
|
|
bio_free_pages(bio);
|
|
}
|
|
kfree(bmd);
|
|
bio_put(bio);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* bio_copy_user_iov - copy user data to bio
|
|
* @q: destination block queue
|
|
* @map_data: pointer to the rq_map_data holding pages (if necessary)
|
|
* @iter: iovec iterator
|
|
* @gfp_mask: memory allocation flags
|
|
*
|
|
* Prepares and returns a bio for indirect user io, bouncing data
|
|
* to/from kernel pages as necessary. Must be paired with
|
|
* call bio_uncopy_user() on io completion.
|
|
*/
|
|
struct bio *bio_copy_user_iov(struct request_queue *q,
|
|
struct rq_map_data *map_data,
|
|
struct iov_iter *iter,
|
|
gfp_t gfp_mask)
|
|
{
|
|
struct bio_map_data *bmd;
|
|
struct page *page;
|
|
struct bio *bio;
|
|
int i = 0, ret;
|
|
int nr_pages;
|
|
unsigned int len = iter->count;
|
|
unsigned int offset = map_data ? offset_in_page(map_data->offset) : 0;
|
|
|
|
bmd = bio_alloc_map_data(iter, gfp_mask);
|
|
if (!bmd)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
/*
|
|
* We need to do a deep copy of the iov_iter including the iovecs.
|
|
* The caller provided iov might point to an on-stack or otherwise
|
|
* shortlived one.
|
|
*/
|
|
bmd->is_our_pages = map_data ? 0 : 1;
|
|
|
|
nr_pages = DIV_ROUND_UP(offset + len, PAGE_SIZE);
|
|
if (nr_pages > BIO_MAX_PAGES)
|
|
nr_pages = BIO_MAX_PAGES;
|
|
|
|
ret = -ENOMEM;
|
|
bio = bio_kmalloc(gfp_mask, nr_pages);
|
|
if (!bio)
|
|
goto out_bmd;
|
|
|
|
ret = 0;
|
|
|
|
if (map_data) {
|
|
nr_pages = 1 << map_data->page_order;
|
|
i = map_data->offset / PAGE_SIZE;
|
|
}
|
|
while (len) {
|
|
unsigned int bytes = PAGE_SIZE;
|
|
|
|
bytes -= offset;
|
|
|
|
if (bytes > len)
|
|
bytes = len;
|
|
|
|
if (map_data) {
|
|
if (i == map_data->nr_entries * nr_pages) {
|
|
ret = -ENOMEM;
|
|
break;
|
|
}
|
|
|
|
page = map_data->pages[i / nr_pages];
|
|
page += (i % nr_pages);
|
|
|
|
i++;
|
|
} else {
|
|
page = alloc_page(q->bounce_gfp | gfp_mask);
|
|
if (!page) {
|
|
ret = -ENOMEM;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bio_add_pc_page(q, bio, page, bytes, offset) < bytes) {
|
|
if (!map_data)
|
|
__free_page(page);
|
|
break;
|
|
}
|
|
|
|
len -= bytes;
|
|
offset = 0;
|
|
}
|
|
|
|
if (ret)
|
|
goto cleanup;
|
|
|
|
if (map_data)
|
|
map_data->offset += bio->bi_iter.bi_size;
|
|
|
|
/*
|
|
* success
|
|
*/
|
|
if ((iov_iter_rw(iter) == WRITE && (!map_data || !map_data->null_mapped)) ||
|
|
(map_data && map_data->from_user)) {
|
|
ret = bio_copy_from_iter(bio, iter);
|
|
if (ret)
|
|
goto cleanup;
|
|
} else {
|
|
if (bmd->is_our_pages)
|
|
zero_fill_bio(bio);
|
|
iov_iter_advance(iter, bio->bi_iter.bi_size);
|
|
}
|
|
|
|
bio->bi_private = bmd;
|
|
if (map_data && map_data->null_mapped)
|
|
bio_set_flag(bio, BIO_NULL_MAPPED);
|
|
return bio;
|
|
cleanup:
|
|
if (!map_data)
|
|
bio_free_pages(bio);
|
|
bio_put(bio);
|
|
out_bmd:
|
|
kfree(bmd);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
/**
|
|
* bio_map_user_iov - map user iovec into bio
|
|
* @q: the struct request_queue for the bio
|
|
* @iter: iovec iterator
|
|
* @gfp_mask: memory allocation flags
|
|
*
|
|
* Map the user space address into a bio suitable for io to a block
|
|
* device. Returns an error pointer in case of error.
|
|
*/
|
|
struct bio *bio_map_user_iov(struct request_queue *q,
|
|
struct iov_iter *iter,
|
|
gfp_t gfp_mask)
|
|
{
|
|
int j;
|
|
struct bio *bio;
|
|
int ret;
|
|
|
|
if (!iov_iter_count(iter))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_PAGES));
|
|
if (!bio)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
while (iov_iter_count(iter)) {
|
|
struct page **pages;
|
|
ssize_t bytes;
|
|
size_t offs, added = 0;
|
|
int npages;
|
|
|
|
bytes = iov_iter_get_pages_alloc(iter, &pages, LONG_MAX, &offs);
|
|
if (unlikely(bytes <= 0)) {
|
|
ret = bytes ? bytes : -EFAULT;
|
|
goto out_unmap;
|
|
}
|
|
|
|
npages = DIV_ROUND_UP(offs + bytes, PAGE_SIZE);
|
|
|
|
if (unlikely(offs & queue_dma_alignment(q))) {
|
|
ret = -EINVAL;
|
|
j = 0;
|
|
} else {
|
|
for (j = 0; j < npages; j++) {
|
|
struct page *page = pages[j];
|
|
unsigned int n = PAGE_SIZE - offs;
|
|
bool same_page = false;
|
|
|
|
if (n > bytes)
|
|
n = bytes;
|
|
|
|
if (!__bio_add_pc_page(q, bio, page, n, offs,
|
|
&same_page)) {
|
|
if (same_page)
|
|
put_page(page);
|
|
break;
|
|
}
|
|
|
|
added += n;
|
|
bytes -= n;
|
|
offs = 0;
|
|
}
|
|
iov_iter_advance(iter, added);
|
|
}
|
|
/*
|
|
* release the pages we didn't map into the bio, if any
|
|
*/
|
|
while (j < npages)
|
|
put_page(pages[j++]);
|
|
kvfree(pages);
|
|
/* couldn't stuff something into bio? */
|
|
if (bytes)
|
|
break;
|
|
}
|
|
|
|
bio_set_flag(bio, BIO_USER_MAPPED);
|
|
|
|
/*
|
|
* subtle -- if bio_map_user_iov() ended up bouncing a bio,
|
|
* it would normally disappear when its bi_end_io is run.
|
|
* however, we need it for the unmap, so grab an extra
|
|
* reference to it
|
|
*/
|
|
bio_get(bio);
|
|
return bio;
|
|
|
|
out_unmap:
|
|
bio_release_pages(bio, false);
|
|
bio_put(bio);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
/**
|
|
* bio_unmap_user - unmap a bio
|
|
* @bio: the bio being unmapped
|
|
*
|
|
* Unmap a bio previously mapped by bio_map_user_iov(). Must be called from
|
|
* process context.
|
|
*
|
|
* bio_unmap_user() may sleep.
|
|
*/
|
|
void bio_unmap_user(struct bio *bio)
|
|
{
|
|
bio_release_pages(bio, bio_data_dir(bio) == READ);
|
|
bio_put(bio);
|
|
bio_put(bio);
|
|
}
|
|
|
|
static void bio_invalidate_vmalloc_pages(struct bio *bio)
|
|
{
|
|
#ifdef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
|
|
if (bio->bi_private && !op_is_write(bio_op(bio))) {
|
|
unsigned long i, len = 0;
|
|
|
|
for (i = 0; i < bio->bi_vcnt; i++)
|
|
len += bio->bi_io_vec[i].bv_len;
|
|
invalidate_kernel_vmap_range(bio->bi_private, len);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void bio_map_kern_endio(struct bio *bio)
|
|
{
|
|
bio_invalidate_vmalloc_pages(bio);
|
|
bio_put(bio);
|
|
}
|
|
|
|
/**
|
|
* bio_map_kern - map kernel address into bio
|
|
* @q: the struct request_queue for the bio
|
|
* @data: pointer to buffer to map
|
|
* @len: length in bytes
|
|
* @gfp_mask: allocation flags for bio allocation
|
|
*
|
|
* Map the kernel address into a bio suitable for io to a block
|
|
* device. Returns an error pointer in case of error.
|
|
*/
|
|
struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
|
|
gfp_t gfp_mask)
|
|
{
|
|
unsigned long kaddr = (unsigned long)data;
|
|
unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
unsigned long start = kaddr >> PAGE_SHIFT;
|
|
const int nr_pages = end - start;
|
|
bool is_vmalloc = is_vmalloc_addr(data);
|
|
struct page *page;
|
|
int offset, i;
|
|
struct bio *bio;
|
|
|
|
bio = bio_kmalloc(gfp_mask, nr_pages);
|
|
if (!bio)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
if (is_vmalloc) {
|
|
flush_kernel_vmap_range(data, len);
|
|
bio->bi_private = data;
|
|
}
|
|
|
|
offset = offset_in_page(kaddr);
|
|
for (i = 0; i < nr_pages; i++) {
|
|
unsigned int bytes = PAGE_SIZE - offset;
|
|
|
|
if (len <= 0)
|
|
break;
|
|
|
|
if (bytes > len)
|
|
bytes = len;
|
|
|
|
if (!is_vmalloc)
|
|
page = virt_to_page(data);
|
|
else
|
|
page = vmalloc_to_page(data);
|
|
if (bio_add_pc_page(q, bio, page, bytes,
|
|
offset) < bytes) {
|
|
/* we don't support partial mappings */
|
|
bio_put(bio);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
|
|
data += bytes;
|
|
len -= bytes;
|
|
offset = 0;
|
|
}
|
|
|
|
bio->bi_end_io = bio_map_kern_endio;
|
|
return bio;
|
|
}
|
|
|
|
static void bio_copy_kern_endio(struct bio *bio)
|
|
{
|
|
bio_free_pages(bio);
|
|
bio_put(bio);
|
|
}
|
|
|
|
static void bio_copy_kern_endio_read(struct bio *bio)
|
|
{
|
|
char *p = bio->bi_private;
|
|
struct bio_vec *bvec;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
memcpy(p, page_address(bvec->bv_page), bvec->bv_len);
|
|
p += bvec->bv_len;
|
|
}
|
|
|
|
bio_copy_kern_endio(bio);
|
|
}
|
|
|
|
/**
|
|
* bio_copy_kern - copy kernel address into bio
|
|
* @q: the struct request_queue for the bio
|
|
* @data: pointer to buffer to copy
|
|
* @len: length in bytes
|
|
* @gfp_mask: allocation flags for bio and page allocation
|
|
* @reading: data direction is READ
|
|
*
|
|
* copy the kernel address into a bio suitable for io to a block
|
|
* device. Returns an error pointer in case of error.
|
|
*/
|
|
struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
|
|
gfp_t gfp_mask, int reading)
|
|
{
|
|
unsigned long kaddr = (unsigned long)data;
|
|
unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
unsigned long start = kaddr >> PAGE_SHIFT;
|
|
struct bio *bio;
|
|
void *p = data;
|
|
int nr_pages = 0;
|
|
|
|
/*
|
|
* Overflow, abort
|
|
*/
|
|
if (end < start)
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
nr_pages = end - start;
|
|
bio = bio_kmalloc(gfp_mask, nr_pages);
|
|
if (!bio)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
while (len) {
|
|
struct page *page;
|
|
unsigned int bytes = PAGE_SIZE;
|
|
|
|
if (bytes > len)
|
|
bytes = len;
|
|
|
|
page = alloc_page(q->bounce_gfp | __GFP_ZERO | gfp_mask);
|
|
if (!page)
|
|
goto cleanup;
|
|
|
|
if (!reading)
|
|
memcpy(page_address(page), p, bytes);
|
|
|
|
if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes)
|
|
break;
|
|
|
|
len -= bytes;
|
|
p += bytes;
|
|
}
|
|
|
|
if (reading) {
|
|
bio->bi_end_io = bio_copy_kern_endio_read;
|
|
bio->bi_private = data;
|
|
} else {
|
|
bio->bi_end_io = bio_copy_kern_endio;
|
|
}
|
|
|
|
return bio;
|
|
|
|
cleanup:
|
|
bio_free_pages(bio);
|
|
bio_put(bio);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
|
|
/*
|
|
* bio_set_pages_dirty() and bio_check_pages_dirty() are support functions
|
|
* for performing direct-IO in BIOs.
|
|
*
|
|
* The problem is that we cannot run set_page_dirty() from interrupt context
|
|
* because the required locks are not interrupt-safe. So what we can do is to
|
|
* mark the pages dirty _before_ performing IO. And in interrupt context,
|
|
* check that the pages are still dirty. If so, fine. If not, redirty them
|
|
* in process context.
|
|
*
|
|
* We special-case compound pages here: normally this means reads into hugetlb
|
|
* pages. The logic in here doesn't really work right for compound pages
|
|
* because the VM does not uniformly chase down the head page in all cases.
|
|
* But dirtiness of compound pages is pretty meaningless anyway: the VM doesn't
|
|
* handle them at all. So we skip compound pages here at an early stage.
|
|
*
|
|
* Note that this code is very hard to test under normal circumstances because
|
|
* direct-io pins the pages with get_user_pages(). This makes
|
|
* is_page_cache_freeable return false, and the VM will not clean the pages.
|
|
* But other code (eg, flusher threads) could clean the pages if they are mapped
|
|
* pagecache.
|
|
*
|
|
* Simply disabling the call to bio_set_pages_dirty() is a good way to test the
|
|
* deferred bio dirtying paths.
|
|
*/
|
|
|
|
/*
|
|
* bio_set_pages_dirty() will mark all the bio's pages as dirty.
|
|
*/
|
|
void bio_set_pages_dirty(struct bio *bio)
|
|
{
|
|
struct bio_vec *bvec;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
set_page_dirty_lock(bvec->bv_page);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* bio_check_pages_dirty() will check that all the BIO's pages are still dirty.
|
|
* If they are, then fine. If, however, some pages are clean then they must
|
|
* have been written out during the direct-IO read. So we take another ref on
|
|
* the BIO and re-dirty the pages in process context.
|
|
*
|
|
* It is expected that bio_check_pages_dirty() will wholly own the BIO from
|
|
* here on. It will run one put_page() against each page and will run one
|
|
* bio_put() against the BIO.
|
|
*/
|
|
|
|
static void bio_dirty_fn(struct work_struct *work);
|
|
|
|
static DECLARE_WORK(bio_dirty_work, bio_dirty_fn);
|
|
static DEFINE_SPINLOCK(bio_dirty_lock);
|
|
static struct bio *bio_dirty_list;
|
|
|
|
/*
|
|
* This runs in process context
|
|
*/
|
|
static void bio_dirty_fn(struct work_struct *work)
|
|
{
|
|
struct bio *bio, *next;
|
|
|
|
spin_lock_irq(&bio_dirty_lock);
|
|
next = bio_dirty_list;
|
|
bio_dirty_list = NULL;
|
|
spin_unlock_irq(&bio_dirty_lock);
|
|
|
|
while ((bio = next) != NULL) {
|
|
next = bio->bi_private;
|
|
|
|
bio_release_pages(bio, true);
|
|
bio_put(bio);
|
|
}
|
|
}
|
|
|
|
void bio_check_pages_dirty(struct bio *bio)
|
|
{
|
|
struct bio_vec *bvec;
|
|
unsigned long flags;
|
|
struct bvec_iter_all iter_all;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
if (!PageDirty(bvec->bv_page))
|
|
goto defer;
|
|
}
|
|
|
|
bio_release_pages(bio, false);
|
|
bio_put(bio);
|
|
return;
|
|
defer:
|
|
spin_lock_irqsave(&bio_dirty_lock, flags);
|
|
bio->bi_private = bio_dirty_list;
|
|
bio_dirty_list = bio;
|
|
spin_unlock_irqrestore(&bio_dirty_lock, flags);
|
|
schedule_work(&bio_dirty_work);
|
|
}
|
|
|
|
void update_io_ticks(struct hd_struct *part, unsigned long now, bool end)
|
|
{
|
|
unsigned long stamp;
|
|
again:
|
|
stamp = READ_ONCE(part->stamp);
|
|
if (unlikely(stamp != now)) {
|
|
if (likely(cmpxchg(&part->stamp, stamp, now) == stamp)) {
|
|
__part_stat_add(part, io_ticks, end ? now - stamp : 1);
|
|
}
|
|
}
|
|
if (part->partno) {
|
|
part = &part_to_disk(part)->part0;
|
|
goto again;
|
|
}
|
|
}
|
|
|
|
void generic_start_io_acct(struct request_queue *q, int op,
|
|
unsigned long sectors, struct hd_struct *part)
|
|
{
|
|
const int sgrp = op_stat_group(op);
|
|
|
|
part_stat_lock();
|
|
|
|
update_io_ticks(part, jiffies, false);
|
|
part_stat_inc(part, ios[sgrp]);
|
|
part_stat_add(part, sectors[sgrp], sectors);
|
|
part_inc_in_flight(q, part, op_is_write(op));
|
|
|
|
part_stat_unlock();
|
|
}
|
|
EXPORT_SYMBOL(generic_start_io_acct);
|
|
|
|
void generic_end_io_acct(struct request_queue *q, int req_op,
|
|
struct hd_struct *part, unsigned long start_time)
|
|
{
|
|
unsigned long now = jiffies;
|
|
unsigned long duration = now - start_time;
|
|
const int sgrp = op_stat_group(req_op);
|
|
|
|
part_stat_lock();
|
|
|
|
update_io_ticks(part, now, true);
|
|
part_stat_add(part, nsecs[sgrp], jiffies_to_nsecs(duration));
|
|
part_stat_add(part, time_in_queue, duration);
|
|
part_dec_in_flight(q, part, op_is_write(req_op));
|
|
|
|
part_stat_unlock();
|
|
}
|
|
EXPORT_SYMBOL(generic_end_io_acct);
|
|
|
|
static inline bool bio_remaining_done(struct bio *bio)
|
|
{
|
|
/*
|
|
* If we're not chaining, then ->__bi_remaining is always 1 and
|
|
* we always end io on the first invocation.
|
|
*/
|
|
if (!bio_flagged(bio, BIO_CHAIN))
|
|
return true;
|
|
|
|
BUG_ON(atomic_read(&bio->__bi_remaining) <= 0);
|
|
|
|
if (atomic_dec_and_test(&bio->__bi_remaining)) {
|
|
bio_clear_flag(bio, BIO_CHAIN);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* bio_endio - end I/O on a bio
|
|
* @bio: bio
|
|
*
|
|
* Description:
|
|
* bio_endio() will end I/O on the whole bio. bio_endio() is the preferred
|
|
* way to end I/O on a bio. No one should call bi_end_io() directly on a
|
|
* bio unless they own it and thus know that it has an end_io function.
|
|
*
|
|
* bio_endio() can be called several times on a bio that has been chained
|
|
* using bio_chain(). The ->bi_end_io() function will only be called the
|
|
* last time. At this point the BLK_TA_COMPLETE tracing event will be
|
|
* generated if BIO_TRACE_COMPLETION is set.
|
|
**/
|
|
void bio_endio(struct bio *bio)
|
|
{
|
|
again:
|
|
if (!bio_remaining_done(bio))
|
|
return;
|
|
|
|
if (!blk_crypto_endio(bio))
|
|
return;
|
|
|
|
if (!bio_integrity_endio(bio))
|
|
return;
|
|
|
|
if (bio->bi_disk)
|
|
rq_qos_done_bio(bio->bi_disk->queue, bio);
|
|
|
|
/*
|
|
* Need to have a real endio function for chained bios, otherwise
|
|
* various corner cases will break (like stacking block devices that
|
|
* save/restore bi_end_io) - however, we want to avoid unbounded
|
|
* recursion and blowing the stack. Tail call optimization would
|
|
* handle this, but compiling with frame pointers also disables
|
|
* gcc's sibling call optimization.
|
|
*/
|
|
if (bio->bi_end_io == bio_chain_endio) {
|
|
bio = __bio_chain_endio(bio);
|
|
goto again;
|
|
}
|
|
|
|
if (bio->bi_disk && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
|
trace_block_bio_complete(bio->bi_disk->queue, bio,
|
|
blk_status_to_errno(bio->bi_status));
|
|
bio_clear_flag(bio, BIO_TRACE_COMPLETION);
|
|
}
|
|
|
|
blk_throtl_bio_endio(bio);
|
|
/* release cgroup info */
|
|
bio_uninit(bio);
|
|
if (bio->bi_end_io)
|
|
bio->bi_end_io(bio);
|
|
}
|
|
EXPORT_SYMBOL(bio_endio);
|
|
|
|
/**
|
|
* bio_split - split a bio
|
|
* @bio: bio to split
|
|
* @sectors: number of sectors to split from the front of @bio
|
|
* @gfp: gfp mask
|
|
* @bs: bio set to allocate from
|
|
*
|
|
* Allocates and returns a new bio which represents @sectors from the start of
|
|
* @bio, and updates @bio to represent the remaining sectors.
|
|
*
|
|
* Unless this is a discard request the newly allocated bio will point
|
|
* to @bio's bi_io_vec. It is the caller's responsibility to ensure that
|
|
* neither @bio nor @bs are freed before the split bio.
|
|
*/
|
|
struct bio *bio_split(struct bio *bio, int sectors,
|
|
gfp_t gfp, struct bio_set *bs)
|
|
{
|
|
struct bio *split;
|
|
|
|
BUG_ON(sectors <= 0);
|
|
BUG_ON(sectors >= bio_sectors(bio));
|
|
|
|
split = bio_clone_fast(bio, gfp, bs);
|
|
if (!split)
|
|
return NULL;
|
|
|
|
split->bi_iter.bi_size = sectors << 9;
|
|
|
|
if (bio_integrity(split))
|
|
bio_integrity_trim(split);
|
|
|
|
bio_advance(bio, split->bi_iter.bi_size);
|
|
|
|
if (bio_flagged(bio, BIO_TRACE_COMPLETION))
|
|
bio_set_flag(split, BIO_TRACE_COMPLETION);
|
|
|
|
return split;
|
|
}
|
|
EXPORT_SYMBOL(bio_split);
|
|
|
|
/**
|
|
* bio_trim - trim a bio
|
|
* @bio: bio to trim
|
|
* @offset: number of sectors to trim from the front of @bio
|
|
* @size: size we want to trim @bio to, in sectors
|
|
*/
|
|
void bio_trim(struct bio *bio, int offset, int size)
|
|
{
|
|
/* 'bio' is a cloned bio which we need to trim to match
|
|
* the given offset and size.
|
|
*/
|
|
|
|
size <<= 9;
|
|
if (offset == 0 && size == bio->bi_iter.bi_size)
|
|
return;
|
|
|
|
bio_advance(bio, offset << 9);
|
|
bio->bi_iter.bi_size = size;
|
|
|
|
if (bio_integrity(bio))
|
|
bio_integrity_trim(bio);
|
|
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_trim);
|
|
|
|
/*
|
|
* create memory pools for biovec's in a bio_set.
|
|
* use the global biovec slabs created for general use.
|
|
*/
|
|
int biovec_init_pool(mempool_t *pool, int pool_entries)
|
|
{
|
|
struct biovec_slab *bp = bvec_slabs + BVEC_POOL_MAX;
|
|
|
|
return mempool_init_slab_pool(pool, pool_entries, bp->slab);
|
|
}
|
|
|
|
/*
|
|
* bioset_exit - exit a bioset initialized with bioset_init()
|
|
*
|
|
* May be called on a zeroed but uninitialized bioset (i.e. allocated with
|
|
* kzalloc()).
|
|
*/
|
|
void bioset_exit(struct bio_set *bs)
|
|
{
|
|
if (bs->rescue_workqueue)
|
|
destroy_workqueue(bs->rescue_workqueue);
|
|
bs->rescue_workqueue = NULL;
|
|
|
|
mempool_exit(&bs->bio_pool);
|
|
mempool_exit(&bs->bvec_pool);
|
|
|
|
bioset_integrity_free(bs);
|
|
if (bs->bio_slab)
|
|
bio_put_slab(bs);
|
|
bs->bio_slab = NULL;
|
|
}
|
|
EXPORT_SYMBOL(bioset_exit);
|
|
|
|
/**
|
|
* bioset_init - Initialize a bio_set
|
|
* @bs: pool to initialize
|
|
* @pool_size: Number of bio and bio_vecs to cache in the mempool
|
|
* @front_pad: Number of bytes to allocate in front of the returned bio
|
|
* @flags: Flags to modify behavior, currently %BIOSET_NEED_BVECS
|
|
* and %BIOSET_NEED_RESCUER
|
|
*
|
|
* Description:
|
|
* Set up a bio_set to be used with @bio_alloc_bioset. Allows the caller
|
|
* to ask for a number of bytes to be allocated in front of the bio.
|
|
* Front pad allocation is useful for embedding the bio inside
|
|
* another structure, to avoid allocating extra data to go with the bio.
|
|
* Note that the bio must be embedded at the END of that structure always,
|
|
* or things will break badly.
|
|
* If %BIOSET_NEED_BVECS is set in @flags, a separate pool will be allocated
|
|
* for allocating iovecs. This pool is not needed e.g. for bio_clone_fast().
|
|
* If %BIOSET_NEED_RESCUER is set, a workqueue is created which can be used to
|
|
* dispatch queued requests when the mempool runs out of space.
|
|
*
|
|
*/
|
|
int bioset_init(struct bio_set *bs,
|
|
unsigned int pool_size,
|
|
unsigned int front_pad,
|
|
int flags)
|
|
{
|
|
unsigned int back_pad = BIO_INLINE_VECS * sizeof(struct bio_vec);
|
|
|
|
bs->front_pad = front_pad;
|
|
|
|
spin_lock_init(&bs->rescue_lock);
|
|
bio_list_init(&bs->rescue_list);
|
|
INIT_WORK(&bs->rescue_work, bio_alloc_rescue);
|
|
|
|
bs->bio_slab = bio_find_or_create_slab(front_pad + back_pad);
|
|
if (!bs->bio_slab)
|
|
return -ENOMEM;
|
|
|
|
if (mempool_init_slab_pool(&bs->bio_pool, pool_size, bs->bio_slab))
|
|
goto bad;
|
|
|
|
if ((flags & BIOSET_NEED_BVECS) &&
|
|
biovec_init_pool(&bs->bvec_pool, pool_size))
|
|
goto bad;
|
|
|
|
if (!(flags & BIOSET_NEED_RESCUER))
|
|
return 0;
|
|
|
|
bs->rescue_workqueue = alloc_workqueue("bioset", WQ_MEM_RECLAIM, 0);
|
|
if (!bs->rescue_workqueue)
|
|
goto bad;
|
|
|
|
return 0;
|
|
bad:
|
|
bioset_exit(bs);
|
|
return -ENOMEM;
|
|
}
|
|
EXPORT_SYMBOL(bioset_init);
|
|
|
|
/*
|
|
* Initialize and setup a new bio_set, based on the settings from
|
|
* another bio_set.
|
|
*/
|
|
int bioset_init_from_src(struct bio_set *bs, struct bio_set *src)
|
|
{
|
|
int flags;
|
|
|
|
flags = 0;
|
|
if (src->bvec_pool.min_nr)
|
|
flags |= BIOSET_NEED_BVECS;
|
|
if (src->rescue_workqueue)
|
|
flags |= BIOSET_NEED_RESCUER;
|
|
|
|
return bioset_init(bs, src->bio_pool.min_nr, src->front_pad, flags);
|
|
}
|
|
EXPORT_SYMBOL(bioset_init_from_src);
|
|
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
|
|
/**
|
|
* bio_disassociate_blkg - puts back the blkg reference if associated
|
|
* @bio: target bio
|
|
*
|
|
* Helper to disassociate the blkg from @bio if a blkg is associated.
|
|
*/
|
|
void bio_disassociate_blkg(struct bio *bio)
|
|
{
|
|
if (bio->bi_blkg) {
|
|
blkg_put(bio->bi_blkg);
|
|
bio->bi_blkg = NULL;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_disassociate_blkg);
|
|
|
|
/**
|
|
* __bio_associate_blkg - associate a bio with the a blkg
|
|
* @bio: target bio
|
|
* @blkg: the blkg to associate
|
|
*
|
|
* This tries to associate @bio with the specified @blkg. Association failure
|
|
* is handled by walking up the blkg tree. Therefore, the blkg associated can
|
|
* be anything between @blkg and the root_blkg. This situation only happens
|
|
* when a cgroup is dying and then the remaining bios will spill to the closest
|
|
* alive blkg.
|
|
*
|
|
* A reference will be taken on the @blkg and will be released when @bio is
|
|
* freed.
|
|
*/
|
|
static void __bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
|
|
{
|
|
bio_disassociate_blkg(bio);
|
|
|
|
bio->bi_blkg = blkg_tryget_closest(blkg);
|
|
}
|
|
|
|
/**
|
|
* bio_associate_blkg_from_css - associate a bio with a specified css
|
|
* @bio: target bio
|
|
* @css: target css
|
|
*
|
|
* Associate @bio with the blkg found by combining the css's blkg and the
|
|
* request_queue of the @bio. This falls back to the queue's root_blkg if
|
|
* the association fails with the css.
|
|
*/
|
|
void bio_associate_blkg_from_css(struct bio *bio,
|
|
struct cgroup_subsys_state *css)
|
|
{
|
|
struct request_queue *q = bio->bi_disk->queue;
|
|
struct blkcg_gq *blkg;
|
|
|
|
rcu_read_lock();
|
|
|
|
if (!css || !css->parent)
|
|
blkg = q->root_blkg;
|
|
else
|
|
blkg = blkg_lookup_create(css_to_blkcg(css), q);
|
|
|
|
__bio_associate_blkg(bio, blkg);
|
|
|
|
rcu_read_unlock();
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_associate_blkg_from_css);
|
|
|
|
#ifdef CONFIG_MEMCG
|
|
/**
|
|
* bio_associate_blkg_from_page - associate a bio with the page's blkg
|
|
* @bio: target bio
|
|
* @page: the page to lookup the blkcg from
|
|
*
|
|
* Associate @bio with the blkg from @page's owning memcg and the respective
|
|
* request_queue. If cgroup_e_css returns %NULL, fall back to the queue's
|
|
* root_blkg.
|
|
*/
|
|
void bio_associate_blkg_from_page(struct bio *bio, struct page *page)
|
|
{
|
|
struct cgroup_subsys_state *css;
|
|
|
|
if (!page->mem_cgroup)
|
|
return;
|
|
|
|
rcu_read_lock();
|
|
|
|
css = cgroup_e_css(page->mem_cgroup->css.cgroup, &io_cgrp_subsys);
|
|
bio_associate_blkg_from_css(bio, css);
|
|
|
|
rcu_read_unlock();
|
|
}
|
|
#endif /* CONFIG_MEMCG */
|
|
|
|
/**
|
|
* bio_associate_blkg - associate a bio with a blkg
|
|
* @bio: target bio
|
|
*
|
|
* Associate @bio with the blkg found from the bio's css and request_queue.
|
|
* If one is not found, bio_lookup_blkg() creates the blkg. If a blkg is
|
|
* already associated, the css is reused and association redone as the
|
|
* request_queue may have changed.
|
|
*/
|
|
void bio_associate_blkg(struct bio *bio)
|
|
{
|
|
struct cgroup_subsys_state *css;
|
|
|
|
rcu_read_lock();
|
|
|
|
if (bio->bi_blkg)
|
|
css = &bio_blkcg(bio)->css;
|
|
else
|
|
css = blkcg_css();
|
|
|
|
bio_associate_blkg_from_css(bio, css);
|
|
|
|
rcu_read_unlock();
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_associate_blkg);
|
|
|
|
/**
|
|
* bio_clone_blkg_association - clone blkg association from src to dst bio
|
|
* @dst: destination bio
|
|
* @src: source bio
|
|
*/
|
|
void bio_clone_blkg_association(struct bio *dst, struct bio *src)
|
|
{
|
|
rcu_read_lock();
|
|
|
|
if (src->bi_blkg)
|
|
bio_associate_blkg_from_css(dst, &bio_blkcg(src)->css);
|
|
|
|
rcu_read_unlock();
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_clone_blkg_association);
|
|
#endif /* CONFIG_BLK_CGROUP */
|
|
|
|
static void __init biovec_init_slabs(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < BVEC_POOL_NR; i++) {
|
|
int size;
|
|
struct biovec_slab *bvs = bvec_slabs + i;
|
|
|
|
if (bvs->nr_vecs <= BIO_INLINE_VECS) {
|
|
bvs->slab = NULL;
|
|
continue;
|
|
}
|
|
|
|
size = bvs->nr_vecs * sizeof(struct bio_vec);
|
|
bvs->slab = kmem_cache_create(bvs->name, size, 0,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
|
|
}
|
|
}
|
|
|
|
static int __init init_bio(void)
|
|
{
|
|
bio_slab_max = 2;
|
|
bio_slab_nr = 0;
|
|
bio_slabs = kcalloc(bio_slab_max, sizeof(struct bio_slab),
|
|
GFP_KERNEL);
|
|
|
|
BUILD_BUG_ON(BIO_FLAG_LAST > BVEC_POOL_OFFSET);
|
|
|
|
if (!bio_slabs)
|
|
panic("bio: can't allocate bios\n");
|
|
|
|
bio_integrity_init();
|
|
biovec_init_slabs();
|
|
|
|
if (bioset_init(&fs_bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS))
|
|
panic("bio: can't allocate bios\n");
|
|
|
|
if (bioset_integrity_create(&fs_bio_set, BIO_POOL_SIZE))
|
|
panic("bio: can't create integrity pool\n");
|
|
|
|
return 0;
|
|
}
|
|
subsys_initcall(init_bio);
|