lkml.org 
[lkml]   [2012]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4/8] PM / Sleep: Use wait queue to signal "no wakeup events in progress"
    Date
    From: Rafael J. Wysocki <rjw@sisk.pl>

    The current wakeup source deactivation code doesn't do anything when
    the counter of wakeup events in progress goes down to zero, which
    requires pm_get_wakeup_count() to poll that counter periodically.
    Although this reduces the average time it takes to deactivate a
    wakeup source, it also may lead to a substantial amount of unnecessary
    polling if there are extended periods of wakeup activity. Thus it
    seems reasonable to use a wait queue for signaling the "no wakeup
    events in progress" condition and remove the polling.

    Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
    ---
    drivers/base/power/wakeup.c | 18 ++++++++++++++----
    1 file changed, 14 insertions(+), 4 deletions(-)

    Index: linux/drivers/base/power/wakeup.c
    ===================================================================
    --- linux.orig/drivers/base/power/wakeup.c
    +++ linux/drivers/base/power/wakeup.c
    @@ -17,8 +17,6 @@

    #include "power.h"

    -#define TIMEOUT 100
    -
    /*
    * If set, the suspend/hibernate code will abort transitions to a sleep state
    * if wakeup events are registered during or immediately before the transition.
    @@ -52,6 +50,8 @@ static void pm_wakeup_timer_fn(unsigned

    static LIST_HEAD(wakeup_sources);

    +static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue);
    +
    /**
    * wakeup_source_create - Create a struct wakeup_source object.
    * @name: Name of the new wakeup source.
    @@ -84,7 +84,7 @@ void wakeup_source_destroy(struct wakeup
    while (ws->active) {
    spin_unlock_irq(&ws->lock);

    - schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT));
    + schedule_timeout_interruptible(msecs_to_jiffies(100));

    spin_lock_irq(&ws->lock);
    }
    @@ -411,6 +411,7 @@ EXPORT_SYMBOL_GPL(pm_stay_awake);
    */
    static void wakeup_source_deactivate(struct wakeup_source *ws)
    {
    + unsigned int cnt, inpr;
    ktime_t duration;
    ktime_t now;

    @@ -444,6 +445,10 @@ static void wakeup_source_deactivate(str
    * couter of wakeup events in progress simultaneously.
    */
    atomic_add(MAX_IN_PROGRESS, &combined_event_count);
    +
    + split_counters(&cnt, &inpr);
    + if (!inpr)
    + wake_up_all(&wakeup_count_wait_queue);
    }

    /**
    @@ -624,14 +629,19 @@ bool pm_wakeup_pending(void)
    bool pm_get_wakeup_count(unsigned int *count)
    {
    unsigned int cnt, inpr;
    + DEFINE_WAIT(wait);

    for (;;) {
    + prepare_to_wait(&wakeup_count_wait_queue, &wait,
    + TASK_INTERRUPTIBLE);
    split_counters(&cnt, &inpr);
    if (inpr == 0 || signal_pending(current))
    break;
    pm_wakeup_update_hit_counts();
    - schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT));
    +
    + schedule();
    }
    + finish_wait(&wakeup_count_wait_queue, &wait);

    split_counters(&cnt, &inpr);
    *count = cnt;


    \
     
     \ /
      Last update: 2012-02-07 02:09    [W:0.045 / U:1.996 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site