]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Aug 2025 13:26:24 +0000 (15:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Aug 2025 13:26:24 +0000 (15:26 +0200)
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

queue-6.6/freezer-sched-clean-saved_state-when-restoring-it-during-thaw.patch [new file with mode: 0644]
queue-6.6/freezer-sched-do-not-restore-saved_state-of-a-thawed-task.patch [new file with mode: 0644]
queue-6.6/freezer-sched-use-saved_state-to-reduce-some-spurious-wakeups.patch [new file with mode: 0644]
queue-6.6/i2c-stm32f7-perform-most-of-irq-job-in-threaded-handler.patch [new file with mode: 0644]
queue-6.6/i2c-stm32f7-simplify-status-messages-in-case-of-errors.patch [new file with mode: 0644]
queue-6.6/i2c-stm32f7-unmap-dma-mapped-buffer.patch [new file with mode: 0644]
queue-6.6/i2c-stm32f7-use-dev_err_probe-upon-calls-of-devm_request_irq.patch [new file with mode: 0644]
queue-6.6/i2c-stm32f7-use-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.6/sched-core-remove-ifdeffery-for-saved_state.patch [new file with mode: 0644]
queue-6.6/sched-freezer-remove-unnecessary-warning-in-__thaw_task.patch [new file with mode: 0644]
queue-6.6/series

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 (file)
index 0000000..7e126f9
--- /dev/null
@@ -0,0 +1,31 @@
+From 418146e39891ef1fb2284dee4cabbfe616cd21cf Mon Sep 17 00:00:00 2001
+From: Elliot Berman <quic_eberman@quicinc.com>
+Date: Mon, 20 Nov 2023 09:36:32 -0800
+Subject: freezer,sched: Clean saved_state when restoring it during thaw
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+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 <quic_eberman@quicinc.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231120-freezer-state-multiple-thaws-v1-2-f2e1dd7ce5a2@quicinc.com
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..c240ac7
--- /dev/null
@@ -0,0 +1,44 @@
+From 23ab79e8e469e2605beec2e3ccb40d19c68dd2e0 Mon Sep 17 00:00:00 2001
+From: Elliot Berman <quic_eberman@quicinc.com>
+Date: Mon, 20 Nov 2023 09:36:31 -0800
+Subject: freezer,sched: Do not restore saved_state of a thawed task
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+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 <quic_eberman@quicinc.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Abhijeet Dharmapurikar <quic_adharmap@quicinc.com>
+Link: https://lore.kernel.org/r/20231120-freezer-state-multiple-thaws-v1-1-f2e1dd7ce5a2@quicinc.com
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d33d343
--- /dev/null
@@ -0,0 +1,172 @@
+From 8f0eed4a78a81668bc78923ea09f51a7a663c2b0 Mon Sep 17 00:00:00 2001
+From: Elliot Berman <quic_eberman@quicinc.com>
+Date: Fri, 8 Sep 2023 15:49:16 -0700
+Subject: freezer,sched: Use saved_state to reduce some spurious wakeups
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+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 <quic_prakashv@quicinc.com>
+Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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(&current->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(&current->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 (file)
index 0000000..bf46e41
--- /dev/null
@@ -0,0 +1,212 @@
+From stable+bounces-165520-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:15 2025
+From: Sasha Levin <sashal@kernel.org>
+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 <alain.volmat@foss.st.com>, Andi Shyti <andi.shyti@kernel.org>, Wolfram Sang <wsa@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250730140002.3814528-3-sashal@kernel.org>
+
+From: Alain Volmat <alain.volmat@foss.st.com>
+
+[ 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 <alain.volmat@foss.st.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..25782b3
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-165521-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:17 2025
+From: Sasha Levin <sashal@kernel.org>
+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 <alain.volmat@foss.st.com>, Andi Shyti <andi.shyti@kernel.org>, Wolfram Sang <wsa@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250730140002.3814528-4-sashal@kernel.org>
+
+From: Alain Volmat <alain.volmat@foss.st.com>
+
+[ 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 <alain.volmat@foss.st.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5b999d1
--- /dev/null
@@ -0,0 +1,106 @@
+From stable+bounces-165522-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:19 2025
+From: Sasha Levin <sashal@kernel.org>
+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" <clement.legoffic@foss.st.com>, "Alain Volmat" <alain.volmat@foss.st.com>, "Andi Shyti" <andi.shyti@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20250730140002.3814528-5-sashal@kernel.org>
+
+From: Clément Le Goffic <clement.legoffic@foss.st.com>
+
+[ 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 <clement.legoffic@foss.st.com>
+Cc: <stable@vger.kernel.org> # v4.18+
+Acked-by: Alain Volmat <alain.volmat@foss.st.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20250704-i2c-upstream-v4-2-84a095a2c728@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d96c7a9
--- /dev/null
@@ -0,0 +1,50 @@
+From stable+bounces-165519-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:13 2025
+From: Sasha Levin <sashal@kernel.org>
+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 <alain.volmat@foss.st.com>, Wolfram Sang <wsa@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250730140002.3814528-2-sashal@kernel.org>
+
+From: Alain Volmat <alain.volmat@foss.st.com>
+
+[ Upstream commit a51e224c2f42417e95a3e1a672ade221bcd006ba ]
+
+Convert error handling upon calls of devm_request_irq functions during
+the probe of the driver.
+
+Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..9c70e4c
--- /dev/null
@@ -0,0 +1,121 @@
+From stable+bounces-165518-greg=kroah.com@vger.kernel.org Wed Jul 30 16:00:12 2025
+From: Sasha Levin <sashal@kernel.org>
+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 <andi.shyti@kernel.org>, Alain Volmat <alain.volmat@foss.st.com>, Wolfram Sang <wsa@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250730140002.3814528-1-sashal@kernel.org>
+
+From: Andi Shyti <andi.shyti@kernel.org>
+
+[ 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 <andi.shyti@kernel.org>
+Acked-by: Alain Volmat <alain.volmat@foss.st.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 6aae87fe7f18 ("i2c: stm32f7: unmap DMA mapped buffer")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4bd076c
--- /dev/null
@@ -0,0 +1,90 @@
+From fbaa6a181a4b1886cbf4214abdf9a2df68471510 Mon Sep 17 00:00:00 2001
+From: Elliot Berman <quic_eberman@quicinc.com>
+Date: Fri, 8 Sep 2023 15:49:15 -0700
+Subject: sched/core: Remove ifdeffery for saved_state
+
+From: Elliot Berman <quic_eberman@quicinc.com>
+
+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 <quic_eberman@quicinc.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3e2d829
--- /dev/null
@@ -0,0 +1,74 @@
+From 9beb8c5e77dc10e3889ff5f967eeffba78617a88 Mon Sep 17 00:00:00 2001
+From: Chen Ridong <chenridong@huawei.com>
+Date: Thu, 17 Jul 2025 08:55:49 +0000
+Subject: sched,freezer: Remove unnecessary warning in __thaw_task
+
+From: Chen Ridong <chenridong@huawei.com>
+
+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<zhongjiawei1@huawei.com>
+Signed-off-by: Chen Ridong <chenridong@huawei.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+ /**
index b8dd6e54bbe1e5542ef49a1ec768c9ac19f9c0f0..5ec948248a017f1bd8e130cff88d8d6954943385 100644 (file)
@@ -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