From: Greg Kroah-Hartman Date: Tue, 12 Aug 2025 13:26:24 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v6.1.148~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=768b7b98177723097dd8778be788a9b5996e74d0;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch i2c-stm32f7-unmap-dma-mapped-buffer.patch i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch i2c-stm32f7-use-devm_clk_get_enabled.patch sched-core-remove-ifdeffery-for-saved_state.patch sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch --- diff --git a/queue-6.6/freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch b/queue-6.6/freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch new file mode 100644 index 0000000000..7e126f920f --- /dev/null +++ b/queue-6.6/freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch @@ -0,0 +1,31 @@ +From 418146e39891ef1fb2284dee4cabbfe616cd21cf Mon Sep 17 00:00:00 2001 +From: Elliot Berman +Date: Mon, 20 Nov 2023 09:36:32 -0800 +Subject: freezer,sched: Clean saved_state when restoring it during thaw + +From: Elliot Berman + +commit 418146e39891ef1fb2284dee4cabbfe616cd21cf upstream. + +Clean saved_state after using it during thaw. Cleaning the saved_state +allows us to avoid some unnecessary branches in ttwu_state_match. + +Signed-off-by: Elliot Berman +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20231120-freezer-state-multiple-thaws-v1-2-f2e1dd7ce5a2@quicinc.com +Signed-off-by: Chen Ridong +Signed-off-by: Greg Kroah-Hartman +--- + kernel/freezer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/freezer.c ++++ b/kernel/freezer.c +@@ -187,6 +187,7 @@ static int __restore_freezer_state(struc + + if (state != TASK_RUNNING) { + WRITE_ONCE(p->__state, state); ++ p->saved_state = TASK_RUNNING; + return 1; + } + diff --git a/queue-6.6/freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch b/queue-6.6/freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch new file mode 100644 index 0000000000..c240ac7ae3 --- /dev/null +++ b/queue-6.6/freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch @@ -0,0 +1,44 @@ +From 23ab79e8e469e2605beec2e3ccb40d19c68dd2e0 Mon Sep 17 00:00:00 2001 +From: Elliot Berman +Date: Mon, 20 Nov 2023 09:36:31 -0800 +Subject: freezer,sched: Do not restore saved_state of a thawed task + +From: Elliot Berman + +commit 23ab79e8e469e2605beec2e3ccb40d19c68dd2e0 upstream. + +It is possible for a task to be thawed multiple times when mixing the +*legacy* cgroup freezer and system-wide freezer. To do this, freeze the +cgroup, do system-wide freeze/thaw, then thaw the cgroup. When this +happens, then a stale saved_state can be written to the task's state +and cause task to hang indefinitely. Fix this by only trying to thaw +tasks that are actually frozen. + +This change also has the marginal benefit avoiding unnecessary +wake_up_state(p, TASK_FROZEN) if we know the task is already thawed. +There is not possibility of time-of-compare/time-of-use race when we skip +the wake_up_state because entering/exiting TASK_FROZEN is guarded by +freezer_lock. + +Fixes: 8f0eed4a78a8 ("freezer,sched: Use saved_state to reduce some spurious wakeups") +Signed-off-by: Elliot Berman +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Abhijeet Dharmapurikar +Link: https://lore.kernel.org/r/20231120-freezer-state-multiple-thaws-v1-1-f2e1dd7ce5a2@quicinc.com +Signed-off-by: Chen Ridong +Signed-off-by: Greg Kroah-Hartman +--- + kernel/freezer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/freezer.c ++++ b/kernel/freezer.c +@@ -201,7 +201,7 @@ void __thaw_task(struct task_struct *p) + if (WARN_ON_ONCE(freezing(p))) + goto unlock; + +- if (task_call_func(p, __restore_freezer_state, NULL)) ++ if (!frozen(p) || task_call_func(p, __restore_freezer_state, NULL)) + goto unlock; + + wake_up_state(p, TASK_FROZEN); diff --git a/queue-6.6/freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch b/queue-6.6/freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch new file mode 100644 index 0000000000..d33d34324d --- /dev/null +++ b/queue-6.6/freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch @@ -0,0 +1,172 @@ +From 8f0eed4a78a81668bc78923ea09f51a7a663c2b0 Mon Sep 17 00:00:00 2001 +From: Elliot Berman +Date: Fri, 8 Sep 2023 15:49:16 -0700 +Subject: freezer,sched: Use saved_state to reduce some spurious wakeups + +From: Elliot Berman + +commit 8f0eed4a78a81668bc78923ea09f51a7a663c2b0 upstream. + +After commit f5d39b020809 ("freezer,sched: Rewrite core freezer logic"), +tasks that transition directly from TASK_FREEZABLE to TASK_FROZEN are +always woken up on the thaw path. Prior to that commit, tasks could ask +freezer to consider them "frozen enough" via freezer_do_not_count(). The +commit replaced freezer_do_not_count() with a TASK_FREEZABLE state which +allows freezer to immediately mark the task as TASK_FROZEN without +waking up the task. This is efficient for the suspend path, but on the +thaw path, the task is always woken up even if the task didn't need to +wake up and goes back to its TASK_(UN)INTERRUPTIBLE state. Although +these tasks are capable of handling of the wakeup, we can observe a +power/perf impact from the extra wakeup. + +We observed on Android many tasks wait in the TASK_FREEZABLE state +(particularly due to many of them being binder clients). We observed +nearly 4x the number of tasks and a corresponding linear increase in +latency and power consumption when thawing the system. The latency +increased from ~15ms to ~50ms. + +Avoid the spurious wakeups by saving the state of TASK_FREEZABLE tasks. +If the task was running before entering TASK_FROZEN state +(__refrigerator()) or if the task received a wake up for the saved +state, then the task is woken on thaw. saved_state from PREEMPT_RT locks +can be re-used because freezer would not stomp on the rtlock wait flow: +TASK_RTLOCK_WAIT isn't considered freezable. + +Reported-by: Prakash Viswalingam +Signed-off-by: Elliot Berman +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Signed-off-by: Chen Ridong +Signed-off-by: Greg Kroah-Hartman +--- + kernel/freezer.c | 41 +++++++++++++++++++---------------------- + kernel/sched/core.c | 21 +++++++++++++-------- + 2 files changed, 32 insertions(+), 30 deletions(-) + +--- a/kernel/freezer.c ++++ b/kernel/freezer.c +@@ -71,7 +71,11 @@ bool __refrigerator(bool check_kthr_stop + for (;;) { + bool freeze; + ++ raw_spin_lock_irq(¤t->pi_lock); + set_current_state(TASK_FROZEN); ++ /* unstale saved_state so that __thaw_task() will wake us up */ ++ current->saved_state = TASK_RUNNING; ++ raw_spin_unlock_irq(¤t->pi_lock); + + spin_lock_irq(&freezer_lock); + freeze = freezing(current) && !(check_kthr_stop && kthread_should_stop()); +@@ -129,6 +133,7 @@ static int __set_task_frozen(struct task + WARN_ON_ONCE(debug_locks && p->lockdep_depth); + #endif + ++ p->saved_state = p->__state; + WRITE_ONCE(p->__state, TASK_FROZEN); + return TASK_FROZEN; + } +@@ -170,42 +175,34 @@ bool freeze_task(struct task_struct *p) + } + + /* +- * The special task states (TASK_STOPPED, TASK_TRACED) keep their canonical +- * state in p->jobctl. If either of them got a wakeup that was missed because +- * TASK_FROZEN, then their canonical state reflects that and the below will +- * refuse to restore the special state and instead issue the wakeup. ++ * Restore the saved_state before the task entered freezer. For typical task ++ * in the __refrigerator(), saved_state == TASK_RUNNING so nothing happens ++ * here. For tasks which were TASK_NORMAL | TASK_FREEZABLE, their initial state ++ * is restored unless they got an expected wakeup (see ttwu_state_match()). ++ * Returns 1 if the task state was restored. + */ +-static int __set_task_special(struct task_struct *p, void *arg) ++static int __restore_freezer_state(struct task_struct *p, void *arg) + { +- unsigned int state = 0; ++ unsigned int state = p->saved_state; + +- if (p->jobctl & JOBCTL_TRACED) +- state = TASK_TRACED; +- +- else if (p->jobctl & JOBCTL_STOPPED) +- state = TASK_STOPPED; +- +- if (state) ++ if (state != TASK_RUNNING) { + WRITE_ONCE(p->__state, state); ++ return 1; ++ } + +- return state; ++ return 0; + } + + void __thaw_task(struct task_struct *p) + { +- unsigned long flags, flags2; ++ unsigned long flags; + + spin_lock_irqsave(&freezer_lock, flags); + if (WARN_ON_ONCE(freezing(p))) + goto unlock; + +- if (lock_task_sighand(p, &flags2)) { +- /* TASK_FROZEN -> TASK_{STOPPED,TRACED} */ +- bool ret = task_call_func(p, __set_task_special, NULL); +- unlock_task_sighand(p, &flags2); +- if (ret) +- goto unlock; +- } ++ if (task_call_func(p, __restore_freezer_state, NULL)) ++ goto unlock; + + wake_up_state(p, TASK_FROZEN); + unlock: +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -2251,7 +2251,7 @@ int task_state_match(struct task_struct + + /* + * Serialize against current_save_and_set_rtlock_wait_state() and +- * current_restore_rtlock_saved_state(). ++ * current_restore_rtlock_saved_state(), and __refrigerator(). + */ + raw_spin_lock_irq(&p->pi_lock); + match = __task_state_match(p, state); +@@ -4034,13 +4034,17 @@ static void ttwu_queue(struct task_struc + * The caller holds p::pi_lock if p != current or has preemption + * disabled when p == current. + * +- * The rules of PREEMPT_RT saved_state: ++ * The rules of saved_state: + * + * The related locking code always holds p::pi_lock when updating + * p::saved_state, which means the code is fully serialized in both cases. + * +- * The lock wait and lock wakeups happen via TASK_RTLOCK_WAIT. No other +- * bits set. This allows to distinguish all wakeup scenarios. ++ * For PREEMPT_RT, the lock wait and lock wakeups happen via TASK_RTLOCK_WAIT. ++ * No other bits set. This allows to distinguish all wakeup scenarios. ++ * ++ * For FREEZER, the wakeup happens via TASK_FROZEN. No other bits set. This ++ * allows us to prevent early wakeup of tasks before they can be run on ++ * asymmetric ISA architectures (eg ARMv9). + */ + static __always_inline + bool ttwu_state_match(struct task_struct *p, unsigned int state, int *success) +@@ -4056,10 +4060,11 @@ bool ttwu_state_match(struct task_struct + + /* + * Saved state preserves the task state across blocking on +- * an RT lock. If the state matches, set p::saved_state to +- * TASK_RUNNING, but do not wake the task because it waits +- * for a lock wakeup. Also indicate success because from +- * the regular waker's point of view this has succeeded. ++ * an RT lock or TASK_FREEZABLE tasks. If the state matches, ++ * set p::saved_state to TASK_RUNNING, but do not wake the task ++ * because it waits for a lock wakeup or __thaw_task(). Also ++ * indicate success because from the regular waker's point of ++ * view this has succeeded. + * + * After acquiring the lock the task will restore p::__state + * from p::saved_state which ensures that the regular diff --git a/queue-6.6/i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch b/queue-6.6/i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch new file mode 100644 index 0000000000..bf46e41bb4 --- /dev/null +++ b/queue-6.6/i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch @@ -0,0 +1,212 @@ +From stable+bounces-165520-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:15 2025 +From: Sasha Levin +Date: Wed, 30 Jul 2025 10:00:00 -0400 +Subject: i2c: stm32f7: perform most of irq job in threaded handler +To: stable@vger.kernel.org +Cc: Alain Volmat , Andi Shyti , Wolfram Sang , Sasha Levin +Message-ID: <20250730140002.3814528-3-sashal@kernel.org> + +From: Alain Volmat + +[ Upstream commit e6103cd45ef0e14eb02f0666bc6b494902cfe821 ] + +The irq handling is currently split between the irq handler +and the threaded irq handler. Some of the handling (such as +dma related stuffs) done within the irq handler might sleep or +take some time leading to issues if the kernel is built with +realtime constraints. In order to fix that, perform an overall +rework to perform most of the job within the threaded handler +and only keep fifo access in the non threaded handler. + +Signed-off-by: Alain Volmat +Reviewed-by: Andi Shyti +Signed-off-by: Wolfram Sang +Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 126 +++++++++++++++++---------------------- + 1 file changed, 56 insertions(+), 70 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -1496,17 +1496,11 @@ static irqreturn_t stm32f7_i2c_slave_isr + static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data) + { + struct stm32f7_i2c_dev *i2c_dev = data; +- struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; +- struct stm32_i2c_dma *dma = i2c_dev->dma; +- void __iomem *base = i2c_dev->base; +- u32 status, mask; +- int ret = IRQ_HANDLED; ++ u32 status; + +- /* Check if the interrupt if for a slave device */ +- if (!i2c_dev->master_mode) { +- ret = stm32f7_i2c_slave_isr_event(i2c_dev); +- return ret; +- } ++ /* Check if the interrupt is for a slave device */ ++ if (!i2c_dev->master_mode) ++ return IRQ_WAKE_THREAD; + + status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); + +@@ -1518,6 +1512,29 @@ static irqreturn_t stm32f7_i2c_isr_event + if (status & STM32F7_I2C_ISR_RXNE) + stm32f7_i2c_read_rx_data(i2c_dev); + ++ /* Wake up the thread if other flags are raised */ ++ if (status & ++ (STM32F7_I2C_ISR_NACKF | STM32F7_I2C_ISR_STOPF | ++ STM32F7_I2C_ISR_TC | STM32F7_I2C_ISR_TCR)) ++ return IRQ_WAKE_THREAD; ++ ++ return IRQ_HANDLED; ++} ++ ++static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) ++{ ++ struct stm32f7_i2c_dev *i2c_dev = data; ++ struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; ++ struct stm32_i2c_dma *dma = i2c_dev->dma; ++ void __iomem *base = i2c_dev->base; ++ u32 status, mask; ++ int ret; ++ ++ if (!i2c_dev->master_mode) ++ return stm32f7_i2c_slave_isr_event(i2c_dev); ++ ++ status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); ++ + /* NACK received */ + if (status & STM32F7_I2C_ISR_NACKF) { + dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", +@@ -1530,33 +1547,28 @@ static irqreturn_t stm32f7_i2c_isr_event + f7_msg->result = -ENXIO; + } + +- /* STOP detection flag */ +- if (status & STM32F7_I2C_ISR_STOPF) { +- /* Disable interrupts */ +- if (stm32f7_i2c_is_slave_registered(i2c_dev)) +- mask = STM32F7_I2C_XFER_IRQ_MASK; ++ if (status & STM32F7_I2C_ISR_TCR) { ++ if (f7_msg->smbus) ++ stm32f7_i2c_smbus_reload(i2c_dev); + else +- mask = STM32F7_I2C_ALL_IRQ_MASK; +- stm32f7_i2c_disable_irq(i2c_dev, mask); +- +- /* Clear STOP flag */ +- writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); +- +- if (i2c_dev->use_dma && !f7_msg->result) { +- ret = IRQ_WAKE_THREAD; +- } else { +- i2c_dev->master_mode = false; +- complete(&i2c_dev->complete); +- } ++ stm32f7_i2c_reload(i2c_dev); + } + + /* Transfer complete */ + if (status & STM32F7_I2C_ISR_TC) { ++ /* Wait for dma transfer completion before sending next message */ ++ if (i2c_dev->use_dma && !f7_msg->result) { ++ ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); ++ if (!ret) { ++ dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); ++ stm32f7_i2c_disable_dma_req(i2c_dev); ++ dmaengine_terminate_async(dma->chan_using); ++ f7_msg->result = -ETIMEDOUT; ++ } ++ } + if (f7_msg->stop) { + mask = STM32F7_I2C_CR2_STOP; + stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); +- } else if (i2c_dev->use_dma && !f7_msg->result) { +- ret = IRQ_WAKE_THREAD; + } else if (f7_msg->smbus) { + stm32f7_i2c_smbus_rep_start(i2c_dev); + } else { +@@ -1566,47 +1578,18 @@ static irqreturn_t stm32f7_i2c_isr_event + } + } + +- if (status & STM32F7_I2C_ISR_TCR) { +- if (f7_msg->smbus) +- stm32f7_i2c_smbus_reload(i2c_dev); ++ /* STOP detection flag */ ++ if (status & STM32F7_I2C_ISR_STOPF) { ++ /* Disable interrupts */ ++ if (stm32f7_i2c_is_slave_registered(i2c_dev)) ++ mask = STM32F7_I2C_XFER_IRQ_MASK; + else +- stm32f7_i2c_reload(i2c_dev); +- } +- +- return ret; +-} +- +-static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data) +-{ +- struct stm32f7_i2c_dev *i2c_dev = data; +- struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; +- struct stm32_i2c_dma *dma = i2c_dev->dma; +- u32 status; +- int ret; +- +- /* +- * Wait for dma transfer completion before sending next message or +- * notity the end of xfer to the client +- */ +- ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); +- if (!ret) { +- dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); +- stm32f7_i2c_disable_dma_req(i2c_dev); +- dmaengine_terminate_async(dma->chan_using); +- f7_msg->result = -ETIMEDOUT; +- } ++ mask = STM32F7_I2C_ALL_IRQ_MASK; ++ stm32f7_i2c_disable_irq(i2c_dev, mask); + +- status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); ++ /* Clear STOP flag */ ++ writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); + +- if (status & STM32F7_I2C_ISR_TC) { +- if (f7_msg->smbus) { +- stm32f7_i2c_smbus_rep_start(i2c_dev); +- } else { +- i2c_dev->msg_id++; +- i2c_dev->msg++; +- stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg); +- } +- } else { + i2c_dev->master_mode = false; + complete(&i2c_dev->complete); + } +@@ -1614,7 +1597,7 @@ static irqreturn_t stm32f7_i2c_isr_event + return IRQ_HANDLED; + } + +-static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) ++static irqreturn_t stm32f7_i2c_isr_error_thread(int irq, void *data) + { + struct stm32f7_i2c_dev *i2c_dev = data; + struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; +@@ -2201,8 +2184,11 @@ static int stm32f7_i2c_probe(struct plat + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to request irq event\n"); + +- ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, +- pdev->name, i2c_dev); ++ ret = devm_request_threaded_irq(&pdev->dev, irq_error, ++ NULL, ++ stm32f7_i2c_isr_error_thread, ++ IRQF_ONESHOT, ++ pdev->name, i2c_dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to request irq error\n"); + diff --git a/queue-6.6/i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch b/queue-6.6/i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch new file mode 100644 index 0000000000..25782b3530 --- /dev/null +++ b/queue-6.6/i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch @@ -0,0 +1,71 @@ +From stable+bounces-165521-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:17 2025 +From: Sasha Levin +Date: Wed, 30 Jul 2025 10:00:01 -0400 +Subject: i2c: stm32f7: simplify status messages in case of errors +To: stable@vger.kernel.org +Cc: Alain Volmat , Andi Shyti , Wolfram Sang , Sasha Levin +Message-ID: <20250730140002.3814528-4-sashal@kernel.org> + +From: Alain Volmat + +[ Upstream commit 33a00d919253022aabafecae6bc88a6fad446589 ] + +Avoid usage of __func__ when reporting an error message +since dev_err/dev_dbg are already providing enough details +to identify the source of the message. + +Signed-off-by: Alain Volmat +Reviewed-by: Andi Shyti +Signed-off-by: Wolfram Sang +Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -1601,6 +1601,7 @@ static irqreturn_t stm32f7_i2c_isr_error + { + struct stm32f7_i2c_dev *i2c_dev = data; + struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; ++ u16 addr = f7_msg->addr; + void __iomem *base = i2c_dev->base; + struct device *dev = i2c_dev->dev; + struct stm32_i2c_dma *dma = i2c_dev->dma; +@@ -1610,8 +1611,7 @@ static irqreturn_t stm32f7_i2c_isr_error + + /* Bus error */ + if (status & STM32F7_I2C_ISR_BERR) { +- dev_err(dev, "<%s>: Bus error accessing addr 0x%x\n", +- __func__, f7_msg->addr); ++ dev_err(dev, "Bus error accessing addr 0x%x\n", addr); + writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR); + stm32f7_i2c_release_bus(&i2c_dev->adap); + f7_msg->result = -EIO; +@@ -1619,21 +1619,19 @@ static irqreturn_t stm32f7_i2c_isr_error + + /* Arbitration loss */ + if (status & STM32F7_I2C_ISR_ARLO) { +- dev_dbg(dev, "<%s>: Arbitration loss accessing addr 0x%x\n", +- __func__, f7_msg->addr); ++ dev_dbg(dev, "Arbitration loss accessing addr 0x%x\n", addr); + writel_relaxed(STM32F7_I2C_ICR_ARLOCF, base + STM32F7_I2C_ICR); + f7_msg->result = -EAGAIN; + } + + if (status & STM32F7_I2C_ISR_PECERR) { +- dev_err(dev, "<%s>: PEC error in reception accessing addr 0x%x\n", +- __func__, f7_msg->addr); ++ dev_err(dev, "PEC error in reception accessing addr 0x%x\n", addr); + writel_relaxed(STM32F7_I2C_ICR_PECCF, base + STM32F7_I2C_ICR); + f7_msg->result = -EINVAL; + } + + if (status & STM32F7_I2C_ISR_ALERT) { +- dev_dbg(dev, "<%s>: SMBus alert received\n", __func__); ++ dev_dbg(dev, "SMBus alert received\n"); + writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR); + i2c_handle_smbus_alert(i2c_dev->alert->ara); + return IRQ_HANDLED; diff --git a/queue-6.6/i2c-stm32f7-unmap-dma-mapped-buffer.patch b/queue-6.6/i2c-stm32f7-unmap-dma-mapped-buffer.patch new file mode 100644 index 0000000000..5b999d1c97 --- /dev/null +++ b/queue-6.6/i2c-stm32f7-unmap-dma-mapped-buffer.patch @@ -0,0 +1,106 @@ +From stable+bounces-165522-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:19 2025 +From: Sasha Levin +Date: Wed, 30 Jul 2025 10:00:02 -0400 +Subject: i2c: stm32f7: unmap DMA mapped buffer +To: stable@vger.kernel.org +Cc: "Clément Le Goffic" , "Alain Volmat" , "Andi Shyti" , "Sasha Levin" +Message-ID: <20250730140002.3814528-5-sashal@kernel.org> + +From: Clément Le Goffic + +[ Upstream commit 6aae87fe7f180cd93a74466cdb6cf2aa9bb28798 ] + +Before each I2C transfer using DMA, the I2C buffer is DMA'pped to make +sure the memory buffer is DMA'able. This is handle in the function +`stm32_i2c_prep_dma_xfer()`. +If the transfer fails for any reason the I2C buffer must be unmap. +Use the dma_callback to factorize the code and fix this issue. + +Note that the `stm32f7_i2c_dma_callback()` is now called in case of DMA +transfer success and error and that the `complete()` on the dma_complete +completion structure is done inconditionnally in case of transfer +success or error as well as the `dmaengine_terminate_async()`. +This is allowed as a `complete()` in case transfer error has no effect +as well as a `dmaengine_terminate_async()` on a transfer success. + +Also fix the unneeded cast and remove not more needed variables. + +Fixes: 7ecc8cfde553 ("i2c: i2c-stm32f7: Add DMA support") +Signed-off-by: Clément Le Goffic +Cc: # v4.18+ +Acked-by: Alain Volmat +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20250704-i2c-upstream-v4-2-84a095a2c728@foss.st.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -726,10 +726,11 @@ static void stm32f7_i2c_disable_dma_req( + + static void stm32f7_i2c_dma_callback(void *arg) + { +- struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg; ++ struct stm32f7_i2c_dev *i2c_dev = arg; + struct stm32_i2c_dma *dma = i2c_dev->dma; + + stm32f7_i2c_disable_dma_req(i2c_dev); ++ dmaengine_terminate_async(dma->chan_using); + dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len, + dma->dma_data_dir); + complete(&dma->dma_complete); +@@ -1525,7 +1526,6 @@ static irqreturn_t stm32f7_i2c_isr_event + { + struct stm32f7_i2c_dev *i2c_dev = data; + struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; +- struct stm32_i2c_dma *dma = i2c_dev->dma; + void __iomem *base = i2c_dev->base; + u32 status, mask; + int ret; +@@ -1540,10 +1540,8 @@ static irqreturn_t stm32f7_i2c_isr_event + dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", + __func__, f7_msg->addr); + writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); +- if (i2c_dev->use_dma) { +- stm32f7_i2c_disable_dma_req(i2c_dev); +- dmaengine_terminate_async(dma->chan_using); +- } ++ if (i2c_dev->use_dma) ++ stm32f7_i2c_dma_callback(i2c_dev); + f7_msg->result = -ENXIO; + } + +@@ -1561,8 +1559,7 @@ static irqreturn_t stm32f7_i2c_isr_event + ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ); + if (!ret) { + dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__); +- stm32f7_i2c_disable_dma_req(i2c_dev); +- dmaengine_terminate_async(dma->chan_using); ++ stm32f7_i2c_dma_callback(i2c_dev); + f7_msg->result = -ETIMEDOUT; + } + } +@@ -1604,7 +1601,6 @@ static irqreturn_t stm32f7_i2c_isr_error + u16 addr = f7_msg->addr; + void __iomem *base = i2c_dev->base; + struct device *dev = i2c_dev->dev; +- struct stm32_i2c_dma *dma = i2c_dev->dma; + u32 status; + + status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); +@@ -1648,10 +1644,8 @@ static irqreturn_t stm32f7_i2c_isr_error + } + + /* Disable dma */ +- if (i2c_dev->use_dma) { +- stm32f7_i2c_disable_dma_req(i2c_dev); +- dmaengine_terminate_async(dma->chan_using); +- } ++ if (i2c_dev->use_dma) ++ stm32f7_i2c_dma_callback(i2c_dev); + + i2c_dev->master_mode = false; + complete(&i2c_dev->complete); diff --git a/queue-6.6/i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch b/queue-6.6/i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch new file mode 100644 index 0000000000..d96c7a934a --- /dev/null +++ b/queue-6.6/i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch @@ -0,0 +1,50 @@ +From stable+bounces-165519-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:13 2025 +From: Sasha Levin +Date: Wed, 30 Jul 2025 09:59:59 -0400 +Subject: i2c: stm32f7: use dev_err_probe upon calls of devm_request_irq +To: stable@vger.kernel.org +Cc: Alain Volmat , Wolfram Sang , Sasha Levin +Message-ID: <20250730140002.3814528-2-sashal@kernel.org> + +From: Alain Volmat + +[ Upstream commit a51e224c2f42417e95a3e1a672ade221bcd006ba ] + +Convert error handling upon calls of devm_request_irq functions during +the probe of the driver. + +Signed-off-by: Alain Volmat +Signed-off-by: Wolfram Sang +Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -2198,19 +2198,13 @@ static int stm32f7_i2c_probe(struct plat + stm32f7_i2c_isr_event_thread, + IRQF_ONESHOT, + pdev->name, i2c_dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to request irq event %i\n", +- irq_event); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "Failed to request irq event\n"); + + ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, + pdev->name, i2c_dev); +- if (ret) { +- dev_err(&pdev->dev, "Failed to request irq error %i\n", +- irq_error); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "Failed to request irq error\n"); + + setup = of_device_get_match_data(&pdev->dev); + if (!setup) { diff --git a/queue-6.6/i2c-stm32f7-use-devm_clk_get_enabled.patch b/queue-6.6/i2c-stm32f7-use-devm_clk_get_enabled.patch new file mode 100644 index 0000000000..9c70e4c612 --- /dev/null +++ b/queue-6.6/i2c-stm32f7-use-devm_clk_get_enabled.patch @@ -0,0 +1,121 @@ +From stable+bounces-165518-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:12 2025 +From: Sasha Levin +Date: Wed, 30 Jul 2025 09:59:58 -0400 +Subject: i2c: stm32f7: Use devm_clk_get_enabled() +To: stable@vger.kernel.org +Cc: Andi Shyti , Alain Volmat , Wolfram Sang , Sasha Levin +Message-ID: <20250730140002.3814528-1-sashal@kernel.org> + +From: Andi Shyti + +[ Upstream commit 7ba2b17a87466e1410ae0ccc94d8eb381de177c2 ] + +Replace the pair of functions, devm_clk_get() and +clk_prepare_enable(), with a single function +devm_clk_get_enabled(). + +Signed-off-by: Andi Shyti +Acked-by: Alain Volmat +Signed-off-by: Wolfram Sang +Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/busses/i2c-stm32f7.c | 37 ++++++++++++------------------------- + 1 file changed, 12 insertions(+), 25 deletions(-) + +--- a/drivers/i2c/busses/i2c-stm32f7.c ++++ b/drivers/i2c/busses/i2c-stm32f7.c +@@ -2177,23 +2177,16 @@ static int stm32f7_i2c_probe(struct plat + i2c_dev->wakeup_src = of_property_read_bool(pdev->dev.of_node, + "wakeup-source"); + +- i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); ++ i2c_dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(i2c_dev->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->clk), +- "Failed to get controller clock\n"); +- +- ret = clk_prepare_enable(i2c_dev->clk); +- if (ret) { +- dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); +- return ret; +- } ++ "Failed to enable controller clock\n"); + + rst = devm_reset_control_get(&pdev->dev, NULL); +- if (IS_ERR(rst)) { +- ret = dev_err_probe(&pdev->dev, PTR_ERR(rst), +- "Error: Missing reset ctrl\n"); +- goto clk_free; +- } ++ if (IS_ERR(rst)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(rst), ++ "Error: Missing reset ctrl\n"); ++ + reset_control_assert(rst); + udelay(2); + reset_control_deassert(rst); +@@ -2208,7 +2201,7 @@ static int stm32f7_i2c_probe(struct plat + if (ret) { + dev_err(&pdev->dev, "Failed to request irq event %i\n", + irq_event); +- goto clk_free; ++ return ret; + } + + ret = devm_request_irq(&pdev->dev, irq_error, stm32f7_i2c_isr_error, 0, +@@ -2216,29 +2209,28 @@ static int stm32f7_i2c_probe(struct plat + if (ret) { + dev_err(&pdev->dev, "Failed to request irq error %i\n", + irq_error); +- goto clk_free; ++ return ret; + } + + setup = of_device_get_match_data(&pdev->dev); + if (!setup) { + dev_err(&pdev->dev, "Can't get device data\n"); +- ret = -ENODEV; +- goto clk_free; ++ return -ENODEV; + } + i2c_dev->setup = *setup; + + ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); + if (ret) +- goto clk_free; ++ return ret; + + /* Setup Fast mode plus if necessary */ + if (i2c_dev->bus_rate > I2C_MAX_FAST_MODE_FREQ) { + ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev); + if (ret) +- goto clk_free; ++ return ret; + ret = stm32f7_i2c_write_fm_plus_bits(i2c_dev, true); + if (ret) +- goto clk_free; ++ return ret; + } + + adap = &i2c_dev->adap; +@@ -2349,9 +2341,6 @@ clr_wakeup_capable: + fmp_clear: + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); + +-clk_free: +- clk_disable_unprepare(i2c_dev->clk); +- + return ret; + } + +@@ -2385,8 +2374,6 @@ static void stm32f7_i2c_remove(struct pl + } + + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); +- +- clk_disable_unprepare(i2c_dev->clk); + } + + static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) diff --git a/queue-6.6/sched-core-remove-ifdeffery-for-saved_state.patch b/queue-6.6/sched-core-remove-ifdeffery-for-saved_state.patch new file mode 100644 index 0000000000..4bd076c353 --- /dev/null +++ b/queue-6.6/sched-core-remove-ifdeffery-for-saved_state.patch @@ -0,0 +1,90 @@ +From fbaa6a181a4b1886cbf4214abdf9a2df68471510 Mon Sep 17 00:00:00 2001 +From: Elliot Berman +Date: Fri, 8 Sep 2023 15:49:15 -0700 +Subject: sched/core: Remove ifdeffery for saved_state + +From: Elliot Berman + +commit fbaa6a181a4b1886cbf4214abdf9a2df68471510 upstream. + +In preparation for freezer to also use saved_state, remove the +CONFIG_PREEMPT_RT compilation guard around saved_state. + +On the arm64 platform I tested which did not have CONFIG_PREEMPT_RT, +there was no statistically significant deviation by applying this patch. + +Test methodology: + +perf bench sched message -g 40 -l 40 + +Signed-off-by: Elliot Berman +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Signed-off-by: Chen Ridong +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/sched.h | 2 -- + kernel/sched/core.c | 10 ++-------- + 2 files changed, 2 insertions(+), 10 deletions(-) + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -753,10 +753,8 @@ struct task_struct { + #endif + unsigned int __state; + +-#ifdef CONFIG_PREEMPT_RT + /* saved state for "spinlock sleepers" */ + unsigned int saved_state; +-#endif + + /* + * This begins the randomizable portion of task_struct. Only +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -2238,17 +2238,15 @@ int __task_state_match(struct task_struc + if (READ_ONCE(p->__state) & state) + return 1; + +-#ifdef CONFIG_PREEMPT_RT + if (READ_ONCE(p->saved_state) & state) + return -1; +-#endif ++ + return 0; + } + + static __always_inline + int task_state_match(struct task_struct *p, unsigned int state) + { +-#ifdef CONFIG_PREEMPT_RT + int match; + + /* +@@ -2260,9 +2258,6 @@ int task_state_match(struct task_struct + raw_spin_unlock_irq(&p->pi_lock); + + return match; +-#else +- return __task_state_match(p, state); +-#endif + } + + /* +@@ -4059,7 +4054,6 @@ bool ttwu_state_match(struct task_struct + + *success = !!(match = __task_state_match(p, state)); + +-#ifdef CONFIG_PREEMPT_RT + /* + * Saved state preserves the task state across blocking on + * an RT lock. If the state matches, set p::saved_state to +@@ -4075,7 +4069,7 @@ bool ttwu_state_match(struct task_struct + */ + if (match < 0) + p->saved_state = TASK_RUNNING; +-#endif ++ + return match > 0; + } + diff --git a/queue-6.6/sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch b/queue-6.6/sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch new file mode 100644 index 0000000000..3e2d829989 --- /dev/null +++ b/queue-6.6/sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch @@ -0,0 +1,74 @@ +From 9beb8c5e77dc10e3889ff5f967eeffba78617a88 Mon Sep 17 00:00:00 2001 +From: Chen Ridong +Date: Thu, 17 Jul 2025 08:55:49 +0000 +Subject: sched,freezer: Remove unnecessary warning in __thaw_task + +From: Chen Ridong + +commit 9beb8c5e77dc10e3889ff5f967eeffba78617a88 upstream. + +Commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if not +frozen") modified the cgroup_freezing() logic to verify that the FROZEN +flag is not set, affecting the return value of the freezing() function, +in order to address a warning in __thaw_task. + +A race condition exists that may allow tasks to escape being frozen. The +following scenario demonstrates this issue: + +CPU 0 (get_signal path) CPU 1 (freezer.state reader) +try_to_freeze read freezer.state +__refrigerator freezer_read + update_if_frozen +WRITE_ONCE(current->__state, TASK_FROZEN); + ... + /* Task is now marked frozen */ + /* frozen(task) == true */ + /* Assuming other tasks are frozen */ + freezer->state |= CGROUP_FROZEN; +/* freezing(current) returns false */ +/* because cgroup is frozen (not freezing) */ +break out +__set_current_state(TASK_RUNNING); +/* Bug: Task resumes running when it should remain frozen */ + +The existing !frozen(p) check in __thaw_task makes the +WARN_ON_ONCE(freezing(p)) warning redundant. Removing this warning enables +reverting commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if +not frozen") to resolve the issue. + +This patch removes the warning from __thaw_task. A subsequent patch will +revert commit cff5f49d433f ("cgroup_freezer: cgroup_freezing: Check if +not frozen") to complete the fix. + +Reported-by: Zhong Jiawei +Signed-off-by: Chen Ridong +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/freezer.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +--- a/kernel/freezer.c ++++ b/kernel/freezer.c +@@ -196,18 +196,9 @@ static int __restore_freezer_state(struc + + void __thaw_task(struct task_struct *p) + { +- unsigned long flags; +- +- spin_lock_irqsave(&freezer_lock, flags); +- if (WARN_ON_ONCE(freezing(p))) +- goto unlock; +- +- if (!frozen(p) || task_call_func(p, __restore_freezer_state, NULL)) +- goto unlock; +- +- wake_up_state(p, TASK_FROZEN); +-unlock: +- spin_unlock_irqrestore(&freezer_lock, flags); ++ guard(spinlock_irqsave)(&freezer_lock); ++ if (frozen(p) && !task_call_func(p, __restore_freezer_state, NULL)) ++ wake_up_state(p, TASK_FROZEN); + } + + /** diff --git a/queue-6.6/series b/queue-6.6/series index b8dd6e54bb..5ec948248a 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -240,3 +240,13 @@ ksmbd-fix-corrupted-mtime-and-ctime-in-smb2_open.patch ksmbd-limit-repeated-connections-from-clients-with-the-same-ip.patch smb-server-fix-extension-string-in-ksmbd_extract_shortname.patch usb-serial-option-add-foxconn-t99w709.patch +i2c-stm32f7-use-devm_clk_get_enabled.patch +i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch +i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch +i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch +i2c-stm32f7-unmap-dma-mapped-buffer.patch +sched-core-remove-ifdeffery-for-saved_state.patch +freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch +freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch +freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch +sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch