Patch "PM: sleep: core: Synchronize runtime PM status of parents and children" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PM: sleep: core: Synchronize runtime PM status of parents and children

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit e3acb3160dd133197b9ae1d36d7ad2c8b3a1f1c5
Author: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
Date:   Tue Jan 28 20:24:41 2025 +0100

    PM: sleep: core: Synchronize runtime PM status of parents and children
    
    [ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
    
    Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
    resume phase") overlooked the case in which the parent of a device with
    DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
    suspended before a transition into a system-wide sleep state.  In that
    case, if the child is resumed during the subsequent transition from
    that state into the working state, its runtime PM status will be set to
    RPM_ACTIVE, but the runtime PM status of the parent will not be updated
    accordingly, even though the parent will be resumed too, because of the
    dev_pm_skip_suspend() check in device_resume_noirq().
    
    Address this problem by tracking the need to set the runtime PM status
    to RPM_ACTIVE during system-wide resume transitions for devices with
    DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
    
    Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
    Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@xxxxxxxxxxxxxxxxxxxx/
    Reported-by: Johan Hovold <johan@xxxxxxxxxx>
    Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
    Reviewed-by: Johan Hovold <johan+linaro@xxxxxxxxxx>
    Tested-by: Johan Hovold <johan+linaro@xxxxxxxxxx>
    Link: https://patch.msgid.link/12619233.O9o76ZdvQC@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fadcd0379dc2d..fd2d975de536f 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -614,13 +614,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
 	 * so change its status accordingly.
 	 *
 	 * Otherwise, the device is going to be resumed, so set its PM-runtime
-	 * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-	 * to avoid confusing drivers that don't use it.
+	 * status to "active" unless its power.set_active flag is clear, in
+	 * which case it is not necessary to update its PM-runtime status.
 	 */
-	if (skip_resume)
+	if (skip_resume) {
 		pm_runtime_set_suspended(dev);
-	else if (dev_pm_skip_suspend(dev))
+	} else if (dev->power.set_active) {
 		pm_runtime_set_active(dev);
+		dev->power.set_active = false;
+	}
 
 	if (dev->pm_domain) {
 		info = "noirq power domain ";
@@ -1170,18 +1172,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
 	return PMSG_ON;
 }
 
-static void dpm_superior_set_must_resume(struct device *dev)
+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
 {
 	struct device_link *link;
 	int idx;
 
-	if (dev->parent)
+	if (dev->parent) {
 		dev->parent->power.must_resume = true;
+		if (set_active)
+			dev->parent->power.set_active = true;
+	}
 
 	idx = device_links_read_lock();
 
-	list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
+	list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
 		link->supplier->power.must_resume = true;
+		if (set_active)
+			link->supplier->power.set_active = true;
+	}
 
 	device_links_read_unlock(idx);
 }
@@ -1257,8 +1265,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
 	      dev->power.may_skip_resume))
 		dev->power.must_resume = true;
 
-	if (dev->power.must_resume)
-		dpm_superior_set_must_resume(dev);
+	if (dev->power.must_resume) {
+		dev->power.set_active = dev->power.set_active ||
+			dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
+		dpm_superior_set_must_resume(dev, dev->power.set_active);
+	}
 
 Complete:
 	complete_all(&dev->power.completion);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 39e7a7c6016f7..c46f4b6b6241d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -655,6 +655,7 @@ struct dev_pm_info {
 	bool			no_pm_callbacks:1;	/* Owned by the PM core */
 	bool			async_in_progress:1;	/* Owned by the PM core */
 	bool			must_resume:1;		/* Owned by the PM core */
+	bool			set_active:1;		/* Owned by the PM core */
 	bool			may_skip_resume:1;	/* Set by subsystems */
 #else
 	bool			should_wakeup:1;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux