From b4802c56712a14068118a0a2af762ccae95de74e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 4 Feb 2026 11:12:52 +0100 Subject: [PATCH] 6.12-stable patches added patches: drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch mptcp-avoid-dup-sub_closed-events-after-disconnect.patch net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch perf-simplify-get_perf_callchain-user-logic.patch pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch --- ...dgpu-gfx11-adjust-kgq-reset-sequence.patch | 93 ++++++ ...p-sub_closed-events-after-disconnect.patch | 56 ++++ ...ature-of-mana_get_primary_netdev_rcu.patch | 115 ++++++++ ...f-crash-with-new-is_user_task-helper.patch | 115 ++++++++ ...mplify-get_perf_callchain-user-logic.patch | 59 ++++ ...t-.get_direction-for-the-gpio-driver.patch | 64 +++++ ...h-sc7280-to-fix-i2s2-and-swr-tx-pins.patch | 265 ++++++++++++++++++ ...t-for-pointing-to-the-current-netdev.patch | 126 +++++++++ queue-6.12/series | 9 + ...-when-dirtytime_expire_interval-is-0.patch | 77 +++++ 10 files changed, 979 insertions(+) create mode 100644 queue-6.12/drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch create mode 100644 queue-6.12/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch create mode 100644 queue-6.12/net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch create mode 100644 queue-6.12/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch create mode 100644 queue-6.12/perf-simplify-get_perf_callchain-user-logic.patch create mode 100644 queue-6.12/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch create mode 100644 queue-6.12/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch create mode 100644 queue-6.12/rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch create mode 100644 queue-6.12/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch diff --git a/queue-6.12/drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch b/queue-6.12/drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch new file mode 100644 index 0000000000..ed31b2090b --- /dev/null +++ b/queue-6.12/drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch @@ -0,0 +1,93 @@ +From stable+bounces-213326-greg=kroah.com@vger.kernel.org Wed Feb 4 01:42:53 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 19:39:21 -0500 +Subject: drm/amdgpu/gfx11: adjust KGQ reset sequence +To: stable@vger.kernel.org +Cc: "Alex Deucher" , "Timur Kristóf" , "Sasha Levin" +Message-ID: <20260204003922.1467007-1-sashal@kernel.org> + +From: Alex Deucher + +[ Upstream commit 3eb46fbb601f9a0b4df8eba79252a0a85e983044 ] + +Kernel gfx queues do not need to be reinitialized or +remapped after a reset. This fixes queue reset failures +on APUs. + +v2: preserve init and remap for MMIO case. + +Fixes: b3e9bfd86658 ("drm/amdgpu/gfx11: add ring reset callbacks") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4789 +Reviewed-by: Timur Kristóf +Signed-off-by: Alex Deucher +(cherry picked from commit b340ff216fdabfe71ba0cdd47e9835a141d08e10) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 45 +++++++++++++++++---------------- + 1 file changed, 24 insertions(+), 21 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -6568,36 +6568,39 @@ static void gfx_v11_0_emit_mem_sync(stru + static int gfx_v11_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid) + { + struct amdgpu_device *adev = ring->adev; ++ bool use_mmio = false; + int r; + + if (amdgpu_sriov_vf(adev)) + return -EINVAL; + +- r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false); ++ r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, use_mmio); + if (r) + return r; + +- r = amdgpu_bo_reserve(ring->mqd_obj, false); +- if (unlikely(r != 0)) { +- dev_err(adev->dev, "fail to resv mqd_obj\n"); +- return r; +- } +- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); +- if (!r) { +- r = gfx_v11_0_kgq_init_queue(ring, true); +- amdgpu_bo_kunmap(ring->mqd_obj); +- ring->mqd_ptr = NULL; +- } +- amdgpu_bo_unreserve(ring->mqd_obj); +- if (r) { +- dev_err(adev->dev, "fail to unresv mqd_obj\n"); +- return r; +- } ++ if (use_mmio) { ++ r = amdgpu_bo_reserve(ring->mqd_obj, false); ++ if (unlikely(r != 0)) { ++ dev_err(adev->dev, "fail to resv mqd_obj\n"); ++ return r; ++ } ++ r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); ++ if (!r) { ++ r = gfx_v11_0_kgq_init_queue(ring, true); ++ amdgpu_bo_kunmap(ring->mqd_obj); ++ ring->mqd_ptr = NULL; ++ } ++ amdgpu_bo_unreserve(ring->mqd_obj); ++ if (r) { ++ dev_err(adev->dev, "fail to unresv mqd_obj\n"); ++ return r; ++ } + +- r = amdgpu_mes_map_legacy_queue(adev, ring); +- if (r) { +- dev_err(adev->dev, "failed to remap kgq\n"); +- return r; ++ r = amdgpu_mes_map_legacy_queue(adev, ring); ++ if (r) { ++ dev_err(adev->dev, "failed to remap kgq\n"); ++ return r; ++ } + } + + return amdgpu_ring_test_ring(ring); diff --git a/queue-6.12/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch b/queue-6.12/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch new file mode 100644 index 0000000000..a5c2393edc --- /dev/null +++ b/queue-6.12/mptcp-avoid-dup-sub_closed-events-after-disconnect.patch @@ -0,0 +1,56 @@ +From stable+bounces-213293-greg=kroah.com@vger.kernel.org Tue Feb 3 18:53:18 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 12:50:55 -0500 +Subject: mptcp: avoid dup SUB_CLOSED events after disconnect +To: stable@vger.kernel.org +Cc: "Matthieu Baerts (NGI0)" , Marco Angaroni , Geliang Tang , Jakub Kicinski , Sasha Levin +Message-ID: <20260203175055.1341617-1-sashal@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +[ Upstream commit 280d654324e33f8e6e3641f76764694c7b64c5db ] + +In case of subflow disconnect(), which can also happen with the first +subflow in case of errors like timeout or reset, mptcp_subflow_ctx_reset +will reset most fields from the mptcp_subflow_context structure, +including close_event_done. Then, when another subflow is closed, yet +another SUB_CLOSED event for the disconnected initial subflow is sent. +Because of the previous reset, there are no source address and +destination port. + +A solution is then to also check the subflow's local id: it shouldn't be +negative anyway. + +Another solution would be not to reset subflow->close_event_done at +disconnect time, but when reused. But then, probably the whole reset +could be done when being reused. Let's not change this logic, similar +to TCP with tcp_disconnect(). + +Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") +Cc: stable@vger.kernel.org +Reported-by: Marco Angaroni +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/603 +Reviewed-by: Geliang Tang +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20260127-net-mptcp-dup-nl-events-v1-1-7f71e1bc4feb@kernel.org +Signed-off-by: Jakub Kicinski +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2591,8 +2591,8 @@ out: + void mptcp_close_ssk(struct sock *sk, struct sock *ssk, + struct mptcp_subflow_context *subflow) + { +- /* The first subflow can already be closed and still in the list */ +- if (subflow->close_event_done) ++ /* The first subflow can already be closed or disconnected */ ++ if (subflow->close_event_done || READ_ONCE(subflow->local_id) < 0) + return; + + subflow->close_event_done = true; diff --git a/queue-6.12/net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch b/queue-6.12/net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch new file mode 100644 index 0000000000..788b9addb5 --- /dev/null +++ b/queue-6.12/net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch @@ -0,0 +1,115 @@ +From stable+bounces-213310-greg=kroah.com@vger.kernel.org Tue Feb 3 21:47:16 2026 +From: longli@linux.microsoft.com +Date: Tue, 3 Feb 2026 12:45:23 -0800 +Subject: net: mana: Change the function signature of mana_get_primary_netdev_rcu +To: stable@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: Long Li , Leon Romanovsky , stable@kernel.org +Message-ID: <20260203204524.827567-1-longli@linux.microsoft.com> + +From: Long Li + +commit a8445cfec101c42e9d64cdb2dac13973b22c205c upstream. + +Change mana_get_primary_netdev_rcu() to mana_get_primary_netdev(), and +return the ndev with refcount held. The caller is responsible for dropping +the refcount. + +Also drop the check for IFF_SLAVE as it is not necessary if the upper +device is present. + +Signed-off-by: Long Li +Link: https://patch.msgid.link/1741821332-9392-1-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Leon Romanovsky +Fixes: 1df03a4b4414 ("RDMA/mana_ib: Set correct device into ib") +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/hw/mana/device.c | 7 +++---- + drivers/infiniband/hw/mana/mana_ib.h | 1 + + drivers/net/ethernet/microsoft/mana/mana_en.c | 22 ++++++++++++++-------- + include/net/mana/mana.h | 4 +++- + 4 files changed, 21 insertions(+), 13 deletions(-) + +--- a/drivers/infiniband/hw/mana/device.c ++++ b/drivers/infiniband/hw/mana/device.c +@@ -84,10 +84,8 @@ static int mana_ib_probe(struct auxiliar + dev->ib_dev.num_comp_vectors = mdev->gdma_context->max_num_queues; + dev->ib_dev.dev.parent = mdev->gdma_context->dev; + +- rcu_read_lock(); /* required to get primary netdev */ +- ndev = mana_get_primary_netdev_rcu(mc, 0); ++ ndev = mana_get_primary_netdev(mc, 0, &dev->dev_tracker); + if (!ndev) { +- rcu_read_unlock(); + ret = -ENODEV; + ibdev_err(&dev->ib_dev, "Failed to get netdev for IB port 1"); + goto free_ib_device; +@@ -95,7 +93,8 @@ static int mana_ib_probe(struct auxiliar + ether_addr_copy(mac_addr, ndev->dev_addr); + addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, ndev->dev_addr); + ret = ib_device_set_netdev(&dev->ib_dev, ndev, 1); +- rcu_read_unlock(); ++ /* mana_get_primary_netdev() returns ndev with refcount held */ ++ netdev_put(ndev, &dev->dev_tracker); + if (ret) { + ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret); + goto free_ib_device; +--- a/drivers/infiniband/hw/mana/mana_ib.h ++++ b/drivers/infiniband/hw/mana/mana_ib.h +@@ -64,6 +64,7 @@ struct mana_ib_dev { + struct gdma_queue **eqs; + struct xarray qp_table_wq; + struct mana_ib_adapter_caps adapter_caps; ++ netdevice_tracker dev_tracker; + }; + + struct mana_ib_wq { +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -3000,21 +3000,27 @@ out: + kfree(ac); + } + +-struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index) ++struct net_device *mana_get_primary_netdev(struct mana_context *ac, ++ u32 port_index, ++ netdevice_tracker *tracker) + { + struct net_device *ndev; + +- RCU_LOCKDEP_WARN(!rcu_read_lock_held(), +- "Taking primary netdev without holding the RCU read lock"); + if (port_index >= ac->num_ports) + return NULL; + +- /* When mana is used in netvsc, the upper netdevice should be returned. */ +- if (ac->ports[port_index]->flags & IFF_SLAVE) +- ndev = netdev_master_upper_dev_get_rcu(ac->ports[port_index]); +- else ++ rcu_read_lock(); ++ ++ /* If mana is used in netvsc, the upper netdevice should be returned. */ ++ ndev = netdev_master_upper_dev_get_rcu(ac->ports[port_index]); ++ ++ /* If there is no upper device, use the parent Ethernet device */ ++ if (!ndev) + ndev = ac->ports[port_index]; + ++ netdev_hold(ndev, tracker, GFP_ATOMIC); ++ rcu_read_unlock(); ++ + return ndev; + } +-EXPORT_SYMBOL_NS(mana_get_primary_netdev_rcu, NET_MANA); ++EXPORT_SYMBOL_NS(mana_get_primary_netdev, NET_MANA); +--- a/include/net/mana/mana.h ++++ b/include/net/mana/mana.h +@@ -819,5 +819,7 @@ int mana_cfg_vport(struct mana_port_cont + u32 doorbell_pg_id); + void mana_uncfg_vport(struct mana_port_context *apc); + +-struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index); ++struct net_device *mana_get_primary_netdev(struct mana_context *ac, ++ u32 port_index, ++ netdevice_tracker *tracker); + #endif /* _MANA_H */ diff --git a/queue-6.12/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch b/queue-6.12/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch new file mode 100644 index 0000000000..7daa4169f8 --- /dev/null +++ b/queue-6.12/perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch @@ -0,0 +1,115 @@ +From stable+bounces-213295-greg=kroah.com@vger.kernel.org Tue Feb 3 18:53:24 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 12:51:12 -0500 +Subject: perf: sched: Fix perf crash with new is_user_task() helper +To: stable@vger.kernel.org +Cc: Steven Rostedt , Guenter Roeck , "Peter Zijlstra (Intel)" , Sasha Levin +Message-ID: <20260203175112.1341936-2-sashal@kernel.org> + +From: Steven Rostedt + +[ Upstream commit 76ed27608f7dd235b727ebbb12163438c2fbb617 ] + +In order to do a user space stacktrace the current task needs to be a user +task that has executed in user space. It use to be possible to test if a +task is a user task or not by simply checking the task_struct mm field. If +it was non NULL, it was a user task and if not it was a kernel task. + +But things have changed over time, and some kernel tasks now have their +own mm field. + +An idea was made to instead test PF_KTHREAD and two functions were used to +wrap this check in case it became more complex to test if a task was a +user task or not[1]. But this was rejected and the C code simply checked +the PF_KTHREAD directly. + +It was later found that not all kernel threads set PF_KTHREAD. The io-uring +helpers instead set PF_USER_WORKER and this needed to be added as well. + +But checking the flags is still not enough. There's a very small window +when a task exits that it frees its mm field and it is set back to NULL. +If perf were to trigger at this moment, the flags test would say its a +user space task but when perf would read the mm field it would crash with +at NULL pointer dereference. + +Now there are flags that can be used to test if a task is exiting, but +they are set in areas that perf may still want to profile the user space +task (to see where it exited). The only real test is to check both the +flags and the mm field. + +Instead of making this modification in every location, create a new +is_user_task() helper function that does all the tests needed to know if +it is safe to read the user space memory or not. + +[1] https://lore.kernel.org/all/20250425204120.639530125@goodmis.org/ + +Fixes: 90942f9fac05 ("perf: Use current->flags & PF_KTHREAD|PF_USER_WORKER instead of current->mm == NULL") +Closes: https://lore.kernel.org/all/0d877e6f-41a7-4724-875d-0b0a27b8a545@roeck-us.net/ +Reported-by: Guenter Roeck +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Peter Zijlstra (Intel) +Tested-by: Guenter Roeck +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260129102821.46484722@gandalf.local.home +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/sched.h | 5 +++++ + kernel/events/callchain.c | 2 +- + kernel/events/core.c | 6 +++--- + 3 files changed, 9 insertions(+), 4 deletions(-) + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1739,6 +1739,11 @@ static __always_inline bool is_percpu_th + #endif + } + ++static __always_inline bool is_user_task(struct task_struct *task) ++{ ++ return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER)); ++} ++ + /* Per-process atomic flags. */ + #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ + #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -245,7 +245,7 @@ get_perf_callchain(struct pt_regs *regs, + + if (user && !crosstask) { + if (!user_mode(regs)) { +- if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) ++ if (!is_user_task(current)) + goto exit_put; + regs = task_pt_regs(current); + } +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7095,7 +7095,7 @@ static void perf_sample_regs_user(struct + if (user_mode(regs)) { + regs_user->abi = perf_reg_abi(current); + regs_user->regs = regs; +- } else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { ++ } else if (is_user_task(current)) { + perf_get_regs_user(regs_user, regs); + } else { + regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; +@@ -7735,7 +7735,7 @@ static u64 perf_virt_to_phys(u64 virt) + * Try IRQ-safe get_user_page_fast_only first. + * If failed, leave phys_addr as 0. + */ +- if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) { ++ if (is_user_task(current)) { + struct page *p; + + pagefault_disable(); +@@ -7848,7 +7848,7 @@ perf_callchain(struct perf_event *event, + { + bool kernel = !event->attr.exclude_callchain_kernel; + bool user = !event->attr.exclude_callchain_user && +- !(current->flags & (PF_KTHREAD | PF_USER_WORKER)); ++ is_user_task(current); + /* Disallow cross-task user callchains. */ + bool crosstask = event->ctx->task && event->ctx->task != current; + const u32 max_stack = event->attr.sample_max_stack; diff --git a/queue-6.12/perf-simplify-get_perf_callchain-user-logic.patch b/queue-6.12/perf-simplify-get_perf_callchain-user-logic.patch new file mode 100644 index 0000000000..84b9450fc8 --- /dev/null +++ b/queue-6.12/perf-simplify-get_perf_callchain-user-logic.patch @@ -0,0 +1,59 @@ +From stable+bounces-213294-greg=kroah.com@vger.kernel.org Tue Feb 3 19:01:15 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 12:51:11 -0500 +Subject: perf: Simplify get_perf_callchain() user logic +To: stable@vger.kernel.org +Cc: Josh Poimboeuf , "Steven Rostedt (Google)" , "Peter Zijlstra (Intel)" , Namhyung Kim , Sasha Levin +Message-ID: <20260203175112.1341936-1-sashal@kernel.org> + +From: Josh Poimboeuf + +[ Upstream commit d77e3319e31098a6cb97b7ce4e71ba676e327fd7 ] + +Simplify the get_perf_callchain() user logic a bit. task_pt_regs() +should never be NULL. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Namhyung Kim +Link: https://lore.kernel.org/r/20250820180428.760066227@kernel.org +Stable-dep-of: 76ed27608f7d ("perf: sched: Fix perf crash with new is_user_task() helper") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + kernel/events/callchain.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -246,21 +246,19 @@ get_perf_callchain(struct pt_regs *regs, + if (user && !crosstask) { + if (!user_mode(regs)) { + if (current->flags & (PF_KTHREAD | PF_USER_WORKER)) +- regs = NULL; +- else +- regs = task_pt_regs(current); ++ goto exit_put; ++ regs = task_pt_regs(current); + } + +- if (regs) { +- if (add_mark) +- perf_callchain_store_context(&ctx, PERF_CONTEXT_USER); ++ if (add_mark) ++ perf_callchain_store_context(&ctx, PERF_CONTEXT_USER); + +- start_entry_idx = entry->nr; +- perf_callchain_user(&ctx, regs); +- fixup_uretprobe_trampoline_entries(entry, start_entry_idx); +- } ++ start_entry_idx = entry->nr; ++ perf_callchain_user(&ctx, regs); ++ fixup_uretprobe_trampoline_entries(entry, start_entry_idx); + } + ++exit_put: + put_callchain_entry(rctx); + + return entry; diff --git a/queue-6.12/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch b/queue-6.12/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch new file mode 100644 index 0000000000..7befb9ae0e --- /dev/null +++ b/queue-6.12/pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch @@ -0,0 +1,64 @@ +From stable+bounces-213314-greg=kroah.com@vger.kernel.org Tue Feb 3 22:19:56 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 16:18:27 -0500 +Subject: pinctrl: lpass-lpi: implement .get_direction() for the GPIO driver +To: stable@vger.kernel.org +Cc: Bartosz Golaszewski , Abel Vesa , Konrad Dybcio , Abel Vesa , Linus Walleij , Sasha Levin +Message-ID: <20260203211827.1414472-1-sashal@kernel.org> + +From: Bartosz Golaszewski + +[ Upstream commit 4f0d22ec60cee420125f4055af76caa0f373a3fe ] + +GPIO controller driver should typically implement the .get_direction() +callback as GPIOLIB internals may try to use it to determine the state +of a pin. Add it for the LPASS LPI driver. + +Reported-by: Abel Vesa +Cc: stable@vger.kernel.org +Fixes: 6e261d1090d6 ("pinctrl: qcom: Add sm8250 lpass lpi pinctrl driver") +Signed-off-by: Bartosz Golaszewski +Reviewed-by: Konrad Dybcio +Tested-by: Konrad Dybcio # X1E CRD +Tested-by: Abel Vesa +Signed-off-by: Linus Walleij +[ PIN_CONFIG_LEVEL => PIN_CONFIG_OUTPUT ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c +@@ -298,6 +298,22 @@ static const struct pinconf_ops lpi_gpio + .pin_config_group_set = lpi_config_set, + }; + ++static int lpi_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) ++{ ++ unsigned long config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, 0); ++ struct lpi_pinctrl *state = gpiochip_get_data(chip); ++ unsigned long arg; ++ int ret; ++ ++ ret = lpi_config_get(state->ctrl, pin, &config); ++ if (ret) ++ return ret; ++ ++ arg = pinconf_to_config_argument(config); ++ ++ return arg ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; ++} ++ + static int lpi_gpio_direction_input(struct gpio_chip *chip, unsigned int pin) + { + struct lpi_pinctrl *state = gpiochip_get_data(chip); +@@ -395,6 +411,7 @@ static void lpi_gpio_dbg_show(struct seq + #endif + + static const struct gpio_chip lpi_gpio_template = { ++ .get_direction = lpi_gpio_get_direction, + .direction_input = lpi_gpio_direction_input, + .direction_output = lpi_gpio_direction_output, + .get = lpi_gpio_get, diff --git a/queue-6.12/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch b/queue-6.12/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch new file mode 100644 index 0000000000..e83a7ccd14 --- /dev/null +++ b/queue-6.12/pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch @@ -0,0 +1,265 @@ +From stable+bounces-213276-greg=kroah.com@vger.kernel.org Tue Feb 3 17:34:25 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 11:29:29 -0500 +Subject: pinctrl: qcom: sm8350-lpass-lpi: Merge with SC7280 to fix I2S2 and SWR TX pins +To: stable@vger.kernel.org +Cc: Krzysztof Kozlowski , Bartosz Golaszewski , Konrad Dybcio , Linus Walleij , Sasha Levin +Message-ID: <20260203162929.1309413-1-sashal@kernel.org> + +From: Krzysztof Kozlowski + +[ Upstream commit 1fbe3abb449c5ef2178e1c3e3e8b9a43a7a410ac ] + +Qualcomm SC7280 and SM8350 SoCs have slightly different LPASS audio +blocks (v9.4.5 and v9.2), however the LPASS LPI pin controllers are +exactly the same. The driver for SM8350 has two issues, which can be +fixed by simply moving over to SC7280 driver which has them correct: + +1. "i2s2_data_groups" listed twice GPIO12, but should have both GPIO12 + and GPIO13, + +2. "swr_tx_data_groups" contained GPIO5 for "swr_tx_data2" function, but + that function is also available on GPIO14, thus listing it twice is + not necessary. OTOH, GPIO5 has also "swr_rx_data1", so selecting + swr_rx_data function should not block the TX one. + +Fixes: be9f6d56381d ("pinctrl: qcom: sm8350-lpass-lpi: add SM8350 LPASS TLMM") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Konrad Dybcio +Signed-off-by: Linus Walleij +[ .remove_new vs .remove ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/configs/defconfig | 1 + drivers/pinctrl/qcom/Kconfig | 15 -- + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c | 3 + drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c | 151 ------------------------ + 5 files changed, 6 insertions(+), 165 deletions(-) + delete mode 100644 drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c + +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -635,7 +635,6 @@ CONFIG_PINCTRL_LPASS_LPI=m + CONFIG_PINCTRL_SC7280_LPASS_LPI=m + CONFIG_PINCTRL_SM6115_LPASS_LPI=m + CONFIG_PINCTRL_SM8250_LPASS_LPI=m +-CONFIG_PINCTRL_SM8350_LPASS_LPI=m + CONFIG_PINCTRL_SM8450_LPASS_LPI=m + CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m + CONFIG_PINCTRL_SM8550_LPASS_LPI=m +--- a/drivers/pinctrl/qcom/Kconfig ++++ b/drivers/pinctrl/qcom/Kconfig +@@ -60,13 +60,14 @@ config PINCTRL_LPASS_LPI + (Low Power Island) found on the Qualcomm Technologies Inc SoCs. + + config PINCTRL_SC7280_LPASS_LPI +- tristate "Qualcomm Technologies Inc SC7280 LPASS LPI pin controller driver" ++ tristate "Qualcomm Technologies Inc SC7280 and SM8350 LPASS LPI pin controller driver" + depends on ARM64 || COMPILE_TEST + depends on PINCTRL_LPASS_LPI + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI +- (Low Power Island) found on the Qualcomm Technologies Inc SC7280 platform. ++ (Low Power Island) found on the Qualcomm Technologies Inc SC7280 ++ and SM8350 platforms. + + config PINCTRL_SM4250_LPASS_LPI + tristate "Qualcomm Technologies Inc SM4250 LPASS LPI pin controller driver" +@@ -95,16 +96,6 @@ config PINCTRL_SM8250_LPASS_LPI + Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI + (Low Power Island) found on the Qualcomm Technologies Inc SM8250 platform. + +-config PINCTRL_SM8350_LPASS_LPI +- tristate "Qualcomm Technologies Inc SM8350 LPASS LPI pin controller driver" +- depends on ARM64 || COMPILE_TEST +- depends on PINCTRL_LPASS_LPI +- help +- This is the pinctrl, pinmux, pinconf and gpiolib driver for the +- Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI +- (Low Power Island) found on the Qualcomm Technologies Inc SM8350 +- platform. +- + config PINCTRL_SM8450_LPASS_LPI + tristate "Qualcomm Technologies Inc SM8450 LPASS LPI pin controller driver" + depends on ARM64 || COMPILE_TEST +--- a/drivers/pinctrl/qcom/Makefile ++++ b/drivers/pinctrl/qcom/Makefile +@@ -55,7 +55,6 @@ obj-$(CONFIG_PINCTRL_SM8150) += pinctrl- + obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o + obj-$(CONFIG_PINCTRL_SM8250_LPASS_LPI) += pinctrl-sm8250-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8350) += pinctrl-sm8350.o +-obj-$(CONFIG_PINCTRL_SM8350_LPASS_LPI) += pinctrl-sm8350-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8450) += pinctrl-sm8450.o + obj-$(CONFIG_PINCTRL_SM8450_LPASS_LPI) += pinctrl-sm8450-lpass-lpi.o + obj-$(CONFIG_PINCTRL_SM8550) += pinctrl-sm8550.o +--- a/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c ++++ b/drivers/pinctrl/qcom/pinctrl-sc7280-lpass-lpi.c +@@ -131,6 +131,9 @@ static const struct of_device_id lpi_pin + { + .compatible = "qcom,sc7280-lpass-lpi-pinctrl", + .data = &sc7280_lpi_data, ++ }, { ++ .compatible = "qcom,sm8350-lpass-lpi-pinctrl", ++ .data = &sc7280_lpi_data, + }, + { } + }; +--- a/drivers/pinctrl/qcom/pinctrl-sm8350-lpass-lpi.c ++++ /dev/null +@@ -1,151 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2020-2023 Linaro Ltd. +- */ +- +-#include +-#include +-#include +- +-#include "pinctrl-lpass-lpi.h" +- +-enum lpass_lpi_functions { +- LPI_MUX_dmic1_clk, +- LPI_MUX_dmic1_data, +- LPI_MUX_dmic2_clk, +- LPI_MUX_dmic2_data, +- LPI_MUX_dmic3_clk, +- LPI_MUX_dmic3_data, +- LPI_MUX_i2s1_clk, +- LPI_MUX_i2s1_data, +- LPI_MUX_i2s1_ws, +- LPI_MUX_i2s2_clk, +- LPI_MUX_i2s2_data, +- LPI_MUX_i2s2_ws, +- LPI_MUX_qua_mi2s_data, +- LPI_MUX_qua_mi2s_sclk, +- LPI_MUX_qua_mi2s_ws, +- LPI_MUX_swr_rx_clk, +- LPI_MUX_swr_rx_data, +- LPI_MUX_swr_tx_clk, +- LPI_MUX_swr_tx_data, +- LPI_MUX_wsa_swr_clk, +- LPI_MUX_wsa_swr_data, +- LPI_MUX_gpio, +- LPI_MUX__, +-}; +- +-static const struct pinctrl_pin_desc sm8350_lpi_pins[] = { +- PINCTRL_PIN(0, "gpio0"), +- PINCTRL_PIN(1, "gpio1"), +- PINCTRL_PIN(2, "gpio2"), +- PINCTRL_PIN(3, "gpio3"), +- PINCTRL_PIN(4, "gpio4"), +- PINCTRL_PIN(5, "gpio5"), +- PINCTRL_PIN(6, "gpio6"), +- PINCTRL_PIN(7, "gpio7"), +- PINCTRL_PIN(8, "gpio8"), +- PINCTRL_PIN(9, "gpio9"), +- PINCTRL_PIN(10, "gpio10"), +- PINCTRL_PIN(11, "gpio11"), +- PINCTRL_PIN(12, "gpio12"), +- PINCTRL_PIN(13, "gpio13"), +- PINCTRL_PIN(14, "gpio14"), +-}; +- +-static const char * const swr_tx_clk_groups[] = { "gpio0" }; +-static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio5", "gpio14" }; +-static const char * const swr_rx_clk_groups[] = { "gpio3" }; +-static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" }; +-static const char * const dmic1_clk_groups[] = { "gpio6" }; +-static const char * const dmic1_data_groups[] = { "gpio7" }; +-static const char * const dmic2_clk_groups[] = { "gpio8" }; +-static const char * const dmic2_data_groups[] = { "gpio9" }; +-static const char * const i2s2_clk_groups[] = { "gpio10" }; +-static const char * const i2s2_ws_groups[] = { "gpio11" }; +-static const char * const dmic3_clk_groups[] = { "gpio12" }; +-static const char * const dmic3_data_groups[] = { "gpio13" }; +-static const char * const qua_mi2s_sclk_groups[] = { "gpio0" }; +-static const char * const qua_mi2s_ws_groups[] = { "gpio1" }; +-static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4" }; +-static const char * const i2s1_clk_groups[] = { "gpio6" }; +-static const char * const i2s1_ws_groups[] = { "gpio7" }; +-static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; +-static const char * const wsa_swr_clk_groups[] = { "gpio10" }; +-static const char * const wsa_swr_data_groups[] = { "gpio11" }; +-static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" }; +- +-static const struct lpi_pingroup sm8350_groups[] = { +- LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), +- LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _), +- LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _), +- LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _), +- LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _), +- LPI_PINGROUP(5, 12, swr_tx_data, swr_rx_data, _, _), +- LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _), +- LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _), +- LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _), +- LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, _, _), +- LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _), +- LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _), +- LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _), +- LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, _, _), +- LPI_PINGROUP(14, 6, swr_tx_data, _, _, _), +-}; +- +-static const struct lpi_function sm8350_functions[] = { +- LPI_FUNCTION(dmic1_clk), +- LPI_FUNCTION(dmic1_data), +- LPI_FUNCTION(dmic2_clk), +- LPI_FUNCTION(dmic2_data), +- LPI_FUNCTION(dmic3_clk), +- LPI_FUNCTION(dmic3_data), +- LPI_FUNCTION(i2s1_clk), +- LPI_FUNCTION(i2s1_data), +- LPI_FUNCTION(i2s1_ws), +- LPI_FUNCTION(i2s2_clk), +- LPI_FUNCTION(i2s2_data), +- LPI_FUNCTION(i2s2_ws), +- LPI_FUNCTION(qua_mi2s_data), +- LPI_FUNCTION(qua_mi2s_sclk), +- LPI_FUNCTION(qua_mi2s_ws), +- LPI_FUNCTION(swr_rx_clk), +- LPI_FUNCTION(swr_rx_data), +- LPI_FUNCTION(swr_tx_clk), +- LPI_FUNCTION(swr_tx_data), +- LPI_FUNCTION(wsa_swr_clk), +- LPI_FUNCTION(wsa_swr_data), +-}; +- +-static const struct lpi_pinctrl_variant_data sm8350_lpi_data = { +- .pins = sm8350_lpi_pins, +- .npins = ARRAY_SIZE(sm8350_lpi_pins), +- .groups = sm8350_groups, +- .ngroups = ARRAY_SIZE(sm8350_groups), +- .functions = sm8350_functions, +- .nfunctions = ARRAY_SIZE(sm8350_functions), +-}; +- +-static const struct of_device_id lpi_pinctrl_of_match[] = { +- { +- .compatible = "qcom,sm8350-lpass-lpi-pinctrl", +- .data = &sm8350_lpi_data, +- }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match); +- +-static struct platform_driver lpi_pinctrl_driver = { +- .driver = { +- .name = "qcom-sm8350-lpass-lpi-pinctrl", +- .of_match_table = lpi_pinctrl_of_match, +- }, +- .probe = lpi_pinctrl_probe, +- .remove_new = lpi_pinctrl_remove, +-}; +-module_platform_driver(lpi_pinctrl_driver); +- +-MODULE_AUTHOR("Krzysztof Kozlowski "); +-MODULE_DESCRIPTION("QTI SM8350 LPI GPIO pin control driver"); +-MODULE_LICENSE("GPL"); diff --git a/queue-6.12/rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch b/queue-6.12/rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch new file mode 100644 index 0000000000..3b30b6ef43 --- /dev/null +++ b/queue-6.12/rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch @@ -0,0 +1,126 @@ +From stable+bounces-213311-greg=kroah.com@vger.kernel.org Tue Feb 3 21:47:36 2026 +From: longli@linux.microsoft.com +Date: Tue, 3 Feb 2026 12:45:24 -0800 +Subject: RDMA/mana_ib: Handle net event for pointing to the current netdev +To: stable@vger.kernel.org, linux-kernel@vger.kernel.org +Cc: Long Li , Leon Romanovsky , stable@kernel.org +Message-ID: <20260203204524.827567-2-longli@linux.microsoft.com> + +From: Long Li + +commit bee35b7161aaaed9831e2f14876c374b9c566952 upstream. + +When running under Hyper-V, the master device to the RDMA device is always +bonded to this RDMA device. This is not user-configurable. + +The master device can be unbind/bind from the kernel. During those events, +the RDMA device should set to the current netdev to reflect the change of +master device from those events. + +Signed-off-by: Long Li +Link: https://patch.msgid.link/1741821332-9392-2-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Leon Romanovsky +Fixes: 1df03a4b4414 ("RDMA/mana_ib: Set correct device into ib") +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/hw/mana/device.c | 47 +++++++++++++++++++++++++++++++++-- + drivers/infiniband/hw/mana/mana_ib.h | 1 + 2 files changed, 46 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mana/device.c ++++ b/drivers/infiniband/hw/mana/device.c +@@ -51,6 +51,38 @@ static const struct ib_device_ops mana_i + ib_ind_table), + }; + ++static int mana_ib_netdev_event(struct notifier_block *this, ++ unsigned long event, void *ptr) ++{ ++ struct mana_ib_dev *dev = container_of(this, struct mana_ib_dev, nb); ++ struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); ++ struct gdma_context *gc = dev->gdma_dev->gdma_context; ++ struct mana_context *mc = gc->mana.driver_data; ++ struct net_device *ndev; ++ ++ /* Only process events from our parent device */ ++ if (event_dev != mc->ports[0]) ++ return NOTIFY_DONE; ++ ++ switch (event) { ++ case NETDEV_CHANGEUPPER: ++ ndev = mana_get_primary_netdev(mc, 0, &dev->dev_tracker); ++ /* ++ * RDMA core will setup GID based on updated netdev. ++ * It's not possible to race with the core as rtnl lock is being ++ * held. ++ */ ++ ib_device_set_netdev(&dev->ib_dev, ndev, 1); ++ ++ /* mana_get_primary_netdev() returns ndev with refcount held */ ++ netdev_put(ndev, &dev->dev_tracker); ++ ++ return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ + static int mana_ib_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) + { +@@ -108,17 +140,25 @@ static int mana_ib_probe(struct auxiliar + } + dev->gdma_dev = &mdev->gdma_context->mana_ib; + ++ dev->nb.notifier_call = mana_ib_netdev_event; ++ ret = register_netdevice_notifier(&dev->nb); ++ if (ret) { ++ ibdev_err(&dev->ib_dev, "Failed to register net notifier, %d", ++ ret); ++ goto deregister_device; ++ } ++ + ret = mana_ib_gd_query_adapter_caps(dev); + if (ret) { + ibdev_err(&dev->ib_dev, "Failed to query device caps, ret %d", + ret); +- goto deregister_device; ++ goto deregister_net_notifier; + } + + ret = mana_ib_create_eqs(dev); + if (ret) { + ibdev_err(&dev->ib_dev, "Failed to create EQs, ret %d", ret); +- goto deregister_device; ++ goto deregister_net_notifier; + } + + ret = mana_ib_gd_create_rnic_adapter(dev); +@@ -147,6 +187,8 @@ destroy_rnic: + mana_ib_gd_destroy_rnic_adapter(dev); + destroy_eqs: + mana_ib_destroy_eqs(dev); ++deregister_net_notifier: ++ unregister_netdevice_notifier(&dev->nb); + deregister_device: + mana_gd_deregister_device(dev->gdma_dev); + free_ib_device: +@@ -162,6 +204,7 @@ static void mana_ib_remove(struct auxili + xa_destroy(&dev->qp_table_wq); + mana_ib_gd_destroy_rnic_adapter(dev); + mana_ib_destroy_eqs(dev); ++ unregister_netdevice_notifier(&dev->nb); + mana_gd_deregister_device(dev->gdma_dev); + ib_dealloc_device(&dev->ib_dev); + } +--- a/drivers/infiniband/hw/mana/mana_ib.h ++++ b/drivers/infiniband/hw/mana/mana_ib.h +@@ -65,6 +65,7 @@ struct mana_ib_dev { + struct xarray qp_table_wq; + struct mana_ib_adapter_caps adapter_caps; + netdevice_tracker dev_tracker; ++ struct notifier_block nb; + }; + + struct mana_ib_wq { diff --git a/queue-6.12/series b/queue-6.12/series index e4b21a29da..48b382120a 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -75,3 +75,12 @@ wifi-ath11k-add-srng-lock-for-ath11k_hal_srng_-in-monitor-mode.patch revert-drm-nouveau-disp-set-drm_mode_config_funcs.atomic_-check-commit.patch btrfs-prevent-use-after-free-on-folio-private-data-in-btrfs_subpage_clear_uptodate.patch net-sched-act_ife-convert-comma-to-semicolon.patch +pinctrl-qcom-sm8350-lpass-lpi-merge-with-sc7280-to-fix-i2s2-and-swr-tx-pins.patch +mptcp-avoid-dup-sub_closed-events-after-disconnect.patch +perf-simplify-get_perf_callchain-user-logic.patch +perf-sched-fix-perf-crash-with-new-is_user_task-helper.patch +writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch +drm-amdgpu-gfx11-adjust-kgq-reset-sequence.patch +pinctrl-lpass-lpi-implement-.get_direction-for-the-gpio-driver.patch +net-mana-change-the-function-signature-of-mana_get_primary_netdev_rcu.patch +rdma-mana_ib-handle-net-event-for-pointing-to-the-current-netdev.patch diff --git a/queue-6.12/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch b/queue-6.12/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch new file mode 100644 index 0000000000..c1f9a18898 --- /dev/null +++ b/queue-6.12/writeback-fix-100-cpu-usage-when-dirtytime_expire_interval-is-0.patch @@ -0,0 +1,77 @@ +From stable+bounces-213297-greg=kroah.com@vger.kernel.org Tue Feb 3 19:08:27 2026 +From: Sasha Levin +Date: Tue, 3 Feb 2026 13:04:25 -0500 +Subject: writeback: fix 100% CPU usage when dirtytime_expire_interval is 0 +To: stable@vger.kernel.org +Cc: Laveesh Bansal , Jan Kara , Christian Brauner , Sasha Levin +Message-ID: <20260203180425.1352516-1-sashal@kernel.org> + +From: Laveesh Bansal + +[ Upstream commit 543467d6fe97e27e22a26e367fda972dbefebbff ] + +When vm.dirtytime_expire_seconds is set to 0, wakeup_dirtytime_writeback() +schedules delayed work with a delay of 0, causing immediate execution. +The function then reschedules itself with 0 delay again, creating an +infinite busy loop that causes 100% kworker CPU usage. + +Fix by: +- Only scheduling delayed work in wakeup_dirtytime_writeback() when + dirtytime_expire_interval is non-zero +- Cancelling the delayed work in dirtytime_interval_handler() when + the interval is set to 0 +- Adding a guard in start_dirtytime_writeback() for defensive coding + +Tested by booting kernel in QEMU with virtme-ng: +- Before fix: kworker CPU spikes to ~73% +- After fix: CPU remains at normal levels +- Setting interval back to non-zero correctly resumes writeback + +Fixes: a2f4870697a5 ("fs: make sure the timestamps for lazytime inodes eventually get written") +Cc: stable@vger.kernel.org +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220227 +Signed-off-by: Laveesh Bansal +Link: https://patch.msgid.link/20260106145059.543282-2-laveeshb@laveeshbansal.com +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +[ adapted system_percpu_wq to system_wq for the workqueue used in dirtytime_interval_handler() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/fs-writeback.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -2418,12 +2418,14 @@ static void wakeup_dirtytime_writeback(s + wb_wakeup(wb); + } + rcu_read_unlock(); +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + } + + static int __init start_dirtytime_writeback(void) + { +- schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); ++ if (dirtytime_expire_interval) ++ schedule_delayed_work(&dirtytime_work, dirtytime_expire_interval * HZ); + return 0; + } + __initcall(start_dirtytime_writeback); +@@ -2434,8 +2436,12 @@ int dirtytime_interval_handler(const str + int ret; + + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- if (ret == 0 && write) +- mod_delayed_work(system_wq, &dirtytime_work, 0); ++ if (ret == 0 && write) { ++ if (dirtytime_expire_interval) ++ mod_delayed_work(system_wq, &dirtytime_work, 0); ++ else ++ cancel_delayed_work_sync(&dirtytime_work); ++ } + return ret; + } + -- 2.47.3