Merge 6.12.20 into android16-6.12
GKI (arm64) relevant 45 out of 232 changes, affecting 66 files +537/-357a74979dce9mm/slab/kvfree_rcu: Switch to WQ_MEM_RECLAIM wq [1 file, +10/-4]4e95072462mm: fix kernel BUG when userfaultfd_move encounters swapcache [1 file, +66/-9]99012b24causerfaultfd: fix PTE unmapping stack-allocated PTE copies [1 file, +10/-10]a5396ee0f5netfilter: nf_conncount: garbage collection is not skipped when jiffies wrap around [1 file, +2/-2]0befa32ac3netfilter: nf_tables: make destruction work queue pernet [3 files, +21/-15]0677a4f3c0Bluetooth: hci_event: Fix enabling passive scanning [1 file, +22/-15]55b098a2beRevert "Bluetooth: hci_core: Fix sleeping function called from invalid context" [6 files, +57/-97]db1e0c0856netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple in insert_tree() [1 file, +2/-0]5c3ca9cb48net_sched: Prevent creation of classes with TC_H_ROOT [1 file, +6/-0]a4d42b5901gre: Fix IPv6 link-local address generation. [1 file, +9/-6]ae5716b463hrtimers: Mark is_migration_base() with __always_inline [1 file, +12/-10]ccdec7ea9apowercap: call put_device() on an error path in powercap_register_control_type() [1 file, +1/-2]aa189c3941futex: Pass in task to futex_queue() [5 files, +15/-9]1207e5d1a2scsi: core: Use GFP_NOIO to avoid circular locking dependency [1 file, +1/-1]3be0408451scsi: ufs: core: Fix error return with query response [1 file, +6/-1]705f251518HID: hid-steam: Fix issues with disabling both gamepad mode and lizard mode [1 file, +3/-3]024d7e006aHID: hid-apple: Apple Magic Keyboard a3203 USB-C support [2 files, +6/-0]3ceaafa26fHID: apple: fix up the F6 key on the Omoton KB066 keyboard [1 file, +3/-0]30a40b5925sched: Clarify wake_up_q()'s write to task->wake_q.next [1 file, +3/-2]a91922e9eathermal/cpufreq_cooling: Remove structure member documentation [1 file, +0/-2]aa3b0ea474arm64: amu: Delay allocating cpumask for AMU FIE support [1 file, +10/-12]f8094625a5Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd [1 file, +34/-5]4ed43c26b7PCI: pci_ids: add INTEL_HDA_PTL_H [1 file, +1/-0]b349a3d1b1io-wq: backoff when retrying worker creation [1 file, +18/-5]fd903dd301nvme-pci: quirk Acer FA100 for non-uniqueue identifiers [1 file, +2/-0]bfe7f298eenvme: only allow entering LIVE from CONNECTING state [1 file, +0/-2]df2ae00d96fuse: don't truncate cached, mutated symlink [3 files, +22/-6]d1ceef54b2net: Handle napi_schedule() calls from non-interrupt [1 file, +1/-1]7184e99610block: fix 'kmem_cache of name 'bio-108' already exists' [1 file, +1/-1]1936b189faInput: xpad - add 8BitDo SN30 Pro, Hyperkin X91 and Gamesir G7 SE controllers [1 file, +8/-5]e2304bbf87Input: xpad - add multiple supported devices [1 file, +19/-1]d91dd818f1Input: xpad - add support for ZOTAC Gaming Zone [1 file, +2/-0]f7ccf4eb4bInput: xpad - add support for TECNO Pocket Go [1 file, +2/-0]0ff93d8956Input: xpad - rename QH controller to Legion Go S [1 file, +2/-2]87ede08ef2USB: serial: ftdi_sio: add support for Altera USB Blaster 3 [2 files, +27/-0]962912aaf8drm/atomic: Filter out redundant DPMS calls [2 files, +8/-0]454825019dnetmem: prevent TX of unreadable skbs [1 file, +3/-0]f6bbea2ffearm64: mm: Populate vmemmap at the page level if not section aligned [1 file, +4/-1]608bbf7ff5Fix mmu notifiers for range-based invalidates [1 file, +12/-10]a46a9371f8ASoC: ops: Consistently treat platform_max as control value [2 files, +11/-9]77213a424anvme: move error logging from nvme_end_req() to __nvme_end_req() [1 file, +6/-6]f415148282mm/hugetlb: wait for hugetlb folios to be freed [3 files, +23/-0]f87271d21dBluetooth: L2CAP: Fix corrupted list in hci_chan_del [3 files, +58/-98]8f324d9930HID: apple: disable Fn key handling on the Omoton KB066 [1 file, +7/-4]62b9ad7e52fs/netfs/read_collect: add to next->prev_donated [1 file, +1/-1] Changes in 6.12.20 mm/slab/kvfree_rcu: Switch to WQ_MEM_RECLAIM wq mm: fix kernel BUG when userfaultfd_move encounters swapcache userfaultfd: fix PTE unmapping stack-allocated PTE copies fbdev: hyperv_fb: iounmap() the correct memory when removing a device pinctrl: bcm281xx: Fix incorrect regmap max_registers value pinctrl: nuvoton: npcm8xx: Add NULL check in npcm8xx_gpio_fw netfilter: nft_ct: Use __refcount_inc() for per-CPU nft_ct_pcpu_template. ice: do not configure destination override for switchdev ice: fix memory leak in aRFS after reset ice: Fix switchdev slow-path in LAG netfilter: nf_conncount: garbage collection is not skipped when jiffies wrap around netfilter: nf_tables: make destruction work queue pernet sched: address a potential NULL pointer dereference in the GRED scheduler. wifi: iwlwifi: mvm: fix PNVM timeout for non-MSI-X platforms wifi: mac80211: don't queue sdata::work for a non-running sdata wifi: cfg80211: cancel wiphy_work before freeing wiphy Bluetooth: hci_event: Fix enabling passive scanning Revert "Bluetooth: hci_core: Fix sleeping function called from invalid context" net/mlx5: Fill out devlink dev info only for PFs net: dsa: mv88e6xxx: Verify after ATU Load ops net: mctp i3c: Copy headers if cloned net: mctp i2c: Copy headers if cloned netpoll: hold rcu read lock in __netpoll_send_skb() drm/hyperv: Fix address space leak when Hyper-V DRM device is removed fbdev: hyperv_fb: Fix hang in kdump kernel when on Hyper-V Gen 2 VMs fbdev: hyperv_fb: Simplify hvfb_putmem fbdev: hyperv_fb: Allow graceful removal of framebuffer Drivers: hv: vmbus: Don't release fb_mmio resource in vmbus_free_mmio() net/mlx5: handle errors in mlx5_chains_create_table() eth: bnxt: fix truesize for mb-xdp-pass case eth: bnxt: return fail if interface is down in bnxt_queue_mem_alloc() eth: bnxt: do not use BNXT_VNIC_NTUPLE unconditionally in queue restart logic eth: bnxt: do not update checksum in bnxt_xdp_build_skb() eth: bnxt: fix kernel panic in the bnxt_get_queue_stats{rx | tx} eth: bnxt: use page pool for head frags bnxt_en: refactor tpa_info alloc/free into helpers bnxt_en: handle tpa_info in queue API implementation eth: bnxt: fix memory leak in queue reset net: switchdev: Convert blocking notification chain to a raw one net: mctp: unshare packets when reassembling bonding: fix incorrect MAC address setting to receive NS messages selftests: bonding: fix incorrect mac address rtase: Fix improper release of ring list entries in rtase_sw_reset netfilter: nf_conncount: Fully initialize struct nf_conncount_tuple in insert_tree() ipvs: prevent integer overflow in do_ip_vs_get_ctl() net_sched: Prevent creation of classes with TC_H_ROOT netfilter: nft_exthdr: fix offset with ipv4_find_option() gre: Fix IPv6 link-local address generation. net: openvswitch: remove misbehaving actions length check Revert "openvswitch: switch to per-action label counting in conntrack" net/mlx5: HWS, Rightsize bwc matcher priority net/mlx5: Fix incorrect IRQ pool usage when releasing IRQs net/mlx5: Lag, Check shared fdb before creating MultiPort E-Switch net/mlx5: Bridge, fix the crash caused by LAG state check net/mlx5e: Prevent bridge link show failure for non-eswitch-allowed devices nvme-fc: go straight to connecting state when initializing nvme-fc: do not ignore connectivity loss during connecting hrtimers: Mark is_migration_base() with __always_inline powercap: call put_device() on an error path in powercap_register_control_type() btrfs: avoid starting new transaction when cleaning qgroup during subvolume drop futex: Pass in task to futex_queue() iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic() sched/debug: Provide slice length for fair tasks platform/x86/intel: pmc: fix ltr decode in pmc_core_ltr_show() drm/amd/display: Fix out-of-bound accesses scsi: core: Use GFP_NOIO to avoid circular locking dependency scsi: ufs: core: Fix error return with query response scsi: qla1280: Fix kernel oops when debug level > 2 ACPI: resource: IRQ override for Eluktronics MECH-17 smb: client: fix noisy when tree connecting to DFS interlink targets alpha/elf: Fix misc/setarch test of util-linux by removing 32bit support vboxsf: fix building with GCC 15 selftests: always check mask returned by statmount(2) sched_ext: selftests/dsp_local_on: Fix sporadic failures HID: intel-ish-hid: fix the length of MNG_SYNC_FW_CLOCK in doorbell HID: intel-ish-hid: Send clock sync message immediately after reset HID: ignore non-functional sensor in HP 5MP Camera HID: hid-steam: Fix issues with disabling both gamepad mode and lizard mode usb: phy: generic: Use proper helper for property detection HID: intel-ish-hid: ipc: Add Panther Lake PCI device IDs HID: topre: Fix n-key rollover on Realforce R3S TKL boards selftests/cgroup: use bash in test_cpuset_v1_hp.sh HID: hid-apple: Apple Magic Keyboard a3203 USB-C support HID: apple: fix up the F6 key on the Omoton KB066 keyboard btrfs: fix two misuses of folio_shift() objtool: Ignore dangling jump table entries sched: Clarify wake_up_q()'s write to task->wake_q.next platform/x86: thinkpad_acpi: Fix invalid fan speed on ThinkPad X120e platform/x86: thinkpad_acpi: Support for V9 DYTC platform profiles platform/x86: int3472: Use correct type for "polarity", call it gpio_flags platform/x86: int3472: Call "reset" GPIO "enable" for INT347E s390/cio: Fix CHPID "configure" attribute caching thermal/cpufreq_cooling: Remove structure member documentation LoongArch: Fix kernel_page_present() for KPRANGE/XKPRANGE LoongArch: KVM: Set host with kernel mode when switch to VM mode arm64: amu: Delay allocating cpumask for AMU FIE support Xen/swiotlb: mark xen_swiotlb_fixup() __init Bluetooth: L2CAP: Fix slab-use-after-free Read in l2cap_send_cmd drm/tests: hdmi: Remove redundant assignments drm/tests: hdmi: Reorder DRM entities variables assignment drm/tests: hdmi: Fix recursive locking selftests/bpf: Fix invalid flag of recv() ASoC: Intel: sof_sdw: Add lookup of quirk using PCI subsystem ID ASoC: Intel: sof_sdw: Add quirk for Asus Zenbook S14 ASoC: Intel: soc-acpi-intel-mtl-match: declare adr as ull ASoC: simple-card-utils.c: add missing dlc->of_node ALSA: hda/realtek: Limit mic boost on Positivo ARN50 ASoC: rsnd: indicate unsupported clock rate ASoC: rsnd: don't indicate warning on rsnd_kctrl_accept_runtime() ASoC: rsnd: adjust convert rate limitation ASoC: arizona/madera: use fsleep() in up/down DAPM event delays. ASoC: SOF: Intel: hda: add softdep pre to snd-hda-codec-hdmi module PCI: pci_ids: add INTEL_HDA_PTL_H ALSA: hda: intel-dsp-config: Add PTL-H support ASoC: SOF: Intel: pci-ptl: Add support for PTL-H ALSA: hda: hda-intel: add Panther Lake-H support ASoC: SOF: amd: Add post_fw_run_delay ACP quirk ASoC: SOF: amd: Handle IPC replies before FW_BOOT_COMPLETE net: wwan: mhi_wwan_mbim: Silence sequence number glitch errors io-wq: backoff when retrying worker creation nvme-pci: quirk Acer FA100 for non-uniqueue identifiers nvmet-rdma: recheck queue state is LIVE in state lock in recv done apple-nvme: Release power domains when probe fails cifs: Treat unhandled directory name surrogate reparse points as mount directory nodes sctp: Fix undefined behavior in left shift operation nvme: only allow entering LIVE from CONNECTING state phy: ti: gmii-sel: Do not use syscon helper to build regmap ASoC: tas2770: Fix volume scale ASoC: tas2764: Fix power control mask ASoC: tas2764: Set the SDOUT polarity correctly fuse: don't truncate cached, mutated symlink ASoC: dapm-graph: set fill colour of turned on nodes ASoC: SOF: Intel: don't check number of sdw links when set dmic_fixup drm/vkms: Round fixp2int conversion in lerp_u16 perf/x86/intel: Use better start period for frequency mode x86/of: Don't use DTB for SMP setup if ACPI is enabled x86/irq: Define trace events conditionally perf/x86/rapl: Add support for Intel Arrow Lake U mptcp: safety check before fallback drm/nouveau: Do not override forced connector status net: Handle napi_schedule() calls from non-interrupt block: fix 'kmem_cache of name 'bio-108' already exists' vhost: return task creation error instead of NULL cifs: Validate content of WSL reparse point buffers cifs: Throw -EOPNOTSUPP error on unsupported reparse point type from parse_reparse_point() Input: goodix-berlin - fix vddio regulator references Input: ads7846 - fix gpiod allocation Input: iqs7222 - preserve system status register Input: xpad - add 8BitDo SN30 Pro, Hyperkin X91 and Gamesir G7 SE controllers Input: xpad - add multiple supported devices Input: xpad - add support for ZOTAC Gaming Zone Input: xpad - add support for TECNO Pocket Go Input: xpad - rename QH controller to Legion Go S Input: i8042 - swap old quirk combination with new quirk for NHxxRZQ Input: i8042 - add required quirks for missing old boardnames Input: i8042 - swap old quirk combination with new quirk for several devices Input: i8042 - swap old quirk combination with new quirk for more devices USB: serial: ftdi_sio: add support for Altera USB Blaster 3 USB: serial: option: add Telit Cinterion FE990B compositions USB: serial: option: fix Telit Cinterion FE990A name USB: serial: option: match on interface class for Telit FN990B rust: lockdep: Remove support for dynamically allocated LockClassKeys rust: remove leftover mentions of the `alloc` crate rust: alloc: satisfy POSIX alignment requirement rust: Disallow BTF generation with Rust + LTO rust: init: fix `Zeroable` implementation for `Option<NonNull<T>>` and `Option<KBox<T>>` x86/microcode/AMD: Fix out-of-bounds on systems with CPU-less NUMA nodes spi: microchip-core: prevent RX overflows when transmit size > FIFO size drm/i915/cdclk: Do cdclk post plane programming later drm/panic: use `div_ceil` to clean Clippy warning drm/panic: fix overindented list items in documentation drm/atomic: Filter out redundant DPMS calls drm/dp_mst: Fix locking when skipping CSN before topology probing drm/amdgpu: NULL-check BO's backing store when determining GFX12 PTE flags drm/amd/amdkfd: Evict all queues even HWS remove queue failed drm/amdgpu/display: Allow DCC for video formats on GFX12 drm/amd/display: Disable unneeded hpd interrupts during dm_init drm/amd/display: fix default brightness drm/amd/display: fix missing .is_two_pixels_per_container drm/amd/display: Restore correct backlight brightness after a GPU reset drm/amd/display: Assign normalized_pix_clk when color depth = 14 drm/amd/display: Fix slab-use-after-free on hdcp_work ksmbd: fix use-after-free in ksmbd_free_work_struct ksmbd: prevent connection release during oplock break notification clk: samsung: update PLL locktime for PLL142XX used on FSD platform clk: samsung: gs101: fix synchronous external abort in samsung_clk_save() ASoC: Intel: sof_sdw: Fix unlikely uninitialized variable use in create_sdw_dailinks() ASoC: amd: yc: Support mic on another Lenovo ThinkPad E16 Gen 2 model netmem: prevent TX of unreadable skbs dm-flakey: Fix memory corruption in optional corrupt_bio_byte feature arm64: mm: Populate vmemmap at the page level if not section aligned Fix mmu notifiers for range-based invalidates qlcnic: fix memory leak issues in qlcnic_sriov_common.c smb: client: fix regression with guest option net: phy: nxp-c45-tja11xx: add TJA112X PHY configuration errata net: phy: nxp-c45-tja11xx: add TJA112XB SGMII PCS restart errata sched_ext: Validate prev_cpu in scx_bpf_select_cpu_dfl() ASoC: ops: Consistently treat platform_max as control value rust: error: add missing newline to pr_warn! calls drm/gma500: Add NULL check for pci_gfx_root in mid_get_vbt_data() ASoC: cs42l43: Fix maximum ADC Volume rust: init: add missing newline to pr_info! calls ASoC: rt722-sdca: add missing readable registers drm/xe: cancel pending job timer before freeing scheduler drm/xe: Release guc ids before cancelling work drm/xe/userptr: Fix an incorrect assert drm/xe/pm: Temporarily disable D3Cold on BMG nvme: move error logging from nvme_end_req() to __nvme_end_req() ASoC: codecs: wm0010: Fix error handling path in wm0010_spi_probe() drm/i915: Increase I915_PARAM_MMAP_GTT_VERSION version to indicate support for partial mmaps scripts: generate_rust_analyzer: add missing macros deps scripts: generate_rust_analyzer: add missing include_dirs scripts: generate_rust_analyzer: add uapi crate block: change blk_mq_add_to_batch() third argument type to bool cifs: Fix integer overflow while processing acregmax mount option cifs: Fix integer overflow while processing acdirmax mount option cifs: Fix integer overflow while processing actimeo mount option cifs: Fix integer overflow while processing closetimeo mount option x86/vmware: Parse MP tables for SEV-SNP enabled guests under VMware hypervisors i2c: ali1535: Fix an error handling path in ali1535_probe() i2c: ali15x3: Fix an error handling path in ali15x3_probe() i2c: sis630: Fix an error handling path in sis630_probe() mm/hugetlb: wait for hugetlb folios to be freed smb3: add support for IAKerb smb: client: Fix match_session bug preventing session reuse sched_ext: selftests/dsp_local_on: Fix selftest on UP systems tools/sched_ext: Add helper to check task migration state Bluetooth: L2CAP: Fix corrupted list in hci_chan_del nvme-fc: rely on state transitions to handle connectivity loss HID: apple: disable Fn key handling on the Omoton KB066 fs/netfs/read_collect: add to next->prev_donated Linux 6.12.20 Change-Id: I5a7652336baaa64b019b6306f78ee5f96aa829aa Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 12
|
||||
SUBLEVEL = 19
|
||||
SUBLEVEL = 20
|
||||
EXTRAVERSION =
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
|
||||
@@ -396,33 +396,35 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
|
||||
#define __flush_tlb_range_op(op, start, pages, stride, \
|
||||
asid, tlb_level, tlbi_user, lpa2) \
|
||||
do { \
|
||||
typeof(start) __flush_start = start; \
|
||||
typeof(pages) __flush_pages = pages; \
|
||||
int num = 0; \
|
||||
int scale = 3; \
|
||||
int shift = lpa2 ? 16 : PAGE_SHIFT; \
|
||||
unsigned long addr; \
|
||||
\
|
||||
while (pages > 0) { \
|
||||
while (__flush_pages > 0) { \
|
||||
if (!system_supports_tlb_range() || \
|
||||
pages == 1 || \
|
||||
(lpa2 && start != ALIGN(start, SZ_64K))) { \
|
||||
addr = __TLBI_VADDR(start, asid); \
|
||||
__flush_pages == 1 || \
|
||||
(lpa2 && __flush_start != ALIGN(__flush_start, SZ_64K))) { \
|
||||
addr = __TLBI_VADDR(__flush_start, asid); \
|
||||
__tlbi_level(op, addr, tlb_level); \
|
||||
if (tlbi_user) \
|
||||
__tlbi_user_level(op, addr, tlb_level); \
|
||||
start += stride; \
|
||||
pages -= stride >> PAGE_SHIFT; \
|
||||
__flush_start += stride; \
|
||||
__flush_pages -= stride >> PAGE_SHIFT; \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
num = __TLBI_RANGE_NUM(pages, scale); \
|
||||
num = __TLBI_RANGE_NUM(__flush_pages, scale); \
|
||||
if (num >= 0) { \
|
||||
addr = __TLBI_VADDR_RANGE(start >> shift, asid, \
|
||||
addr = __TLBI_VADDR_RANGE(__flush_start >> shift, asid, \
|
||||
scale, num, tlb_level); \
|
||||
__tlbi(r##op, addr); \
|
||||
if (tlbi_user) \
|
||||
__tlbi_user(r##op, addr); \
|
||||
start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
|
||||
pages -= __TLBI_RANGE_PAGES(num, scale); \
|
||||
__flush_start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
|
||||
__flush_pages -= __TLBI_RANGE_PAGES(num, scale);\
|
||||
} \
|
||||
scale--; \
|
||||
} \
|
||||
|
||||
+4
-1
@@ -1177,8 +1177,11 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
|
||||
struct vmem_altmap *altmap)
|
||||
{
|
||||
WARN_ON((start < VMEMMAP_START) || (end > VMEMMAP_END));
|
||||
/* [start, end] should be within one section */
|
||||
WARN_ON_ONCE(end - start > PAGES_PER_SECTION * sizeof(struct page));
|
||||
|
||||
if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
|
||||
if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) ||
|
||||
(end - start < PAGES_PER_SECTION * sizeof(struct page)))
|
||||
return vmemmap_populate_basepages(start, end, node, altmap);
|
||||
else
|
||||
return vmemmap_populate_hugepages(start, end, node, altmap);
|
||||
|
||||
@@ -1075,7 +1075,7 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
|
||||
if (ret != UCODE_OK)
|
||||
return ret;
|
||||
|
||||
for_each_node(nid) {
|
||||
for_each_node_with_cpus(nid) {
|
||||
cpu = cpumask_first(cpumask_of_node(nid));
|
||||
c = &cpu_data(cpu);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/efi.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/static_call.h>
|
||||
#include <asm/div64.h>
|
||||
@@ -429,6 +430,9 @@ static void __init vmware_platform_setup(void)
|
||||
pr_warn("Failed to get TSC freq from the hypervisor\n");
|
||||
}
|
||||
|
||||
if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !efi_enabled(EFI_BOOT))
|
||||
x86_init.mpparse.find_mptable = mpparse_find_mptable;
|
||||
|
||||
vmware_paravirt_ops_setup();
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
|
||||
@@ -1541,8 +1541,8 @@ static int null_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
|
||||
cmd = blk_mq_rq_to_pdu(req);
|
||||
cmd->error = null_process_cmd(cmd, req_op(req), blk_rq_pos(req),
|
||||
blk_rq_sectors(req));
|
||||
if (!blk_mq_add_to_batch(req, iob, (__force int) cmd->error,
|
||||
blk_mq_end_request_batch))
|
||||
if (!blk_mq_add_to_batch(req, iob, cmd->error != BLK_STS_OK,
|
||||
blk_mq_end_request_batch))
|
||||
blk_mq_end_request(req, cmd->error);
|
||||
nr++;
|
||||
}
|
||||
|
||||
@@ -1210,11 +1210,12 @@ static int virtblk_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
|
||||
|
||||
while ((vbr = virtqueue_get_buf(vq->vq, &len)) != NULL) {
|
||||
struct request *req = blk_mq_rq_from_pdu(vbr);
|
||||
u8 status = virtblk_vbr_status(vbr);
|
||||
|
||||
found++;
|
||||
if (!blk_mq_complete_request_remote(req) &&
|
||||
!blk_mq_add_to_batch(req, iob, virtblk_vbr_status(vbr),
|
||||
virtblk_complete_batch))
|
||||
!blk_mq_add_to_batch(req, iob, status != VIRTIO_BLK_S_OK,
|
||||
virtblk_complete_batch))
|
||||
virtblk_request_done(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -382,17 +382,9 @@ static const unsigned long cmu_top_clk_regs[] __initconst = {
|
||||
EARLY_WAKEUP_DPU_DEST,
|
||||
EARLY_WAKEUP_CSIS_DEST,
|
||||
EARLY_WAKEUP_SW_TRIG_APM,
|
||||
EARLY_WAKEUP_SW_TRIG_APM_SET,
|
||||
EARLY_WAKEUP_SW_TRIG_APM_CLEAR,
|
||||
EARLY_WAKEUP_SW_TRIG_CLUSTER0,
|
||||
EARLY_WAKEUP_SW_TRIG_CLUSTER0_SET,
|
||||
EARLY_WAKEUP_SW_TRIG_CLUSTER0_CLEAR,
|
||||
EARLY_WAKEUP_SW_TRIG_DPU,
|
||||
EARLY_WAKEUP_SW_TRIG_DPU_SET,
|
||||
EARLY_WAKEUP_SW_TRIG_DPU_CLEAR,
|
||||
EARLY_WAKEUP_SW_TRIG_CSIS,
|
||||
EARLY_WAKEUP_SW_TRIG_CSIS_SET,
|
||||
EARLY_WAKEUP_SW_TRIG_CSIS_CLEAR,
|
||||
CLK_CON_MUX_MUX_CLKCMU_BO_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_BUS0_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_BUS1_BUS,
|
||||
|
||||
@@ -206,6 +206,7 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
|
||||
*/
|
||||
/* Maximum lock time can be 270 * PDIV cycles */
|
||||
#define PLL35XX_LOCK_FACTOR (270)
|
||||
#define PLL142XX_LOCK_FACTOR (150)
|
||||
|
||||
#define PLL35XX_MDIV_MASK (0x3FF)
|
||||
#define PLL35XX_PDIV_MASK (0x3F)
|
||||
@@ -272,7 +273,11 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
|
||||
if (pll->type == pll_142xx)
|
||||
writel_relaxed(rate->pdiv * PLL142XX_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
else
|
||||
writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
|
||||
@@ -525,8 +525,9 @@ static void gmc_v12_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
|
||||
bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
coherent = bo->flags & AMDGPU_GEM_CREATE_COHERENT;
|
||||
is_system = (bo->tbo.resource->mem_type == TTM_PL_TT) ||
|
||||
(bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT);
|
||||
is_system = bo->tbo.resource &&
|
||||
(bo->tbo.resource->mem_type == TTM_PL_TT ||
|
||||
bo->tbo.resource->mem_type == AMDGPU_PL_PREEMPT);
|
||||
|
||||
if (bo && bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
|
||||
*flags |= AMDGPU_PTE_DCC;
|
||||
|
||||
@@ -1199,11 +1199,13 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
|
||||
decrement_queue_count(dqm, qpd, q);
|
||||
|
||||
if (dqm->dev->kfd->shared_resources.enable_mes) {
|
||||
retval = remove_queue_mes(dqm, q, qpd);
|
||||
if (retval) {
|
||||
int err;
|
||||
|
||||
err = remove_queue_mes(dqm, q, qpd);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to evict queue %d\n",
|
||||
q->properties.queue_id);
|
||||
goto out;
|
||||
retval = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector);
|
||||
static void handle_hpd_rx_irq(void *param);
|
||||
|
||||
static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
|
||||
int bl_idx,
|
||||
u32 user_brightness);
|
||||
|
||||
static bool
|
||||
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
|
||||
struct drm_crtc_state *new_crtc_state);
|
||||
@@ -3295,6 +3299,12 @@ static int dm_resume(void *handle)
|
||||
|
||||
mutex_unlock(&dm->dc_lock);
|
||||
|
||||
/* set the backlight after a reset */
|
||||
for (i = 0; i < dm->num_of_edps; i++) {
|
||||
if (dm->backlight_dev[i])
|
||||
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Recreate dc_state - DC invalidates it when setting power state to S3. */
|
||||
@@ -4822,6 +4832,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
|
||||
dm->backlight_dev[aconnector->bl_idx] =
|
||||
backlight_device_register(bl_name, aconnector->base.kdev, dm,
|
||||
&amdgpu_dm_backlight_ops, &props);
|
||||
dm->brightness[aconnector->bl_idx] = props.brightness;
|
||||
|
||||
if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
|
||||
DRM_ERROR("DM: Backlight registration failed!\n");
|
||||
@@ -4889,7 +4900,6 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm,
|
||||
aconnector->bl_idx = bl_idx;
|
||||
|
||||
amdgpu_dm_update_backlight_caps(dm, bl_idx);
|
||||
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
|
||||
dm->backlight_link[bl_idx] = link;
|
||||
dm->num_of_edps++;
|
||||
|
||||
|
||||
@@ -455,6 +455,7 @@ void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
||||
for (i = 0; i < hdcp_work->max_link; i++) {
|
||||
cancel_delayed_work_sync(&hdcp_work[i].callback_dwork);
|
||||
cancel_delayed_work_sync(&hdcp_work[i].watchdog_timer_dwork);
|
||||
cancel_delayed_work_sync(&hdcp_work[i].property_validate_dwork);
|
||||
}
|
||||
|
||||
sysfs_remove_bin_file(kobj, &hdcp_work[0].attr);
|
||||
|
||||
@@ -894,8 +894,16 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int irq_type;
|
||||
int i;
|
||||
|
||||
/* First, clear all hpd and hpdrx interrupts */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= DC_IRQ_SOURCE_HPD6RX; i++) {
|
||||
if (!dc_interrupt_set(adev->dm.dc, i, false))
|
||||
drm_err(dev, "Failed to clear hpd(rx) source=%d on init\n",
|
||||
i);
|
||||
}
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector;
|
||||
@@ -908,10 +916,31 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
|
||||
dc_link = amdgpu_dm_connector->dc_link;
|
||||
|
||||
/*
|
||||
* Get a base driver irq reference for hpd ints for the lifetime
|
||||
* of dm. Note that only hpd interrupt types are registered with
|
||||
* base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on
|
||||
* hpd_rx isn't available. DM currently controls hpd_rx
|
||||
* explicitly with dc_interrupt_set()
|
||||
*/
|
||||
if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
true);
|
||||
irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
|
||||
/*
|
||||
* TODO: There's a mismatch between mode_info.num_hpd
|
||||
* and what bios reports as the # of connectors with hpd
|
||||
* sources. Since the # of hpd source types registered
|
||||
* with base driver == mode_info.num_hpd, we have to
|
||||
* fallback to dc_interrupt_set for the remaining types.
|
||||
*/
|
||||
if (irq_type < adev->mode_info.num_hpd) {
|
||||
if (amdgpu_irq_get(adev, &adev->hpd_irq, irq_type))
|
||||
drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n",
|
||||
dc_link->irq_source_hpd);
|
||||
} else {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
|
||||
@@ -921,12 +950,6 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
/* Update reference counts for HPDs */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
|
||||
if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
|
||||
drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -942,7 +965,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
struct drm_device *dev = adev_to_drm(adev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter iter;
|
||||
int i;
|
||||
int irq_type;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
@@ -956,9 +979,18 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
dc_link = amdgpu_dm_connector->dc_link;
|
||||
|
||||
if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
false);
|
||||
irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
/* TODO: See same TODO in amdgpu_dm_hpd_init() */
|
||||
if (irq_type < adev->mode_info.num_hpd) {
|
||||
if (amdgpu_irq_put(adev, &adev->hpd_irq, irq_type))
|
||||
drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n",
|
||||
dc_link->irq_source_hpd);
|
||||
} else {
|
||||
dc_interrupt_set(adev->dm.dc,
|
||||
dc_link->irq_source_hpd,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_link->irq_source_hpd_rx != DC_IRQ_SOURCE_INVALID) {
|
||||
@@ -968,10 +1000,4 @@ void amdgpu_dm_hpd_fini(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
/* Update reference counts for HPDs */
|
||||
for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
|
||||
if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
|
||||
drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,8 +275,11 @@ static int amdgpu_dm_plane_validate_dcc(struct amdgpu_device *adev,
|
||||
if (!dcc->enable)
|
||||
return 0;
|
||||
|
||||
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
|
||||
!dc->cap_funcs.get_dcc_compression_cap)
|
||||
if (adev->family < AMDGPU_FAMILY_GC_12_0_0 &&
|
||||
format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dc->cap_funcs.get_dcc_compression_cap)
|
||||
return -EINVAL;
|
||||
|
||||
input.format = format;
|
||||
|
||||
@@ -3388,10 +3388,13 @@ static int get_norm_pix_clk(const struct dc_crtc_timing *timing)
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
normalized_pix_clk = (pix_clk * 36) / 24;
|
||||
break;
|
||||
break;
|
||||
case COLOR_DEPTH_141414:
|
||||
normalized_pix_clk = (pix_clk * 42) / 24;
|
||||
break;
|
||||
case COLOR_DEPTH_161616:
|
||||
normalized_pix_clk = (pix_clk * 48) / 24;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
|
||||
@@ -239,6 +239,7 @@ static const struct timing_generator_funcs dce60_tg_funcs = {
|
||||
dce60_timing_generator_enable_advanced_request,
|
||||
.configure_crc = dce60_configure_crc,
|
||||
.get_crc = dce110_get_crc,
|
||||
.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
|
||||
};
|
||||
|
||||
void dce60_timing_generator_construct(
|
||||
|
||||
@@ -4034,6 +4034,22 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool primary_mstb_probing_is_done(struct drm_dp_mst_topology_mgr *mgr)
|
||||
{
|
||||
bool probing_done = false;
|
||||
|
||||
mutex_lock(&mgr->lock);
|
||||
|
||||
if (mgr->mst_primary && drm_dp_mst_topology_try_get_mstb(mgr->mst_primary)) {
|
||||
probing_done = mgr->mst_primary->link_address_sent;
|
||||
drm_dp_mst_topology_put_mstb(mgr->mst_primary);
|
||||
}
|
||||
|
||||
mutex_unlock(&mgr->lock);
|
||||
|
||||
return probing_done;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
drm_dp_mst_process_up_req(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_dp_pending_up_req *up_req)
|
||||
@@ -4064,8 +4080,12 @@ drm_dp_mst_process_up_req(struct drm_dp_mst_topology_mgr *mgr,
|
||||
|
||||
/* TODO: Add missing handler for DP_RESOURCE_STATUS_NOTIFY events */
|
||||
if (msg->req_type == DP_CONNECTION_STATUS_NOTIFY) {
|
||||
dowork = drm_dp_mst_handle_conn_stat(mstb, &msg->u.conn_stat);
|
||||
hotplug = true;
|
||||
if (!primary_mstb_probing_is_done(mgr)) {
|
||||
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.\n");
|
||||
} else {
|
||||
dowork = drm_dp_mst_handle_conn_stat(mstb, &msg->u.conn_stat);
|
||||
hotplug = true;
|
||||
}
|
||||
}
|
||||
|
||||
drm_dp_mst_topology_put_mstb(mstb);
|
||||
@@ -4144,10 +4164,11 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
drm_dp_send_up_ack_reply(mgr, mst_primary, up_req->msg.req_type,
|
||||
false);
|
||||
|
||||
drm_dp_mst_topology_put_mstb(mst_primary);
|
||||
|
||||
if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
|
||||
const struct drm_dp_connection_status_notify *conn_stat =
|
||||
&up_req->msg.u.conn_stat;
|
||||
bool handle_csn;
|
||||
|
||||
drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
|
||||
conn_stat->port_number,
|
||||
@@ -4156,16 +4177,6 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
conn_stat->message_capability_status,
|
||||
conn_stat->input_port,
|
||||
conn_stat->peer_device_type);
|
||||
|
||||
mutex_lock(&mgr->probe_lock);
|
||||
handle_csn = mst_primary->link_address_sent;
|
||||
mutex_unlock(&mgr->probe_lock);
|
||||
|
||||
if (!handle_csn) {
|
||||
drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
|
||||
kfree(up_req);
|
||||
goto out_put_primary;
|
||||
}
|
||||
} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
|
||||
const struct drm_dp_resource_status_notify *res_stat =
|
||||
&up_req->msg.u.resource_stat;
|
||||
@@ -4180,9 +4191,6 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
|
||||
list_add_tail(&up_req->next, &mgr->up_req_list);
|
||||
mutex_unlock(&mgr->up_req_lock);
|
||||
queue_work(system_long_wq, &mgr->up_req_work);
|
||||
|
||||
out_put_primary:
|
||||
drm_dp_mst_topology_put_mstb(mst_primary);
|
||||
out_clear_reply:
|
||||
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
|
||||
return 0;
|
||||
|
||||
@@ -956,6 +956,10 @@ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
|
||||
|
||||
if (mode != DRM_MODE_DPMS_ON)
|
||||
mode = DRM_MODE_DPMS_OFF;
|
||||
|
||||
if (connector->dpms == mode)
|
||||
goto out;
|
||||
|
||||
connector->dpms = mode;
|
||||
|
||||
crtc = connector->state->crtc;
|
||||
|
||||
@@ -1308,6 +1308,10 @@ EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name);
|
||||
* callback. For atomic drivers the remapping to the "ACTIVE" property is
|
||||
* implemented in the DRM core.
|
||||
*
|
||||
* On atomic drivers any DPMS setproperty ioctl where the value does not
|
||||
* change is completely skipped, otherwise a full atomic commit will occur.
|
||||
* On legacy drivers the exact behavior is driver specific.
|
||||
*
|
||||
* Note that this property cannot be set through the MODE_ATOMIC ioctl,
|
||||
* userspace must use "ACTIVE" on the CRTC instead.
|
||||
*
|
||||
|
||||
@@ -545,7 +545,7 @@ impl EncodedMsg<'_> {
|
||||
}
|
||||
self.push(&mut offset, (MODE_STOP, 4));
|
||||
|
||||
let pad_offset = (offset + 7) / 8;
|
||||
let pad_offset = offset.div_ceil(8);
|
||||
for i in pad_offset..self.version.max_data() {
|
||||
self.data[i] = PADDING[(i & 1) ^ (pad_offset & 1)];
|
||||
}
|
||||
@@ -659,7 +659,7 @@ struct QrImage<'a> {
|
||||
impl QrImage<'_> {
|
||||
fn new<'a, 'b>(em: &'b EncodedMsg<'b>, qrdata: &'a mut [u8]) -> QrImage<'a> {
|
||||
let width = em.version.width();
|
||||
let stride = (width + 7) / 8;
|
||||
let stride = width.div_ceil(8);
|
||||
let data = qrdata;
|
||||
|
||||
let mut qr_image = QrImage {
|
||||
@@ -911,16 +911,16 @@ impl QrImage<'_> {
|
||||
///
|
||||
/// * `url`: The base URL of the QR code. It will be encoded as Binary segment.
|
||||
/// * `data`: A pointer to the binary data, to be encoded. if URL is NULL, it
|
||||
/// will be encoded as binary segment, otherwise it will be encoded
|
||||
/// efficiently as a numeric segment, and appended to the URL.
|
||||
/// will be encoded as binary segment, otherwise it will be encoded
|
||||
/// efficiently as a numeric segment, and appended to the URL.
|
||||
/// * `data_len`: Length of the data, that needs to be encoded, must be less
|
||||
/// than data_size.
|
||||
/// than data_size.
|
||||
/// * `data_size`: Size of data buffer, it should be at least 4071 bytes to hold
|
||||
/// a V40 QR code. It will then be overwritten with the QR code image.
|
||||
/// a V40 QR code. It will then be overwritten with the QR code image.
|
||||
/// * `tmp`: A temporary buffer that the QR code encoder will use, to write the
|
||||
/// segments and ECC.
|
||||
/// segments and ECC.
|
||||
/// * `tmp_size`: Size of the temporary buffer, it must be at least 3706 bytes
|
||||
/// long for V40.
|
||||
/// long for V40.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
|
||||
@@ -279,6 +279,11 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
|
||||
0, PCI_DEVFN(2, 0));
|
||||
int ret = -1;
|
||||
|
||||
if (pci_gfx_root == NULL) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the address of the platform config vbt */
|
||||
pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
|
||||
pci_dev_put(pci_gfx_root);
|
||||
|
||||
@@ -7438,9 +7438,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
|
||||
dev_priv->display.funcs.display->commit_modeset_enables(state);
|
||||
|
||||
if (state->modeset)
|
||||
intel_set_cdclk_post_plane_update(state);
|
||||
|
||||
intel_wait_for_vblank_workers(state);
|
||||
|
||||
/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
|
||||
@@ -7521,6 +7518,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
||||
intel_verify_planes(state);
|
||||
|
||||
intel_sagv_post_plane_update(state);
|
||||
if (state->modeset)
|
||||
intel_set_cdclk_post_plane_update(state);
|
||||
intel_pmdemand_post_plane_update(state);
|
||||
|
||||
drm_atomic_helper_commit_hw_done(&state->base);
|
||||
|
||||
@@ -164,6 +164,9 @@ static unsigned int tile_row_pages(const struct drm_i915_gem_object *obj)
|
||||
* 4 - Support multiple fault handlers per object depending on object's
|
||||
* backing storage (a.k.a. MMAP_OFFSET).
|
||||
*
|
||||
* 5 - Support multiple partial mmaps(mmap part of BO + unmap a offset, multiple
|
||||
* times with different size and offset).
|
||||
*
|
||||
* Restrictions:
|
||||
*
|
||||
* * snoopable objects cannot be accessed via the GTT. It can cause machine
|
||||
@@ -191,7 +194,7 @@ static unsigned int tile_row_pages(const struct drm_i915_gem_object *obj)
|
||||
*/
|
||||
int i915_gem_mmap_gtt_version(void)
|
||||
{
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
static inline struct i915_gtt_view
|
||||
|
||||
@@ -1213,9 +1213,11 @@ static void __guc_exec_queue_fini_async(struct work_struct *w)
|
||||
xe_pm_runtime_get(guc_to_xe(guc));
|
||||
trace_xe_exec_queue_destroy(q);
|
||||
|
||||
release_guc_id(guc, q);
|
||||
if (xe_exec_queue_is_lr(q))
|
||||
cancel_work_sync(&ge->lr_tdr);
|
||||
release_guc_id(guc, q);
|
||||
/* Confirm no work left behind accessing device structures */
|
||||
cancel_delayed_work_sync(&ge->sched.base.work_tdr);
|
||||
xe_sched_entity_fini(&ge->entity);
|
||||
xe_sched_fini(&ge->sched);
|
||||
|
||||
|
||||
@@ -138,13 +138,17 @@ static int xe_build_sg(struct xe_device *xe, struct hmm_range *range,
|
||||
i += size;
|
||||
|
||||
if (unlikely(j == st->nents - 1)) {
|
||||
xe_assert(xe, i >= npages);
|
||||
if (i > npages)
|
||||
size -= (i - npages);
|
||||
|
||||
sg_mark_end(sgl);
|
||||
} else {
|
||||
xe_assert(xe, i < npages);
|
||||
}
|
||||
|
||||
sg_set_page(sgl, page, size << PAGE_SHIFT, 0);
|
||||
}
|
||||
xe_assert(xe, i == npages);
|
||||
|
||||
return dma_map_sgtable(dev, st, write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE,
|
||||
DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
|
||||
@@ -264,6 +264,15 @@ int xe_pm_init_early(struct xe_device *xe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 vram_threshold_value(struct xe_device *xe)
|
||||
{
|
||||
/* FIXME: D3Cold temporarily disabled by default on BMG */
|
||||
if (xe->info.platform == XE_BATTLEMAGE)
|
||||
return 0;
|
||||
|
||||
return DEFAULT_VRAM_THRESHOLD;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_pm_init - Initialize Xe Power Management
|
||||
* @xe: xe device instance
|
||||
@@ -274,6 +283,7 @@ int xe_pm_init_early(struct xe_device *xe)
|
||||
*/
|
||||
int xe_pm_init(struct xe_device *xe)
|
||||
{
|
||||
u32 vram_threshold;
|
||||
int err;
|
||||
|
||||
/* For now suspend/resume is only allowed with GuC */
|
||||
@@ -287,7 +297,8 @@ int xe_pm_init(struct xe_device *xe)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = xe_pm_set_vram_threshold(xe, DEFAULT_VRAM_THRESHOLD);
|
||||
vram_threshold = vram_threshold_value(xe);
|
||||
err = xe_pm_set_vram_threshold(xe, vram_threshold);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -378,6 +378,12 @@ static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool apple_is_omoton_kb066(struct hid_device *hdev)
|
||||
{
|
||||
return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
|
||||
strcmp(hdev->name, "Bluetooth Keyboard") == 0;
|
||||
}
|
||||
|
||||
static inline void apple_setup_key_translation(struct input_dev *input,
|
||||
const struct apple_key_translation *table)
|
||||
{
|
||||
@@ -546,9 +552,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
|
||||
}
|
||||
}
|
||||
|
||||
if (usage->hid == 0xc0301) /* Omoton KB066 quirk */
|
||||
code = KEY_F6;
|
||||
|
||||
if (usage->code != code) {
|
||||
input_event_with_scancode(input, usage->type, code, usage->hid, value);
|
||||
|
||||
@@ -728,7 +731,7 @@ static int apple_input_configured(struct hid_device *hdev,
|
||||
{
|
||||
struct apple_sc *asc = hid_get_drvdata(hdev);
|
||||
|
||||
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
|
||||
if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
|
||||
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
|
||||
asc->quirks &= ~APPLE_HAS_FN;
|
||||
}
|
||||
|
||||
@@ -485,6 +485,8 @@ MODULE_DEVICE_TABLE(pci, ali1535_ids);
|
||||
|
||||
static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ali1535_setup(dev)) {
|
||||
dev_warn(&dev->dev,
|
||||
"ALI1535 not detected, module not inserted.\n");
|
||||
@@ -496,7 +498,15 @@ static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
|
||||
"SMBus ALI1535 adapter at %04x", ali1535_offset);
|
||||
return i2c_add_adapter(&ali1535_adapter);
|
||||
ret = i2c_add_adapter(&ali1535_adapter);
|
||||
if (ret)
|
||||
goto release_region;
|
||||
|
||||
return 0;
|
||||
|
||||
release_region:
|
||||
release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ali1535_remove(struct pci_dev *dev)
|
||||
|
||||
@@ -472,6 +472,8 @@ MODULE_DEVICE_TABLE (pci, ali15x3_ids);
|
||||
|
||||
static int ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ali15x3_setup(dev)) {
|
||||
dev_err(&dev->dev,
|
||||
"ALI15X3 not detected, module not inserted.\n");
|
||||
@@ -483,7 +485,15 @@ static int ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
|
||||
snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
|
||||
"SMBus ALI15X3 adapter at %04x", ali15x3_smba);
|
||||
return i2c_add_adapter(&ali15x3_adapter);
|
||||
ret = i2c_add_adapter(&ali15x3_adapter);
|
||||
if (ret)
|
||||
goto release_region;
|
||||
|
||||
return 0;
|
||||
|
||||
release_region:
|
||||
release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ali15x3_remove(struct pci_dev *dev)
|
||||
|
||||
@@ -509,6 +509,8 @@ MODULE_DEVICE_TABLE(pci, sis630_ids);
|
||||
|
||||
static int sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sis630_setup(dev)) {
|
||||
dev_err(&dev->dev,
|
||||
"SIS630 compatible bus not detected, "
|
||||
@@ -522,7 +524,15 @@ static int sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
snprintf(sis630_adapter.name, sizeof(sis630_adapter.name),
|
||||
"SMBus SIS630 adapter at %04x", smbus_base + SMB_STS);
|
||||
|
||||
return i2c_add_adapter(&sis630_adapter);
|
||||
ret = i2c_add_adapter(&sis630_adapter);
|
||||
if (ret)
|
||||
goto release_region;
|
||||
|
||||
return 0;
|
||||
|
||||
release_region:
|
||||
release_region(smbus_base + SMB_STS, SIS630_SMB_IOREGION);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sis630_remove(struct pci_dev *dev)
|
||||
|
||||
@@ -426,7 +426,7 @@ static struct bio *clone_bio(struct dm_target *ti, struct flakey_c *fc, struct b
|
||||
if (!clone)
|
||||
return NULL;
|
||||
|
||||
bio_init(clone, fc->dev->bdev, bio->bi_inline_vecs, nr_iovecs, bio->bi_opf);
|
||||
bio_init(clone, fc->dev->bdev, clone->bi_inline_vecs, nr_iovecs, bio->bi_opf);
|
||||
|
||||
clone->bi_iter.bi_sector = flakey_map_sector(ti, bio->bi_iter.bi_sector);
|
||||
clone->bi_private = bio;
|
||||
|
||||
@@ -454,8 +454,10 @@ static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,
|
||||
|
||||
num_vlans = sriov->num_allowed_vlans;
|
||||
sriov->allowed_vlans = kcalloc(num_vlans, sizeof(u16), GFP_KERNEL);
|
||||
if (!sriov->allowed_vlans)
|
||||
if (!sriov->allowed_vlans) {
|
||||
qlcnic_sriov_free_vlans(adapter);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vlans = (u16 *)&cmd->rsp.arg[3];
|
||||
for (i = 0; i < num_vlans; i++)
|
||||
@@ -2167,8 +2169,10 @@ int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)
|
||||
vf = &sriov->vf_info[i];
|
||||
vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans,
|
||||
sizeof(*vf->sriov_vlans), GFP_KERNEL);
|
||||
if (!vf->sriov_vlans)
|
||||
if (!vf->sriov_vlans) {
|
||||
qlcnic_sriov_free_vlans(adapter);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
#define PHY_ID_TJA_1103 0x001BB010
|
||||
#define PHY_ID_TJA_1120 0x001BB031
|
||||
|
||||
#define VEND1_DEVICE_ID3 0x0004
|
||||
#define TJA1120_DEV_ID3_SILICON_VERSION GENMASK(15, 12)
|
||||
#define TJA1120_DEV_ID3_SAMPLE_TYPE GENMASK(11, 8)
|
||||
#define DEVICE_ID3_SAMPLE_TYPE_R 0x9
|
||||
|
||||
#define VEND1_DEVICE_CONTROL 0x0040
|
||||
#define DEVICE_CONTROL_RESET BIT(15)
|
||||
#define DEVICE_CONTROL_CONFIG_GLOBAL_EN BIT(14)
|
||||
@@ -108,6 +113,9 @@
|
||||
#define MII_BASIC_CONFIG_RMII 0x5
|
||||
#define MII_BASIC_CONFIG_MII 0x4
|
||||
|
||||
#define VEND1_SGMII_BASIC_CONTROL 0xB000
|
||||
#define SGMII_LPM BIT(11)
|
||||
|
||||
#define VEND1_SYMBOL_ERROR_CNT_XTD 0x8351
|
||||
#define EXTENDED_CNT_EN BIT(15)
|
||||
#define VEND1_MONITOR_STATUS 0xAC80
|
||||
@@ -1583,6 +1591,63 @@ static int nxp_c45_set_phy_mode(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Errata: ES_TJA1120 and ES_TJA1121 Rev. 1.0 — 28 November 2024 Section 3.1 & 3.2 */
|
||||
static void nxp_c45_tja1120_errata(struct phy_device *phydev)
|
||||
{
|
||||
bool macsec_ability, sgmii_ability;
|
||||
int silicon_version, sample_type;
|
||||
int phy_abilities;
|
||||
int ret = 0;
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_ID3);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
sample_type = FIELD_GET(TJA1120_DEV_ID3_SAMPLE_TYPE, ret);
|
||||
if (sample_type != DEVICE_ID3_SAMPLE_TYPE_R)
|
||||
return;
|
||||
|
||||
silicon_version = FIELD_GET(TJA1120_DEV_ID3_SILICON_VERSION, ret);
|
||||
|
||||
phy_abilities = phy_read_mmd(phydev, MDIO_MMD_VEND1,
|
||||
VEND1_PORT_ABILITIES);
|
||||
macsec_ability = !!(phy_abilities & MACSEC_ABILITY);
|
||||
sgmii_ability = !!(phy_abilities & SGMII_ABILITY);
|
||||
if ((!macsec_ability && silicon_version == 2) ||
|
||||
(macsec_ability && silicon_version == 1)) {
|
||||
/* TJA1120/TJA1121 PHY configuration errata workaround.
|
||||
* Apply PHY writes sequence before link up.
|
||||
*/
|
||||
if (!macsec_ability) {
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 0x4b95);
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 0xf3cd);
|
||||
} else {
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 0x89c7);
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 0x0893);
|
||||
}
|
||||
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x0476, 0x58a0);
|
||||
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, 0x8921, 0xa3a);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, 0x89F1, 0x16c1);
|
||||
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 0x0);
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 0x0);
|
||||
|
||||
if (sgmii_ability) {
|
||||
/* TJA1120B/TJA1121B SGMII PCS restart errata workaround.
|
||||
* Put SGMII PCS into power down mode and back up.
|
||||
*/
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
|
||||
VEND1_SGMII_BASIC_CONTROL,
|
||||
SGMII_LPM);
|
||||
phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
|
||||
VEND1_SGMII_BASIC_CONTROL,
|
||||
SGMII_LPM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int nxp_c45_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@@ -1599,6 +1664,9 @@ static int nxp_c45_config_init(struct phy_device *phydev)
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F8, 1);
|
||||
phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x01F9, 2);
|
||||
|
||||
if (phy_id_compare(phydev->phy_id, PHY_ID_TJA_1120, GENMASK(31, 4)))
|
||||
nxp_c45_tja1120_errata(phydev);
|
||||
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONFIG,
|
||||
PHY_CONFIG_AUTO);
|
||||
|
||||
|
||||
@@ -599,7 +599,8 @@ static inline void apple_nvme_handle_cqe(struct apple_nvme_queue *q,
|
||||
}
|
||||
|
||||
if (!nvme_try_complete_req(req, cqe->status, cqe->result) &&
|
||||
!blk_mq_add_to_batch(req, iob, nvme_req(req)->status,
|
||||
!blk_mq_add_to_batch(req, iob,
|
||||
nvme_req(req)->status != NVME_SC_SUCCESS,
|
||||
apple_nvme_complete_batch))
|
||||
apple_nvme_complete_rq(req);
|
||||
}
|
||||
|
||||
@@ -429,6 +429,12 @@ static inline void nvme_end_req_zoned(struct request *req)
|
||||
|
||||
static inline void __nvme_end_req(struct request *req)
|
||||
{
|
||||
if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) {
|
||||
if (blk_rq_is_passthrough(req))
|
||||
nvme_log_err_passthru(req);
|
||||
else
|
||||
nvme_log_error(req);
|
||||
}
|
||||
nvme_end_req_zoned(req);
|
||||
nvme_trace_bio_complete(req);
|
||||
if (req->cmd_flags & REQ_NVME_MPATH)
|
||||
@@ -439,12 +445,6 @@ void nvme_end_req(struct request *req)
|
||||
{
|
||||
blk_status_t status = nvme_error_status(nvme_req(req)->status);
|
||||
|
||||
if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) {
|
||||
if (blk_rq_is_passthrough(req))
|
||||
nvme_log_err_passthru(req);
|
||||
else
|
||||
nvme_log_error(req);
|
||||
}
|
||||
__nvme_end_req(req);
|
||||
blk_mq_end_request(req, status);
|
||||
}
|
||||
|
||||
+8
-63
@@ -782,61 +782,12 @@ restart:
|
||||
static void
|
||||
nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctrl)
|
||||
{
|
||||
enum nvme_ctrl_state state;
|
||||
unsigned long flags;
|
||||
|
||||
dev_info(ctrl->ctrl.device,
|
||||
"NVME-FC{%d}: controller connectivity lost. Awaiting "
|
||||
"Reconnect", ctrl->cnum);
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
set_bit(ASSOC_FAILED, &ctrl->flags);
|
||||
state = nvme_ctrl_state(&ctrl->ctrl);
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
switch (state) {
|
||||
case NVME_CTRL_NEW:
|
||||
case NVME_CTRL_LIVE:
|
||||
/*
|
||||
* Schedule a controller reset. The reset will terminate the
|
||||
* association and schedule the reconnect timer. Reconnects
|
||||
* will be attempted until either the ctlr_loss_tmo
|
||||
* (max_retries * connect_delay) expires or the remoteport's
|
||||
* dev_loss_tmo expires.
|
||||
*/
|
||||
if (nvme_reset_ctrl(&ctrl->ctrl)) {
|
||||
dev_warn(ctrl->ctrl.device,
|
||||
"NVME-FC{%d}: Couldn't schedule reset.\n",
|
||||
ctrl->cnum);
|
||||
nvme_delete_ctrl(&ctrl->ctrl);
|
||||
}
|
||||
break;
|
||||
|
||||
case NVME_CTRL_CONNECTING:
|
||||
/*
|
||||
* The association has already been terminated and the
|
||||
* controller is attempting reconnects. No need to do anything
|
||||
* futher. Reconnects will be attempted until either the
|
||||
* ctlr_loss_tmo (max_retries * connect_delay) expires or the
|
||||
* remoteport's dev_loss_tmo expires.
|
||||
*/
|
||||
break;
|
||||
|
||||
case NVME_CTRL_RESETTING:
|
||||
/*
|
||||
* Controller is already in the process of terminating the
|
||||
* association. No need to do anything further. The reconnect
|
||||
* step will kick in naturally after the association is
|
||||
* terminated.
|
||||
*/
|
||||
break;
|
||||
|
||||
case NVME_CTRL_DELETING:
|
||||
case NVME_CTRL_DELETING_NOIO:
|
||||
default:
|
||||
/* no action to take - let it delete */
|
||||
break;
|
||||
}
|
||||
nvme_reset_ctrl(&ctrl->ctrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3072,7 +3023,6 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
|
||||
struct nvmefc_ls_rcv_op *disls = NULL;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
bool changed;
|
||||
|
||||
++ctrl->ctrl.nr_reconnects;
|
||||
|
||||
@@ -3178,23 +3128,18 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
|
||||
else
|
||||
ret = nvme_fc_recreate_io_queues(ctrl);
|
||||
}
|
||||
if (ret)
|
||||
goto out_term_aen_ops;
|
||||
|
||||
spin_lock_irqsave(&ctrl->lock, flags);
|
||||
if (!test_bit(ASSOC_FAILED, &ctrl->flags))
|
||||
changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE);
|
||||
else
|
||||
if (!ret && test_bit(ASSOC_FAILED, &ctrl->flags))
|
||||
ret = -EIO;
|
||||
spin_unlock_irqrestore(&ctrl->lock, flags);
|
||||
|
||||
if (ret)
|
||||
goto out_term_aen_ops;
|
||||
|
||||
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE)) {
|
||||
ret = -EIO;
|
||||
goto out_term_aen_ops;
|
||||
}
|
||||
|
||||
ctrl->ctrl.nr_reconnects = 0;
|
||||
|
||||
if (changed)
|
||||
nvme_start_ctrl(&ctrl->ctrl);
|
||||
nvme_start_ctrl(&ctrl->ctrl);
|
||||
|
||||
return 0; /* Success */
|
||||
|
||||
|
||||
@@ -1131,8 +1131,9 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
|
||||
|
||||
trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail);
|
||||
if (!nvme_try_complete_req(req, cqe->status, cqe->result) &&
|
||||
!blk_mq_add_to_batch(req, iob, nvme_req(req)->status,
|
||||
nvme_pci_complete_batch))
|
||||
!blk_mq_add_to_batch(req, iob,
|
||||
nvme_req(req)->status != NVME_SC_SUCCESS,
|
||||
nvme_pci_complete_batch))
|
||||
nvme_pci_complete_rq(req);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,7 @@
|
||||
#define INT_RX_CHANNEL_OVERFLOW BIT(2)
|
||||
#define INT_TX_CHANNEL_UNDERRUN BIT(3)
|
||||
|
||||
#define INT_ENABLE_MASK (CONTROL_RX_DATA_INT | CONTROL_TX_DATA_INT | \
|
||||
CONTROL_RX_OVER_INT | CONTROL_TX_UNDER_INT)
|
||||
#define INT_ENABLE_MASK (CONTROL_RX_OVER_INT | CONTROL_TX_UNDER_INT)
|
||||
|
||||
#define REG_CONTROL (0x00)
|
||||
#define REG_FRAME_SIZE (0x04)
|
||||
@@ -133,10 +132,15 @@ static inline void mchp_corespi_disable(struct mchp_corespi *spi)
|
||||
mchp_corespi_write(spi, REG_CONTROL, control);
|
||||
}
|
||||
|
||||
static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi)
|
||||
static inline void mchp_corespi_read_fifo(struct mchp_corespi *spi, int fifo_max)
|
||||
{
|
||||
while (spi->rx_len >= spi->n_bytes && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)) {
|
||||
u32 data = mchp_corespi_read(spi, REG_RX_DATA);
|
||||
for (int i = 0; i < fifo_max; i++) {
|
||||
u32 data;
|
||||
|
||||
while (mchp_corespi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)
|
||||
;
|
||||
|
||||
data = mchp_corespi_read(spi, REG_RX_DATA);
|
||||
|
||||
spi->rx_len -= spi->n_bytes;
|
||||
|
||||
@@ -211,11 +215,10 @@ static inline void mchp_corespi_set_xfer_size(struct mchp_corespi *spi, int len)
|
||||
mchp_corespi_write(spi, REG_FRAMESUP, len);
|
||||
}
|
||||
|
||||
static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi)
|
||||
static inline void mchp_corespi_write_fifo(struct mchp_corespi *spi, int fifo_max)
|
||||
{
|
||||
int fifo_max, i = 0;
|
||||
int i = 0;
|
||||
|
||||
fifo_max = DIV_ROUND_UP(min(spi->tx_len, FIFO_DEPTH), spi->n_bytes);
|
||||
mchp_corespi_set_xfer_size(spi, fifo_max);
|
||||
|
||||
while ((i < fifo_max) && !(mchp_corespi_read(spi, REG_STATUS) & STATUS_TXFIFO_FULL)) {
|
||||
@@ -413,19 +416,6 @@ static irqreturn_t mchp_corespi_interrupt(int irq, void *dev_id)
|
||||
if (intfield == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (intfield & INT_TXDONE)
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_TXDONE);
|
||||
|
||||
if (intfield & INT_RXRDY) {
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_RXRDY);
|
||||
|
||||
if (spi->rx_len)
|
||||
mchp_corespi_read_fifo(spi);
|
||||
}
|
||||
|
||||
if (!spi->rx_len && !spi->tx_len)
|
||||
finalise = true;
|
||||
|
||||
if (intfield & INT_RX_CHANNEL_OVERFLOW) {
|
||||
mchp_corespi_write(spi, REG_INT_CLEAR, INT_RX_CHANNEL_OVERFLOW);
|
||||
finalise = true;
|
||||
@@ -512,9 +502,14 @@ static int mchp_corespi_transfer_one(struct spi_controller *host,
|
||||
|
||||
mchp_corespi_write(spi, REG_SLAVE_SELECT, spi->pending_slave_select);
|
||||
|
||||
while (spi->tx_len)
|
||||
mchp_corespi_write_fifo(spi);
|
||||
while (spi->tx_len) {
|
||||
int fifo_max = DIV_ROUND_UP(min(spi->tx_len, FIFO_DEPTH), spi->n_bytes);
|
||||
|
||||
mchp_corespi_write_fifo(spi, fifo_max);
|
||||
mchp_corespi_read_fifo(spi, fifo_max);
|
||||
}
|
||||
|
||||
spi_finalize_current_transfer(host);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ donation_changed:
|
||||
netfs_trace_donate_to_deferred_next);
|
||||
} else {
|
||||
next = list_next_entry(subreq, rreq_link);
|
||||
WRITE_ONCE(next->prev_donated, excess);
|
||||
WRITE_ONCE(next->prev_donated, next->prev_donated + excess);
|
||||
trace_netfs_donate(rreq, subreq, next, excess,
|
||||
netfs_trace_donate_to_next);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ int cifs_neg_token_init_mech_type(void *context, size_t hdrlen,
|
||||
server->sec_kerberos = true;
|
||||
else if (oid == OID_ntlmssp)
|
||||
server->sec_ntlmssp = true;
|
||||
else if (oid == OID_IAKerb)
|
||||
server->sec_iakerb = true;
|
||||
else {
|
||||
char buf[50];
|
||||
|
||||
|
||||
@@ -130,11 +130,13 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo,
|
||||
|
||||
dp = description + strlen(description);
|
||||
|
||||
/* for now, only sec=krb5 and sec=mskrb5 are valid */
|
||||
/* for now, only sec=krb5 and sec=mskrb5 and iakerb are valid */
|
||||
if (server->sec_kerberos)
|
||||
sprintf(dp, ";sec=krb5");
|
||||
else if (server->sec_mskerberos)
|
||||
sprintf(dp, ";sec=mskrb5");
|
||||
else if (server->sec_iakerb)
|
||||
sprintf(dp, ";sec=iakerb");
|
||||
else {
|
||||
cifs_dbg(VFS, "unknown or missing server auth type, use krb5\n");
|
||||
sprintf(dp, ";sec=krb5");
|
||||
|
||||
@@ -151,6 +151,7 @@ enum securityEnum {
|
||||
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
|
||||
RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
|
||||
Kerberos, /* Kerberos via SPNEGO */
|
||||
IAKerb, /* Kerberos proxy */
|
||||
};
|
||||
|
||||
enum cifs_reparse_type {
|
||||
@@ -743,6 +744,7 @@ struct TCP_Server_Info {
|
||||
bool sec_kerberosu2u; /* supports U2U Kerberos */
|
||||
bool sec_kerberos; /* supports plain Kerberos */
|
||||
bool sec_mskerberos; /* supports legacy MS Kerberos */
|
||||
bool sec_iakerb; /* supports pass-through auth for Kerberos (krb5 proxy) */
|
||||
bool large_buf; /* is current buffer large? */
|
||||
/* use SMBD connection instead of socket */
|
||||
bool rdma;
|
||||
@@ -2115,6 +2117,8 @@ static inline char *get_security_type_str(enum securityEnum sectype)
|
||||
return "Kerberos";
|
||||
case NTLMv2:
|
||||
return "NTLMv2";
|
||||
case IAKerb:
|
||||
return "IAKerb";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
+12
-4
@@ -1873,9 +1873,8 @@ static int match_session(struct cifs_ses *ses,
|
||||
struct smb3_fs_context *ctx,
|
||||
bool match_super)
|
||||
{
|
||||
if (ctx->sectype != Unspecified &&
|
||||
ctx->sectype != ses->sectype)
|
||||
return 0;
|
||||
struct TCP_Server_Info *server = ses->server;
|
||||
enum securityEnum ctx_sec, ses_sec;
|
||||
|
||||
if (!match_super && ctx->dfs_root_ses != ses->dfs_root_ses)
|
||||
return 0;
|
||||
@@ -1887,11 +1886,20 @@ static int match_session(struct cifs_ses *ses,
|
||||
if (ses->chan_max < ctx->max_channels)
|
||||
return 0;
|
||||
|
||||
switch (ses->sectype) {
|
||||
ctx_sec = server->ops->select_sectype(server, ctx->sectype);
|
||||
ses_sec = server->ops->select_sectype(server, ses->sectype);
|
||||
|
||||
if (ctx_sec != ses_sec)
|
||||
return 0;
|
||||
|
||||
switch (ctx_sec) {
|
||||
case IAKerb:
|
||||
case Kerberos:
|
||||
if (!uid_eq(ctx->cred_uid, ses->cred_uid))
|
||||
return 0;
|
||||
break;
|
||||
case NTLMv2:
|
||||
case RawNTLMSSP:
|
||||
default:
|
||||
/* NULL username means anonymous session */
|
||||
if (ses->user_name == NULL) {
|
||||
|
||||
@@ -164,6 +164,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
|
||||
fsparam_string("username", Opt_user),
|
||||
fsparam_string("pass", Opt_pass),
|
||||
fsparam_string("password", Opt_pass),
|
||||
fsparam_string("pass2", Opt_pass2),
|
||||
fsparam_string("password2", Opt_pass2),
|
||||
fsparam_string("ip", Opt_ip),
|
||||
fsparam_string("addr", Opt_ip),
|
||||
@@ -1041,6 +1042,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
} else if (!strcmp("user", param->key) || !strcmp("username", param->key)) {
|
||||
skip_parsing = true;
|
||||
opt = Opt_user;
|
||||
} else if (!strcmp("pass2", param->key) || !strcmp("password2", param->key)) {
|
||||
skip_parsing = true;
|
||||
opt = Opt_pass2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1250,21 +1254,21 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
}
|
||||
break;
|
||||
case Opt_acregmax:
|
||||
ctx->acregmax = HZ * result.uint_32;
|
||||
if (ctx->acregmax > CIFS_MAX_ACTIMEO) {
|
||||
if (result.uint_32 > CIFS_MAX_ACTIMEO / HZ) {
|
||||
cifs_errorf(fc, "acregmax too large\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
ctx->acregmax = HZ * result.uint_32;
|
||||
break;
|
||||
case Opt_acdirmax:
|
||||
ctx->acdirmax = HZ * result.uint_32;
|
||||
if (ctx->acdirmax > CIFS_MAX_ACTIMEO) {
|
||||
if (result.uint_32 > CIFS_MAX_ACTIMEO / HZ) {
|
||||
cifs_errorf(fc, "acdirmax too large\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
ctx->acdirmax = HZ * result.uint_32;
|
||||
break;
|
||||
case Opt_actimeo:
|
||||
if (HZ * result.uint_32 > CIFS_MAX_ACTIMEO) {
|
||||
if (result.uint_32 > CIFS_MAX_ACTIMEO / HZ) {
|
||||
cifs_errorf(fc, "timeout too large\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
@@ -1276,11 +1280,11 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
ctx->acdirmax = ctx->acregmax = HZ * result.uint_32;
|
||||
break;
|
||||
case Opt_closetimeo:
|
||||
ctx->closetimeo = HZ * result.uint_32;
|
||||
if (ctx->closetimeo > SMB3_MAX_DCLOSETIMEO) {
|
||||
if (result.uint_32 > SMB3_MAX_DCLOSETIMEO / HZ) {
|
||||
cifs_errorf(fc, "closetimeo too large\n");
|
||||
goto cifs_parse_mount_err;
|
||||
}
|
||||
ctx->closetimeo = HZ * result.uint_32;
|
||||
break;
|
||||
case Opt_echo_interval:
|
||||
ctx->echo_interval = result.uint_32;
|
||||
|
||||
@@ -1263,12 +1263,13 @@ cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
|
||||
switch (requested) {
|
||||
case Kerberos:
|
||||
case RawNTLMSSP:
|
||||
case IAKerb:
|
||||
return requested;
|
||||
case Unspecified:
|
||||
if (server->sec_ntlmssp &&
|
||||
(global_secflags & CIFSSEC_MAY_NTLMSSP))
|
||||
return RawNTLMSSP;
|
||||
if ((server->sec_kerberos || server->sec_mskerberos) &&
|
||||
if ((server->sec_kerberos || server->sec_mskerberos || server->sec_iakerb) &&
|
||||
(global_secflags & CIFSSEC_MAY_KRB5))
|
||||
return Kerberos;
|
||||
fallthrough;
|
||||
|
||||
@@ -1435,7 +1435,7 @@ smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
|
||||
if (server->sec_ntlmssp &&
|
||||
(global_secflags & CIFSSEC_MAY_NTLMSSP))
|
||||
return RawNTLMSSP;
|
||||
if ((server->sec_kerberos || server->sec_mskerberos) &&
|
||||
if ((server->sec_kerberos || server->sec_mskerberos || server->sec_iakerb) &&
|
||||
(global_secflags & CIFSSEC_MAY_KRB5))
|
||||
return Kerberos;
|
||||
fallthrough;
|
||||
|
||||
@@ -432,6 +432,26 @@ void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops)
|
||||
default_conn_ops.terminate_fn = ops->terminate_fn;
|
||||
}
|
||||
|
||||
void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn)
|
||||
{
|
||||
atomic_inc(&conn->r_count);
|
||||
}
|
||||
|
||||
void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn)
|
||||
{
|
||||
/*
|
||||
* Checking waitqueue to dropping pending requests on
|
||||
* disconnection. waitqueue_active is safe because it
|
||||
* uses atomic operation for condition.
|
||||
*/
|
||||
atomic_inc(&conn->refcnt);
|
||||
if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
|
||||
wake_up(&conn->r_count_q);
|
||||
|
||||
if (atomic_dec_and_test(&conn->refcnt))
|
||||
kfree(conn);
|
||||
}
|
||||
|
||||
int ksmbd_conn_transport_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -168,6 +168,8 @@ int ksmbd_conn_transport_init(void);
|
||||
void ksmbd_conn_transport_destroy(void);
|
||||
void ksmbd_conn_lock(struct ksmbd_conn *conn);
|
||||
void ksmbd_conn_unlock(struct ksmbd_conn *conn);
|
||||
void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn);
|
||||
void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn);
|
||||
|
||||
/*
|
||||
* WARNING
|
||||
|
||||
@@ -26,7 +26,6 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void)
|
||||
INIT_LIST_HEAD(&work->request_entry);
|
||||
INIT_LIST_HEAD(&work->async_request_entry);
|
||||
INIT_LIST_HEAD(&work->fp_entry);
|
||||
INIT_LIST_HEAD(&work->interim_entry);
|
||||
INIT_LIST_HEAD(&work->aux_read_list);
|
||||
work->iov_alloc_cnt = 4;
|
||||
work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec),
|
||||
@@ -56,8 +55,6 @@ void ksmbd_free_work_struct(struct ksmbd_work *work)
|
||||
kfree(work->tr_buf);
|
||||
kvfree(work->request_buf);
|
||||
kfree(work->iov);
|
||||
if (!list_empty(&work->interim_entry))
|
||||
list_del(&work->interim_entry);
|
||||
|
||||
if (work->async_id)
|
||||
ksmbd_release_id(&work->conn->async_ida, work->async_id);
|
||||
|
||||
@@ -89,7 +89,6 @@ struct ksmbd_work {
|
||||
/* List head at conn->async_requests */
|
||||
struct list_head async_request_entry;
|
||||
struct list_head fp_entry;
|
||||
struct list_head interim_entry;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+21
-22
@@ -46,7 +46,6 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work,
|
||||
opinfo->fid = id;
|
||||
opinfo->Tid = Tid;
|
||||
INIT_LIST_HEAD(&opinfo->op_entry);
|
||||
INIT_LIST_HEAD(&opinfo->interim_list);
|
||||
init_waitqueue_head(&opinfo->oplock_q);
|
||||
init_waitqueue_head(&opinfo->oplock_brk);
|
||||
atomic_set(&opinfo->refcount, 1);
|
||||
@@ -635,6 +634,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
|
||||
{
|
||||
struct smb2_oplock_break *rsp = NULL;
|
||||
struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
struct oplock_break_info *br_info = work->request_buf;
|
||||
struct smb2_hdr *rsp_hdr;
|
||||
struct ksmbd_file *fp;
|
||||
@@ -690,6 +690,7 @@ static void __smb2_oplock_break_noti(struct work_struct *wk)
|
||||
|
||||
out:
|
||||
ksmbd_free_work_struct(work);
|
||||
ksmbd_conn_r_count_dec(conn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -724,6 +725,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo)
|
||||
work->sess = opinfo->sess;
|
||||
|
||||
if (opinfo->op_state == OPLOCK_ACK_WAIT) {
|
||||
ksmbd_conn_r_count_inc(conn);
|
||||
INIT_WORK(&work->work, __smb2_oplock_break_noti);
|
||||
ksmbd_queue_work(work);
|
||||
|
||||
@@ -745,6 +747,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
|
||||
{
|
||||
struct smb2_lease_break *rsp = NULL;
|
||||
struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
struct lease_break_info *br_info = work->request_buf;
|
||||
struct smb2_hdr *rsp_hdr;
|
||||
|
||||
@@ -791,6 +794,7 @@ static void __smb2_lease_break_noti(struct work_struct *wk)
|
||||
|
||||
out:
|
||||
ksmbd_free_work_struct(work);
|
||||
ksmbd_conn_r_count_dec(conn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -803,7 +807,6 @@ out:
|
||||
static int smb2_lease_break_noti(struct oplock_info *opinfo)
|
||||
{
|
||||
struct ksmbd_conn *conn = opinfo->conn;
|
||||
struct list_head *tmp, *t;
|
||||
struct ksmbd_work *work;
|
||||
struct lease_break_info *br_info;
|
||||
struct lease *lease = opinfo->o_lease;
|
||||
@@ -831,16 +834,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
|
||||
work->sess = opinfo->sess;
|
||||
|
||||
if (opinfo->op_state == OPLOCK_ACK_WAIT) {
|
||||
list_for_each_safe(tmp, t, &opinfo->interim_list) {
|
||||
struct ksmbd_work *in_work;
|
||||
|
||||
in_work = list_entry(tmp, struct ksmbd_work,
|
||||
interim_entry);
|
||||
setup_async_work(in_work, NULL, NULL);
|
||||
smb2_send_interim_resp(in_work, STATUS_PENDING);
|
||||
list_del_init(&in_work->interim_entry);
|
||||
release_async_work(in_work);
|
||||
}
|
||||
ksmbd_conn_r_count_inc(conn);
|
||||
INIT_WORK(&work->work, __smb2_lease_break_noti);
|
||||
ksmbd_queue_work(work);
|
||||
wait_for_break_ack(opinfo);
|
||||
@@ -871,7 +865,8 @@ static void wait_lease_breaking(struct oplock_info *opinfo)
|
||||
}
|
||||
}
|
||||
|
||||
static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
|
||||
static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level,
|
||||
struct ksmbd_work *in_work)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
@@ -914,9 +909,15 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
|
||||
}
|
||||
|
||||
if (lease->state & (SMB2_LEASE_WRITE_CACHING_LE |
|
||||
SMB2_LEASE_HANDLE_CACHING_LE))
|
||||
SMB2_LEASE_HANDLE_CACHING_LE)) {
|
||||
if (in_work) {
|
||||
setup_async_work(in_work, NULL, NULL);
|
||||
smb2_send_interim_resp(in_work, STATUS_PENDING);
|
||||
release_async_work(in_work);
|
||||
}
|
||||
|
||||
brk_opinfo->op_state = OPLOCK_ACK_WAIT;
|
||||
else
|
||||
} else
|
||||
atomic_dec(&brk_opinfo->breaking_cnt);
|
||||
} else {
|
||||
err = oplock_break_pending(brk_opinfo, req_op_level);
|
||||
@@ -1116,7 +1117,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
|
||||
if (ksmbd_conn_releasing(opinfo->conn))
|
||||
continue;
|
||||
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
|
||||
opinfo_put(opinfo);
|
||||
}
|
||||
}
|
||||
@@ -1152,7 +1153,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
|
||||
|
||||
if (ksmbd_conn_releasing(opinfo->conn))
|
||||
continue;
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
|
||||
oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL);
|
||||
opinfo_put(opinfo);
|
||||
}
|
||||
}
|
||||
@@ -1252,8 +1253,7 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
|
||||
goto op_break_not_needed;
|
||||
}
|
||||
|
||||
list_add(&work->interim_entry, &prev_opinfo->interim_list);
|
||||
err = oplock_break(prev_opinfo, SMB2_OPLOCK_LEVEL_II);
|
||||
err = oplock_break(prev_opinfo, SMB2_OPLOCK_LEVEL_II, work);
|
||||
opinfo_put(prev_opinfo);
|
||||
if (err == -ENOENT)
|
||||
goto set_lev;
|
||||
@@ -1322,8 +1322,7 @@ static void smb_break_all_write_oplock(struct ksmbd_work *work,
|
||||
}
|
||||
|
||||
brk_opinfo->open_trunc = is_trunc;
|
||||
list_add(&work->interim_entry, &brk_opinfo->interim_list);
|
||||
oplock_break(brk_opinfo, SMB2_OPLOCK_LEVEL_II);
|
||||
oplock_break(brk_opinfo, SMB2_OPLOCK_LEVEL_II, work);
|
||||
opinfo_put(brk_opinfo);
|
||||
}
|
||||
|
||||
@@ -1386,7 +1385,7 @@ void smb_break_all_levII_oplock(struct ksmbd_work *work, struct ksmbd_file *fp,
|
||||
SMB2_LEASE_KEY_SIZE))
|
||||
goto next;
|
||||
brk_op->open_trunc = is_trunc;
|
||||
oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE);
|
||||
oplock_break(brk_op, SMB2_OPLOCK_LEVEL_NONE, NULL);
|
||||
next:
|
||||
opinfo_put(brk_op);
|
||||
rcu_read_lock();
|
||||
|
||||
@@ -67,7 +67,6 @@ struct oplock_info {
|
||||
bool is_lease;
|
||||
bool open_trunc; /* truncate on open */
|
||||
struct lease *o_lease;
|
||||
struct list_head interim_list;
|
||||
struct list_head op_entry;
|
||||
struct list_head lease_entry;
|
||||
wait_queue_head_t oplock_q; /* Other server threads */
|
||||
|
||||
+2
-12
@@ -270,17 +270,7 @@ static void handle_ksmbd_work(struct work_struct *wk)
|
||||
|
||||
ksmbd_conn_try_dequeue_request(work);
|
||||
ksmbd_free_work_struct(work);
|
||||
/*
|
||||
* Checking waitqueue to dropping pending requests on
|
||||
* disconnection. waitqueue_active is safe because it
|
||||
* uses atomic operation for condition.
|
||||
*/
|
||||
atomic_inc(&conn->refcnt);
|
||||
if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
|
||||
wake_up(&conn->r_count_q);
|
||||
|
||||
if (atomic_dec_and_test(&conn->refcnt))
|
||||
kfree(conn);
|
||||
ksmbd_conn_r_count_dec(conn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,7 +300,7 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
|
||||
conn->request_buf = NULL;
|
||||
|
||||
ksmbd_conn_enqueue_request(work);
|
||||
atomic_inc(&conn->r_count);
|
||||
ksmbd_conn_r_count_inc(conn);
|
||||
/* update activity on connection */
|
||||
conn->last_active = jiffies;
|
||||
INIT_WORK(&work->work, handle_ksmbd_work);
|
||||
|
||||
+12
-4
@@ -874,12 +874,20 @@ static inline bool blk_mq_is_reserved_rq(struct request *rq)
|
||||
return rq->rq_flags & RQF_RESV;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* blk_mq_add_to_batch() - add a request to the completion batch
|
||||
* @req: The request to add to batch
|
||||
* @iob: The batch to add the request
|
||||
* @is_error: Specify true if the request failed with an error
|
||||
* @complete: The completaion handler for the request
|
||||
*
|
||||
* Batched completions only work when there is no I/O error and no special
|
||||
* ->end_io handler.
|
||||
*
|
||||
* Return: true when the request was added to the batch, otherwise false
|
||||
*/
|
||||
static inline bool blk_mq_add_to_batch(struct request *req,
|
||||
struct io_comp_batch *iob, int ioerror,
|
||||
struct io_comp_batch *iob, bool is_error,
|
||||
void (*complete)(struct io_comp_batch *))
|
||||
{
|
||||
/*
|
||||
@@ -887,7 +895,7 @@ static inline bool blk_mq_add_to_batch(struct request *req,
|
||||
* 1) No batch container
|
||||
* 2) Has scheduler data attached
|
||||
* 3) Not a passthrough request and end_io set
|
||||
* 4) Not a passthrough request and an ioerror
|
||||
* 4) Not a passthrough request and failed with an error
|
||||
*/
|
||||
if (!iob)
|
||||
return false;
|
||||
@@ -896,7 +904,7 @@ static inline bool blk_mq_add_to_batch(struct request *req,
|
||||
if (!blk_rq_is_passthrough(req)) {
|
||||
if (req->end_io)
|
||||
return false;
|
||||
if (ioerror < 0)
|
||||
if (is_error)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -687,6 +687,7 @@ struct huge_bootmem_page {
|
||||
};
|
||||
|
||||
int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list);
|
||||
void wait_for_freed_hugetlb_folios(void);
|
||||
struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
|
||||
unsigned long addr, int avoid_reserve);
|
||||
struct folio *alloc_hugetlb_folio_nodemask(struct hstate *h, int preferred_nid,
|
||||
@@ -1057,6 +1058,10 @@ static inline int isolate_or_dissolve_huge_page(struct page *page,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static inline void wait_for_freed_hugetlb_folios(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
|
||||
unsigned long addr,
|
||||
int avoid_reserve)
|
||||
|
||||
@@ -668,7 +668,7 @@ struct l2cap_conn {
|
||||
struct l2cap_chan *smp;
|
||||
|
||||
struct list_head chan_l;
|
||||
struct mutex chan_lock;
|
||||
struct mutex lock;
|
||||
struct kref ref;
|
||||
struct list_head users;
|
||||
};
|
||||
@@ -970,6 +970,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err);
|
||||
void l2cap_send_conn_req(struct l2cap_chan *chan);
|
||||
|
||||
struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn);
|
||||
struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *conn);
|
||||
void l2cap_conn_put(struct l2cap_conn *conn);
|
||||
|
||||
int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
|
||||
|
||||
+4
-1
@@ -1251,7 +1251,10 @@ void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd);
|
||||
|
||||
/* mixer control */
|
||||
struct soc_mixer_control {
|
||||
int min, max, platform_max;
|
||||
/* Minimum and maximum specified as written to the hardware */
|
||||
int min, max;
|
||||
/* Limited maximum value specified as presented through the control */
|
||||
int platform_max;
|
||||
int reg, rreg;
|
||||
unsigned int shift, rshift;
|
||||
unsigned int sign_bit;
|
||||
|
||||
@@ -6079,6 +6079,9 @@ __bpf_kfunc_start_defs();
|
||||
__bpf_kfunc s32 scx_bpf_select_cpu_dfl(struct task_struct *p, s32 prev_cpu,
|
||||
u64 wake_flags, bool *is_idle)
|
||||
{
|
||||
if (!ops_cpu_valid(prev_cpu, NULL))
|
||||
goto prev_cpu;
|
||||
|
||||
if (!static_branch_likely(&scx_builtin_idle_enabled)) {
|
||||
scx_ops_error("built-in idle tracking is disabled");
|
||||
goto prev_cpu;
|
||||
|
||||
@@ -2955,6 +2955,14 @@ int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wait_for_freed_hugetlb_folios(void)
|
||||
{
|
||||
if (llist_empty(&hpage_freelist))
|
||||
return;
|
||||
|
||||
flush_work(&free_hpage_work);
|
||||
}
|
||||
|
||||
struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
|
||||
unsigned long addr, int avoid_reserve)
|
||||
{
|
||||
|
||||
@@ -612,6 +612,16 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
|
||||
struct zone *zone;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Due to the deferred freeing of hugetlb folios, the hugepage folios may
|
||||
* not immediately release to the buddy system. This can cause PageBuddy()
|
||||
* to fail in __test_page_isolated_in_pageblock(). To ensure that the
|
||||
* hugetlb folios are properly released back to the buddy system, we
|
||||
* invoke the wait_for_freed_hugetlb_folios() function to wait for the
|
||||
* release to complete.
|
||||
*/
|
||||
wait_for_freed_hugetlb_folios();
|
||||
|
||||
/*
|
||||
* Note: pageblock_nr_pages != MAX_PAGE_ORDER. Then, chunks of free
|
||||
* pages are not aligned to pageblock_nr_pages.
|
||||
|
||||
+49
-89
@@ -119,7 +119,6 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
|
||||
{
|
||||
struct l2cap_chan *c;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
c = __l2cap_get_chan_by_scid(conn, cid);
|
||||
if (c) {
|
||||
/* Only lock if chan reference is not 0 */
|
||||
@@ -127,7 +126,6 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
|
||||
if (c)
|
||||
l2cap_chan_lock(c);
|
||||
}
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -140,7 +138,6 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
|
||||
{
|
||||
struct l2cap_chan *c;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
c = __l2cap_get_chan_by_dcid(conn, cid);
|
||||
if (c) {
|
||||
/* Only lock if chan reference is not 0 */
|
||||
@@ -148,7 +145,6 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
|
||||
if (c)
|
||||
l2cap_chan_lock(c);
|
||||
}
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -418,7 +414,7 @@ static void l2cap_chan_timeout(struct work_struct *work)
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
/* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
|
||||
* this work. No need to call l2cap_chan_hold(chan) here again.
|
||||
*/
|
||||
@@ -439,7 +435,7 @@ static void l2cap_chan_timeout(struct work_struct *work)
|
||||
l2cap_chan_unlock(chan);
|
||||
l2cap_chan_put(chan);
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
struct l2cap_chan *l2cap_chan_create(void)
|
||||
@@ -642,9 +638,9 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||
|
||||
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||
{
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
__l2cap_chan_add(conn, chan);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
void l2cap_chan_del(struct l2cap_chan *chan, int err)
|
||||
@@ -732,9 +728,9 @@ void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
__l2cap_chan_list(conn, func, data);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(l2cap_chan_list);
|
||||
@@ -746,7 +742,7 @@ static void l2cap_conn_update_id_addr(struct work_struct *work)
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
struct l2cap_chan *chan;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||
l2cap_chan_lock(chan);
|
||||
@@ -755,7 +751,7 @@ static void l2cap_conn_update_id_addr(struct work_struct *work)
|
||||
l2cap_chan_unlock(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
|
||||
@@ -1508,8 +1504,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
|
||||
l2cap_chan_lock(chan);
|
||||
|
||||
@@ -1578,8 +1572,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
|
||||
|
||||
l2cap_chan_unlock(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
}
|
||||
|
||||
static void l2cap_le_conn_ready(struct l2cap_conn *conn)
|
||||
@@ -1625,7 +1617,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
|
||||
if (hcon->type == ACL_LINK)
|
||||
l2cap_request_info(conn);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||
|
||||
@@ -1643,7 +1635,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
|
||||
l2cap_chan_unlock(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
|
||||
if (hcon->type == LE_LINK)
|
||||
l2cap_le_conn_ready(conn);
|
||||
@@ -1658,14 +1650,10 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||
if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
|
||||
l2cap_chan_set_err(chan, err);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
}
|
||||
|
||||
static void l2cap_info_timeout(struct work_struct *work)
|
||||
@@ -1676,7 +1664,9 @@ static void l2cap_info_timeout(struct work_struct *work)
|
||||
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
|
||||
conn->info_ident = 0;
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
l2cap_conn_start(conn);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1768,6 +1758,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
|
||||
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
kfree_skb(conn->rx_skb);
|
||||
|
||||
skb_queue_purge(&conn->pending_rx);
|
||||
@@ -1786,8 +1778,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
/* Force the connection to be immediately dropped */
|
||||
hcon->disc_timeout = 0;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
/* Kill channels */
|
||||
list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
|
||||
l2cap_chan_hold(chan);
|
||||
@@ -1801,12 +1791,14 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
|
||||
l2cap_chan_put(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
|
||||
cancel_delayed_work_sync(&conn->info_timer);
|
||||
|
||||
hci_chan_del(conn->hchan);
|
||||
conn->hchan = NULL;
|
||||
|
||||
hcon->l2cap_data = NULL;
|
||||
mutex_unlock(&conn->lock);
|
||||
l2cap_conn_put(conn);
|
||||
}
|
||||
|
||||
@@ -1814,7 +1806,6 @@ static void l2cap_conn_free(struct kref *ref)
|
||||
{
|
||||
struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
|
||||
|
||||
hci_chan_del(conn->hchan);
|
||||
hci_conn_put(conn->hcon);
|
||||
kfree(conn);
|
||||
}
|
||||
@@ -2925,8 +2916,6 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
|
||||
BT_DBG("conn %p", conn);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||
if (chan->chan_type != L2CAP_CHAN_RAW)
|
||||
continue;
|
||||
@@ -2941,8 +2930,6 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
if (chan->ops->recv(chan, nskb))
|
||||
kfree_skb(nskb);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
}
|
||||
|
||||
/* ---- L2CAP signalling commands ---- */
|
||||
@@ -3965,7 +3952,6 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
|
||||
goto response;
|
||||
}
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
l2cap_chan_lock(pchan);
|
||||
|
||||
/* Check if the ACL is secure enough (if not SDP) */
|
||||
@@ -4072,7 +4058,6 @@ response:
|
||||
}
|
||||
|
||||
l2cap_chan_unlock(pchan);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
l2cap_chan_put(pchan);
|
||||
}
|
||||
|
||||
@@ -4111,27 +4096,19 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
||||
BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
|
||||
dcid, scid, result, status);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
if (scid) {
|
||||
chan = __l2cap_get_chan_by_scid(conn, scid);
|
||||
if (!chan) {
|
||||
err = -EBADSLT;
|
||||
goto unlock;
|
||||
}
|
||||
if (!chan)
|
||||
return -EBADSLT;
|
||||
} else {
|
||||
chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
|
||||
if (!chan) {
|
||||
err = -EBADSLT;
|
||||
goto unlock;
|
||||
}
|
||||
if (!chan)
|
||||
return -EBADSLT;
|
||||
}
|
||||
|
||||
chan = l2cap_chan_hold_unless_zero(chan);
|
||||
if (!chan) {
|
||||
err = -EBADSLT;
|
||||
goto unlock;
|
||||
}
|
||||
if (!chan)
|
||||
return -EBADSLT;
|
||||
|
||||
err = 0;
|
||||
|
||||
@@ -4169,9 +4146,6 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
|
||||
l2cap_chan_unlock(chan);
|
||||
l2cap_chan_put(chan);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -4459,11 +4433,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
|
||||
|
||||
chan->ops->set_shutdown(chan);
|
||||
|
||||
l2cap_chan_unlock(chan);
|
||||
mutex_lock(&conn->chan_lock);
|
||||
l2cap_chan_lock(chan);
|
||||
l2cap_chan_del(chan, ECONNRESET);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
chan->ops->close(chan);
|
||||
|
||||
@@ -4500,11 +4470,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
l2cap_chan_unlock(chan);
|
||||
mutex_lock(&conn->chan_lock);
|
||||
l2cap_chan_lock(chan);
|
||||
l2cap_chan_del(chan, 0);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
chan->ops->close(chan);
|
||||
|
||||
@@ -4702,13 +4668,9 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
|
||||
BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
|
||||
dcid, mtu, mps, credits, result);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
|
||||
if (!chan) {
|
||||
err = -EBADSLT;
|
||||
goto unlock;
|
||||
}
|
||||
if (!chan)
|
||||
return -EBADSLT;
|
||||
|
||||
err = 0;
|
||||
|
||||
@@ -4756,9 +4718,6 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
|
||||
|
||||
l2cap_chan_unlock(chan);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -4870,7 +4829,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
|
||||
goto response;
|
||||
}
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
l2cap_chan_lock(pchan);
|
||||
|
||||
if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
|
||||
@@ -4936,7 +4894,6 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
|
||||
|
||||
response_unlock:
|
||||
l2cap_chan_unlock(pchan);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
l2cap_chan_put(pchan);
|
||||
|
||||
if (result == L2CAP_CR_PEND)
|
||||
@@ -5070,7 +5027,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||
goto response;
|
||||
}
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
l2cap_chan_lock(pchan);
|
||||
|
||||
if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
|
||||
@@ -5145,7 +5101,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
|
||||
|
||||
unlock:
|
||||
l2cap_chan_unlock(pchan);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
l2cap_chan_put(pchan);
|
||||
|
||||
response:
|
||||
@@ -5182,8 +5137,6 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
|
||||
BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits,
|
||||
result);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
cmd_len -= sizeof(*rsp);
|
||||
|
||||
list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
|
||||
@@ -5269,8 +5222,6 @@ static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
|
||||
l2cap_chan_unlock(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -5383,8 +5334,6 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
|
||||
if (cmd_len < sizeof(*rej))
|
||||
return -EPROTO;
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
|
||||
chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
|
||||
if (!chan)
|
||||
goto done;
|
||||
@@ -5399,7 +5348,6 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
|
||||
l2cap_chan_put(chan);
|
||||
|
||||
done:
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6854,8 +6802,12 @@ static void process_pending_rx(struct work_struct *work)
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
while ((skb = skb_dequeue(&conn->pending_rx)))
|
||||
l2cap_recv_frame(conn, skb);
|
||||
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
|
||||
@@ -6894,7 +6846,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
|
||||
conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
|
||||
|
||||
mutex_init(&conn->ident_lock);
|
||||
mutex_init(&conn->chan_lock);
|
||||
mutex_init(&conn->lock);
|
||||
|
||||
INIT_LIST_HEAD(&conn->chan_l);
|
||||
INIT_LIST_HEAD(&conn->users);
|
||||
@@ -7085,7 +7037,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
l2cap_chan_lock(chan);
|
||||
|
||||
if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
|
||||
@@ -7126,7 +7078,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
|
||||
|
||||
chan_unlock:
|
||||
l2cap_chan_unlock(chan);
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
done:
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
@@ -7338,7 +7290,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||
|
||||
BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
|
||||
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
list_for_each_entry(chan, &conn->chan_l, list) {
|
||||
l2cap_chan_lock(chan);
|
||||
@@ -7412,7 +7364,7 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
|
||||
l2cap_chan_unlock(chan);
|
||||
}
|
||||
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
}
|
||||
|
||||
/* Append fragment into frame respecting the maximum len of rx_skb */
|
||||
@@ -7479,8 +7431,11 @@ static void l2cap_recv_reset(struct l2cap_conn *conn)
|
||||
conn->rx_len = 0;
|
||||
}
|
||||
|
||||
static struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
|
||||
struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
|
||||
{
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref));
|
||||
|
||||
if (!kref_get_unless_zero(&c->ref))
|
||||
@@ -7506,11 +7461,15 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
|
||||
hci_dev_unlock(hcon->hdev);
|
||||
|
||||
if (!conn)
|
||||
goto drop;
|
||||
if (!conn) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags);
|
||||
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
switch (flags) {
|
||||
case ACL_START:
|
||||
case ACL_START_NO_FLUSH:
|
||||
@@ -7535,7 +7494,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
if (len == skb->len) {
|
||||
/* Complete frame received */
|
||||
l2cap_recv_frame(conn, skb);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
BT_DBG("Start: total len %d, frag len %u", len, skb->len);
|
||||
@@ -7597,10 +7556,11 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
|
||||
break;
|
||||
}
|
||||
|
||||
l2cap_conn_put(conn);
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
unlock:
|
||||
mutex_unlock(&conn->lock);
|
||||
l2cap_conn_put(conn);
|
||||
}
|
||||
|
||||
static struct hci_cb l2cap_cb = {
|
||||
|
||||
@@ -1326,9 +1326,10 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
|
||||
/* prevent sk structure from being freed whilst unlocked */
|
||||
sock_hold(sk);
|
||||
|
||||
chan = l2cap_pi(sk)->chan;
|
||||
/* prevent chan structure from being freed whilst unlocked */
|
||||
l2cap_chan_hold(chan);
|
||||
chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
|
||||
if (!chan)
|
||||
goto shutdown_already;
|
||||
|
||||
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
|
||||
|
||||
@@ -1358,22 +1359,20 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
|
||||
release_sock(sk);
|
||||
|
||||
l2cap_chan_lock(chan);
|
||||
conn = chan->conn;
|
||||
if (conn)
|
||||
/* prevent conn structure from being freed */
|
||||
l2cap_conn_get(conn);
|
||||
/* prevent conn structure from being freed */
|
||||
conn = l2cap_conn_hold_unless_zero(chan->conn);
|
||||
l2cap_chan_unlock(chan);
|
||||
|
||||
if (conn)
|
||||
/* mutex lock must be taken before l2cap_chan_lock() */
|
||||
mutex_lock(&conn->chan_lock);
|
||||
mutex_lock(&conn->lock);
|
||||
|
||||
l2cap_chan_lock(chan);
|
||||
l2cap_chan_close(chan, 0);
|
||||
l2cap_chan_unlock(chan);
|
||||
|
||||
if (conn) {
|
||||
mutex_unlock(&conn->chan_lock);
|
||||
mutex_unlock(&conn->lock);
|
||||
l2cap_conn_put(conn);
|
||||
}
|
||||
|
||||
|
||||
@@ -3734,6 +3734,9 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
|
||||
{
|
||||
netdev_features_t features;
|
||||
|
||||
if (!skb_frags_readable(skb))
|
||||
goto out_kfree_skb;
|
||||
|
||||
features = netif_skb_features(skb);
|
||||
skb = validate_xmit_vlan(skb, features);
|
||||
if (unlikely(!skb))
|
||||
|
||||
@@ -104,7 +104,7 @@ impl Error {
|
||||
if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 {
|
||||
// TODO: Make it a `WARN_ONCE` once available.
|
||||
crate::pr_warn!(
|
||||
"attempted to create `Error` with out of range `errno`: {}",
|
||||
"attempted to create `Error` with out of range `errno`: {}\n",
|
||||
errno
|
||||
);
|
||||
return code::EINVAL;
|
||||
|
||||
+6
-6
@@ -259,7 +259,7 @@ pub mod macros;
|
||||
/// },
|
||||
/// }));
|
||||
/// let foo: Pin<&mut Foo> = foo;
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// ```
|
||||
///
|
||||
/// # Syntax
|
||||
@@ -311,7 +311,7 @@ macro_rules! stack_pin_init {
|
||||
/// }, GFP_KERNEL)?,
|
||||
/// }));
|
||||
/// let foo = foo.unwrap();
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// ```
|
||||
///
|
||||
/// ```rust,ignore
|
||||
@@ -336,7 +336,7 @@ macro_rules! stack_pin_init {
|
||||
/// x: 64,
|
||||
/// }, GFP_KERNEL)?,
|
||||
/// }));
|
||||
/// pr_info!("a: {}", &*foo.a.lock());
|
||||
/// pr_info!("a: {}\n", &*foo.a.lock());
|
||||
/// # Ok::<_, AllocError>(())
|
||||
/// ```
|
||||
///
|
||||
@@ -866,7 +866,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn setup(self: Pin<&mut Self>) {
|
||||
/// pr_info!("Setting up foo");
|
||||
/// pr_info!("Setting up foo\n");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
@@ -970,7 +970,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
|
||||
///
|
||||
/// impl Foo {
|
||||
/// fn setup(&mut self) {
|
||||
/// pr_info!("Setting up foo");
|
||||
/// pr_info!("Setting up foo\n");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
@@ -1318,7 +1318,7 @@ impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
|
||||
/// #[pinned_drop]
|
||||
/// impl PinnedDrop for Foo {
|
||||
/// fn drop(self: Pin<&mut Self>) {
|
||||
/// pr_info!("Foo is being dropped!");
|
||||
/// pr_info!("Foo is being dropped!\n");
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
//! #[pinned_drop]
|
||||
//! impl PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
@@ -412,7 +412,7 @@
|
||||
//! #[pinned_drop]
|
||||
//! impl PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
@@ -423,7 +423,7 @@
|
||||
//! // `unsafe`, full path and the token parameter are added, everything else stays the same.
|
||||
//! unsafe impl ::kernel::init::PinnedDrop for Foo {
|
||||
//! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyCallFromDrop) {
|
||||
//! pr_info!("{self:p} is getting dropped.");
|
||||
//! pr_info!("{self:p} is getting dropped.\n");
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
@@ -49,14 +49,26 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
}
|
||||
})
|
||||
|
||||
# First, the ones in `rust/` since they are a bit special.
|
||||
append_crate(
|
||||
"core",
|
||||
sysroot_src / "core" / "src" / "lib.rs",
|
||||
[],
|
||||
cfg=crates_cfgs.get("core", []),
|
||||
is_workspace_member=False,
|
||||
)
|
||||
def append_sysroot_crate(
|
||||
display_name,
|
||||
deps,
|
||||
cfg=[],
|
||||
):
|
||||
append_crate(
|
||||
display_name,
|
||||
sysroot_src / display_name / "src" / "lib.rs",
|
||||
deps,
|
||||
cfg,
|
||||
is_workspace_member=False,
|
||||
)
|
||||
|
||||
# NB: sysroot crates reexport items from one another so setting up our transitive dependencies
|
||||
# here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
|
||||
# for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
|
||||
append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
|
||||
append_sysroot_crate("alloc", ["core"])
|
||||
append_sysroot_crate("std", ["alloc", "core"])
|
||||
append_sysroot_crate("proc_macro", ["core", "std"])
|
||||
|
||||
append_crate(
|
||||
"compiler_builtins",
|
||||
@@ -67,7 +79,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
append_crate(
|
||||
"macros",
|
||||
srctree / "rust" / "macros" / "lib.rs",
|
||||
[],
|
||||
["std", "proc_macro"],
|
||||
is_proc_macro=True,
|
||||
)
|
||||
crates[-1]["proc_macro_dylib_path"] = f"{objtree}/rust/libmacros.so"
|
||||
@@ -78,27 +90,28 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
|
||||
["core", "compiler_builtins"],
|
||||
)
|
||||
|
||||
append_crate(
|
||||
"bindings",
|
||||
srctree / "rust"/ "bindings" / "lib.rs",
|
||||
["core"],
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
|
||||
def append_crate_with_generated(
|
||||
display_name,
|
||||
deps,
|
||||
):
|
||||
append_crate(
|
||||
display_name,
|
||||
srctree / "rust"/ display_name / "lib.rs",
|
||||
deps,
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
|
||||
crates[-1]["source"] = {
|
||||
"include_dirs": [
|
||||
str(srctree / "rust" / display_name),
|
||||
str(objtree / "rust")
|
||||
],
|
||||
"exclude_dirs": [],
|
||||
}
|
||||
|
||||
append_crate(
|
||||
"kernel",
|
||||
srctree / "rust" / "kernel" / "lib.rs",
|
||||
["core", "macros", "build_error", "bindings"],
|
||||
cfg=cfg,
|
||||
)
|
||||
crates[-1]["source"] = {
|
||||
"include_dirs": [
|
||||
str(srctree / "rust" / "kernel"),
|
||||
str(objtree / "rust")
|
||||
],
|
||||
"exclude_dirs": [],
|
||||
}
|
||||
append_crate_with_generated("bindings", ["core"])
|
||||
append_crate_with_generated("uapi", ["core"])
|
||||
append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "uapi"])
|
||||
|
||||
def is_root_crate(build_file, target):
|
||||
try:
|
||||
|
||||
@@ -248,6 +248,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21M5"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21M6"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
||||
@@ -1146,7 +1146,7 @@ static const struct snd_kcontrol_new cs42l43_controls[] = {
|
||||
|
||||
SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L43_ADC_B_CTRL1, CS42L43_ADC_B_CTRL2,
|
||||
CS42L43_ADC_PGA_GAIN_SHIFT,
|
||||
0xF, 5, cs42l43_adc_tlv),
|
||||
0xF, 4, cs42l43_adc_tlv),
|
||||
|
||||
SOC_DOUBLE("PDM1 Invert Switch", CS42L43_DMIC_PDM_CTRL,
|
||||
CS42L43_PDM1L_INV_SHIFT, CS42L43_PDM1R_INV_SHIFT, 1, 0),
|
||||
|
||||
@@ -86,6 +86,10 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re
|
||||
case 0x6100067:
|
||||
case 0x6100070 ... 0x610007c:
|
||||
case 0x6100080:
|
||||
case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15, RT722_SDCA_CTL_FU_CH_GAIN,
|
||||
CH_01) ...
|
||||
SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_FU15, RT722_SDCA_CTL_FU_CH_GAIN,
|
||||
CH_04):
|
||||
case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME,
|
||||
CH_01):
|
||||
case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, RT722_SDCA_CTL_FU_VOLUME,
|
||||
|
||||
@@ -920,7 +920,7 @@ static int wm0010_spi_probe(struct spi_device *spi)
|
||||
if (ret) {
|
||||
dev_err(wm0010->dev, "Failed to set IRQ %d as wake source: %d\n",
|
||||
irq, ret);
|
||||
return ret;
|
||||
goto free_irq;
|
||||
}
|
||||
|
||||
if (spi->max_speed_hz)
|
||||
@@ -932,9 +932,18 @@ static int wm0010_spi_probe(struct spi_device *spi)
|
||||
&soc_component_dev_wm0010, wm0010_dai,
|
||||
ARRAY_SIZE(wm0010_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto disable_irq_wake;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_irq_wake:
|
||||
irq_set_irq_wake(wm0010->irq, 0);
|
||||
|
||||
free_irq:
|
||||
if (wm0010->irq)
|
||||
free_irq(wm0010->irq, wm0010);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wm0010_spi_remove(struct spi_device *spi)
|
||||
|
||||
@@ -871,7 +871,7 @@ static int create_sdw_dailinks(struct snd_soc_card *card,
|
||||
|
||||
/* generate DAI links by each sdw link */
|
||||
while (sof_dais->initialised) {
|
||||
int current_be_id;
|
||||
int current_be_id = 0;
|
||||
|
||||
ret = create_sdw_dailink(card, sof_dais, dai_links,
|
||||
¤t_be_id, codec_conf);
|
||||
|
||||
+7
-8
@@ -337,7 +337,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
if (ucontrol->value.integer.value[0] < 0)
|
||||
return -EINVAL;
|
||||
val = ucontrol->value.integer.value[0];
|
||||
if (mc->platform_max && ((int)val + min) > mc->platform_max)
|
||||
if (mc->platform_max && val > mc->platform_max)
|
||||
return -EINVAL;
|
||||
if (val > max - min)
|
||||
return -EINVAL;
|
||||
@@ -350,7 +350,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
if (ucontrol->value.integer.value[1] < 0)
|
||||
return -EINVAL;
|
||||
val2 = ucontrol->value.integer.value[1];
|
||||
if (mc->platform_max && ((int)val2 + min) > mc->platform_max)
|
||||
if (mc->platform_max && val2 > mc->platform_max)
|
||||
return -EINVAL;
|
||||
if (val2 > max - min)
|
||||
return -EINVAL;
|
||||
@@ -503,17 +503,16 @@ int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
int platform_max;
|
||||
int min = mc->min;
|
||||
int max;
|
||||
|
||||
if (!mc->platform_max)
|
||||
mc->platform_max = mc->max;
|
||||
platform_max = mc->platform_max;
|
||||
max = mc->max - mc->min;
|
||||
if (mc->platform_max && mc->platform_max < max)
|
||||
max = mc->platform_max;
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = platform_max - min;
|
||||
uinfo->value.integer.max = max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -333,6 +333,17 @@ static __always_inline const struct cpumask *cast_mask(struct bpf_cpumask *mask)
|
||||
return (const struct cpumask *)mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if task @p cannot migrate to a different CPU, false
|
||||
* otherwise.
|
||||
*/
|
||||
static inline bool is_migration_disabled(const struct task_struct *p)
|
||||
{
|
||||
if (bpf_core_field_exists(p->migration_disabled))
|
||||
return p->migration_disabled;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* rcu */
|
||||
void bpf_rcu_read_lock(void) __ksym;
|
||||
void bpf_rcu_read_unlock(void) __ksym;
|
||||
|
||||
@@ -43,7 +43,7 @@ void BPF_STRUCT_OPS(dsp_local_on_dispatch, s32 cpu, struct task_struct *prev)
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (p->nr_cpus_allowed == nr_cpus && !p->migration_disabled)
|
||||
if (p->nr_cpus_allowed == nr_cpus && !is_migration_disabled(p))
|
||||
target = bpf_get_prandom_u32() % nr_cpus;
|
||||
else
|
||||
target = scx_bpf_task_cpu(p);
|
||||
|
||||
Reference in New Issue
Block a user