Skip to content

Commit e0e398e

Browse files
committed
PM: runtime: Drop runtime PM references to supplier on link removal
While removing a device link, drop the supplier device's runtime PM usage counter as many times as needed to drop all of the runtime PM references to it from the consumer in addition to dropping the consumer's link count. Fixes: baa8809 ("PM / runtime: Optimize the use of device links") Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: 5.1+ <stable@vger.kernel.org> # 5.1+ Tested-by: Xiang Chen <chenxiang66@hisilicon.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 3cea11c commit e0e398e

3 files changed

Lines changed: 24 additions & 7 deletions

File tree

drivers/base/core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,7 @@ static void __device_link_del(struct kref *kref)
773773
dev_dbg(link->consumer, "Dropping the link to %s\n",
774774
dev_name(link->supplier));
775775

776-
if (link->flags & DL_FLAG_PM_RUNTIME)
777-
pm_runtime_drop_link(link->consumer);
776+
pm_runtime_drop_link(link);
778777

779778
list_del_rcu(&link->s_node);
780779
list_del_rcu(&link->c_node);
@@ -788,8 +787,7 @@ static void __device_link_del(struct kref *kref)
788787
dev_info(link->consumer, "Dropping the link to %s\n",
789788
dev_name(link->supplier));
790789

791-
if (link->flags & DL_FLAG_PM_RUNTIME)
792-
pm_runtime_drop_link(link->consumer);
790+
pm_runtime_drop_link(link);
793791

794792
list_del(&link->s_node);
795793
list_del(&link->c_node);

drivers/base/power/runtime.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1729,14 +1729,33 @@ void pm_runtime_new_link(struct device *dev)
17291729
spin_unlock_irq(&dev->power.lock);
17301730
}
17311731

1732-
void pm_runtime_drop_link(struct device *dev)
1732+
static void pm_runtime_drop_link_count(struct device *dev)
17331733
{
17341734
spin_lock_irq(&dev->power.lock);
17351735
WARN_ON(dev->power.links_count == 0);
17361736
dev->power.links_count--;
17371737
spin_unlock_irq(&dev->power.lock);
17381738
}
17391739

1740+
/**
1741+
* pm_runtime_drop_link - Prepare for device link removal.
1742+
* @link: Device link going away.
1743+
*
1744+
* Drop the link count of the consumer end of @link and decrement the supplier
1745+
* device's runtime PM usage counter as many times as needed to drop all of the
1746+
* PM runtime reference to it from the consumer.
1747+
*/
1748+
void pm_runtime_drop_link(struct device_link *link)
1749+
{
1750+
if (!(link->flags & DL_FLAG_PM_RUNTIME))
1751+
return;
1752+
1753+
pm_runtime_drop_link_count(link->consumer);
1754+
1755+
while (refcount_dec_not_one(&link->rpm_active))
1756+
pm_runtime_put(link->supplier);
1757+
}
1758+
17401759
static bool pm_runtime_need_not_resume(struct device *dev)
17411760
{
17421761
return atomic_read(&dev->power.usage_count) <= 1 &&

include/linux/pm_runtime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern void pm_runtime_clean_up_links(struct device *dev);
5858
extern void pm_runtime_get_suppliers(struct device *dev);
5959
extern void pm_runtime_put_suppliers(struct device *dev);
6060
extern void pm_runtime_new_link(struct device *dev);
61-
extern void pm_runtime_drop_link(struct device *dev);
61+
extern void pm_runtime_drop_link(struct device_link *link);
6262

6363
/**
6464
* pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage counter.
@@ -280,7 +280,7 @@ static inline void pm_runtime_clean_up_links(struct device *dev) {}
280280
static inline void pm_runtime_get_suppliers(struct device *dev) {}
281281
static inline void pm_runtime_put_suppliers(struct device *dev) {}
282282
static inline void pm_runtime_new_link(struct device *dev) {}
283-
static inline void pm_runtime_drop_link(struct device *dev) {}
283+
static inline void pm_runtime_drop_link(struct device_link *link) {}
284284

285285
#endif /* !CONFIG_PM */
286286

0 commit comments

Comments
 (0)