• Rafael J. Wysocki's avatar
    PM: runtime: Fix supplier device management during consumer probe · 88737106
    Rafael J. Wysocki authored
    Because pm_runtime_get_suppliers() bumps up the rpm_active counter
    of each device link to a supplier of the given device in addition
    to bumping up the supplier's PM-runtime usage counter, a runtime
    suspend of the consumer device may case the latter to go down to 0
    when pm_runtime_put_suppliers() is running on a remote CPU.  If that
    happens after pm_runtime_put_suppliers() has released power.lock for
    the consumer device, and a runtime resume of that device takes place
    immediately after it, before pm_runtime_put() is called for the
    supplier, that pm_runtime_put() call may cause the supplier to be
    suspended even though the consumer is active.
    
    To prevent that from happening, modify pm_runtime_get_suppliers() to
    call pm_runtime_get_sync() for the given device's suppliers without
    touching the rpm_active counters of the involved device links
    Accordingly, modify pm_runtime_put_suppliers() to call pm_runtime_put()
    for the given device's suppliers without looking at the rpm_active
    counters of the device links at hand.  [This is analogous to what
    happened before commit 4c06c4e6 ("driver core: Fix possible
    supplier PM-usage counter imbalance").]
    
    Since pm_runtime_get_suppliers() sets supplier_preactivated for each
    device link where the supplier's PM-runtime usage counter has been
    incremented and pm_runtime_put_suppliers() calls pm_runtime_put() for
    the suppliers whose device links have supplier_preactivated set, the
    PM-runtime usage counter is balanced for each supplier and this is
    independent of the runtime suspend and resume of the consumer device.
    
    However, in case a device link with DL_FLAG_PM_RUNTIME set is dropped
    during the consumer device probe, so pm_runtime_get_suppliers() bumps
    up the supplier's PM-runtime usage counter, but it cannot be dropped by
    pm_runtime_put_suppliers(), make device_link_release_fn() take care of
    that.
    
    Fixes: 4c06c4e6 ("driver core: Fix possible supplier PM-usage counter imbalance")
    Reported-by: default avatarPeter Wang <peter.wang@mediatek.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Reviewed-by: default avatarPeter Wang <peter.wang@mediatek.com>
    Cc: 5.1+ <stable@vger.kernel.org> # 5.1+
    88737106
runtime.c 52.7 KB