lkml.org 
[lkml]   [2007]   [Mar]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: [5/6] 2.6.21-rc2: known regressions
    From
    Date
    On Mon, 2007-03-05 at 15:45 -0800, Linus Torvalds wrote:
    >
    > On Tue, 6 Mar 2007, Thomas Gleixner wrote:
    > > >
    > > > Subject : macbook pro suspend to ram broken (clockevents)
    > > > References : http://lkml.org/lkml/2007/3/4/110
    > > > Submitter : Soeren Sonnenburg <kernel@nn7.de>
    > > > Caused-By : Thomas Gleixner <tglx@linutronix.de>
    > > > commit e9e2cdb412412326c4827fc78ba27f410d837e6e
    > > > Status : unknown
    > >
    > > I can reproduce this on my dual core VAIO. There are some issues:
    >
    > Yeah, I think I can too, on my dual-core Mac Mini.
    >
    > I'm not done with my bisection, but e9e2cdb4 is among the 28 commits left,
    > so I'm pretty sure I'm hitting the same bug. I'll do a few more bootups to
    > be 100% sure.

    I just got the resume fix cleaned up. The suspend / resume thing was
    dropped unintentionally during the -mm code reshuffling.

    It still needs the broadcast fix though.

    Does this make the problem go away ?

    tglx

    diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
    index 12b3efe..5567745 100644
    --- a/kernel/time/tick-broadcast.c
    +++ b/kernel/time/tick-broadcast.c
    @@ -284,6 +284,42 @@ void tick_shutdown_broadcast(unsigned int *cpup)
    spin_unlock_irqrestore(&tick_broadcast_lock, flags);
    }

    +void tick_suspend_broadcast(void)
    +{
    + struct clock_event_device *bc;
    + unsigned long flags;
    +
    + spin_lock_irqsave(&tick_broadcast_lock, flags);
    +
    + bc = tick_broadcast_device.evtdev;
    + if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
    + clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
    +
    + spin_unlock_irqrestore(&tick_broadcast_lock, flags);
    +}
    +
    +int tick_resume_broadcast(void)
    +{
    + struct clock_event_device *bc;
    + unsigned long flags;
    + int broadcast = 0;
    +
    + spin_lock_irqsave(&tick_broadcast_lock, flags);
    +
    + bc = tick_broadcast_device.evtdev;
    + if (bc) {
    + if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC &&
    + !cpus_empty(tick_broadcast_mask))
    + tick_broadcast_start_periodic(bc);
    +
    + broadcast = cpu_isset(smp_processor_id(), tick_broadcast_mask);
    + }
    + spin_unlock_irqrestore(&tick_broadcast_lock, flags);
    +
    + return broadcast;
    +}
    +
    +
    #ifdef CONFIG_TICK_ONESHOT

    static cpumask_t tick_broadcast_oneshot_mask;
    diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
    index 0986a2b..43ba1bd 100644
    --- a/kernel/time/tick-common.c
    +++ b/kernel/time/tick-common.c
    @@ -298,6 +298,28 @@ static void tick_shutdown(unsigned int *cpup)
    spin_unlock_irqrestore(&tick_device_lock, flags);
    }

    +static void tick_suspend_periodic(void)
    +{
    + struct tick_device *td = &__get_cpu_var(tick_cpu_device);
    + unsigned long flags;
    +
    + spin_lock_irqsave(&tick_device_lock, flags);
    + if (td->mode == TICKDEV_MODE_PERIODIC)
    + clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
    + spin_unlock_irqrestore(&tick_device_lock, flags);
    +}
    +
    +static void tick_resume_periodic(void)
    +{
    + struct tick_device *td = &__get_cpu_var(tick_cpu_device);
    + unsigned long flags;
    +
    + spin_lock_irqsave(&tick_device_lock, flags);
    + if (td->mode == TICKDEV_MODE_PERIODIC)
    + tick_setup_periodic(td->evtdev, 0);
    + spin_unlock_irqrestore(&tick_device_lock, flags);
    +}
    +
    /*
    * Notification about clock event devices
    */
    @@ -325,6 +347,16 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
    tick_shutdown(dev);
    break;

    + case CLOCK_EVT_NOTIFY_SUSPEND:
    + tick_suspend_periodic();
    + tick_suspend_broadcast();
    + break;
    +
    + case CLOCK_EVT_NOTIFY_RESUME:
    + if (!tick_resume_broadcast())
    + tick_resume_periodic();
    + break;
    +
    default:
    break;
    }
    diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
    index 54861a0..75890ef 100644
    --- a/kernel/time/tick-internal.h
    +++ b/kernel/time/tick-internal.h
    @@ -67,6 +67,8 @@ extern int tick_check_broadcast_device(struct clock_event_device *dev);
    extern int tick_is_broadcast_device(struct clock_event_device *dev);
    extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
    extern void tick_shutdown_broadcast(unsigned int *cpup);
    +extern void tick_suspend_broadcast(void);
    +extern int tick_resume_broadcast(void);

    extern void
    tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
    @@ -90,6 +92,8 @@ static inline int tick_device_uses_broadcast(struct clock_event_device *dev,
    static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
    static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
    static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
    +static inline void tick_suspend_broadcast(void) { }
    +static inline int tick_resume_broadcast(void) { return 0; }

    /*
    * Set the periodic handler in non broadcast mode
    diff --git a/kernel/timer.c b/kernel/timer.c
    index 6663a87..718437f 100644
    --- a/kernel/timer.c
    +++ b/kernel/timer.c
    @@ -997,6 +997,9 @@ static int timekeeping_resume(struct sys_device *dev)
    write_sequnlock_irqrestore(&xtime_lock, flags);

    touch_softlockup_watchdog();
    +
    + clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
    +
    /* Resume hrtimers */
    clock_was_set();

    @@ -1011,6 +1014,9 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
    timekeeping_suspended = 1;
    timekeeping_suspend_time = read_persistent_clock();
    write_sequnlock_irqrestore(&xtime_lock, flags);
    +
    + clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
    +
    return 0;
    }


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-03-06 01:23    [W:0.031 / U:91.624 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site