mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
* remotes/origin/tmp-b7e55e8: Linux 4.14.61 scsi: sg: fix minor memory leak in error path drm/vc4: Reset ->{x, y}_scaling[1] when dealing with uniplanar formats crypto: padlock-aes - Fix Nano workaround data corruption RDMA/uverbs: Expand primary and alt AV port checks iwlwifi: add more card IDs for 9000 series userfaultfd: remove uffd flags from vma->vm_flags if UFFD_EVENT_FORK fails audit: fix potential null dereference 'context->module.name' kvm: x86: vmx: fix vpid leak x86/entry/64: Remove %ebx handling from error_entry/exit x86/apic: Future-proof the TSC_DEADLINE quirk for SKX virtio_balloon: fix another race between migration and ballooning net: socket: fix potential spectre v1 gadget in socketcall can: ems_usb: Fix memory leak on ems_usb_disconnect() squashfs: more metadata hardenings squashfs: more metadata hardening net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager rxrpc: Fix user call ID check in rxrpc_service_prealloc_one net: stmmac: Fix WoL for PCI-based setups netlink: Fix spectre v1 gadget in netlink_create() net: dsa: Do not suspend/resume closed slave_dev ipv4: frags: handle possible skb truesize change inet: frag: enforce memory limits earlier bonding: avoid lockdep confusion in bond_get_stats() Linux 4.14.60 tcp: add one more quick ack after after ECN events tcp: refactor tcp_ecn_check_ce to remove sk type cast tcp: do not aggressively quick ack after ECN events tcp: add max_quickacks param to tcp_incr_quickack and tcp_enter_quickack_mode tcp: do not force quickack when receiving out-of-order packets netlink: Don't shift with UB on nlk->ngroups netlink: Do not subscribe to non-existent groups xen-netfront: wait xenbus state change when load module manually tcp_bbr: fix bw probing to raise in-flight data for very small BDPs NET: stmmac: align DMA stuff to largest cache line length net: mdio-mux: bcm-iproc: fix wrong getter and setter pair net: lan78xx: fix rx handling before first packet is send net: fix amd-xgbe flow-control issue net: ena: Fix use of uninitialized DMA address bits field ipv4: remove BUG_ON() from fib_compute_spec_dst net: dsa: qca8k: Allow overwriting CPU port setting net: dsa: qca8k: Add QCA8334 binding documentation net: dsa: qca8k: Enable RXMAC when bringing up a port net: dsa: qca8k: Force CPU port to its highest bandwidth RDMA/uverbs: Protect from attempts to create flows on unsupported QP usb: gadget: udc: renesas_usb3: should remove debugfs ovl: Sync upper dirty data when syncing overlayfs PCI: xgene: Remove leftover pci_scan_child_bus() call PCI: pciehp: Assume NoCompl+ for Thunderbolt ports ext4: fix check to prevent initializing reserved inodes ext4: check for allocation block validity with block group locked ext4: fix inline data updates with checksums enabled squashfs: be more careful about metadata corruption random: mix rdrand with entropy sent in from userspace block: reset bi_iter.bi_done after splitting bio blkdev: __blkdev_direct_IO_simple: fix leak in error case block: bio_iov_iter_get_pages: fix size of last iovec drm/dp/mst: Fix off-by-one typo when dump payload table drm/atomic-helper: Drop plane->fb references only for drm_atomic_helper_shutdown() drm: Add DP PSR2 sink enable bit ASoC: topology: Add missing clock gating parameter when parsing hw_configs ASoC: topology: Fix bclk and fsync inversion in set_link_hw_format() media: si470x: fix __be16 annotations media: atomisp: compat32: fix __user annotations scsi: cxlflash: Avoid clobbering context control register value scsi: cxlflash: Synchronize reset and remove ops scsi: megaraid_sas: Increase timeout by 1 sec for non-RAID fastpath IOs scsi: scsi_dh: replace too broad "TP9" string with the exact models regulator: Don't return or expect -errno from of_map_mode() media: omap3isp: fix unbalanced dma_iommu_mapping crypto: authenc - don't leak pointers to authenc keys crypto: authencesn - don't leak pointers to authenc keys usb: hub: Don't wait for connect state at resume for powered-off ports microblaze: Fix simpleImage format generation soc: imx: gpcv2: Do not pass static memory as platform data serial: core: Make sure compiler barfs for 16-byte earlycon names staging: lustre: ldlm: free resource when ldlm_lock_create() fails. staging: lustre: llite: correct removexattr detection staging: vchiq_core: Fix missing semaphore release in error case audit: allow not equal op for audit by executable rsi: fix nommu_map_sg overflow kernel panic rsi: Fix 'invalid vdd' warning in mmc ipconfig: Correctly initialise ic_nameservers drm/gma500: fix psb_intel_lvds_mode_valid()'s return type igb: Fix queue selection on MAC filters on i210 arm64: defconfig: Enable Rockchip io-domain driver nvme: lightnvm: add granby support memory: tegra: Apply interrupts mask per SoC memory: tegra: Do not handle spurious interrupts delayacct: Use raw_spinlocks stop_machine: Use raw spinlocks backlight: pwm_bl: Don't use GPIOF_* with gpiod_get_direction dt-bindings: net: meson-dwmac: new compatible name for AXG SoC net: hns3: Fixes the out of bounds access in hclge_map_tqp spi: meson-spicc: Fix error handling in meson_spicc_probe() dt-bindings: pinctrl: meson: add support for the Meson8m2 SoC mmc: pwrseq: Use kmalloc_array instead of stack VLA mmc: dw_mmc: update actual clock for mmc debugfs ALSA: hda/ca0132: fix build failure when a local macro is defined drm/atomic: Handling the case when setting old crtc for plane media: siano: get rid of __le32/__le16 cast warnings f2fs: avoid fsync() failure caused by EAGAIN in writepage() bpf: fix references to free_bpf_prog_info() in comments thermal: exynos: fix setting rising_threshold for Exynos5433 staging: lustre: o2iblnd: Fix FastReg map/unmap for MLX5 staging: lustre: o2iblnd: fix race at kiblnd_connect_peer scsi: qedf: Set the UNLOADING flag when removing a vport scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw scsi: megaraid: silence a static checker bug scsi: 3w-xxxx: fix a missing-check bug scsi: 3w-9xxx: fix a missing-check bug bnxt_en: Check unsupported speeds in bnxt_update_link() on PF only. perf: fix invalid bit in diagnostic entry s390/cpum_sf: Add data entry sizes to sampling trailer entry brcmfmac: Add support for bcm43364 wireless chipset mtd: rawnand: fsl_ifc: fix FSL NAND driver to read all ONFI parameter pages media: saa7164: Fix driver name in debug output media: media-device: fix ioctl function types ACPI / LPSS: Only call pwm_add_table() for Bay Trail PWM if PMIC HRV is 2 libata: Fix command retry decision media: rcar_jpu: Add missing clk_disable_unprepare() on error in jpu_open() net: phy: phylink: Release link GPIO dma-iommu: Fix compilation when !CONFIG_IOMMU_DMA tty: Fix data race in tty_insert_flip_string_fixed_flag i40e: free the skb after clearing the bitlock nvmem: properly handle returned value nvmem_reg_read ARM: dts: sh73a0: Add missing interrupt-affinity to PMU node ARM: dts: emev2: Add missing interrupt-affinity to PMU node ARM: dts: stih407-pinctrl: Fix complain about IRQ_TYPE_NONE usage EDAC, altera: Fix ARM64 build warning HID: i2c-hid: check if device is there before really probing powerpc/embedded6xx/hlwd-pic: Prevent interrupts from being handled by Starlet drm/amdgpu: Remove VRAM from shared bo domains. drm/radeon: fix mode_valid's return type arm64: dts: renesas: salvator-common: use audio-graph-card for Sound HID: hid-plantronics: Re-resend Update to map button for PTT products arm64: cmpwait: Clear event register before arming exclusive monitor media: atomisp: ov2680: don't declare unused vars ALSA: usb-audio: Apply rate limit to warning messages in URB complete callback net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value media: smiapp: fix timeout checking in smiapp_read_nvm ixgbevf: fix MAC address changes through ixgbevf_set_mac() md: fix NULL dereference of mddev->pers in remove_and_add_spares() md/raid1: add error handling of read error from FailFast device regulator: pfuze100: add .is_enable() for pfuze100_swb_regulator_ops ALSA: emu10k1: Rate-limit error messages about page errors rtc: tps65910: fix possible race condition rtc: vr41xx: fix possible race condition rtc: tps6586x: fix possible race condition Bluetooth: btusb: add ID for LiteOn 04ca:301a drm/nouveau/fifo/gk104-: poll for runlist update completion scsi: zfcp: assert that the ERP lock is held when tracing a recovery trigger scsi: ufs: fix exception event handling scsi: ufs: ufshcd: fix possible unclocked register access fscrypt: use unbound workqueue for decryption net: hns3: Fix the missing client list node initialization spi: Add missing pm_runtime_put_noidle() after failed get drivers/perf: arm-ccn: don't log to dmesg in event_init ima: based on policy verify firmware signatures (pre-allocated buffer) mwifiex: correct histogram data with appropriate index net: dsa: qca8k: Add support for QCA8334 switch PCI: pciehp: Request control of native hotplug only if supported bpf: powerpc64: pad function address loads with NOPs pinctrl: at91-pio4: add missing of_node_put powerpc/8xx: fix invalid register expression in head_8xx.S spi: sh-msiof: Fix setting SIRMDR1.SYNCAC to match SITMDR1.SYNCAC powerpc: Add __printf verification to prom_printf powerpc/powermac: Mark variable x as unused powerpc/powermac: Add missing prototype for note_bootable_part() powerpc/chrp/time: Make some functions static, add missing header include powerpc/32: Add a missing include header ath: Add regulatory mapping for Bahamas ath: Add regulatory mapping for Bermuda ath: Add regulatory mapping for Serbia ath: Add regulatory mapping for Tanzania ath: Add regulatory mapping for Uganda ath: Add regulatory mapping for APL2_FCCA ath: Add regulatory mapping for APL13_WORLD ath: Add regulatory mapping for ETSI8_WORLD ath: Add regulatory mapping for FCC3_ETSIC nvme-pci: Fix AER reset handling nvme-rdma: stop admin queue before freeing it PCI: Prevent sysfs disable of device while driver is attached PM / wakeup: Make s2idle_lock a RAW_SPINLOCK x86/microcode: Make the late update update_lock a raw lock for RT btrfs: qgroup: Finish rescan when hit the last leaf of extent tree btrfs: add barriers to btrfs_sync_log before log_commit_wait wakeups Btrfs: don't BUG_ON() in btrfs_truncate_inode_items() Btrfs: don't return ino to ino cache if inode item removal fails media: videobuf2-core: don't call memop 'finish' when queueing media: tw686x: Fix incorrect vb2_mem_ops GFP flags net: hns3: Fixes the init of the VALID BD info in the descriptor wlcore: sdio: check for valid platform device data before suspend mwifiex: handle race during mwifiex_usb_disconnect mfd: cros_ec: Fail early if we cannot identify the EC ASoC: dpcm: fix BE dai not hw_free and shutdown Bluetooth: btusb: Add a new Realtek 8723DE ID 2ff8:b011 Bluetooth: hci_qca: Fix "Sleep inside atomic section" warning iwlwifi: pcie: fix race in Rx buffer allocator btrfs: balance dirty metadata pages in btrfs_finish_ordered_io PCI: Fix devm_pci_alloc_host_bridge() memory leak selftests: intel_pstate: return Kselftest Skip code for skipped tests selftests: memfd: return Kselftest Skip code for skipped tests selftests/intel_pstate: Improve test, minor fixes perf/x86/intel/uncore: Correct fixed counter index check for NHM perf/x86/intel/uncore: Correct fixed counter index check in generic code usbip: dynamically allocate idev by nports found in sysfs usbip: usbip_detach: Fix memory, udev context and udev leak block, bfq: remove wrong lock in bfq_requests_merged f2fs: fix race in between GC and atomic open f2fs: fix to detect failure of dquot_initialize f2fs: Fix deadlock in shutdown ioctl f2fs: fix to wait page writeback during revoking atomic write f2fs: fix to don't trigger writeback during recovery f2fs: fix error path of move_data_page disable loading f2fs module on PAGE_SIZE > 4KB pnfs: Don't release the sequence slot until we've processed layoutget on open netfilter: nf_tables: check msg_type before nft_trans_set(trans) lightnvm: pblk: warn in case of corrupted write buffer RDMA/mad: Convert BUG_ONs to error flows powerpc/64s: Fix compiler store ordering to SLB shadow area hvc_opal: don't set tb_ticks_per_usec in udbg_init_opal_common() powerpc/eeh: Fix use-after-release of EEH driver powerpc/64s: Add barrier_nospec powerpc/lib: Adjust .balign inside string functions for PPC32 infiniband: fix a possible use-after-free bug e1000e: Ignore TSYNCRXCTL when getting I219 clock attributes ceph: fix alignment of rasize bpf, arm32: fix inconsistent naming about emit_a32_lsr_{r64,i64} printk: drop in_nmi check from printk_safe_flush_on_panic() watchdog: da9063: Fix updating timeout value irqchip/ls-scfg-msi: Map MSIs in the iommu netfilter: ipset: List timing out entries with "timeout 1" instead of zero netfilter: ipset: forbid family for hash:mac sets perf tools: Fix pmu events parsing rule rtc: ensure rtc_set_alarm fails when alarms are not supported mm/slub.c: add __printf verification to slab_err() mm: vmalloc: avoid racy handling of debugobjects in vunmap mm: /proc/pid/pagemap: hide swap entries from unprivileged users kernel/hung_task.c: show all hung tasks before panic vfio/type1: Fix task tracking for QEMU vCPU hotplug vfio/mdev: Check globally for duplicate devices vfio: platform: Fix reset module leak in error path nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo NFSv4.1: Fix the client behaviour on NFS4ERR_SEQ_FALSE_RETRY ALSA: fm801: add error handling for snd_ctl_add ALSA: emu10k1: add error handling for snd_ctl_add skip LAYOUTRETURN if layout is invalid hv_netvsc: fix network namespace issues with VF support xen/netfront: raise max number of slots in xennet_get_responses() kcov: ensure irq code sees a valid area mlxsw: spectrum_switchdev: Fix port_vlan refcounting arm64: fix vmemmap BUILD_BUG_ON() triggering on !vmemmap setups tracing: Quiet gcc warning about maybe unused link variable tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure kthread, tracing: Don't expose half-written comm when creating kthreads tracing: Fix possible double free in event_enable_trigger_func() tracing: Fix double free of event_trigger_data delayacct: fix crash in delayacct_blkio_end() after delayacct init failure kvm, mm: account shadow page tables to kmemcg Input: elan_i2c - add another ACPI ID for Lenovo Ideapad 330-15AST Input: i8042 - add Lenovo LaVie Z to the i8042 reset list Input: elan_i2c - add ACPI ID for lenovo ideapad 330 spi: spi-s3c64xx: Fix system resume support drivers/infiniband/ulp/srpt/ib_srpt.c: fix build with gcc-4.4.4 IB/srpt: Fix an out-of-bounds stack access in srpt_zerolength_write() drivers/infiniband/core/verbs.c: fix build with gcc-4.4.4 RDMA/core: Avoid that ib_drain_qp() triggers an out-of-bounds stack access i2c: core: decrease reference count of device node in i2c_unregister_device fork: unconditionally clear stack on fork Linux 4.14.59 turn off -Wattribute-alias can: m_can.c: fix setup of CCCR register: clear CCCR NISO bit before checking can.ctrlmode can: peak_canfd: fix firmware < v3.3.0: limit allocation to 32-bit DMA addr only can: xilinx_can: fix RX overflow interrupt not being enabled can: xilinx_can: fix incorrect clear of non-processed interrupts can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting can: xilinx_can: fix device dropping off bus on RX overrun can: xilinx_can: fix recovery from error states not being propagated can: xilinx_can: fix power management handling can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK driver core: Partially revert "driver core: correct device's shutdown order" usb: gadget: f_fs: Only return delayed status when len is 0 usb: dwc2: Fix DMA alignment to start at allocated boundary usb: core: handle hub C_PORT_OVER_CURRENT condition usb: cdc_acm: Add quirk for Castles VEGA3000 staging: speakup: fix wraparound in uaccess length check tcp: add tcp_ooo_try_coalesce() helper tcp: call tcp_drop() from tcp_data_queue_ofo() tcp: detect malicious patterns in tcp_collapse_ofo_queue() tcp: avoid collapses in tcp_prune_queue() if possible tcp: free batches of packets in tcp_prune_ofo_queue() tcp: do not delay ACK in DCTCP upon CE status change tcp: do not cancel delay-AcK on DCTCP special ACK tcp: helpers to send special DCTCP ack tcp: fix dctcp delayed ACK schedule vxlan: fix default fdb entry netlink notify ordering during netdev create vxlan: make netlink notify in vxlan_fdb_destroy optional vxlan: add new fdb alloc and create helpers rtnetlink: add rtnl_link_state check in rtnl_configure_link sock: fix sg page frag coalescing in sk_alloc_sg net: phy: consider PHY_IGNORE_INTERRUPT in phy_start_aneg_priv multicast: do not restore deleted record source filter mode to new one net/ipv6: Fix linklocal to global address with VRF net/mlx5e: Fix quota counting in aRFS expire flow net/mlx5e: Don't allow aRFS for encapsulated packets net/mlx5: Adjust clock overflow work period net: skb_segment() should not return NULL net/mlx4_core: Save the qpn from the input modifier in RST2INIT wrapper ip: in cmsg IP(V6)_ORIGDSTADDR call pskb_may_pull ip: hash fragments consistently bonding: set default miimon value for non-arp modes if not set drm/nouveau: Set DRIVER_ATOMIC cap earlier to fix debugfs drm/nouveau/drm/nouveau: Fix runtime PM leak in nv50_disp_atomic_commit() KVM: PPC: Check if IOMMU page is contained in the pinned physical page xen/PVH: Set up GS segment for stack canary MIPS: Fix off-by-one in pci_resource_to_user() MIPS: ath79: fix register address in ath79_ddr_wb_flush() Revert "cifs: Fix slab-out-of-bounds in send_set_info() on SMB2 ACE setting" ANDROID: verity: really fix android-verity Kconfig tcp: add tcp_ooo_try_coalesce() helper tcp: call tcp_drop() from tcp_data_queue_ofo() tcp: detect malicious patterns in tcp_collapse_ofo_queue() tcp: avoid collapses in tcp_prune_queue() if possible tcp: free batches of packets in tcp_prune_ofo_queue() x86_64_cuttlefish_defconfig: Enable android-verity x86_64_cuttlefish_defconfig: enable verity cert ANDROID: android-verity: Fix broken parameter handling. ANDROID: android-verity: Make it work with newer kernels ANDROID: android-verity: Add API to verify signature with builtin keys. ANDROID: verity: fix android-verity Kconfig dependencies Linux 4.14.58 xhci: Fix perceived dead host due to runtime suspend race with event handler powerpc/powernv: Fix save/restore of SPRG3 on entry/exit from stop (idle) cxl_getfile(): fix double-iput() on alloc_file() failures alpha: fix osf_wait4() breakage net: usb: asix: replace mii_nway_restart in resume path ipv6: make DAD fail with enhanced DAD when nonce length differs net: systemport: Fix CRC forwarding check for SYSTEMPORT Lite net/mlx4_en: Don't reuse RX page when XDP is set hv_netvsc: Fix napi reschedule while receive completion is busy tg3: Add higher cpu clock for 5762. qmi_wwan: add support for Quectel EG91 ptp: fix missing break in switch net: phy: fix flag masking in __set_phy_supported net/ipv4: Set oif in fib_compute_spec_dst skbuff: Unconditionally copy pfmemalloc in __skb_clone() net: Don't copy pfmemalloc flag in __copy_skb_header() net: diag: Don't double-free TCP_NEW_SYN_RECV sockets in tcp_abort lib/rhashtable: consider param->min_size when setting initial table size ipv6: ila: select CONFIG_DST_CACHE ipv6: fix useless rol32 call on hash ipv4: Return EINVAL when ping_group_range sysctl doesn't map to user ns gen_stats: Fix netlink stats dumping in the presence of padding drm/nouveau: Avoid looping through fake MST connectors drm/nouveau: Use drm_connector_list_iter_* for iterating connectors drm/i915: Fix hotplug irq ack on i965/g4x stop_machine: Disable preemption when waking two stopper threads vfio/spapr: Use IOMMU pageshift rather than pagesize vfio/pci: Fix potential Spectre v1 cpufreq: intel_pstate: Register when ACPI PCCH is present mm/huge_memory.c: fix data loss when splitting a file pmd mm: memcg: fix use after free in mem_cgroup_iter() ARC: mm: allow mprotect to make stack mappings executable ARC: configs: Remove CONFIG_INITRAMFS_SOURCE from defconfigs ARC: Fix CONFIG_SWAP ARCv2: [plat-hsdk]: Save accl reg pair by default ALSA: hda: add mute led support for HP ProBook 455 G5 ALSA: hda/realtek - Add Panasonic CF-SZ6 headset jack quirk ALSA: rawmidi: Change resized buffers atomically fat: fix memory allocation failure handling of match_strdup() x86/MCE: Remove min interval polling limitation x86/events/intel/ds: Fix bts_interrupt_threshold alignment x86/apm: Don't access __preempt_count with zeroed fs KVM/Eventfd: Avoid crash when assign and deassign specific eventfd in parallel. scsi: sd_zbc: Fix variable type and bogus comment ANDROID: uid_sys_stats: Replace tasklist lock with RCU in uid_cputime_show Linux 4.14.57 string: drop __must_check from strscpy() and restore strscpy() usages in cgroup arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests arm64: KVM: Add ARCH_WORKAROUND_2 support for guests arm64: KVM: Add HYP per-cpu accessors arm64: ssbd: Add prctl interface for per-thread mitigation arm64: ssbd: Introduce thread flag to control userspace mitigation arm64: ssbd: Restore mitigation status on CPU resume arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation arm64: ssbd: Add global mitigation state accessor arm64: Add 'ssbd' command-line option arm64: Add ARCH_WORKAROUND_2 probing arm64: Add per-cpu infrastructure to call ARCH_WORKAROUND_2 arm64: Call ARCH_WORKAROUND_2 on transitions between EL0 and EL1 arm/arm64: smccc: Add SMCCC-specific return codes KVM: arm64: Avoid storing the vcpu pointer on the stack KVM: arm/arm64: Do not use kern_hyp_va() with kvm_vgic_global_state arm64: alternatives: Add dynamic patching feature KVM: arm64: Stop save/restoring host tpidr_el1 on VHE arm64: alternatives: use tpidr_el2 on VHE hosts KVM: arm64: Change hyp_panic()s dependency on tpidr_el2 KVM: arm/arm64: Convert kvm_host_cpu_state to a static per-cpu allocation KVM: arm64: Store vcpu on the stack during __guest_enter() net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL. rds: avoid unenecessary cong_update in loop transport bdi: Fix another oops in wb_workfn() netfilter: ipv6: nf_defrag: drop skb dst before queueing nsh: set mac len based on inner packet autofs: fix slab out of bounds read in getname_kernel() tls: Stricter error checking in zerocopy sendmsg path KEYS: DNS: fix parsing multiple options reiserfs: fix buffer overflow with long warning messages netfilter: ebtables: reject non-bridge targets PCI: hv: Disable/enable IRQs rather than BH in hv_compose_msi_msg() block: do not use interruptible wait anywhere mtd: rawnand: denali_dt: set clk_x_rate to 200 MHz unconditionally crypto: af_alg - Initialize sg_num_bytes in error code path clocksource: Initialize cs->wd_list media: rc: oops in ir_timer_keyup after device unplug xhci: Fix USB3 NULL pointer dereference at logical disconnect. net: lan78xx: Fix race in tx pending skb size calculation rtlwifi: rtl8821ae: fix firmware is not ready to run rtlwifi: Fix kernel Oops "Fw download fail!!" net: cxgb3_main: fix potential Spectre v1 VSOCK: fix loopback on big-endian systems vhost_net: validate sock before trying to put its fd tcp: prevent bogus FRTO undos with non-SACK flows tcp: fix Fast Open key endianness strparser: Remove early eaten to fix full tcp receive buffer stall stmmac: fix DMA channel hang in half-duplex mode r8152: napi hangup fix after disconnect qmi_wwan: add support for the Dell Wireless 5821e module qed: Limit msix vectors in kdump kernel to the minimum required count. qed: Fix use of incorrect size in memcpy call. qed: Fix setting of incorrect eswitch mode. qede: Adverstise software timestamp caps when PHC is not available. net/tcp: Fix socket lookups with SO_BINDTODEVICE net: sungem: fix rx checksum support net_sched: blackhole: tell upper qdisc about dropped packets net/packet: fix use-after-free net: mvneta: fix the Rx desc DMA address in the Rx path net/mlx5: Fix wrong size allocation for QoS ETC TC regitster net/mlx5: Fix required capability for manipulating MPFS net/mlx5: Fix incorrect raw command length parsing net/mlx5: Fix command interface race in polling mode net/mlx5: E-Switch, Avoid setup attempt if not being e-switch manager net/mlx5e: Don't attempt to dereference the ppriv struct if not being eswitch manager net/mlx5e: Avoid dealing with vport representors if not being e-switch manager net: macb: Fix ptp time adjustment for large negative delta net: fix use-after-free in GRO with ESP net: dccp: switch rx_tstamp_last_feedback to monotonic clock net: dccp: avoid crash in ccid3_hc_rx_send_feedback() ixgbe: split XDP_TX tail and XDP_REDIRECT map flushing ipvlan: fix IFLA_MTU ignored on NEWLINK ipv6: sr: fix passing wrong flags to crypto_alloc_shash() hv_netvsc: split sub-channel setup into async and sync atm: zatm: Fix potential Spectre v1 atm: Preserve value of skb->truesize when accounting to vcc alx: take rtnl before calling __alx_open from resume crypto: crypto4xx - fix crypto4xx_build_pdr, crypto4xx_build_sdr leak crypto: crypto4xx - remove bad list_del PCI: exynos: Fix a potential init_clk_resources NULL pointer dereference bcm63xx_enet: do not write to random DMA channel on BCM6345 bcm63xx_enet: correct clock usage ocfs2: ip_alloc_sem should be taken in ocfs2_get_block() ocfs2: subsystem.su_mutex is required while accessing the item->ci_parent xprtrdma: Fix corner cases when handling device removal cpufreq / CPPC: Set platform specific transition_delay_us Btrfs: fix duplicate extents after fsync of file with prealloc extents x86/paravirt: Make native_save_fl() extern inline x86/asm: Add _ASM_ARG* constants for argument registers to <asm/asm.h> compiler-gcc.h: Add __attribute__((gnu_inline)) to all inline declarations ANDROID: Add hold functionality to schedtune CPU boost ANDROID: sched/rt: Add schedtune accounting to rt task enqueue/dequeue UPSTREAM: cpuidle: menu: Avoid selecting shallow states with stopped tick UPSTREAM: cpuidle: menu: Refine idle state selection for running tick UPSTREAM: sched: idle: Select idle state before stopping the tick BACKPORT: time: hrtimer: Introduce hrtimer_next_event_without() BACKPORT: time: tick-sched: Split tick_nohz_stop_sched_tick() UPSTREAM: cpuidle: Return nohz hint from cpuidle_select() UPSTREAM: jiffies: Introduce USER_TICK_USEC and redefine TICK_USEC UPSTREAM: sched: idle: Do not stop the tick before cpuidle_idle_call() BACKPORT: sched: idle: Do not stop the tick upfront in the idle loop BACKPORT: time: tick-sched: Reorganize idle tick management code ANDROID: sched/fair: fix a warning ANDROID: sched/walt: Fix compilation issue for x86_64 ANDROID: mnt: Fix next_descendent ANDROID: sched/events: Introduce util_est trace events ANDROID: sched/fair: schedtune: update before schedutil FROMLIST: sched/fair: add support to tune PELT ramp/decay timings BACKPORT: sched/fair: Update util_est before updating schedutil BACKPORT: sched/fair: Update util_est only on util_avg updates BACKPORT: sched/fair: Use util_est in LB and WU paths BACKPORT: sched/fair: Add util_est on top of PELT ANDROID: sched/fair: Cleanup cpu_util{_wake}() ANDROID: sched: Update max cpu capacity in case of max frequency constraints ANDROID: arm: enable max frequency capping ANDROID: arm64: enable max frequency capping ANDROID: implement max frequency capping ANDROID: sched/fair: add arch scaling function for max frequency capping ANDROID: trace: Add WALT util signal to trace event sched_load_cfs_rq ANDROID: sched, trace: Remove trace event sched_load_avg_cpu ANDROID: Rename and move include/linux/sched_energy.h ANDROID: Adjust juno energy model ANDROID: Check equality of max cap state cap and cpu scale ANDROID: Move energy model init call into arch_topology driver ANDROID: Streamline sched_domain_energy_f functions ANDROID: Separate cpu_scale and energy model setup ANDROID: update_group_capacity for single cpu in cluster ANDROID: sched/fair: return idle CPU immediately for prefer_idle ANDROID: sched/fair: add idle state filter to prefer_idle case ANDROID: sched/fair: remove order from CPU selection ANDROID: sched/fair: unify spare capacity calculation ANDROID:sched/fair: prefer energy efficient CPUs for !prefer_idle tasks ANDROID: sched/fair: fix CPU selection for non latency sensitive tasks ANDROID: sched/fair: Also do misfit in overloaded groups ANDROID: sched/fair: Don't balance misfits if it would overload local group ANDROID: sched/fair: Attempt to improve throughput for asym cap systems FROMLIST: sched/fair: Don't move tasks to lower capacity cpus unless necessary FROMLIST: sched/core: Disable SD_PREFER_SIBLING on asymmetric cpu capacity domains FROMLIST: sched/core: Disable SD_ASYM_CPUCAPACITY for root_domains without asymmetry FROMLIST: sched/fair: Set rq->rd->overload when misfit FROMLIST: sched: Wrap rq->rd->overload accesses with READ/WRITE_ONCE FROMLIST: sched: Change root_domain->overload type to int FROMLIST: sched/fair: Change prefer_sibling type to bool FROMLIST: sched/fair: Consider misfit tasks when load-balancing FROMLIST: sched: Add sched_group per-cpu max capacity FROMLIST: sched/fair: Add group_misfit_task load-balance type FROMLIST: sched: Add static_key for asymmetric cpu capacity optimizations UPSTREAM: ANDROID: binder: change down_write to down_read UPSTREAM: ANDROID: binder: correct the cmd print for BINDER_WORK_RETURN_ERROR UPSTREAM: ANDROID: binder: remove 32-bit binder interface. UPSTREAM: android: binder: Use true and false for boolean values UPSTREAM: android: binder: Use octal permissions UPSTREAM: android: binder: Prefer __func__ to using hardcoded function name UPSTREAM: ANDROID: binder: make binder_alloc_new_buf_locked static and indent its arguments UPSTREAM: android: binder: Check for errors in binder_alloc_shrinker_init(). Conflicts: arch/arm64/Kconfig arch/arm64/include/asm/cpucaps.h arch/arm64/include/asm/cpufeature.h arch/arm64/include/asm/thread_info.h arch/arm64/kernel/cpu_errata.c arch/arm64/kernel/cpufeature.c arch/arm64/kernel/entry.S arch/arm64/kernel/ssbd.c drivers/base/arch_topology.c drivers/md/Kconfig drivers/scsi/ufs/ufshcd.c drivers/usb/gadget/function/f_fs.c include/trace/events/sched.h kernel/sched/cpufreq_schedutil.c kernel/sched/energy.c kernel/sched/fair.c kernel/sched/features.h kernel/sched/sched.h kernel/sched/topology.c kernel/sched/tune.c kernel/sched/walt.c kernel/sched/walt.h kernel/stop_machine.c kernel/time/tick-sched.c net/socket.c sound/core/rawmidi.c Change-Id: Ia246711317930ecd55bb42565a04e6b4fdfc26d2 Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
1175 lines
32 KiB
C
1175 lines
32 KiB
C
/* Kernel thread helper functions.
|
|
* Copyright (C) 2004 IBM Corporation, Rusty Russell.
|
|
*
|
|
* Creation is done via kthreadd, so that we get a clean environment
|
|
* even if we're invoked from userspace (think modprobe, hotplug cpu,
|
|
* etc.).
|
|
*/
|
|
#include <uapi/linux/sched/types.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/sched/task.h>
|
|
#include <linux/kthread.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/err.h>
|
|
#include <linux/cpuset.h>
|
|
#include <linux/unistd.h>
|
|
#include <linux/file.h>
|
|
#include <linux/export.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/freezer.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/cgroup.h>
|
|
#include <trace/events/sched.h>
|
|
|
|
static DEFINE_SPINLOCK(kthread_create_lock);
|
|
static LIST_HEAD(kthread_create_list);
|
|
struct task_struct *kthreadd_task;
|
|
|
|
struct kthread_create_info
|
|
{
|
|
/* Information passed to kthread() from kthreadd. */
|
|
int (*threadfn)(void *data);
|
|
void *data;
|
|
int node;
|
|
|
|
/* Result passed back to kthread_create() from kthreadd. */
|
|
struct task_struct *result;
|
|
struct completion *done;
|
|
|
|
struct list_head list;
|
|
};
|
|
|
|
struct kthread {
|
|
unsigned long flags;
|
|
unsigned int cpu;
|
|
void *data;
|
|
struct completion parked;
|
|
struct completion exited;
|
|
};
|
|
|
|
enum KTHREAD_BITS {
|
|
KTHREAD_IS_PER_CPU = 0,
|
|
KTHREAD_SHOULD_STOP,
|
|
KTHREAD_SHOULD_PARK,
|
|
};
|
|
|
|
static inline void set_kthread_struct(void *kthread)
|
|
{
|
|
/*
|
|
* We abuse ->set_child_tid to avoid the new member and because it
|
|
* can't be wrongly copied by copy_process(). We also rely on fact
|
|
* that the caller can't exec, so PF_KTHREAD can't be cleared.
|
|
*/
|
|
current->set_child_tid = (__force void __user *)kthread;
|
|
}
|
|
|
|
static inline struct kthread *to_kthread(struct task_struct *k)
|
|
{
|
|
WARN_ON(!(k->flags & PF_KTHREAD));
|
|
return (__force void *)k->set_child_tid;
|
|
}
|
|
|
|
void free_kthread_struct(struct task_struct *k)
|
|
{
|
|
/*
|
|
* Can be NULL if this kthread was created by kernel_thread()
|
|
* or if kmalloc() in kthread() failed.
|
|
*/
|
|
kfree(to_kthread(k));
|
|
}
|
|
|
|
/**
|
|
* kthread_should_stop - should this kthread return now?
|
|
*
|
|
* When someone calls kthread_stop() on your kthread, it will be woken
|
|
* and this will return true. You should then return, and your return
|
|
* value will be passed through to kthread_stop().
|
|
*/
|
|
bool kthread_should_stop(void)
|
|
{
|
|
return test_bit(KTHREAD_SHOULD_STOP, &to_kthread(current)->flags);
|
|
}
|
|
EXPORT_SYMBOL(kthread_should_stop);
|
|
|
|
/**
|
|
* kthread_should_park - should this kthread park now?
|
|
*
|
|
* When someone calls kthread_park() on your kthread, it will be woken
|
|
* and this will return true. You should then do the necessary
|
|
* cleanup and call kthread_parkme()
|
|
*
|
|
* Similar to kthread_should_stop(), but this keeps the thread alive
|
|
* and in a park position. kthread_unpark() "restarts" the thread and
|
|
* calls the thread function again.
|
|
*/
|
|
bool kthread_should_park(void)
|
|
{
|
|
return test_bit(KTHREAD_SHOULD_PARK, &to_kthread(current)->flags);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_should_park);
|
|
|
|
/**
|
|
* kthread_freezable_should_stop - should this freezable kthread return now?
|
|
* @was_frozen: optional out parameter, indicates whether %current was frozen
|
|
*
|
|
* kthread_should_stop() for freezable kthreads, which will enter
|
|
* refrigerator if necessary. This function is safe from kthread_stop() /
|
|
* freezer deadlock and freezable kthreads should use this function instead
|
|
* of calling try_to_freeze() directly.
|
|
*/
|
|
bool kthread_freezable_should_stop(bool *was_frozen)
|
|
{
|
|
bool frozen = false;
|
|
|
|
might_sleep();
|
|
|
|
if (unlikely(freezing(current)))
|
|
frozen = __refrigerator(true);
|
|
|
|
if (was_frozen)
|
|
*was_frozen = frozen;
|
|
|
|
return kthread_should_stop();
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_freezable_should_stop);
|
|
|
|
/**
|
|
* kthread_data - return data value specified on kthread creation
|
|
* @task: kthread task in question
|
|
*
|
|
* Return the data value specified when kthread @task was created.
|
|
* The caller is responsible for ensuring the validity of @task when
|
|
* calling this function.
|
|
*/
|
|
void *kthread_data(struct task_struct *task)
|
|
{
|
|
return to_kthread(task)->data;
|
|
}
|
|
|
|
/**
|
|
* kthread_probe_data - speculative version of kthread_data()
|
|
* @task: possible kthread task in question
|
|
*
|
|
* @task could be a kthread task. Return the data value specified when it
|
|
* was created if accessible. If @task isn't a kthread task or its data is
|
|
* inaccessible for any reason, %NULL is returned. This function requires
|
|
* that @task itself is safe to dereference.
|
|
*/
|
|
void *kthread_probe_data(struct task_struct *task)
|
|
{
|
|
struct kthread *kthread = to_kthread(task);
|
|
void *data = NULL;
|
|
|
|
probe_kernel_read(&data, &kthread->data, sizeof(data));
|
|
return data;
|
|
}
|
|
|
|
static void __kthread_parkme(struct kthread *self)
|
|
{
|
|
for (;;) {
|
|
/*
|
|
* TASK_PARKED is a special state; we must serialize against
|
|
* possible pending wakeups to avoid store-store collisions on
|
|
* task->state.
|
|
*
|
|
* Such a collision might possibly result in the task state
|
|
* changin from TASK_PARKED and us failing the
|
|
* wait_task_inactive() in kthread_park().
|
|
*/
|
|
set_special_state(TASK_PARKED);
|
|
if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
|
|
break;
|
|
|
|
complete_all(&self->parked);
|
|
schedule();
|
|
}
|
|
__set_current_state(TASK_RUNNING);
|
|
}
|
|
|
|
void kthread_parkme(void)
|
|
{
|
|
__kthread_parkme(to_kthread(current));
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_parkme);
|
|
|
|
static int kthread(void *_create)
|
|
{
|
|
/* Copy data: it's on kthread's stack */
|
|
struct kthread_create_info *create = _create;
|
|
int (*threadfn)(void *data) = create->threadfn;
|
|
void *data = create->data;
|
|
struct completion *done;
|
|
struct kthread *self;
|
|
int ret;
|
|
|
|
self = kmalloc(sizeof(*self), GFP_KERNEL);
|
|
set_kthread_struct(self);
|
|
|
|
/* If user was SIGKILLed, I release the structure. */
|
|
done = xchg(&create->done, NULL);
|
|
if (!done) {
|
|
kfree(create);
|
|
do_exit(-EINTR);
|
|
}
|
|
|
|
if (!self) {
|
|
create->result = ERR_PTR(-ENOMEM);
|
|
complete(done);
|
|
do_exit(-ENOMEM);
|
|
}
|
|
|
|
self->flags = 0;
|
|
self->data = data;
|
|
init_completion(&self->exited);
|
|
init_completion(&self->parked);
|
|
current->vfork_done = &self->exited;
|
|
|
|
/* OK, tell user we're spawned, wait for stop or wakeup */
|
|
__set_current_state(TASK_UNINTERRUPTIBLE);
|
|
create->result = current;
|
|
complete(done);
|
|
schedule();
|
|
|
|
ret = -EINTR;
|
|
if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {
|
|
cgroup_kthread_ready();
|
|
__kthread_parkme(self);
|
|
ret = threadfn(data);
|
|
}
|
|
do_exit(ret);
|
|
}
|
|
|
|
/* called from do_fork() to get node information for about to be created task */
|
|
int tsk_fork_get_node(struct task_struct *tsk)
|
|
{
|
|
#ifdef CONFIG_NUMA
|
|
if (tsk == kthreadd_task)
|
|
return tsk->pref_node_fork;
|
|
#endif
|
|
return NUMA_NO_NODE;
|
|
}
|
|
|
|
static void create_kthread(struct kthread_create_info *create)
|
|
{
|
|
int pid;
|
|
|
|
#ifdef CONFIG_NUMA
|
|
current->pref_node_fork = create->node;
|
|
#endif
|
|
/* We want our own signal handler (we take no signals by default). */
|
|
pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
|
|
if (pid < 0) {
|
|
/* If user was SIGKILLed, I release the structure. */
|
|
struct completion *done = xchg(&create->done, NULL);
|
|
|
|
if (!done) {
|
|
kfree(create);
|
|
return;
|
|
}
|
|
create->result = ERR_PTR(pid);
|
|
complete(done);
|
|
}
|
|
}
|
|
|
|
static __printf(4, 0)
|
|
struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
|
|
void *data, int node,
|
|
const char namefmt[],
|
|
va_list args)
|
|
{
|
|
DECLARE_COMPLETION_ONSTACK(done);
|
|
struct task_struct *task;
|
|
struct kthread_create_info *create = kmalloc(sizeof(*create),
|
|
GFP_KERNEL);
|
|
|
|
if (!create)
|
|
return ERR_PTR(-ENOMEM);
|
|
create->threadfn = threadfn;
|
|
create->data = data;
|
|
create->node = node;
|
|
create->done = &done;
|
|
|
|
spin_lock(&kthread_create_lock);
|
|
list_add_tail(&create->list, &kthread_create_list);
|
|
spin_unlock(&kthread_create_lock);
|
|
|
|
wake_up_process(kthreadd_task);
|
|
/*
|
|
* Wait for completion in killable state, for I might be chosen by
|
|
* the OOM killer while kthreadd is trying to allocate memory for
|
|
* new kernel thread.
|
|
*/
|
|
if (unlikely(wait_for_completion_killable(&done))) {
|
|
/*
|
|
* If I was SIGKILLed before kthreadd (or new kernel thread)
|
|
* calls complete(), leave the cleanup of this structure to
|
|
* that thread.
|
|
*/
|
|
if (xchg(&create->done, NULL))
|
|
return ERR_PTR(-EINTR);
|
|
/*
|
|
* kthreadd (or new kernel thread) will call complete()
|
|
* shortly.
|
|
*/
|
|
wait_for_completion(&done);
|
|
}
|
|
task = create->result;
|
|
if (!IS_ERR(task)) {
|
|
static const struct sched_param param = { .sched_priority = 0 };
|
|
char name[TASK_COMM_LEN];
|
|
|
|
/*
|
|
* task is already visible to other tasks, so updating
|
|
* COMM must be protected.
|
|
*/
|
|
vsnprintf(name, sizeof(name), namefmt, args);
|
|
set_task_comm(task, name);
|
|
/*
|
|
* root may have changed our (kthreadd's) priority or CPU mask.
|
|
* The kernel thread should not inherit these properties.
|
|
*/
|
|
sched_setscheduler_nocheck(task, SCHED_NORMAL, ¶m);
|
|
set_cpus_allowed_ptr(task, cpu_all_mask);
|
|
}
|
|
kfree(create);
|
|
return task;
|
|
}
|
|
|
|
/**
|
|
* kthread_create_on_node - create a kthread.
|
|
* @threadfn: the function to run until signal_pending(current).
|
|
* @data: data ptr for @threadfn.
|
|
* @node: task and thread structures for the thread are allocated on this node
|
|
* @namefmt: printf-style name for the thread.
|
|
*
|
|
* Description: This helper function creates and names a kernel
|
|
* thread. The thread will be stopped: use wake_up_process() to start
|
|
* it. See also kthread_run(). The new thread has SCHED_NORMAL policy and
|
|
* is affine to all CPUs.
|
|
*
|
|
* If thread is going to be bound on a particular cpu, give its node
|
|
* in @node, to get NUMA affinity for kthread stack, or else give NUMA_NO_NODE.
|
|
* When woken, the thread will run @threadfn() with @data as its
|
|
* argument. @threadfn() can either call do_exit() directly if it is a
|
|
* standalone thread for which no one will call kthread_stop(), or
|
|
* return when 'kthread_should_stop()' is true (which means
|
|
* kthread_stop() has been called). The return value should be zero
|
|
* or a negative error number; it will be passed to kthread_stop().
|
|
*
|
|
* Returns a task_struct or ERR_PTR(-ENOMEM) or ERR_PTR(-EINTR).
|
|
*/
|
|
struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
|
|
void *data, int node,
|
|
const char namefmt[],
|
|
...)
|
|
{
|
|
struct task_struct *task;
|
|
va_list args;
|
|
|
|
va_start(args, namefmt);
|
|
task = __kthread_create_on_node(threadfn, data, node, namefmt, args);
|
|
va_end(args);
|
|
|
|
return task;
|
|
}
|
|
EXPORT_SYMBOL(kthread_create_on_node);
|
|
|
|
static void __kthread_bind_mask(struct task_struct *p, const struct cpumask *mask, long state)
|
|
{
|
|
unsigned long flags;
|
|
|
|
if (!wait_task_inactive(p, state)) {
|
|
WARN_ON(1);
|
|
return;
|
|
}
|
|
|
|
/* It's safe because the task is inactive. */
|
|
raw_spin_lock_irqsave(&p->pi_lock, flags);
|
|
do_set_cpus_allowed(p, mask);
|
|
p->flags |= PF_NO_SETAFFINITY;
|
|
raw_spin_unlock_irqrestore(&p->pi_lock, flags);
|
|
}
|
|
|
|
static void __kthread_bind(struct task_struct *p, unsigned int cpu, long state)
|
|
{
|
|
__kthread_bind_mask(p, cpumask_of(cpu), state);
|
|
}
|
|
|
|
void kthread_bind_mask(struct task_struct *p, const struct cpumask *mask)
|
|
{
|
|
__kthread_bind_mask(p, mask, TASK_UNINTERRUPTIBLE);
|
|
}
|
|
|
|
/**
|
|
* kthread_bind - bind a just-created kthread to a cpu.
|
|
* @p: thread created by kthread_create().
|
|
* @cpu: cpu (might not be online, must be possible) for @k to run on.
|
|
*
|
|
* Description: This function is equivalent to set_cpus_allowed(),
|
|
* except that @cpu doesn't need to be online, and the thread must be
|
|
* stopped (i.e., just returned from kthread_create()).
|
|
*/
|
|
void kthread_bind(struct task_struct *p, unsigned int cpu)
|
|
{
|
|
__kthread_bind(p, cpu, TASK_UNINTERRUPTIBLE);
|
|
}
|
|
EXPORT_SYMBOL(kthread_bind);
|
|
|
|
/**
|
|
* kthread_create_on_cpu - Create a cpu bound kthread
|
|
* @threadfn: the function to run until signal_pending(current).
|
|
* @data: data ptr for @threadfn.
|
|
* @cpu: The cpu on which the thread should be bound,
|
|
* @namefmt: printf-style name for the thread. Format is restricted
|
|
* to "name.*%u". Code fills in cpu number.
|
|
*
|
|
* Description: This helper function creates and names a kernel thread
|
|
* The thread will be woken and put into park mode.
|
|
*/
|
|
struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
|
|
void *data, unsigned int cpu,
|
|
const char *namefmt)
|
|
{
|
|
struct task_struct *p;
|
|
|
|
p = kthread_create_on_node(threadfn, data, cpu_to_node(cpu), namefmt,
|
|
cpu);
|
|
if (IS_ERR(p))
|
|
return p;
|
|
kthread_bind(p, cpu);
|
|
/* CPU hotplug need to bind once again when unparking the thread. */
|
|
set_bit(KTHREAD_IS_PER_CPU, &to_kthread(p)->flags);
|
|
to_kthread(p)->cpu = cpu;
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
* kthread_unpark - unpark a thread created by kthread_create().
|
|
* @k: thread created by kthread_create().
|
|
*
|
|
* Sets kthread_should_park() for @k to return false, wakes it, and
|
|
* waits for it to return. If the thread is marked percpu then its
|
|
* bound to the cpu again.
|
|
*/
|
|
void kthread_unpark(struct task_struct *k)
|
|
{
|
|
struct kthread *kthread = to_kthread(k);
|
|
|
|
/*
|
|
* Newly created kthread was parked when the CPU was offline.
|
|
* The binding was lost and we need to set it again.
|
|
*/
|
|
if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags))
|
|
__kthread_bind(k, kthread->cpu, TASK_PARKED);
|
|
|
|
reinit_completion(&kthread->parked);
|
|
clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
|
|
/*
|
|
* __kthread_parkme() will either see !SHOULD_PARK or get the wakeup.
|
|
*/
|
|
wake_up_state(k, TASK_PARKED);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_unpark);
|
|
|
|
/**
|
|
* kthread_park - park a thread created by kthread_create().
|
|
* @k: thread created by kthread_create().
|
|
*
|
|
* Sets kthread_should_park() for @k to return true, wakes it, and
|
|
* waits for it to return. This can also be called after kthread_create()
|
|
* instead of calling wake_up_process(): the thread will park without
|
|
* calling threadfn().
|
|
*
|
|
* Returns 0 if the thread is parked, -ENOSYS if the thread exited.
|
|
* If called by the kthread itself just the park bit is set.
|
|
*/
|
|
int kthread_park(struct task_struct *k)
|
|
{
|
|
struct kthread *kthread = to_kthread(k);
|
|
|
|
if (WARN_ON(k->flags & PF_EXITING))
|
|
return -ENOSYS;
|
|
|
|
set_bit(KTHREAD_SHOULD_PARK, &kthread->flags);
|
|
if (k != current) {
|
|
wake_up_process(k);
|
|
/*
|
|
* Wait for __kthread_parkme() to complete(), this means we
|
|
* _will_ have TASK_PARKED and are about to call schedule().
|
|
*/
|
|
wait_for_completion(&kthread->parked);
|
|
/*
|
|
* Now wait for that schedule() to complete and the task to
|
|
* get scheduled out.
|
|
*/
|
|
WARN_ON_ONCE(!wait_task_inactive(k, TASK_PARKED));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_park);
|
|
|
|
/**
|
|
* kthread_stop - stop a thread created by kthread_create().
|
|
* @k: thread created by kthread_create().
|
|
*
|
|
* Sets kthread_should_stop() for @k to return true, wakes it, and
|
|
* waits for it to exit. This can also be called after kthread_create()
|
|
* instead of calling wake_up_process(): the thread will exit without
|
|
* calling threadfn().
|
|
*
|
|
* If threadfn() may call do_exit() itself, the caller must ensure
|
|
* task_struct can't go away.
|
|
*
|
|
* Returns the result of threadfn(), or %-EINTR if wake_up_process()
|
|
* was never called.
|
|
*/
|
|
int kthread_stop(struct task_struct *k)
|
|
{
|
|
struct kthread *kthread;
|
|
int ret;
|
|
|
|
trace_sched_kthread_stop(k);
|
|
|
|
get_task_struct(k);
|
|
kthread = to_kthread(k);
|
|
set_bit(KTHREAD_SHOULD_STOP, &kthread->flags);
|
|
kthread_unpark(k);
|
|
wake_up_process(k);
|
|
wait_for_completion(&kthread->exited);
|
|
ret = k->exit_code;
|
|
put_task_struct(k);
|
|
|
|
trace_sched_kthread_stop_ret(ret);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(kthread_stop);
|
|
|
|
int kthreadd(void *unused)
|
|
{
|
|
struct task_struct *tsk = current;
|
|
|
|
/* Setup a clean context for our children to inherit. */
|
|
set_task_comm(tsk, "kthreadd");
|
|
ignore_signals(tsk);
|
|
set_cpus_allowed_ptr(tsk, cpu_all_mask);
|
|
set_mems_allowed(node_states[N_MEMORY]);
|
|
|
|
current->flags |= PF_NOFREEZE;
|
|
cgroup_init_kthreadd();
|
|
|
|
for (;;) {
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
if (list_empty(&kthread_create_list))
|
|
schedule();
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
spin_lock(&kthread_create_lock);
|
|
while (!list_empty(&kthread_create_list)) {
|
|
struct kthread_create_info *create;
|
|
|
|
create = list_entry(kthread_create_list.next,
|
|
struct kthread_create_info, list);
|
|
list_del_init(&create->list);
|
|
spin_unlock(&kthread_create_lock);
|
|
|
|
create_kthread(create);
|
|
|
|
spin_lock(&kthread_create_lock);
|
|
}
|
|
spin_unlock(&kthread_create_lock);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void __kthread_init_worker(struct kthread_worker *worker,
|
|
const char *name,
|
|
struct lock_class_key *key)
|
|
{
|
|
memset(worker, 0, sizeof(struct kthread_worker));
|
|
spin_lock_init(&worker->lock);
|
|
lockdep_set_class_and_name(&worker->lock, key, name);
|
|
INIT_LIST_HEAD(&worker->work_list);
|
|
INIT_LIST_HEAD(&worker->delayed_work_list);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__kthread_init_worker);
|
|
|
|
/**
|
|
* kthread_worker_fn - kthread function to process kthread_worker
|
|
* @worker_ptr: pointer to initialized kthread_worker
|
|
*
|
|
* This function implements the main cycle of kthread worker. It processes
|
|
* work_list until it is stopped with kthread_stop(). It sleeps when the queue
|
|
* is empty.
|
|
*
|
|
* The works are not allowed to keep any locks, disable preemption or interrupts
|
|
* when they finish. There is defined a safe point for freezing when one work
|
|
* finishes and before a new one is started.
|
|
*
|
|
* Also the works must not be handled by more than one worker at the same time,
|
|
* see also kthread_queue_work().
|
|
*/
|
|
int kthread_worker_fn(void *worker_ptr)
|
|
{
|
|
struct kthread_worker *worker = worker_ptr;
|
|
struct kthread_work *work;
|
|
|
|
/*
|
|
* FIXME: Update the check and remove the assignment when all kthread
|
|
* worker users are created using kthread_create_worker*() functions.
|
|
*/
|
|
WARN_ON(worker->task && worker->task != current);
|
|
worker->task = current;
|
|
|
|
if (worker->flags & KTW_FREEZABLE)
|
|
set_freezable();
|
|
|
|
repeat:
|
|
set_current_state(TASK_INTERRUPTIBLE); /* mb paired w/ kthread_stop */
|
|
|
|
if (kthread_should_stop()) {
|
|
__set_current_state(TASK_RUNNING);
|
|
spin_lock_irq(&worker->lock);
|
|
worker->task = NULL;
|
|
spin_unlock_irq(&worker->lock);
|
|
return 0;
|
|
}
|
|
|
|
work = NULL;
|
|
spin_lock_irq(&worker->lock);
|
|
if (!list_empty(&worker->work_list)) {
|
|
work = list_first_entry(&worker->work_list,
|
|
struct kthread_work, node);
|
|
list_del_init(&work->node);
|
|
}
|
|
worker->current_work = work;
|
|
spin_unlock_irq(&worker->lock);
|
|
|
|
if (work) {
|
|
__set_current_state(TASK_RUNNING);
|
|
work->func(work);
|
|
} else if (!freezing(current))
|
|
schedule();
|
|
|
|
try_to_freeze();
|
|
cond_resched();
|
|
goto repeat;
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_worker_fn);
|
|
|
|
static __printf(3, 0) struct kthread_worker *
|
|
__kthread_create_worker(int cpu, unsigned int flags,
|
|
const char namefmt[], va_list args)
|
|
{
|
|
struct kthread_worker *worker;
|
|
struct task_struct *task;
|
|
int node = -1;
|
|
|
|
worker = kzalloc(sizeof(*worker), GFP_KERNEL);
|
|
if (!worker)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
kthread_init_worker(worker);
|
|
|
|
if (cpu >= 0)
|
|
node = cpu_to_node(cpu);
|
|
|
|
task = __kthread_create_on_node(kthread_worker_fn, worker,
|
|
node, namefmt, args);
|
|
if (IS_ERR(task))
|
|
goto fail_task;
|
|
|
|
if (cpu >= 0)
|
|
kthread_bind(task, cpu);
|
|
|
|
worker->flags = flags;
|
|
worker->task = task;
|
|
wake_up_process(task);
|
|
return worker;
|
|
|
|
fail_task:
|
|
kfree(worker);
|
|
return ERR_CAST(task);
|
|
}
|
|
|
|
/**
|
|
* kthread_create_worker - create a kthread worker
|
|
* @flags: flags modifying the default behavior of the worker
|
|
* @namefmt: printf-style name for the kthread worker (task).
|
|
*
|
|
* Returns a pointer to the allocated worker on success, ERR_PTR(-ENOMEM)
|
|
* when the needed structures could not get allocated, and ERR_PTR(-EINTR)
|
|
* when the worker was SIGKILLed.
|
|
*/
|
|
struct kthread_worker *
|
|
kthread_create_worker(unsigned int flags, const char namefmt[], ...)
|
|
{
|
|
struct kthread_worker *worker;
|
|
va_list args;
|
|
|
|
va_start(args, namefmt);
|
|
worker = __kthread_create_worker(-1, flags, namefmt, args);
|
|
va_end(args);
|
|
|
|
return worker;
|
|
}
|
|
EXPORT_SYMBOL(kthread_create_worker);
|
|
|
|
/**
|
|
* kthread_create_worker_on_cpu - create a kthread worker and bind it
|
|
* it to a given CPU and the associated NUMA node.
|
|
* @cpu: CPU number
|
|
* @flags: flags modifying the default behavior of the worker
|
|
* @namefmt: printf-style name for the kthread worker (task).
|
|
*
|
|
* Use a valid CPU number if you want to bind the kthread worker
|
|
* to the given CPU and the associated NUMA node.
|
|
*
|
|
* A good practice is to add the cpu number also into the worker name.
|
|
* For example, use kthread_create_worker_on_cpu(cpu, "helper/%d", cpu).
|
|
*
|
|
* Returns a pointer to the allocated worker on success, ERR_PTR(-ENOMEM)
|
|
* when the needed structures could not get allocated, and ERR_PTR(-EINTR)
|
|
* when the worker was SIGKILLed.
|
|
*/
|
|
struct kthread_worker *
|
|
kthread_create_worker_on_cpu(int cpu, unsigned int flags,
|
|
const char namefmt[], ...)
|
|
{
|
|
struct kthread_worker *worker;
|
|
va_list args;
|
|
|
|
va_start(args, namefmt);
|
|
worker = __kthread_create_worker(cpu, flags, namefmt, args);
|
|
va_end(args);
|
|
|
|
return worker;
|
|
}
|
|
EXPORT_SYMBOL(kthread_create_worker_on_cpu);
|
|
|
|
/*
|
|
* Returns true when the work could not be queued at the moment.
|
|
* It happens when it is already pending in a worker list
|
|
* or when it is being cancelled.
|
|
*/
|
|
static inline bool queuing_blocked(struct kthread_worker *worker,
|
|
struct kthread_work *work)
|
|
{
|
|
lockdep_assert_held(&worker->lock);
|
|
|
|
return !list_empty(&work->node) || work->canceling;
|
|
}
|
|
|
|
static void kthread_insert_work_sanity_check(struct kthread_worker *worker,
|
|
struct kthread_work *work)
|
|
{
|
|
lockdep_assert_held(&worker->lock);
|
|
WARN_ON_ONCE(!list_empty(&work->node));
|
|
/* Do not use a work with >1 worker, see kthread_queue_work() */
|
|
WARN_ON_ONCE(work->worker && work->worker != worker);
|
|
}
|
|
|
|
/* insert @work before @pos in @worker */
|
|
static void kthread_insert_work(struct kthread_worker *worker,
|
|
struct kthread_work *work,
|
|
struct list_head *pos)
|
|
{
|
|
kthread_insert_work_sanity_check(worker, work);
|
|
|
|
list_add_tail(&work->node, pos);
|
|
work->worker = worker;
|
|
if (!worker->current_work && likely(worker->task))
|
|
wake_up_process(worker->task);
|
|
}
|
|
|
|
/**
|
|
* kthread_queue_work - queue a kthread_work
|
|
* @worker: target kthread_worker
|
|
* @work: kthread_work to queue
|
|
*
|
|
* Queue @work to work processor @task for async execution. @task
|
|
* must have been created with kthread_worker_create(). Returns %true
|
|
* if @work was successfully queued, %false if it was already pending.
|
|
*
|
|
* Reinitialize the work if it needs to be used by another worker.
|
|
* For example, when the worker was stopped and started again.
|
|
*/
|
|
bool kthread_queue_work(struct kthread_worker *worker,
|
|
struct kthread_work *work)
|
|
{
|
|
bool ret = false;
|
|
unsigned long flags;
|
|
|
|
spin_lock_irqsave(&worker->lock, flags);
|
|
if (!queuing_blocked(worker, work)) {
|
|
kthread_insert_work(worker, work, &worker->work_list);
|
|
ret = true;
|
|
}
|
|
spin_unlock_irqrestore(&worker->lock, flags);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_queue_work);
|
|
|
|
/**
|
|
* kthread_delayed_work_timer_fn - callback that queues the associated kthread
|
|
* delayed work when the timer expires.
|
|
* @__data: pointer to the data associated with the timer
|
|
*
|
|
* The format of the function is defined by struct timer_list.
|
|
* It should have been called from irqsafe timer with irq already off.
|
|
*/
|
|
void kthread_delayed_work_timer_fn(unsigned long __data)
|
|
{
|
|
struct kthread_delayed_work *dwork =
|
|
(struct kthread_delayed_work *)__data;
|
|
struct kthread_work *work = &dwork->work;
|
|
struct kthread_worker *worker = work->worker;
|
|
|
|
/*
|
|
* This might happen when a pending work is reinitialized.
|
|
* It means that it is used a wrong way.
|
|
*/
|
|
if (WARN_ON_ONCE(!worker))
|
|
return;
|
|
|
|
spin_lock(&worker->lock);
|
|
/* Work must not be used with >1 worker, see kthread_queue_work(). */
|
|
WARN_ON_ONCE(work->worker != worker);
|
|
|
|
/* Move the work from worker->delayed_work_list. */
|
|
WARN_ON_ONCE(list_empty(&work->node));
|
|
list_del_init(&work->node);
|
|
kthread_insert_work(worker, work, &worker->work_list);
|
|
|
|
spin_unlock(&worker->lock);
|
|
}
|
|
EXPORT_SYMBOL(kthread_delayed_work_timer_fn);
|
|
|
|
void __kthread_queue_delayed_work(struct kthread_worker *worker,
|
|
struct kthread_delayed_work *dwork,
|
|
unsigned long delay)
|
|
{
|
|
struct timer_list *timer = &dwork->timer;
|
|
struct kthread_work *work = &dwork->work;
|
|
|
|
WARN_ON_ONCE(timer->function != kthread_delayed_work_timer_fn ||
|
|
timer->data != (unsigned long)dwork);
|
|
|
|
/*
|
|
* If @delay is 0, queue @dwork->work immediately. This is for
|
|
* both optimization and correctness. The earliest @timer can
|
|
* expire is on the closest next tick and delayed_work users depend
|
|
* on that there's no such delay when @delay is 0.
|
|
*/
|
|
if (!delay) {
|
|
kthread_insert_work(worker, work, &worker->work_list);
|
|
return;
|
|
}
|
|
|
|
/* Be paranoid and try to detect possible races already now. */
|
|
kthread_insert_work_sanity_check(worker, work);
|
|
|
|
list_add(&work->node, &worker->delayed_work_list);
|
|
work->worker = worker;
|
|
timer->expires = jiffies + delay;
|
|
add_timer(timer);
|
|
}
|
|
|
|
/**
|
|
* kthread_queue_delayed_work - queue the associated kthread work
|
|
* after a delay.
|
|
* @worker: target kthread_worker
|
|
* @dwork: kthread_delayed_work to queue
|
|
* @delay: number of jiffies to wait before queuing
|
|
*
|
|
* If the work has not been pending it starts a timer that will queue
|
|
* the work after the given @delay. If @delay is zero, it queues the
|
|
* work immediately.
|
|
*
|
|
* Return: %false if the @work has already been pending. It means that
|
|
* either the timer was running or the work was queued. It returns %true
|
|
* otherwise.
|
|
*/
|
|
bool kthread_queue_delayed_work(struct kthread_worker *worker,
|
|
struct kthread_delayed_work *dwork,
|
|
unsigned long delay)
|
|
{
|
|
struct kthread_work *work = &dwork->work;
|
|
unsigned long flags;
|
|
bool ret = false;
|
|
|
|
spin_lock_irqsave(&worker->lock, flags);
|
|
|
|
if (!queuing_blocked(worker, work)) {
|
|
__kthread_queue_delayed_work(worker, dwork, delay);
|
|
ret = true;
|
|
}
|
|
|
|
spin_unlock_irqrestore(&worker->lock, flags);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_queue_delayed_work);
|
|
|
|
struct kthread_flush_work {
|
|
struct kthread_work work;
|
|
struct completion done;
|
|
};
|
|
|
|
static void kthread_flush_work_fn(struct kthread_work *work)
|
|
{
|
|
struct kthread_flush_work *fwork =
|
|
container_of(work, struct kthread_flush_work, work);
|
|
complete(&fwork->done);
|
|
}
|
|
|
|
/**
|
|
* kthread_flush_work - flush a kthread_work
|
|
* @work: work to flush
|
|
*
|
|
* If @work is queued or executing, wait for it to finish execution.
|
|
*/
|
|
void kthread_flush_work(struct kthread_work *work)
|
|
{
|
|
struct kthread_flush_work fwork = {
|
|
KTHREAD_WORK_INIT(fwork.work, kthread_flush_work_fn),
|
|
COMPLETION_INITIALIZER_ONSTACK(fwork.done),
|
|
};
|
|
struct kthread_worker *worker;
|
|
bool noop = false;
|
|
|
|
worker = work->worker;
|
|
if (!worker)
|
|
return;
|
|
|
|
spin_lock_irq(&worker->lock);
|
|
/* Work must not be used with >1 worker, see kthread_queue_work(). */
|
|
WARN_ON_ONCE(work->worker != worker);
|
|
|
|
if (!list_empty(&work->node))
|
|
kthread_insert_work(worker, &fwork.work, work->node.next);
|
|
else if (worker->current_work == work)
|
|
kthread_insert_work(worker, &fwork.work,
|
|
worker->work_list.next);
|
|
else
|
|
noop = true;
|
|
|
|
spin_unlock_irq(&worker->lock);
|
|
|
|
if (!noop)
|
|
wait_for_completion(&fwork.done);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_flush_work);
|
|
|
|
/*
|
|
* This function removes the work from the worker queue. Also it makes sure
|
|
* that it won't get queued later via the delayed work's timer.
|
|
*
|
|
* The work might still be in use when this function finishes. See the
|
|
* current_work proceed by the worker.
|
|
*
|
|
* Return: %true if @work was pending and successfully canceled,
|
|
* %false if @work was not pending
|
|
*/
|
|
static bool __kthread_cancel_work(struct kthread_work *work, bool is_dwork,
|
|
unsigned long *flags)
|
|
{
|
|
/* Try to cancel the timer if exists. */
|
|
if (is_dwork) {
|
|
struct kthread_delayed_work *dwork =
|
|
container_of(work, struct kthread_delayed_work, work);
|
|
struct kthread_worker *worker = work->worker;
|
|
|
|
/*
|
|
* del_timer_sync() must be called to make sure that the timer
|
|
* callback is not running. The lock must be temporary released
|
|
* to avoid a deadlock with the callback. In the meantime,
|
|
* any queuing is blocked by setting the canceling counter.
|
|
*/
|
|
work->canceling++;
|
|
spin_unlock_irqrestore(&worker->lock, *flags);
|
|
del_timer_sync(&dwork->timer);
|
|
spin_lock_irqsave(&worker->lock, *flags);
|
|
work->canceling--;
|
|
}
|
|
|
|
/*
|
|
* Try to remove the work from a worker list. It might either
|
|
* be from worker->work_list or from worker->delayed_work_list.
|
|
*/
|
|
if (!list_empty(&work->node)) {
|
|
list_del_init(&work->node);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* kthread_mod_delayed_work - modify delay of or queue a kthread delayed work
|
|
* @worker: kthread worker to use
|
|
* @dwork: kthread delayed work to queue
|
|
* @delay: number of jiffies to wait before queuing
|
|
*
|
|
* If @dwork is idle, equivalent to kthread_queue_delayed_work(). Otherwise,
|
|
* modify @dwork's timer so that it expires after @delay. If @delay is zero,
|
|
* @work is guaranteed to be queued immediately.
|
|
*
|
|
* Return: %true if @dwork was pending and its timer was modified,
|
|
* %false otherwise.
|
|
*
|
|
* A special case is when the work is being canceled in parallel.
|
|
* It might be caused either by the real kthread_cancel_delayed_work_sync()
|
|
* or yet another kthread_mod_delayed_work() call. We let the other command
|
|
* win and return %false here. The caller is supposed to synchronize these
|
|
* operations a reasonable way.
|
|
*
|
|
* This function is safe to call from any context including IRQ handler.
|
|
* See __kthread_cancel_work() and kthread_delayed_work_timer_fn()
|
|
* for details.
|
|
*/
|
|
bool kthread_mod_delayed_work(struct kthread_worker *worker,
|
|
struct kthread_delayed_work *dwork,
|
|
unsigned long delay)
|
|
{
|
|
struct kthread_work *work = &dwork->work;
|
|
unsigned long flags;
|
|
int ret = false;
|
|
|
|
spin_lock_irqsave(&worker->lock, flags);
|
|
|
|
/* Do not bother with canceling when never queued. */
|
|
if (!work->worker)
|
|
goto fast_queue;
|
|
|
|
/* Work must not be used with >1 worker, see kthread_queue_work() */
|
|
WARN_ON_ONCE(work->worker != worker);
|
|
|
|
/* Do not fight with another command that is canceling this work. */
|
|
if (work->canceling)
|
|
goto out;
|
|
|
|
ret = __kthread_cancel_work(work, true, &flags);
|
|
fast_queue:
|
|
__kthread_queue_delayed_work(worker, dwork, delay);
|
|
out:
|
|
spin_unlock_irqrestore(&worker->lock, flags);
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_mod_delayed_work);
|
|
|
|
static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork)
|
|
{
|
|
struct kthread_worker *worker = work->worker;
|
|
unsigned long flags;
|
|
int ret = false;
|
|
|
|
if (!worker)
|
|
goto out;
|
|
|
|
spin_lock_irqsave(&worker->lock, flags);
|
|
/* Work must not be used with >1 worker, see kthread_queue_work(). */
|
|
WARN_ON_ONCE(work->worker != worker);
|
|
|
|
ret = __kthread_cancel_work(work, is_dwork, &flags);
|
|
|
|
if (worker->current_work != work)
|
|
goto out_fast;
|
|
|
|
/*
|
|
* The work is in progress and we need to wait with the lock released.
|
|
* In the meantime, block any queuing by setting the canceling counter.
|
|
*/
|
|
work->canceling++;
|
|
spin_unlock_irqrestore(&worker->lock, flags);
|
|
kthread_flush_work(work);
|
|
spin_lock_irqsave(&worker->lock, flags);
|
|
work->canceling--;
|
|
|
|
out_fast:
|
|
spin_unlock_irqrestore(&worker->lock, flags);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* kthread_cancel_work_sync - cancel a kthread work and wait for it to finish
|
|
* @work: the kthread work to cancel
|
|
*
|
|
* Cancel @work and wait for its execution to finish. This function
|
|
* can be used even if the work re-queues itself. On return from this
|
|
* function, @work is guaranteed to be not pending or executing on any CPU.
|
|
*
|
|
* kthread_cancel_work_sync(&delayed_work->work) must not be used for
|
|
* delayed_work's. Use kthread_cancel_delayed_work_sync() instead.
|
|
*
|
|
* The caller must ensure that the worker on which @work was last
|
|
* queued can't be destroyed before this function returns.
|
|
*
|
|
* Return: %true if @work was pending, %false otherwise.
|
|
*/
|
|
bool kthread_cancel_work_sync(struct kthread_work *work)
|
|
{
|
|
return __kthread_cancel_work_sync(work, false);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_cancel_work_sync);
|
|
|
|
/**
|
|
* kthread_cancel_delayed_work_sync - cancel a kthread delayed work and
|
|
* wait for it to finish.
|
|
* @dwork: the kthread delayed work to cancel
|
|
*
|
|
* This is kthread_cancel_work_sync() for delayed works.
|
|
*
|
|
* Return: %true if @dwork was pending, %false otherwise.
|
|
*/
|
|
bool kthread_cancel_delayed_work_sync(struct kthread_delayed_work *dwork)
|
|
{
|
|
return __kthread_cancel_work_sync(&dwork->work, true);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_cancel_delayed_work_sync);
|
|
|
|
/**
|
|
* kthread_flush_worker - flush all current works on a kthread_worker
|
|
* @worker: worker to flush
|
|
*
|
|
* Wait until all currently executing or pending works on @worker are
|
|
* finished.
|
|
*/
|
|
void kthread_flush_worker(struct kthread_worker *worker)
|
|
{
|
|
struct kthread_flush_work fwork = {
|
|
KTHREAD_WORK_INIT(fwork.work, kthread_flush_work_fn),
|
|
COMPLETION_INITIALIZER_ONSTACK(fwork.done),
|
|
};
|
|
|
|
kthread_queue_work(worker, &fwork.work);
|
|
wait_for_completion(&fwork.done);
|
|
}
|
|
EXPORT_SYMBOL_GPL(kthread_flush_worker);
|
|
|
|
/**
|
|
* kthread_destroy_worker - destroy a kthread worker
|
|
* @worker: worker to be destroyed
|
|
*
|
|
* Flush and destroy @worker. The simple flush is enough because the kthread
|
|
* worker API is used only in trivial scenarios. There are no multi-step state
|
|
* machines needed.
|
|
*/
|
|
void kthread_destroy_worker(struct kthread_worker *worker)
|
|
{
|
|
struct task_struct *task;
|
|
|
|
task = worker->task;
|
|
if (WARN_ON(!task))
|
|
return;
|
|
|
|
kthread_flush_worker(worker);
|
|
kthread_stop(task);
|
|
WARN_ON(!list_empty(&worker->work_list));
|
|
kfree(worker);
|
|
}
|
|
EXPORT_SYMBOL(kthread_destroy_worker);
|