Changes in 6.1.16 HID: asus: use spinlock to protect concurrent accesses HID: asus: use spinlock to safely schedule workers powerpc/mm: Rearrange if-else block to avoid clang warning ata: ahci: Revert "ata: ahci: Add Tiger Lake UP{3,4} AHCI controller" ARM: OMAP2+: Fix memory leak in realtime_counter_init() arm64: dts: qcom: qcs404: use symbol names for PCIe resets arm64: dts: qcom: msm8996-tone: Fix USB taking 6 minutes to wake up arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k arm64: dts: qcom: sm6350: Fix up the ramoops node arm64: dts: qcom: sm6125: Reorder HSUSB PHY clocks to match bindings arm64: dts: qcom: sm6125-seine: Clean up gpio-keys (volume down) arm64: dts: imx8m: Align SoC unique ID node unit address ARM: zynq: Fix refcount leak in zynq_early_slcr_init arm64: dts: mediatek: mt8195: Add power domain to U3PHY1 T-PHY arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description arm64: dts: mediatek: mt8192: Fix systimer 13 MHz clock description arm64: dts: mediatek: mt8195: Fix systimer 13 MHz clock description arm64: dts: mediatek: mt8186: Fix systimer 13 MHz clock description arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name x86/acpi/boot: Do not register processors that cannot be onlined for x2APIC arm64: dts: qcom: sc7180: correct SPMI bus address cells arm64: dts: qcom: sc7280: correct SPMI bus address cells arm64: dts: qcom: sc8280xp: correct SPMI bus address cells arm64: dts: qcom: sc8280xp: Vote for CX in USB controllers arm64: dts: meson-gxl: jethub-j80: Fix WiFi MAC address node arm64: dts: meson-gxl: jethub-j80: Fix Bluetooth MAC node name arm64: dts: meson-axg: jethub-j1xx: Fix MAC address node names arm64: dts: meson-gx: Fix Ethernet MAC address unit name arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again* arm64: dts: ti: k3-am62: Enable SPI nodes at the board level arm64: dts: ti: k3-am62-main: Fix clocks for McSPI arm64: tegra: Fix duplicate regulator on Jetson TX1 arm64: dts: msm8992-bullhead: add memory hole region arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem size arm64: dts: qcom: msm8992-bullhead: Disable dfps_data_mem arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges arm64: dts: qcom: ipq8074: fix Gen3 PCIe node arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names arm64: dts: meson: remove CPU opps below 1GHz for G12A boards ARM: OMAP1: call platform_device_put() in error case in omap1_dm_timer_init() arm64: dts: mediatek: mt8192: Mark scp_adsp clock as broken ARM: bcm2835_defconfig: Enable the framebuffer ARM: s3c: fix s3c64xx_set_timer_source prototype arm64: dts: ti: k3-j7200: Fix wakeup pinmux range ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato ARM: imx: Call ida_simple_remove() for ida_simple_get arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix supply name of USB controller node arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names property arm64: dts: amlogic: meson-gx: add missing unit address to rng node name arm64: dts: amlogic: meson-gxl-s905w-jethome-jethub-j80: fix invalid rtc node name arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix invalid rtc node name arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node name arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name arm64: dts: amlogic: meson-sm1-bananapi-m5: fix adc keys node names arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name arm64: dts: amlogic: meson-sm1-odroid-hc4: fix active fan thermal trip locking/rwsem: Disable preemption in all down_read*() and up_read() code paths arm64: dts: renesas: beacon-renesom: Fix gpio expander reference arm64: dts: meson: radxa-zero: allow usb otg mode arm64: dts: meson: bananapi-m5: switch VDDIO_C pin to OPEN_DRAIN ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference ublk_drv: remove nr_aborted_queues from ublk_device ublk_drv: don't probe partitions if the ubq daemon isn't trusted ARM: dts: imx7s: correct iomuxc gpr mux controller cells sbitmap: remove redundant check in __sbitmap_queue_get_batch sbitmap: Use single per-bitmap counting to wake up queued tags sbitmap: correct wake_batch recalculation to avoid potential IO hung arm64: dts: mt8195: Fix CPU map for single-cluster SoC arm64: dts: mt8192: Fix CPU map for single-cluster SoC arm64: dts: mt8186: Fix CPU map for single-cluster SoC arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node arm64: dts: mediatek: mt8186: Fix watchdog compatible arm64: dts: mediatek: mt8195: Fix watchdog compatible arm64: dts: mediatek: mt7986: Fix watchdog compatible ARM: dts: stm32: Update part number NVMEM description on stm32mp131 blk-mq: avoid sleep in blk_mq_alloc_request_hctx blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait blk-mq: Fix potential io hung for shared sbitmap per tagset blk-mq: correct stale comment of .get_budget arm64: dts: qcom: msm8996: support using GPLL0 as kryocc input arm64: dts: qcom: msm8996 switch from RPM_SMD_BB_CLK1 to RPM_SMD_XO_CLK_SRC arm64: dts: qcom: sm8350: drop incorrect cells from serial arm64: dts: qcom: sm8450: drop incorrect cells from serial arm64: dts: qcom: msm8992-lg-bullhead: Correct memory overlaps with the SMEM and MPSS memory regions arm64: dts: qcom: msm8953: correct TLMM gpio-ranges arm64: dts: qcom: msm8992-*: Fix up comments arm64: dts: qcom: msm8992-lg-bullhead: Enable regulators s390/dasd: Fix potential memleak in dasd_eckd_init() sched/rt: pick_next_rt_entity(): check list_entry perf/x86/intel/ds: Fix the conversion from TSC to perf time x86/perf/zhaoxin: Add stepping check for ZXC KEYS: asymmetric: Fix ECDSA use via keyctl uapi block: ublk: check IO buffer based on flag need_get_data arm64: dts: qcom: pmk8350: Specify PBS register for PON arm64: dts: qcom: pmk8350: Use the correct PON compatible erofs: relinquish volume with mutex held block: sync mixed merged request's failfast with 1st bio's block: Fix io statistics for cgroup in throttle path block: bio-integrity: Copy flags when bio_integrity_payload is cloned block: use proper return value from bio_failfast() wifi: mt76: mt7915: add missing of_node_put() wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host wifi: mt76: mt7915: check return value before accessing free_block_num wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr() wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read() wifi: mt76: fix coverity uninit_use_in_call in mt76_connac2_reverse_frag0_hdr_trans() wifi: rsi: Fix memory leak in rsi_coex_attach() wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave() wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave() wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave() wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave() wifi: libertas: fix memory leak in lbs_init_adapter() wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave() wifi: rtw89: 8852c: rfk: correct DACK setting wifi: rtw89: 8852c: rfk: correct DPK settings wifi: rtlwifi: Fix global-out-of-bounds bug in _rtl8812ae_phy_set_txpower_limit() libbpf: Fix btf__align_of() by taking into account field offsets wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave() wifi: ipw2200: fix memory leak in ipw_wdev_init() wifi: wilc1000: fix potential memory leak in wilc_mac_xmit() wifi: wilc1000: add missing unregister_netdev() in wilc_netdev_ifc_init() wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit() wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid() wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave() wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave() wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave() wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave() wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave() libbpf: Fix invalid return address register in s390 crypto: x86/ghash - fix unaligned access in ghash_setkey() ACPICA: Drop port I/O validation for some regions genirq: Fix the return type of kstat_cpu_irqs_sum() rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes() lib/mpi: Fix buffer overrun when SG is too long crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2 platform/chrome: cros_ec_typec: Update port DP VDO ACPICA: nsrepair: handle cases without a return value correctly selftests/xsk: print correct payload for packet dump selftests/xsk: print correct error codes when exiting arm64/cpufeature: Fix field sign for DIT hwcap detection kselftest/arm64: Fix syscall-abi for systems without 128 bit SME workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex s390/early: fix sclp_early_sccb variable lifetime s390/vfio-ap: fix an error handling path in vfio_ap_mdev_probe_queue() x86/signal: Fix the value returned by strict_sas_size() thermal/drivers/tsens: Drop msm8976-specific defines thermal/drivers/tsens: Sort out msm8976 vs msm8956 data thermal/drivers/tsens: fix slope values for msm8939 thermal/drivers/tsens: limit num_sensors to 9 for msm8939 wifi: rtw89: fix potential leak in rtw89_append_probe_req_ie() wifi: rtw89: Add missing check for alloc_workqueue wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU wifi: orinoco: check return value of hermes_write_wordrec() thermal/drivers/imx_sc_thermal: Drop empty platform remove function thermal/drivers/imx_sc_thermal: Fix the loop condition wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback function wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails wifi: ath9k: Fix potential stack-out-of-bounds write in ath9k_wmi_rsp_callback() wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup wifi: cfg80211: Fix extended KCK key length check in nl80211_set_rekey_data() ACPI: battery: Fix missing NUL-termination with large strings selftests/bpf: Fix build errors if CONFIG_NF_CONNTRACK=m crypto: ccp - Failure on re-initialization due to duplicate sysfs filename crypto: essiv - Handle EBUSY correctly crypto: seqiv - Handle EBUSY correctly powercap: fix possible name leak in powercap_register_zone() x86/microcode: Add a parameter to microcode_check() to store CPU capabilities x86/microcode: Check CPU capabilities after late microcode update correctly x86/microcode: Adjust late loading result reporting message selftests/bpf: Use consistent build-id type for liburandom_read.so selftests/bpf: Fix vmtest static compilation error crypto: xts - Handle EBUSY correctly leds: led-class: Add missing put_device() to led_put() s390/bpf: Add expoline to tail calls wifi: iwlwifi: mei: fix compilation errors in rfkill() kselftest/arm64: Fix enumeration of systems without 128 bit SME can: rcar_canfd: Fix R-Car V3U GAFLCFG field accesses selftests/bpf: Initialize tc in xdp_synproxy crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware bpftool: profile online CPUs instead of possible wifi: mt76: mt7915: call mt7915_mcu_set_thermal_throttling() only after init_work wifi: mt76: mt7915: fix memory leak in mt7915_mcu_exit wifi: mt76: mt7915: fix WED TxS reporting wifi: mt76: add memory barrier to SDIO queue kick wifi: mt76: mt7921: fix error code of return in mt7921_acpi_read net/mlx5: Enhance debug print in page allocation failure irqchip: Fix refcount leak in platform_irqchip_probe irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe s390/mem_detect: fix detect_memory() error handling s390/vmem: fix empty page tables cleanup under KASAN s390/boot: cleanup decompressor header files s390/mem_detect: rely on diag260() if sclp_early_get_memsize() fails s390/boot: fix mem_detect extended area allocation net: add sock_init_data_uid() tun: tun_chr_open(): correctly initialize socket uid tap: tap_open(): correctly initialize socket uid OPP: fix error checking in opp_migrate_dentry() cpufreq: davinci: Fix clk use after free Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds Bluetooth: L2CAP: Fix potential user-after-free Bluetooth: hci_qca: get wakeup status from serdev device handle net: ipa: generic command param fix s390: vfio-ap: tighten the NIB validity check s390/ap: fix status returned by ap_aqic() s390/ap: fix status returned by ap_qact() libbpf: Fix alen calculation in libbpf_nla_dump_errormsg() xen/grant-dma-iommu: Implement a dummy probe_device() callback rds: rds_rm_zerocopy_callback() correct order for list_add_tail() crypto: rsa-pkcs1pad - Use akcipher_request_complete m68k: /proc/hardware should depend on PROC_FS RISC-V: time: initialize hrtimer based broadcast clock event device clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first use wifi: iwl3945: Add missing check for create_singlethread_workqueue wifi: iwl4965: Add missing check for create_singlethread_workqueue() wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize() selftests/bpf: Fix out-of-srctree build ACPI: resource: Add IRQ overrides for MAINGEAR Vector Pro 2 models ACPI: resource: Do IRQ override on all TongFang GMxRGxx crypto: octeontx2 - Fix objects shared between several modules crypto: crypto4xx - Call dma_unmap_page when done wifi: mac80211: move color collision detection report in a delayed work wifi: mac80211: make rate u32 in sta_set_rate_info_rx() wifi: mac80211: fix non-MLO station association wifi: mac80211: Don't translate MLD addresses for multicast wifi: mac80211: avoid u32_encode_bits() warning wifi: mac80211: fix off-by-one link setting tools/lib/thermal: Fix thermal_sampling_exit() thermal/drivers/hisi: Drop second sensor hi3660 selftests/bpf: Fix map_kptr test. wifi: mac80211: pass 'sta' to ieee80211_rx_data_set_sta() bpf: Zeroing allocated object from slab in bpf memory allocator selftests/bpf: Fix xdp_do_redirect on s390x can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a bus error can: esd_usb: Make use of can_change_state() and relocate checking skb for NULL xsk: check IFF_UP earlier in Tx path LoongArch, bpf: Use 4 instructions for function address in JIT bpf: Fix global subprog context argument resolution logic irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts net/smc: fix potential panic dues to unprotected smc_llc_srv_add_link() net/smc: fix application data exception selftests/net: Interpret UDP_GRO cmsg data as an int value l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register() net: bcmgenet: fix MoCA LED control net: lan966x: Fix possible deadlock inside PTP net/mlx4_en: Introduce flexible array to silence overflow warning selftest: fib_tests: Always cleanup before exit sefltests: netdevsim: wait for devlink instance after netns removal drm: Fix potential null-ptr-deref due to drmm_mode_config_init() drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats drm/bridge: ti-sn65dsi83: Fix delay after reset deassert to match spec drm: mxsfb: DRM_IMX_LCDIF should depend on ARCH_MXC drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC drm/bridge: megachips: Fix error handling in i2c_register_driver() drm/vkms: Fix memory leak in vkms_init() drm/vkms: Fix null-ptr-deref in vkms_release() drm/vc4: dpi: Fix format mapping for RGB565 drm: tidss: Fix pixel format definition gpu: ipu-v3: common: Add of_node_put() for reference returned by of_graph_get_port_by_id() drm/vc4: drop all currently held locks if deadlock happens hwmon: (ftsteutates) Fix scaling of measurements drm/msm/dpu: check for null return of devm_kzalloc() in dpu_writeback_init() drm/msm/hdmi: Add missing check for alloc_ordered_workqueue pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups drm/vc4: hvs: Set AXI panic modes drm/vc4: hvs: SCALER_DISPBKGND_AUTOHS is only valid on HVS4 drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5 drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5 drm/vc4: hdmi: Correct interlaced timings again drm/msm: clean event_thread->worker in case of an error drm/panel-edp: fix name for IVO product id 854b scsi: qla2xxx: Fix exchange oversubscription scsi: qla2xxx: Fix exchange oversubscription for management commands scsi: qla2xxx: edif: Fix clang warning ASoC: fsl_sai: initialize is_dsp_mode flag drm/bridge: tc358767: Set default CLRSIPO count drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup() ALSA: hda/ca0132: minor fix for allocation size drm/amdgpu: Use the sched from entity for amdgpu_cs trace drm/msm/gem: Add check for kmalloc drm/msm/dpu: Disallow unallocated resources to be returned drm/bridge: lt9611: fix sleep mode setup drm/bridge: lt9611: fix HPD reenablement drm/bridge: lt9611: fix polarity programming drm/bridge: lt9611: fix programming of video modes drm/bridge: lt9611: fix clock calculation drm/bridge: lt9611: pass a pointer to the of node regulator: tps65219: use IS_ERR() to detect an error pointer drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags drm/msm/dsi: Allow 2 CTRLs on v2.5.0 scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096 drm/msm/dpu: sc7180: add missing WB2 clock control drm/msm: use strscpy instead of strncpy drm/msm/dpu: Add check for cstate drm/msm/dpu: Add check for pstates drm/msm/mdp5: Add check for kzalloc habanalabs: bugs fixes in timestamps buff alloc pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback() pinctrl: mediatek: Initialize variable pullen and pullup to zero pinctrl: mediatek: Initialize variable *buf to zero gpu: host1x: Fix mask for syncpoint increment register gpu: host1x: Don't skip assigning syncpoints to channels drm/tegra: firewall: Check for is_addr_reg existence in IMM check pinctrl: renesas: rzg2l: Fix configuring the GPIO pins as interrupts drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update() drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd drm/mediatek: Use NULL instead of 0 for NULL pointer drm/mediatek: Drop unbalanced obj unref drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc drm/mediatek: Clean dangling pointer on bind error path ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress() dt-bindings: display: mediatek: Fix the fallback for mediatek,mt8186-disp-ccorr gpio: vf610: connect GPIO label to dev name ASoC: topology: Properly access value coming from topology file spi: dw_bt1: fix MUX_MMIO dependencies ASoC: mchp-spdifrx: fix controls which rely on rsr register ASoC: mchp-spdifrx: fix return value in case completion times out ASoC: mchp-spdifrx: fix controls that works with completion mechanism ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove() dm: improve shrinker debug names regmap: apply reg_base and reg_downshift for single register ops ASoC: rsnd: fixup #endif position ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params() ASoC: dt-bindings: meson: fix gx-card codec node regex regulator: tps65219: use generic set_bypass() hwmon: (asus-ec-sensors) add missing mutex path hwmon: (ltc2945) Handle error case in ltc2945_value_store ALSA: hda: Fix the control element identification for multiple codecs drm/amdgpu: fix enum odm_combine_mode mismatch scsi: mpt3sas: Fix a memory leak scsi: aic94xx: Add missing check for dma_map_single() HID: multitouch: Add quirks for flipped axes HID: retain initial quirks set up when creating HID devices ASoC: qcom: q6apm-lpass-dai: unprepare stream if its already prepared ASoC: qcom: q6apm-dai: fix race condition while updating the position pointer ASoC: qcom: q6apm-dai: Add SNDRV_PCM_INFO_BATCH flag ASoC: codecs: lpass: register mclk after runtime pm ASoC: codecs: lpass: fix incorrect mclk rate drm/amd/display: don't call dc_interrupt_set() for disabled crtcs HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support spi: bcm63xx-hsspi: Fix multi-bit mode setting hwmon: (mlxreg-fan) Return zero speed for broken fan ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init dm: remove flush_scheduled_work() during local_exit() nfs4trace: fix state manager flag printing NFS: fix disabling of swap spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared HID: bigben: use spinlock to protect concurrent accesses HID: bigben_worker() remove unneeded check on report_field HID: bigben: use spinlock to safely schedule workers hid: bigben_probe(): validate report count ALSA: hda/hdmi: Register with vga_switcheroo on Dual GPU Macbooks drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt() NFSD: enhance inter-server copy cleanup NFSD: fix leaked reference count of nfsd4_ssc_umount_item nfsd: fix race to check ls_layouts nfsd: clean up potential nfsd_file refcount leaks in COPY codepath NFSD: fix problems with cleanup on errors in nfsd4_copy nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open nfsd: don't fsync nfsd_files on last close NFSD: copy the whole verifier in nfsd_copy_write_verifier cifs: Fix lost destroy smbd connection when MR allocate failed cifs: Fix warning and UAF when destroy the MR list cifs: use tcon allocation functions even for dummy tcon gfs2: jdata writepage fix perf llvm: Fix inadvertent file creation leds: led-core: Fix refcount leak in of_led_get() leds: is31fl319x: Wrap mutex_destroy() for devm_add_action_or_rest() leds: simatic-ipc-leds-gpio: Make sure we have the GPIO providing driver tools/tracing/rtla: osnoise_hist: use total duration for average calculation perf inject: Use perf_data__read() for auxtrace perf intel-pt: Do not try to queue auxtrace data on pipe perf test bpf: Skip test if kernel-debuginfo is not present perf tools: Fix auto-complete on aarch64 sparc: allow PM configs for sparc32 COMPILE_TEST selftests: find echo binary to use -ne options selftests/ftrace: Fix bash specific "==" operator selftests: use printf instead of echo -ne perf record: Fix segfault with --overwrite and --max-size printf: fix errname.c list perf tests stat_all_metrics: Change true workload to sleep workload for system wide check objtool: add UACCESS exceptions for __tsan_volatile_read/write mfd: cs5535: Don't build on UML mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read() dmaengine: idxd: Set traffic class values in GRPCFG on DSA 2.0 RDMA/erdma: Fix refcount leak in erdma_mmap dmaengine: HISI_DMA should depend on ARCH_HISI RDMA/hns: Fix refcount leak in hns_roce_mmap iio: light: tsl2563: Do not hardcode interrupt trigger type usb: gadget: fusb300_udc: free irq on the error path in fusb300_probe() i2c: designware: fix i2c_dw_clk_rate() return size to be u32 soundwire: cadence: Don't overflow the command FIFOs driver core: fix potential null-ptr-deref in device_add() kobject: modify kobject_get_path() to take a const * kobject: Fix slab-out-of-bounds in fill_kobj_path() alpha/boot/tools/objstrip: fix the check for ELF header media: uvcvideo: Check for INACTIVE in uvc_ctrl_is_accessible() media: uvcvideo: Implement mask for V4L2_CTRL_TYPE_MENU media: uvcvideo: Refactor uvc_ctrl_mappings_uvcXX media: uvcvideo: Refactor power_line_frequency_controls_limited coresight: etm4x: Fix accesses to TRCSEQRSTEVR and TRCSEQSTR coresight: cti: Prevent negative values of enable count coresight: cti: Add PM runtime call in enable_store usb: typec: intel_pmc_mux: Don't leak the ACPI device reference count PCI/IOV: Enlarge virtfn sysfs name buffer PCI: switchtec: Return -EFAULT for copy_to_user() errors PCI: endpoint: pci-epf-vntb: Clean up kernel_doc warning PCI: endpoint: pci-epf-vntb: Add epf_ntb_mw_bar_clear() num_mws kernel-doc hwtracing: hisi_ptt: Only add the supported devices to the filters list tty: serial: fsl_lpuart: disable Rx/Tx DMA in lpuart32_shutdown() tty: serial: fsl_lpuart: clear LPUART Status Register in lpuart32_shutdown() serial: tegra: Add missing clk_disable_unprepare() in tegra_uart_hw_init() Revert "char: pcmcia: cm4000_cs: Replace mdelay with usleep_range in set_protocol" eeprom: idt_89hpesx: Fix error handling in idt_init() applicom: Fix PCI device refcount leak in applicom_init() firmware: stratix10-svc: add missing gen_pool_destroy() in stratix10_svc_drv_probe() firmware: stratix10-svc: fix error handle while alloc/add device failed VMCI: check context->notify_page after call to get_user_pages_fast() to avoid GPF mei: pxp: Use correct macros to initialize uuid_le misc/mei/hdcp: Use correct macros to initialize uuid_le misc: fastrpc: Fix an error handling path in fastrpc_rpmsg_probe() driver core: fix resource leak in device_add() driver core: location: Free struct acpi_pld_info *pld before return false drivers: base: transport_class: fix possible memory leak drivers: base: transport_class: fix resource leak when transport_add_device() fails firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle fotg210-udc: Add missing completion handler dmaengine: dw-edma: Fix missing src/dst address of interleaved xfers fpga: microchip-spi: move SPI I/O buffers out of stack fpga: microchip-spi: rewrite status polling in a time measurable way usb: early: xhci-dbc: Fix a potential out-of-bound memory access tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case RDMA/cxgb4: add null-ptr-check after ip_dev_find() usb: musb: mediatek: don't unregister something that wasn't registered usb: gadget: configfs: Restrict symlink creation is UDC already binded phy: mediatek: remove temporary variable @mask_ PCI: mt7621: Delay phy ports initialization iommu: dart: Add suspend/resume support iommu: dart: Support >64 stream IDs iommu/dart: Fix apple_dart_device_group for PCI groups iommu/vt-d: Set No Execute Enable bit in PASID table entry power: supply: remove faulty cooling logic RDMA/cxgb4: Fix potential null-ptr-deref in pass_establish() usb: max-3421: Fix setting of I/O pins RDMA/irdma: Cap MSIX used to online CPUs + 1 serial: fsl_lpuart: fix RS485 RTS polariy inverse issue tty: serial: imx: Handle RS485 DE signal active high tty: serial: imx: disable Ageing Timer interrupt request irq driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links driver core: fw_devlink: Don't purge child fwnode's consumer links driver core: fw_devlink: Allow marking a fwnode link as being part of a cycle driver core: fw_devlink: Consolidate device link flag computation driver core: fw_devlink: Improve check for fwnode with no device/driver driver core: fw_devlink: Make cycle detection more robust mtd: mtdpart: Don't create platform device that'll never probe usb: host: fsl-mph-dr-of: reuse device_set_of_node_from_dev dmaengine: dw-edma: Fix readq_ch() return value truncation PCI: Fix dropping valid root bus resources with .end = zero phy: rockchip-typec: fix tcphy_get_mode error case PCI: qcom: Fix host-init error handling iw_cxgb4: Fix potential NULL dereference in c4iw_fill_res_cm_id_entry() iommu: Fix error unwind in iommu_group_alloc() iommu/amd: Do not identity map v2 capable device when snp is enabled dmaengine: sf-pdma: pdma_desc memory leak fix dmaengine: dw-axi-dmac: Do not dereference NULL structure dmaengine: ptdma: check for null desc before calling pt_cmd_callback iommu/vt-d: Fix error handling in sva enable/disable paths iommu/vt-d: Allow to use flush-queue when first level is default RDMA/rxe: cleanup some error handling in rxe_verbs.c RDMA/rxe: Fix missing memory barriers in rxe_queue.h IB/hfi1: Fix math bugs in hfi1_can_pin_pages() IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors Revert "remoteproc: qcom_q6v5_mss: map/unmap metadata region before/after use" remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers media: ti: cal: fix possible memory leak in cal_ctx_create() media: platform: ti: Add missing check for devm_regulator_get media: imx: imx7-media-csi: fix missing clk_disable_unprepare() in imx7_csi_init() powerpc: Remove linker flag from KBUILD_AFLAGS s390/vdso: Drop '-shared' from KBUILD_CFLAGS_64 builddeb: clean generated package content media: max9286: Fix memleak in max9286_v4l2_register() media: ov2740: Fix memleak in ov2740_init_controls() media: ov5675: Fix memleak in ov5675_init_controls() media: ov5640: Fix soft reset sequence and timings media: ov5640: Handle delays when no reset_gpio set media: mc: Get media_device directly from pad media: i2c: ov772x: Fix memleak in ov772x_probe() media: i2c: imx219: Split common registers from mode tables media: i2c: imx219: Fix binning for RAW8 capture media: platform: mtk-mdp3: Fix return value check in mdp_probe() media: camss: csiphy-3ph: avoid undefined behavior media: platform: mtk-mdp3: remove unused VIDEO_MEDIATEK_VPU config media: platform: mtk-mdp3: fix Kconfig dependencies media: v4l2-jpeg: correct the skip count in jpeg_parse_app14_data media: v4l2-jpeg: ignore the unknown APP14 marker media: hantro: Fix JPEG encoder ENUM_FRMSIZE on RK3399 media: imx-jpeg: Apply clk_bulk api instead of operating specific clk media: amphion: correct the unspecified color space media: drivers/media/v4l2-core/v4l2-h264 : add detection of null pointers media: rc: Fix use-after-free bugs caused by ene_tx_irqsim() media: atomisp: Only set default_run_mode on first open of a stream/asd media: i2c: ov7670: 0 instead of -EINVAL was returned media: usb: siano: Fix use after free bugs caused by do_submit_urb media: saa7134: Use video_unregister_device for radio_dev rpmsg: glink: Avoid infinite loop on intent for missing channel rpmsg: glink: Release driver_override ARM: OMAP2+: omap4-common: Fix refcount leak bug arm64: dts: qcom: msm8996: Add additional A2NoC clocks udf: Define EFSCORRUPTED error code context_tracking: Fix noinstr vs KASAN exit: Detect and fix irq disabled state in oops ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy fs: Use CHECK_DATA_CORRUPTION() when kernel bugs are detected blk-iocost: fix divide by 0 error in calc_lcoefs() blk-cgroup: dropping parent refcount after pd_free_fn() is done blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and blkcg_deactivate_policy() trace/blktrace: fix memory leak with using debugfs_lookup() btrfs: scrub: improve tree block error reporting arm64: zynqmp: Enable hs termination flag for USB dwc3 controller cpuidle, intel_idle: Fix CPUIDLE_FLAG_INIT_XSTATE x86/fpu: Don't set TIF_NEED_FPU_LOAD for PF_IO_WORKER threads cpuidle: drivers: firmware: psci: Dont instrument suspend code cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG perf/x86/intel/uncore: Add Meteor Lake support wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect() wifi: ath11k: fix monitor mode bringup crash wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds() rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks rcu: Suppress smp_processor_id() complaint in synchronize_rcu_expedited_wait() srcu: Delegate work to the boot cpu if using SRCU_SIZE_SMALL rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug rcu-tasks: Handle queue-shrink/callback-enqueue race condition wifi: ath11k: debugfs: fix to work with multiple PCI devices thermal: intel: Fix unsigned comparison with less than zero timers: Prevent union confusion from unexpected restart_syscall() x86/bugs: Reset speculation control settings on init bpftool: Always disable stack protection for BPF objects wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-of-bounds wifi: mt7601u: fix an integer underflow inet: fix fast path in __inet_hash_connect() ice: restrict PTP HW clock freq adjustments to 100, 000, 000 PPB ice: add missing checks for PF vsi type ACPI: Don't build ACPICA with '-Os' bpf, docs: Fix modulo zero, division by zero, overflow, and underflow thermal: intel: intel_pch: Add support for Wellsburg PCH clocksource: Suspend the watchdog temporarily when high read latency detected crypto: hisilicon: Wipe entire pool on error net: bcmgenet: Add a check for oversized packets m68k: Check syscall_trace_enter() return code s390/mm,ptdump: avoid Kasan vs Memcpy Real markers swapping netfilter: nf_tables: NULL pointer dereference in nf_tables_updobj() can: isotp: check CAN address family in isotp_bind() gcc-plugins: drop -std=gnu++11 to fix GCC 13 build tools/power/x86/intel-speed-select: Add Emerald Rapid quirk wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup ACPI: video: Fix Lenovo Ideapad Z570 DMI match net/mlx5: fw_tracer: Fix debug print coda: Avoid partial allocation of sig_inputArgs uaccess: Add minimum bounds check on kernel buffer size s390/idle: mark arch_cpu_idle() noinstr time/debug: Fix memory leak with using debugfs_lookup() PM: domains: fix memory leak with using debugfs_lookup() PM: EM: fix memory leak with using debugfs_lookup() Bluetooth: Fix issue with Actions Semi ATS2851 based devices Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921 Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30 hv_netvsc: Check status in SEND_RNDIS_PKT completion message s390/kfence: fix page fault reporting devlink: Fix TP_STRUCT_entry in trace of devlink health report scm: add user copy checks to put_cmsg() drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F drm: panel-orientation-quirks: Add quirk for DynaBook K50 drm/amd/display: Reduce expected sdp bandwidth for dcn321 drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h write drm/amd/display: Fix potential null-deref in dm_resume drm/omap: dsi: Fix excessive stack usage HID: Add Mapping for System Microphone Mute drm/tiny: ili9486: Do not assume 8-bit only SPI controllers drm/amd/display: Defer DIG FIFO disable after VID stream enable drm/radeon: free iio for atombios when driver shutdown drm/amd: Avoid BUG() for case of SRIOV missing IP version drm/amdkfd: Page aligned memory reserve size scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write Revert "fbcon: don't lose the console font across generic->chip driver switch" drm/amd: Avoid ASSERT for some message failures drm: amd: display: Fix memory leakage drm/amd/display: fix mapping to non-allocated address HID: uclogic: Add frame type quirk HID: uclogic: Add battery quirk HID: uclogic: Add support for XP-PEN Deco Pro SW HID: uclogic: Add support for XP-PEN Deco Pro MW drm/msm/dsi: Add missing check for alloc_ordered_workqueue drm: rcar-du: Add quirk for H3 ES1.x pclk workaround drm: rcar-du: Fix setting a reserved bit in DPLLCR drm/drm_print: correct format problem drm/amd/display: Set hvm_enabled flag for S/G mode habanalabs: extend fatal messages to contain PCI info habanalabs: fix bug in timestamps registration code docs/scripts/gdb: add necessary make scripts_gdb step drm/msm/dpu: Add DSC hardware blocks to register snapshot ASoC: soc-compress: Reposition and add pcm_mutex ASoC: kirkwood: Iterate over array indexes instead of using pointer math regulator: max77802: Bounds check regulator id against opmode regulator: s5m8767: Bounds check id indexing into arrays Revert "drm/amdgpu: TA unload messages are not actually sent to psp when amdgpu is uninstalled" drm/amd/display: fix FCLK pstate change underflow gfs2: Improve gfs2_make_fs_rw error handling hwmon: (coretemp) Simplify platform device handling hwmon: (nct6775) Directly call ASUS ACPI WMI method hwmon: (nct6775) B650/B660/X670 ASUS boards support pinctrl: at91: use devm_kasprintf() to avoid potential leaks drm/amd/display: Do not commit pipe when updating DRR scsi: snic: Fix memory leak with using debugfs_lookup() scsi: ufs: core: Fix device management cmd timeout flow HID: logitech-hidpp: Don't restart communication if not necessary drm/amd/display: Enable P-state validation checks for DCN314 drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 drm/amd/display: Disable HUBP/DPP PG on DCN314 for now dm thin: add cond_resched() to various workqueue loops dm cache: add cond_resched() to various workqueue loops nfsd: zero out pointers after putting nfsd_files on COPY setup error nfsd: don't hand out delegation on setuid files being opened for write cifs: prevent data race in smb2_reconnect() drm/shmem-helper: Revert accidental non-GPL export driver core: fw_devlink: Avoid spurious error message wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu scsi: mpt3sas: Remove usage of dma_get_required_mask() API firmware: coreboot: framebuffer: Ignore reserved pixel color bits block: don't allow multiple bios for IOCB_NOWAIT issue block: clear bio->bi_bdev when putting a bio back in the cache block: be a bit more careful in checking for NULL bdev while polling rtc: pm8xxx: fix set-alarm race ipmi: ipmb: Fix the MODULE_PARM_DESC associated to 'retry_time_ms' ipmi:ssif: resend_msg() cannot fail ipmi_ssif: Rename idle state and check io_uring: Replace 0-length array with flexible array io_uring: use user visible tail in io_uring_poll() io_uring: handle TIF_NOTIFY_RESUME when checking for task_work io_uring: add a conditional reschedule to the IOPOLL cancelation loop io_uring: add reschedule point to handle_tw_list() io_uring/rsrc: disallow multi-source reg buffers io_uring: remove MSG_NOSIGNAL from recvmsg io_uring: fix fget leak when fs don't support nowait buffered read s390/extmem: return correct segment type in __segment_load() s390: discard .interp section s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler s390/kprobes: fix current_kprobe never cleared after kprobes reenter KVM: s390: disable migration mode when dirty tracking is disabled cifs: Fix uninitialized memory read in smb3_qfs_tcon() cifs: Fix uninitialized memory reads for oparms.mode cifs: fix mount on old smb servers cifs: introduce cifs_io_parms in smb2_async_writev() cifs: split out smb3_use_rdma_offload() helper cifs: don't try to use rdma offload on encrypted connections cifs: Check the lease context if we actually got a lease cifs: return a single-use cfid if we did not get a lease scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info() scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi btrfs: hold block group refcount during async discard locking/rwsem: Prevent non-first waiter from spinning in down_write() slowpath ksmbd: fix wrong data area length for smb2 lock request ksmbd: do not allow the actual frame length to be smaller than the rfc1002 length ksmbd: fix possible memory leak in smb2_lock() torture: Fix hang during kthread shutdown phase ARM: dts: exynos: correct HDMI phy compatible in Exynos4 io_uring: mark task TASK_RUNNING before handling resume/task work hfs: fix missing hfs_bnode_get() in __hfs_bnode_create fs: hfsplus: fix UAF issue in hfsplus_put_super exfat: fix reporting fs error when reading dir beyond EOF exfat: fix unexpected EOF while reading dir exfat: redefine DIR_DELETED as the bad cluster number exfat: fix inode->i_blocks for non-512 byte sector size device fs: dlm: don't set stop rx flag after node reset fs: dlm: move sending fin message into state change handling fs: dlm: send FIN ack back in right cases f2fs: fix information leak in f2fs_move_inline_dirents() f2fs: retry to update the inode page given data corruption f2fs: fix cgroup writeback accounting with fs-layer encryption f2fs: fix kernel crash due to null io->bio ocfs2: fix defrag path triggering jbd2 ASSERT ocfs2: fix non-auto defrag path not working issue fs/cramfs/inode.c: initialize file_ra_state selftests/landlock: Skip overlayfs tests when not supported selftests/landlock: Test ptrace as much as possible with Yama udf: Truncate added extents on failed expansion udf: Do not bother merging very long extents udf: Do not update file length for failed writes to inline files udf: Preserve link count of system files udf: Detect system inodes linked into directory hierarchy udf: Fix file corruption when appending just after end of preallocated extent md: don't update recovery_cp when curr_resync is ACTIVE RDMA/siw: Fix user page pinning accounting KVM: Destroy target device if coalesced MMIO unregistration fails KVM: VMX: Fix crash due to uninitialized current_vmcs KVM: Register /dev/kvm as the _very_ last thing during initialization KVM: x86: Purge "highest ISR" cache when updating APICv state KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID KVM: SVM: Flush the "current" TLB when activating AVIC KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target KVM: SVM: Don't put/load AVIC when setting virtual APIC mode KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI KVM: x86: Inject #GP on x2APIC WRMSR that sets reserved bits 63:32 KVM: SVM: Fix potential overflow in SEV's send|receive_update_data() KVM: SVM: hyper-v: placate modpost section mismatch error selftests: x86: Fix incorrect kernel headers search path x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows) x86/crash: Disable virt in core NMI crash handler to avoid double shootdown x86/reboot: Disable virtualization in an emergency if SVM is supported x86/reboot: Disable SVM, not just VMX, when stopping CPUs x86/kprobes: Fix __recover_optprobed_insn check optimizing logic x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe range x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter x86/microcode/AMD: Add a @cpu parameter to the reloading functions x86/microcode/AMD: Fix mixed steppings support x86/speculation: Allow enabling STIBP with legacy IBRS Documentation/hw-vuln: Document the interaction between IBRS and STIBP virt/sev-guest: Return -EIO if certificate buffer is not large enough brd: mark as nowait compatible brd: return 0/-error from brd_insert_page() brd: check for REQ_NOWAIT and set correct page allocation mask ima: fix error handling logic when file measurement failed ima: Align ima_file_mmap() parameters with mmap_file LSM hook selftests/powerpc: Fix incorrect kernel headers search path selftests/ftrace: Fix eprobe syntax test case to check filter support selftests: sched: Fix incorrect kernel headers search path selftests: core: Fix incorrect kernel headers search path selftests: pid_namespace: Fix incorrect kernel headers search path selftests: arm64: Fix incorrect kernel headers search path selftests: clone3: Fix incorrect kernel headers search path selftests: pidfd: Fix incorrect kernel headers search path selftests: membarrier: Fix incorrect kernel headers search path selftests: kcmp: Fix incorrect kernel headers search path selftests: media_tests: Fix incorrect kernel headers search path selftests: gpio: Fix incorrect kernel headers search path selftests: filesystems: Fix incorrect kernel headers search path selftests: user_events: Fix incorrect kernel headers search path selftests: ptp: Fix incorrect kernel headers search path selftests: sync: Fix incorrect kernel headers search path selftests: rseq: Fix incorrect kernel headers search path selftests: move_mount_set_group: Fix incorrect kernel headers search path selftests: mount_setattr: Fix incorrect kernel headers search path selftests: perf_events: Fix incorrect kernel headers search path selftests: ipc: Fix incorrect kernel headers search path selftests: futex: Fix incorrect kernel headers search path selftests: drivers: Fix incorrect kernel headers search path selftests: dmabuf-heaps: Fix incorrect kernel headers search path selftests: vm: Fix incorrect kernel headers search path selftests: seccomp: Fix incorrect kernel headers search path irqdomain: Fix association race irqdomain: Fix disassociation race irqdomain: Look for existing mapping only once irqdomain: Drop bogus fwspec-mapping error handling irqdomain: Refactor __irq_domain_alloc_irqs() irqdomain: Fix mapping-creation race irqdomain: Fix domain registration race crypto: qat - fix out-of-bounds read mm/damon/paddr: fix missing folio_put() ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC jbd2: fix data missing when reusing bh which is ready to be checkpointed ext4: optimize ea_inode block expansion ext4: refuse to create ea block when umounted cxl/pmem: Fix nvdimm registration races mtd: spi-nor: sfdp: Fix index value for SCCR dwords mtd: spi-nor: spansion: Consider reserved bits in CFR5 register mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type dm: send just one event on resize, not two dm: add cond_resched() to dm_wq_work() dm: add cond_resched() to dm_wq_requeue_work() wifi: rtw88: use RTW_FLAG_POWERON flag to prevent to power on/off twice wifi: rtl8xxxu: Use a longer retry limit of 48 wifi: ath11k: allow system suspend to survive ath11k wifi: cfg80211: Fix use after free for wext wifi: cfg80211: Set SSID if it is not already set cpuidle: add ARCH_SUSPEND_POSSIBLE dependencies qede: fix interrupt coalescing configuration thermal: intel: powerclamp: Fix cur_state for multi package system dm flakey: fix logic when corrupting a bio dm cache: free background tracker's queued work in btracker_destroy dm flakey: don't corrupt the zero page dm flakey: fix a bug with 32-bit highmem systems hwmon: (peci/cputemp) Fix off-by-one in coretemp_label allocation hwmon: (nct6775) Fix incorrect parenthesization in nct6775_write_fan_div() ARM: dts: qcom: sdx65: Add Qcom SMMU-500 as the fallback for IOMMU node ARM: dts: qcom: sdx55: Add Qcom SMMU-500 as the fallback for IOMMU node ARM: dts: exynos: correct TMU phandle in Exynos4210 ARM: dts: exynos: correct TMU phandle in Exynos4 ARM: dts: exynos: correct TMU phandle in Odroid XU3 family ARM: dts: exynos: correct TMU phandle in Exynos5250 ARM: dts: exynos: correct TMU phandle in Odroid XU ARM: dts: exynos: correct TMU phandle in Odroid HC1 arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP fuse: add inode/permission checks to fileattr_get/fileattr_set rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails ceph: update the time stamps and try to drop the suid/sgid regulator: core: Use ktime_get_boottime() to determine how long a regulator was off panic: fix the panic_print NMI backtrace setting mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON alpha: fix FEN fault handling dax/kmem: Fix leak of memory-hotplug resources mips: fix syscall_get_nr media: ipu3-cio2: Fix PM runtime usage_count in driver unbind remoteproc/mtk_scp: Move clk ops outside send_lock docs: gdbmacros: print newest record mm: memcontrol: deprecate charge moving mm/thp: check and bail out if page in deferred queue already ktest.pl: Give back console on Ctrt^C on monitor kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list ktest.pl: Fix missing "end_monitor" when machine check fails ktest.pl: Add RUN_TIMEOUT option with default unlimited memory tier: release the new_memtier in find_create_memory_tier() ring-buffer: Handle race between rb_move_tail and rb_check_pages tools/bootconfig: fix single & used for logical condition tracing/eprobe: Fix to add filter on eprobe description in README file iommu/amd: Add a length limitation for the ivrs_acpihid command-line parameter iommu/amd: Improve page fault error reporting scsi: aacraid: Allocate cmd_priv with scsicmd scsi: qla2xxx: Fix link failure in NPIV environment scsi: qla2xxx: Check if port is online before sending ELS scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests scsi: qla2xxx: Remove unintended flag clearing scsi: qla2xxx: Fix erroneous link down scsi: qla2xxx: Remove increment of interface err cnt scsi: ses: Don't attach if enclosure has no components scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process() scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses scsi: ses: Fix possible desc_ptr out-of-bounds accesses scsi: ses: Fix slab-out-of-bounds in ses_intf_remove() RISC-V: add a spin_shadow_stack declaration riscv: Avoid enabling interrupts in die() riscv: mm: fix regression due to update_mmu_cache change riscv: jump_label: Fixup unaligned arch_static_branch function riscv, mm: Perform BPF exhandler fixup on page fault riscv: ftrace: Remove wasted nops for !RISCV_ISA_C riscv: ftrace: Reduce the detour code size to half MIPS: DTS: CI20: fix otg power gpio PCI/PM: Observe reset delay irrespective of bridge_d3 PCI: Unify delay handling for reset and resume PCI: hotplug: Allow marking devices as disconnected during bind/unbind PCI: Avoid FLR for AMD FCH AHCI adapters PCI/DPC: Await readiness of secondary bus after reset bus: mhi: ep: Only send -ENOTCONN status if client driver is available bus: mhi: ep: Move chan->lock to the start of processing queued ch ring bus: mhi: ep: Save channel state locally during suspend and resume iommu/vt-d: Avoid superfluous IOTLB tracking in lazy mode iommu/vt-d: Fix PASID directory pointer coherency vfio/type1: exclude mdevs from VFIO_UPDATE_VADDR vfio/type1: prevent underflow of locked_vm via exec() vfio/type1: track locked_vm per dma vfio/type1: restore locked_vm drm/amd: Fix initialization for nbio 7.5.1 drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv drm/radeon: Fix eDP for single-display iMac11,2 drm/i915: Don't use stolen memory for ring buffers with LLC drm/i915: Don't use BAR mappings for ring buffers with LLC drm/gud: Fix UBSAN warning drm/edid: fix AVI infoframe aspect ratio handling drm/edid: fix parsing of 3D modes from HDMI VSDB qede: avoid uninitialized entries in coal_entry array brd: use radix_tree_maybe_preload instead of radix_tree_preload sbitmap: Advance the queue index before waking up a queue wait: Return number of exclusive waiters awaken sbitmap: Try each queue to wake up at least one waiter kbuild: Port silent mode detection to future gnu make. net: avoid double iput when sock_alloc_file fails Linux 6.1.16 Change-Id: I705caf70ee547e6d55f38d133bdcd50713aed745 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
1763 lines
48 KiB
C
1763 lines
48 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/highmem.h>
|
|
#include <linux/sched/sysctl.h>
|
|
#include <linux/blk-crypto.h>
|
|
#include <linux/xarray.h>
|
|
|
|
#include <trace/events/block.h>
|
|
#include "blk.h"
|
|
#include "blk-rq-qos.h"
|
|
#include "blk-cgroup.h"
|
|
|
|
struct bio_alloc_cache {
|
|
struct bio *free_list;
|
|
unsigned int nr;
|
|
};
|
|
|
|
static struct biovec_slab {
|
|
int nr_vecs;
|
|
char *name;
|
|
struct kmem_cache *slab;
|
|
} bvec_slabs[] __read_mostly = {
|
|
{ .nr_vecs = 16, .name = "biovec-16" },
|
|
{ .nr_vecs = 64, .name = "biovec-64" },
|
|
{ .nr_vecs = 128, .name = "biovec-128" },
|
|
{ .nr_vecs = BIO_MAX_VECS, .name = "biovec-max" },
|
|
};
|
|
|
|
static struct biovec_slab *biovec_slab(unsigned short nr_vecs)
|
|
{
|
|
switch (nr_vecs) {
|
|
/* smaller bios use inline vecs */
|
|
case 5 ... 16:
|
|
return &bvec_slabs[0];
|
|
case 17 ... 64:
|
|
return &bvec_slabs[1];
|
|
case 65 ... 128:
|
|
return &bvec_slabs[2];
|
|
case 129 ... BIO_MAX_VECS:
|
|
return &bvec_slabs[3];
|
|
default:
|
|
BUG();
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 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[8];
|
|
};
|
|
static DEFINE_MUTEX(bio_slab_lock);
|
|
static DEFINE_XARRAY(bio_slabs);
|
|
|
|
static struct bio_slab *create_bio_slab(unsigned int size)
|
|
{
|
|
struct bio_slab *bslab = kzalloc(sizeof(*bslab), GFP_KERNEL);
|
|
|
|
if (!bslab)
|
|
return NULL;
|
|
|
|
snprintf(bslab->name, sizeof(bslab->name), "bio-%d", size);
|
|
bslab->slab = kmem_cache_create(bslab->name, size,
|
|
ARCH_KMALLOC_MINALIGN,
|
|
SLAB_HWCACHE_ALIGN | SLAB_TYPESAFE_BY_RCU, NULL);
|
|
if (!bslab->slab)
|
|
goto fail_alloc_slab;
|
|
|
|
bslab->slab_ref = 1;
|
|
bslab->slab_size = size;
|
|
|
|
if (!xa_err(xa_store(&bio_slabs, size, bslab, GFP_KERNEL)))
|
|
return bslab;
|
|
|
|
kmem_cache_destroy(bslab->slab);
|
|
|
|
fail_alloc_slab:
|
|
kfree(bslab);
|
|
return NULL;
|
|
}
|
|
|
|
static inline unsigned int bs_bio_slab_size(struct bio_set *bs)
|
|
{
|
|
return bs->front_pad + sizeof(struct bio) + bs->back_pad;
|
|
}
|
|
|
|
static struct kmem_cache *bio_find_or_create_slab(struct bio_set *bs)
|
|
{
|
|
unsigned int size = bs_bio_slab_size(bs);
|
|
struct bio_slab *bslab;
|
|
|
|
mutex_lock(&bio_slab_lock);
|
|
bslab = xa_load(&bio_slabs, size);
|
|
if (bslab)
|
|
bslab->slab_ref++;
|
|
else
|
|
bslab = create_bio_slab(size);
|
|
mutex_unlock(&bio_slab_lock);
|
|
|
|
if (bslab)
|
|
return bslab->slab;
|
|
return NULL;
|
|
}
|
|
|
|
static void bio_put_slab(struct bio_set *bs)
|
|
{
|
|
struct bio_slab *bslab = NULL;
|
|
unsigned int slab_size = bs_bio_slab_size(bs);
|
|
|
|
mutex_lock(&bio_slab_lock);
|
|
|
|
bslab = xa_load(&bio_slabs, slab_size);
|
|
if (WARN(!bslab, KERN_ERR "bio: unable to find slab!\n"))
|
|
goto out;
|
|
|
|
WARN_ON_ONCE(bslab->slab != bs->bio_slab);
|
|
|
|
WARN_ON(!bslab->slab_ref);
|
|
|
|
if (--bslab->slab_ref)
|
|
goto out;
|
|
|
|
xa_erase(&bio_slabs, slab_size);
|
|
|
|
kmem_cache_destroy(bslab->slab);
|
|
kfree(bslab);
|
|
|
|
out:
|
|
mutex_unlock(&bio_slab_lock);
|
|
}
|
|
|
|
void bvec_free(mempool_t *pool, struct bio_vec *bv, unsigned short nr_vecs)
|
|
{
|
|
BUG_ON(nr_vecs > BIO_MAX_VECS);
|
|
|
|
if (nr_vecs == BIO_MAX_VECS)
|
|
mempool_free(bv, pool);
|
|
else if (nr_vecs > BIO_INLINE_VECS)
|
|
kmem_cache_free(biovec_slab(nr_vecs)->slab, bv);
|
|
}
|
|
|
|
/*
|
|
* Make the first allocation restricted and don't dump info on allocation
|
|
* failures, since we'll fall back to the mempool in case of failure.
|
|
*/
|
|
static inline gfp_t bvec_alloc_gfp(gfp_t gfp)
|
|
{
|
|
return (gfp & ~(__GFP_DIRECT_RECLAIM | __GFP_IO)) |
|
|
__GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN;
|
|
}
|
|
|
|
struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs,
|
|
gfp_t gfp_mask)
|
|
{
|
|
struct biovec_slab *bvs = biovec_slab(*nr_vecs);
|
|
|
|
if (WARN_ON_ONCE(!bvs))
|
|
return NULL;
|
|
|
|
/*
|
|
* Upgrade the nr_vecs request to take full advantage of the allocation.
|
|
* We also rely on this in the bvec_free path.
|
|
*/
|
|
*nr_vecs = bvs->nr_vecs;
|
|
|
|
/*
|
|
* Try a slab allocation first for all smaller allocations. If that
|
|
* fails and __GFP_DIRECT_RECLAIM is set retry with the mempool.
|
|
* The mempool is sized to handle up to BIO_MAX_VECS entries.
|
|
*/
|
|
if (*nr_vecs < BIO_MAX_VECS) {
|
|
struct bio_vec *bvl;
|
|
|
|
bvl = kmem_cache_alloc(bvs->slab, bvec_alloc_gfp(gfp_mask));
|
|
if (likely(bvl) || !(gfp_mask & __GFP_DIRECT_RECLAIM))
|
|
return bvl;
|
|
*nr_vecs = BIO_MAX_VECS;
|
|
}
|
|
|
|
return mempool_alloc(pool, gfp_mask);
|
|
}
|
|
|
|
void bio_uninit(struct bio *bio)
|
|
{
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
if (bio->bi_blkg) {
|
|
blkg_put(bio->bi_blkg);
|
|
bio->bi_blkg = NULL;
|
|
}
|
|
#endif
|
|
if (bio_integrity(bio))
|
|
bio_integrity_free(bio);
|
|
|
|
bio_crypt_free_ctx(bio);
|
|
}
|
|
EXPORT_SYMBOL(bio_uninit);
|
|
|
|
static void bio_free(struct bio *bio)
|
|
{
|
|
struct bio_set *bs = bio->bi_pool;
|
|
void *p = bio;
|
|
|
|
WARN_ON_ONCE(!bs);
|
|
|
|
bio_uninit(bio);
|
|
bvec_free(&bs->bvec_pool, bio->bi_io_vec, bio->bi_max_vecs);
|
|
mempool_free(p - bs->front_pad, &bs->bio_pool);
|
|
}
|
|
|
|
/*
|
|
* 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 block_device *bdev, struct bio_vec *table,
|
|
unsigned short max_vecs, blk_opf_t opf)
|
|
{
|
|
bio->bi_next = NULL;
|
|
bio->bi_bdev = bdev;
|
|
bio->bi_opf = opf;
|
|
bio->bi_flags = 0;
|
|
bio->bi_ioprio = 0;
|
|
bio->bi_status = 0;
|
|
bio->bi_iter.bi_sector = 0;
|
|
bio->bi_iter.bi_size = 0;
|
|
bio->bi_iter.bi_idx = 0;
|
|
bio->bi_iter.bi_bvec_done = 0;
|
|
bio->bi_end_io = NULL;
|
|
bio->bi_private = NULL;
|
|
#ifdef CONFIG_BLK_CGROUP
|
|
bio->bi_blkg = NULL;
|
|
bio->bi_issue.value = 0;
|
|
if (bdev)
|
|
bio_associate_blkg(bio);
|
|
#ifdef CONFIG_BLK_CGROUP_IOCOST
|
|
bio->bi_iocost_cost = 0;
|
|
#endif
|
|
#endif
|
|
#ifdef CONFIG_BLK_INLINE_ENCRYPTION
|
|
bio->bi_crypt_context = NULL;
|
|
#if IS_ENABLED(CONFIG_DM_DEFAULT_KEY)
|
|
bio->bi_skip_dm_default_key = false;
|
|
#endif
|
|
#endif
|
|
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
|
bio->bi_integrity = NULL;
|
|
#endif
|
|
bio->bi_vcnt = 0;
|
|
|
|
atomic_set(&bio->__bi_remaining, 1);
|
|
atomic_set(&bio->__bi_cnt, 1);
|
|
bio->bi_cookie = BLK_QC_T_NONE;
|
|
|
|
bio->bi_max_vecs = max_vecs;
|
|
bio->bi_io_vec = table;
|
|
bio->bi_pool = NULL;
|
|
}
|
|
EXPORT_SYMBOL(bio_init);
|
|
|
|
/**
|
|
* bio_reset - reinitialize a bio
|
|
* @bio: bio to reset
|
|
* @bdev: block device to use the bio for
|
|
* @opf: operation and flags for bio
|
|
*
|
|
* 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, struct block_device *bdev, blk_opf_t opf)
|
|
{
|
|
bio_uninit(bio);
|
|
memset(bio, 0, BIO_RESET_BYTES);
|
|
atomic_set(&bio->__bi_remaining, 1);
|
|
bio->bi_bdev = bdev;
|
|
if (bio->bi_bdev)
|
|
bio_associate_blkg(bio);
|
|
bio->bi_opf = opf;
|
|
}
|
|
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 parent bio of @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);
|
|
|
|
struct bio *blk_next_bio(struct bio *bio, struct block_device *bdev,
|
|
unsigned int nr_pages, blk_opf_t opf, gfp_t gfp)
|
|
{
|
|
struct bio *new = bio_alloc(bdev, nr_pages, opf, gfp);
|
|
|
|
if (bio) {
|
|
bio_chain(bio, new);
|
|
submit_bio(bio);
|
|
}
|
|
|
|
return new;
|
|
}
|
|
EXPORT_SYMBOL_GPL(blk_next_bio);
|
|
|
|
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;
|
|
|
|
submit_bio_noacct(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);
|
|
}
|
|
|
|
static struct bio *bio_alloc_percpu_cache(struct block_device *bdev,
|
|
unsigned short nr_vecs, blk_opf_t opf, gfp_t gfp,
|
|
struct bio_set *bs)
|
|
{
|
|
struct bio_alloc_cache *cache;
|
|
struct bio *bio;
|
|
|
|
cache = per_cpu_ptr(bs->cache, get_cpu());
|
|
if (!cache->free_list) {
|
|
put_cpu();
|
|
return NULL;
|
|
}
|
|
bio = cache->free_list;
|
|
cache->free_list = bio->bi_next;
|
|
cache->nr--;
|
|
put_cpu();
|
|
|
|
bio_init(bio, bdev, nr_vecs ? bio->bi_inline_vecs : NULL, nr_vecs, opf);
|
|
bio->bi_pool = bs;
|
|
return bio;
|
|
}
|
|
|
|
/**
|
|
* bio_alloc_bioset - allocate a bio for I/O
|
|
* @bdev: block device to allocate the bio for (can be %NULL)
|
|
* @nr_vecs: number of bvecs to pre-allocate
|
|
* @opf: operation and flags for bio
|
|
* @gfp_mask: the GFP_* mask given to the slab allocator
|
|
* @bs: the bio_set to allocate from.
|
|
*
|
|
* Allocate a bio from the mempools in @bs.
|
|
*
|
|
* 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 the general 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 submit_bio_noacct() (i.e. any block driver),
|
|
* bios are not submitted until after you return - see the code in
|
|
* submit_bio_noacct() that converts recursion into iteration, to prevent
|
|
* stack overflows.
|
|
*
|
|
* This would normally mean allocating multiple bios under submit_bio_noacct()
|
|
* 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
|
|
* submit_bio_noacct() should be avoided - instead, use bio_set's front_pad
|
|
* for per bio allocations.
|
|
*
|
|
* If REQ_ALLOC_CACHE is set, the final put of the bio MUST be done from process
|
|
* context, not hard/soft IRQ.
|
|
*
|
|
* Returns: Pointer to new bio on success, NULL on failure.
|
|
*/
|
|
struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
|
|
blk_opf_t opf, gfp_t gfp_mask,
|
|
struct bio_set *bs)
|
|
{
|
|
gfp_t saved_gfp = gfp_mask;
|
|
struct bio *bio;
|
|
void *p;
|
|
|
|
/* should not use nobvec bioset for nr_vecs > 0 */
|
|
if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
|
|
return NULL;
|
|
|
|
if (opf & REQ_ALLOC_CACHE) {
|
|
if (bs->cache && nr_vecs <= BIO_INLINE_VECS) {
|
|
bio = bio_alloc_percpu_cache(bdev, nr_vecs, opf,
|
|
gfp_mask, bs);
|
|
if (bio)
|
|
return bio;
|
|
/*
|
|
* No cached bio available, bio returned below marked with
|
|
* REQ_ALLOC_CACHE to particpate in per-cpu alloc cache.
|
|
*/
|
|
} else {
|
|
opf &= ~REQ_ALLOC_CACHE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* submit_bio_noacct() 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 submit_bio_noacct().
|
|
* 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);
|
|
}
|
|
if (unlikely(!p))
|
|
return NULL;
|
|
|
|
bio = p + bs->front_pad;
|
|
if (nr_vecs > BIO_INLINE_VECS) {
|
|
struct bio_vec *bvl = NULL;
|
|
|
|
bvl = bvec_alloc(&bs->bvec_pool, &nr_vecs, gfp_mask);
|
|
if (!bvl && gfp_mask != saved_gfp) {
|
|
punt_bios_to_rescuer(bs);
|
|
gfp_mask = saved_gfp;
|
|
bvl = bvec_alloc(&bs->bvec_pool, &nr_vecs, gfp_mask);
|
|
}
|
|
if (unlikely(!bvl))
|
|
goto err_free;
|
|
|
|
bio_init(bio, bdev, bvl, nr_vecs, opf);
|
|
} else if (nr_vecs) {
|
|
bio_init(bio, bdev, bio->bi_inline_vecs, BIO_INLINE_VECS, opf);
|
|
} else {
|
|
bio_init(bio, bdev, NULL, 0, opf);
|
|
}
|
|
|
|
bio->bi_pool = bs;
|
|
return bio;
|
|
|
|
err_free:
|
|
mempool_free(p, &bs->bio_pool);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(bio_alloc_bioset);
|
|
|
|
/**
|
|
* bio_kmalloc - kmalloc a bio
|
|
* @nr_vecs: number of bio_vecs to allocate
|
|
* @gfp_mask: the GFP_* mask given to the slab allocator
|
|
*
|
|
* Use kmalloc to allocate a bio (including bvecs). The bio must be initialized
|
|
* using bio_init() before use. To free a bio returned from this function use
|
|
* kfree() after calling bio_uninit(). A bio returned from this function can
|
|
* be reused by calling bio_uninit() before calling bio_init() again.
|
|
*
|
|
* Note that unlike bio_alloc() or bio_alloc_bioset() allocations from this
|
|
* function are not backed by a mempool can fail. Do not use this function
|
|
* for allocations in the file system I/O path.
|
|
*
|
|
* Returns: Pointer to new bio on success, NULL on failure.
|
|
*/
|
|
struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)
|
|
{
|
|
struct bio *bio;
|
|
|
|
if (nr_vecs > UIO_MAXIOV)
|
|
return NULL;
|
|
return kmalloc(struct_size(bio, bi_inline_vecs, nr_vecs), gfp_mask);
|
|
}
|
|
EXPORT_SYMBOL(bio_kmalloc);
|
|
|
|
void zero_fill_bio(struct bio *bio)
|
|
{
|
|
struct bio_vec bv;
|
|
struct bvec_iter iter;
|
|
|
|
bio_for_each_segment(bv, bio, iter)
|
|
memzero_bvec(&bv);
|
|
}
|
|
EXPORT_SYMBOL(zero_fill_bio);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
static 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;
|
|
}
|
|
|
|
/**
|
|
* guard_bio_eod - truncate a BIO to fit the block device
|
|
* @bio: bio to truncate
|
|
*
|
|
* This allows us to do IO even on the odd last sectors of a device, even if the
|
|
* block size is some multiple of the physical sector size.
|
|
*
|
|
* We'll just truncate the bio to the size of the device, and clear the end of
|
|
* the buffer head manually. Truly out-of-range accesses will turn into actual
|
|
* I/O errors, this only handles the "we need to be able to do I/O at the final
|
|
* sector" case.
|
|
*/
|
|
void guard_bio_eod(struct bio *bio)
|
|
{
|
|
sector_t maxsector = bdev_nr_sectors(bio->bi_bdev);
|
|
|
|
if (!maxsector)
|
|
return;
|
|
|
|
/*
|
|
* If the *whole* IO is past the end of the device,
|
|
* let it through, and the IO layer will turn it into
|
|
* an EIO.
|
|
*/
|
|
if (unlikely(bio->bi_iter.bi_sector >= maxsector))
|
|
return;
|
|
|
|
maxsector -= bio->bi_iter.bi_sector;
|
|
if (likely((bio->bi_iter.bi_size >> 9) <= maxsector))
|
|
return;
|
|
|
|
bio_truncate(bio, maxsector << 9);
|
|
}
|
|
|
|
#define ALLOC_CACHE_MAX 512
|
|
#define ALLOC_CACHE_SLACK 64
|
|
|
|
static void bio_alloc_cache_prune(struct bio_alloc_cache *cache,
|
|
unsigned int nr)
|
|
{
|
|
unsigned int i = 0;
|
|
struct bio *bio;
|
|
|
|
while ((bio = cache->free_list) != NULL) {
|
|
cache->free_list = bio->bi_next;
|
|
cache->nr--;
|
|
bio_free(bio);
|
|
if (++i == nr)
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int bio_cpu_dead(unsigned int cpu, struct hlist_node *node)
|
|
{
|
|
struct bio_set *bs;
|
|
|
|
bs = hlist_entry_safe(node, struct bio_set, cpuhp_dead);
|
|
if (bs->cache) {
|
|
struct bio_alloc_cache *cache = per_cpu_ptr(bs->cache, cpu);
|
|
|
|
bio_alloc_cache_prune(cache, -1U);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void bio_alloc_cache_destroy(struct bio_set *bs)
|
|
{
|
|
int cpu;
|
|
|
|
if (!bs->cache)
|
|
return;
|
|
|
|
cpuhp_state_remove_instance_nocalls(CPUHP_BIO_DEAD, &bs->cpuhp_dead);
|
|
for_each_possible_cpu(cpu) {
|
|
struct bio_alloc_cache *cache;
|
|
|
|
cache = per_cpu_ptr(bs->cache, cpu);
|
|
bio_alloc_cache_prune(cache, -1U);
|
|
}
|
|
free_percpu(bs->cache);
|
|
bs->cache = NULL;
|
|
}
|
|
|
|
/**
|
|
* 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 (unlikely(bio_flagged(bio, BIO_REFFED))) {
|
|
BUG_ON(!atomic_read(&bio->__bi_cnt));
|
|
if (!atomic_dec_and_test(&bio->__bi_cnt))
|
|
return;
|
|
}
|
|
|
|
if ((bio->bi_opf & REQ_ALLOC_CACHE) && !WARN_ON_ONCE(in_interrupt())) {
|
|
struct bio_alloc_cache *cache;
|
|
|
|
bio_uninit(bio);
|
|
cache = per_cpu_ptr(bio->bi_pool->cache, get_cpu());
|
|
bio->bi_next = cache->free_list;
|
|
bio->bi_bdev = NULL;
|
|
cache->free_list = bio;
|
|
if (++cache->nr > ALLOC_CACHE_MAX + ALLOC_CACHE_SLACK)
|
|
bio_alloc_cache_prune(cache, ALLOC_CACHE_SLACK);
|
|
put_cpu();
|
|
} else {
|
|
bio_free(bio);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(bio_put);
|
|
|
|
static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
|
|
{
|
|
bio_set_flag(bio, BIO_CLONED);
|
|
bio->bi_ioprio = bio_src->bi_ioprio;
|
|
bio->bi_iter = bio_src->bi_iter;
|
|
|
|
if (bio->bi_bdev) {
|
|
if (bio->bi_bdev == bio_src->bi_bdev &&
|
|
bio_flagged(bio_src, BIO_REMAPPED))
|
|
bio_set_flag(bio, BIO_REMAPPED);
|
|
bio_clone_blkg_association(bio, bio_src);
|
|
}
|
|
|
|
if (bio_crypt_clone(bio, bio_src, gfp) < 0)
|
|
return -ENOMEM;
|
|
if (bio_integrity(bio_src) &&
|
|
bio_integrity_clone(bio, bio_src, gfp) < 0)
|
|
return -ENOMEM;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* bio_alloc_clone - clone a bio that shares the original bio's biovec
|
|
* @bdev: block_device to clone onto
|
|
* @bio_src: bio to clone from
|
|
* @gfp: allocation priority
|
|
* @bs: bio_set to allocate from
|
|
*
|
|
* Allocate a new bio that is a clone of @bio_src. The caller owns the returned
|
|
* bio, but not the actual data it points to.
|
|
*
|
|
* The caller must ensure that the return bio is not freed before @bio_src.
|
|
*/
|
|
struct bio *bio_alloc_clone(struct block_device *bdev, struct bio *bio_src,
|
|
gfp_t gfp, struct bio_set *bs)
|
|
{
|
|
struct bio *bio;
|
|
|
|
bio = bio_alloc_bioset(bdev, 0, bio_src->bi_opf, gfp, bs);
|
|
if (!bio)
|
|
return NULL;
|
|
|
|
if (__bio_clone(bio, bio_src, gfp) < 0) {
|
|
bio_put(bio);
|
|
return NULL;
|
|
}
|
|
bio->bi_io_vec = bio_src->bi_io_vec;
|
|
|
|
return bio;
|
|
}
|
|
EXPORT_SYMBOL(bio_alloc_clone);
|
|
|
|
/**
|
|
* bio_init_clone - clone a bio that shares the original bio's biovec
|
|
* @bdev: block_device to clone onto
|
|
* @bio: bio to clone into
|
|
* @bio_src: bio to clone from
|
|
* @gfp: allocation priority
|
|
*
|
|
* Initialize a new bio in caller provided memory that is a clone of @bio_src.
|
|
* The caller owns the returned bio, but not the actual data it points to.
|
|
*
|
|
* The caller must ensure that @bio_src is not freed before @bio.
|
|
*/
|
|
int bio_init_clone(struct block_device *bdev, struct bio *bio,
|
|
struct bio *bio_src, gfp_t gfp)
|
|
{
|
|
int ret;
|
|
|
|
bio_init(bio, bdev, bio_src->bi_io_vec, 0, bio_src->bi_opf);
|
|
ret = __bio_clone(bio, bio_src, gfp);
|
|
if (ret)
|
|
bio_uninit(bio);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(bio_init_clone);
|
|
|
|
/**
|
|
* bio_full - check if the bio is full
|
|
* @bio: bio to check
|
|
* @len: length of one segment to be added
|
|
*
|
|
* Return true if @bio is full and one segment with @len bytes can't be
|
|
* added to the bio, otherwise return false
|
|
*/
|
|
static inline bool bio_full(struct bio *bio, unsigned len)
|
|
{
|
|
if (bio->bi_vcnt >= bio->bi_max_vecs)
|
|
return true;
|
|
if (bio->bi_iter.bi_size > UINT_MAX - len)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
else if (IS_ENABLED(CONFIG_KMSAN))
|
|
return false;
|
|
return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
|
|
}
|
|
|
|
/**
|
|
* __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
|
|
* 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.
|
|
*/
|
|
static 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_is_mergeable(bv, page, len, off, same_page)) {
|
|
if (bio->bi_iter.bi_size > UINT_MAX - len) {
|
|
*same_page = false;
|
|
return false;
|
|
}
|
|
bv->bv_len += len;
|
|
bio->bi_iter.bi_size += len;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Try to merge a page into a segment, while obeying the hardware segment
|
|
* size limit. This is not for normal read/write bios, but for passthrough
|
|
* or Zone Append operations that we can't split.
|
|
*/
|
|
static bool bio_try_merge_hw_seg(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 (bv->bv_len + len > queue_max_segment_size(q))
|
|
return false;
|
|
return __bio_try_merge_page(bio, page, len, offset, same_page);
|
|
}
|
|
|
|
/**
|
|
* bio_add_hw_page - attempt to add a page to a bio with hw constraints
|
|
* @q: the target queue
|
|
* @bio: destination bio
|
|
* @page: page to add
|
|
* @len: vec entry length
|
|
* @offset: vec entry offset
|
|
* @max_sectors: maximum number of sectors that can be added
|
|
* @same_page: return if the segment has been merged inside the same page
|
|
*
|
|
* Add a page to a bio while respecting the hardware max_sectors, max_segment
|
|
* and gap limitations.
|
|
*/
|
|
int bio_add_hw_page(struct request_queue *q, struct bio *bio,
|
|
struct page *page, unsigned int len, unsigned int offset,
|
|
unsigned int max_sectors, bool *same_page)
|
|
{
|
|
struct bio_vec *bvec;
|
|
|
|
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
|
|
return 0;
|
|
|
|
if (((bio->bi_iter.bi_size + len) >> 9) > max_sectors)
|
|
return 0;
|
|
|
|
if (bio->bi_vcnt > 0) {
|
|
if (bio_try_merge_hw_seg(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->limits, 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;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*
|
|
* 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.
|
|
*/
|
|
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_hw_page(q, bio, page, len, offset,
|
|
queue_max_hw_sectors(q), &same_page);
|
|
}
|
|
EXPORT_SYMBOL(bio_add_pc_page);
|
|
|
|
/**
|
|
* bio_add_zone_append_page - attempt to add page to zone-append bio
|
|
* @bio: destination bio
|
|
* @page: page to add
|
|
* @len: vec entry length
|
|
* @offset: vec entry offset
|
|
*
|
|
* Attempt to add a page to the bio_vec maplist of a bio that will be submitted
|
|
* for a zone-append request. This can fail for a number of reasons, such as the
|
|
* bio being full or the target block device is not a zoned block device or
|
|
* other limitations of the target block device. 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.
|
|
*
|
|
* Returns: number of bytes added to the bio, or 0 in case of a failure.
|
|
*/
|
|
int bio_add_zone_append_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int offset)
|
|
{
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
bool same_page = false;
|
|
|
|
if (WARN_ON_ONCE(bio_op(bio) != REQ_OP_ZONE_APPEND))
|
|
return 0;
|
|
|
|
if (WARN_ON_ONCE(!bdev_is_zoned(bio->bi_bdev)))
|
|
return 0;
|
|
|
|
return bio_add_hw_page(q, bio, page, len, offset,
|
|
queue_max_zone_append_sectors(q), &same_page);
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_add_zone_append_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++;
|
|
}
|
|
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);
|
|
|
|
/**
|
|
* bio_add_folio - Attempt to add part of a folio to a bio.
|
|
* @bio: BIO to add to.
|
|
* @folio: Folio to add.
|
|
* @len: How many bytes from the folio to add.
|
|
* @off: First byte in this folio to add.
|
|
*
|
|
* Filesystems that use folios can call this function instead of calling
|
|
* bio_add_page() for each page in the folio. If @off is bigger than
|
|
* PAGE_SIZE, this function can create a bio_vec that starts in a page
|
|
* after the bv_page. BIOs do not support folios that are 4GiB or larger.
|
|
*
|
|
* Return: Whether the addition was successful.
|
|
*/
|
|
bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
|
|
size_t off)
|
|
{
|
|
if (len > UINT_MAX || off > UINT_MAX)
|
|
return false;
|
|
return bio_add_page(bio, &folio->page, len, off) > 0;
|
|
}
|
|
|
|
void __bio_release_pages(struct bio *bio, bool mark_dirty)
|
|
{
|
|
struct bvec_iter_all iter_all;
|
|
struct bio_vec *bvec;
|
|
|
|
bio_for_each_segment_all(bvec, bio, iter_all) {
|
|
if (mark_dirty && !PageCompound(bvec->bv_page))
|
|
set_page_dirty_lock(bvec->bv_page);
|
|
put_page(bvec->bv_page);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(__bio_release_pages);
|
|
|
|
void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
|
|
{
|
|
size_t size = iov_iter_count(iter);
|
|
|
|
WARN_ON_ONCE(bio->bi_max_vecs);
|
|
|
|
if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
size_t max_sectors = queue_max_zone_append_sectors(q);
|
|
|
|
size = min(size, max_sectors << SECTOR_SHIFT);
|
|
}
|
|
|
|
bio->bi_vcnt = iter->nr_segs;
|
|
bio->bi_io_vec = (struct bio_vec *)iter->bvec;
|
|
bio->bi_iter.bi_bvec_done = iter->iov_offset;
|
|
bio->bi_iter.bi_size = size;
|
|
bio_set_flag(bio, BIO_NO_PAGE_REF);
|
|
bio_set_flag(bio, BIO_CLONED);
|
|
}
|
|
|
|
static int bio_iov_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)) {
|
|
__bio_add_page(bio, page, len, offset);
|
|
return 0;
|
|
}
|
|
|
|
if (same_page)
|
|
put_page(page);
|
|
return 0;
|
|
}
|
|
|
|
static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page,
|
|
unsigned int len, unsigned int offset)
|
|
{
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
bool same_page = false;
|
|
|
|
if (bio_add_hw_page(q, bio, page, len, offset,
|
|
queue_max_zone_append_sectors(q), &same_page) != len)
|
|
return -EINVAL;
|
|
if (same_page)
|
|
put_page(page);
|
|
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
|
|
* 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;
|
|
ssize_t size, left;
|
|
unsigned len, i = 0;
|
|
size_t offset, trim;
|
|
int ret = 0;
|
|
|
|
/*
|
|
* 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);
|
|
|
|
/*
|
|
* Each segment in the iov is required to be a block size multiple.
|
|
* However, we may not be able to get the entire segment if it spans
|
|
* more pages than bi_max_vecs allows, so we have to ALIGN_DOWN the
|
|
* result to ensure the bio's total size is correct. The remainder of
|
|
* the iov data will be picked up in the next bio iteration.
|
|
*/
|
|
size = iov_iter_get_pages2(iter, pages, UINT_MAX - bio->bi_iter.bi_size,
|
|
nr_pages, &offset);
|
|
if (unlikely(size <= 0))
|
|
return size ? size : -EFAULT;
|
|
|
|
nr_pages = DIV_ROUND_UP(offset + size, PAGE_SIZE);
|
|
|
|
trim = size & (bdev_logical_block_size(bio->bi_bdev) - 1);
|
|
iov_iter_revert(iter, trim);
|
|
|
|
size -= trim;
|
|
if (unlikely(!size)) {
|
|
ret = -EFAULT;
|
|
goto out;
|
|
}
|
|
|
|
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_op(bio) == REQ_OP_ZONE_APPEND) {
|
|
ret = bio_iov_add_zone_append_page(bio, page, len,
|
|
offset);
|
|
if (ret)
|
|
break;
|
|
} else
|
|
bio_iov_add_page(bio, page, len, offset);
|
|
|
|
offset = 0;
|
|
}
|
|
|
|
iov_iter_revert(iter, left);
|
|
out:
|
|
while (i < nr_pages)
|
|
put_page(pages[i++]);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* 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. For bvec based iterators bio_iov_iter_get_pages() uses the provided
|
|
* bvecs rather than copying them. Hence anyone issuing kiocb based IO needs
|
|
* to ensure the bvecs and pages stay referenced until the submitted I/O is
|
|
* completed by a call to ->ki_complete() or returns with an error other than
|
|
* -EIOCBQUEUED. 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)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (iov_iter_is_bvec(iter)) {
|
|
bio_iov_bvec_set(bio, iter);
|
|
iov_iter_advance(iter, bio->bi_iter.bi_size);
|
|
return 0;
|
|
}
|
|
|
|
do {
|
|
ret = __bio_iov_iter_get_pages(bio, iter);
|
|
} while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
|
|
|
|
return bio->bi_vcnt ? 0 : ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
|
|
|
|
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_bdev->bd_disk->lockdep_map);
|
|
unsigned long hang_check;
|
|
|
|
bio->bi_private = &done;
|
|
bio->bi_end_io = submit_bio_wait_endio;
|
|
bio->bi_opf |= REQ_SYNC;
|
|
submit_bio(bio);
|
|
|
|
/* Prevent hang_check timer from firing at us during very long I/O */
|
|
hang_check = sysctl_hung_task_timeout_secs;
|
|
if (hang_check)
|
|
while (!wait_for_completion_io_timeout(&done,
|
|
hang_check * (HZ/2)))
|
|
;
|
|
else
|
|
wait_for_completion_io(&done);
|
|
|
|
return blk_status_to_errno(bio->bi_status);
|
|
}
|
|
EXPORT_SYMBOL(submit_bio_wait);
|
|
|
|
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)
|
|
{
|
|
while (src_iter->bi_size && dst_iter->bi_size) {
|
|
struct bio_vec src_bv = bio_iter_iovec(src, *src_iter);
|
|
struct bio_vec dst_bv = bio_iter_iovec(dst, *dst_iter);
|
|
unsigned int bytes = min(src_bv.bv_len, dst_bv.bv_len);
|
|
void *src_buf = bvec_kmap_local(&src_bv);
|
|
void *dst_buf = bvec_kmap_local(&dst_bv);
|
|
|
|
memcpy(dst_buf, src_buf, bytes);
|
|
|
|
kunmap_local(dst_buf);
|
|
kunmap_local(src_buf);
|
|
|
|
bio_advance_iter_single(src, src_iter, bytes);
|
|
bio_advance_iter_single(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);
|
|
|
|
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_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) {
|
|
if (!PageCompound(bvec->bv_page))
|
|
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) && !PageCompound(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);
|
|
}
|
|
|
|
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.
|
|
**/
|
|
void bio_endio(struct bio *bio)
|
|
{
|
|
again:
|
|
if (!bio_remaining_done(bio))
|
|
return;
|
|
if (!bio_integrity_endio(bio))
|
|
return;
|
|
|
|
rq_qos_done_bio(bio);
|
|
|
|
if (bio->bi_bdev && bio_flagged(bio, BIO_TRACE_COMPLETION)) {
|
|
trace_block_bio_complete(bdev_get_queue(bio->bi_bdev), bio);
|
|
bio_clear_flag(bio, BIO_TRACE_COMPLETION);
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
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));
|
|
|
|
/* Zone append commands cannot be split */
|
|
if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND))
|
|
return NULL;
|
|
|
|
split = bio_alloc_clone(bio->bi_bdev, 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
|
|
*
|
|
* This function is typically used for bios that are cloned and submitted
|
|
* to the underlying device in parts.
|
|
*/
|
|
void bio_trim(struct bio *bio, sector_t offset, sector_t size)
|
|
{
|
|
if (WARN_ON_ONCE(offset > BIO_MAX_SECTORS || size > BIO_MAX_SECTORS ||
|
|
offset + size > bio_sectors(bio)))
|
|
return;
|
|
|
|
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 + ARRAY_SIZE(bvec_slabs) - 1;
|
|
|
|
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)
|
|
{
|
|
bio_alloc_cache_destroy(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_init_clone().
|
|
* 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)
|
|
{
|
|
bs->front_pad = front_pad;
|
|
if (flags & BIOSET_NEED_BVECS)
|
|
bs->back_pad = BIO_INLINE_VECS * sizeof(struct bio_vec);
|
|
else
|
|
bs->back_pad = 0;
|
|
|
|
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(bs);
|
|
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) {
|
|
bs->rescue_workqueue = alloc_workqueue("bioset",
|
|
WQ_MEM_RECLAIM, 0);
|
|
if (!bs->rescue_workqueue)
|
|
goto bad;
|
|
}
|
|
if (flags & BIOSET_PERCPU_CACHE) {
|
|
bs->cache = alloc_percpu(struct bio_alloc_cache);
|
|
if (!bs->cache)
|
|
goto bad;
|
|
cpuhp_state_add_instance_nocalls(CPUHP_BIO_DEAD, &bs->cpuhp_dead);
|
|
}
|
|
|
|
return 0;
|
|
bad:
|
|
bioset_exit(bs);
|
|
return -ENOMEM;
|
|
}
|
|
EXPORT_SYMBOL(bioset_init);
|
|
|
|
static int __init init_bio(void)
|
|
{
|
|
int i;
|
|
|
|
bio_integrity_init();
|
|
|
|
for (i = 0; i < ARRAY_SIZE(bvec_slabs); i++) {
|
|
struct biovec_slab *bvs = bvec_slabs + i;
|
|
|
|
bvs->slab = kmem_cache_create(bvs->name,
|
|
bvs->nr_vecs * sizeof(struct bio_vec), 0,
|
|
SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
|
|
}
|
|
|
|
cpuhp_setup_state_multi(CPUHP_BIO_DEAD, "block/bio:dead", NULL,
|
|
bio_cpu_dead);
|
|
|
|
if (bioset_init(&fs_bio_set, BIO_POOL_SIZE, 0,
|
|
BIOSET_NEED_BVECS | BIOSET_PERCPU_CACHE))
|
|
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);
|