lkml.org 
[lkml]   [2008]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 42/71] clockevents: prevent multiple init/shutdown
    2.6.26-stable review patch.  If anyone has any objections, please let us
    know.

    ------------------
    From: Thomas Gleixner <tglx@linutronix.de>

    commit 9c17bcda991000351cb2373f78be7e4b1c44caa3 upstream

    While chasing the C1E/HPET bugreports I went through the clock events
    code inch by inch and found that the broadcast device can be initialized
    and shutdown multiple times. Multiple shutdowns are not critical, but
    useless waste of time. Multiple initializations are simply broken. Another
    CPU might have the device in use already after the first initialization and
    the second init could just render it unusable again.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    kernel/time/tick-broadcast.c | 20 +++++++++++++-------
    1 file changed, 13 insertions(+), 7 deletions(-)

    --- a/kernel/time/tick-broadcast.c
    +++ b/kernel/time/tick-broadcast.c
    @@ -209,7 +209,7 @@ static void tick_do_broadcast_on_off(voi
    struct clock_event_device *bc, *dev;
    struct tick_device *td;
    unsigned long flags, *reason = why;
    - int cpu;
    + int cpu, bc_stopped;

    spin_lock_irqsave(&tick_broadcast_lock, flags);

    @@ -227,6 +227,8 @@ static void tick_do_broadcast_on_off(voi
    if (!tick_device_is_functional(dev))
    goto out;

    + bc_stopped = cpus_empty(tick_broadcast_mask);
    +
    switch (*reason) {
    case CLOCK_EVT_NOTIFY_BROADCAST_ON:
    case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
    @@ -248,9 +250,10 @@ static void tick_do_broadcast_on_off(voi
    break;
    }

    - if (cpus_empty(tick_broadcast_mask))
    - clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
    - else {
    + if (cpus_empty(tick_broadcast_mask)) {
    + if (!bc_stopped)
    + clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
    + } else if (bc_stopped) {
    if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
    tick_broadcast_start_periodic(bc);
    else
    @@ -500,9 +503,12 @@ static void tick_broadcast_clear_oneshot
    */
    void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
    {
    - bc->event_handler = tick_handle_oneshot_broadcast;
    - clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
    - bc->next_event.tv64 = KTIME_MAX;
    + /* Set it up only once ! */
    + if (bc->event_handler != tick_handle_oneshot_broadcast) {
    + bc->event_handler = tick_handle_oneshot_broadcast;
    + clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
    + bc->next_event.tv64 = KTIME_MAX;
    + }
    }

    /*
    --


    \
     
     \ /
      Last update: 2008-10-07 02:59    [W:0.024 / U:93.768 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site