• Rafael J. Wysocki's avatar
    PM / Wakeup: Combine atomic counters to avoid reordering issues · 023d3779
    Rafael J. Wysocki authored
    The memory barrier in wakeup_source_deactivate() is supposed to
    prevent the callers of pm_wakeup_pending() and pm_get_wakeup_count()
    from seeing the new value of events_in_progress (0, in particular)
    and the old value of event_count at the same time.  However, if
    wakeup_source_deactivate() is executed by CPU0 and, for instance,
    pm_wakeup_pending() is executed by CPU1, where both processors can
    reorder operations, the memory barrier in wakeup_source_deactivate()
    doesn't affect CPU1 which can reorder reads.  In that case CPU1 may
    very well decide to fetch event_count before it's modified and
    events_in_progress after it's been updated, so pm_wakeup_pending()
    may fail to detect a wakeup event.  This issue can be addressed by
    using a single atomic variable to store both events_in_progress
    and event_count, so that they can be updated together in a single
    atomic operation.
    Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
    023d3779
wakeup.c 19 KB