lkml.org 
[lkml]   [2006]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 06/19] ACPI: Keep track of timer broadcast
    From: Thomas Gleixner <tglx@linutronix.de>

    This is a preperatory patch for highres/dyntick:

    - replace the big #ifdef ARCH_APICTIMER_STOPS_ON_C3 hackery by
    functions
    - remove the double switch in the power verify function
    (in the worst case we switched ipi to apic and 20usec later
    apic to ipi)
    - keep track of the the state which stops local APIC timer

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

    diff -puN drivers/acpi/processor_idle.c~acpi-keep-track-of-timer-broadcast drivers/acpi/processor_idle.c
    --- a/drivers/acpi/processor_idle.c~acpi-keep-track-of-timer-broadcast
    +++ a/drivers/acpi/processor_idle.c
    @@ -246,6 +246,49 @@ static void acpi_cstate_enter(struct acp
    }
    }

    +#ifdef ARCH_APICTIMER_STOPS_ON_C3
    +
    +/*
    + * Some BIOS implementations switch to C3 in the published C2 state. This seems
    + * to be a common problem on AMD boxen.
    + */
    +static void acpi_timer_check_state(int state, struct acpi_processor *pr,
    + struct acpi_processor_cx *cx)
    +{
    + struct acpi_processor_power *pwr = &pr->power;
    +
    + /*
    + * Check, if one of the previous states already marked the lapic
    + * unstable
    + */
    + if (pwr->timer_broadcast_on_state < state)
    + return;
    +
    + if(cx->type == ACPI_STATE_C3 ||
    + boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
    + pr->power.timer_broadcast_on_state = state;
    + return;
    + }
    +}
    +
    +static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
    +{
    + cpumask_t mask = cpumask_of_cpu(pr->id);
    +
    + if (pr->power.timer_broadcast_on_state < INT_MAX)
    + on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
    + else
    + on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
    +}
    +
    +#else
    +
    +static void acpi_timer_check_state(int state, struct acpi_processor *pr,
    + struct acpi_processor_cx *cstate) { }
    +static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
    +
    +#endif
    +
    static void acpi_processor_idle(void)
    {
    struct acpi_processor *pr = NULL;
    @@ -912,11 +955,7 @@ static int acpi_processor_power_verify(s
    unsigned int i;
    unsigned int working = 0;

    -#ifdef ARCH_APICTIMER_STOPS_ON_C3
    - int timer_broadcast = 0;
    - cpumask_t mask = cpumask_of_cpu(pr->id);
    - on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
    -#endif
    + pr->power.timer_broadcast_on_state = INT_MAX;

    for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
    struct acpi_processor_cx *cx = &pr->power.states[i];
    @@ -928,21 +967,14 @@ static int acpi_processor_power_verify(s

    case ACPI_STATE_C2:
    acpi_processor_power_verify_c2(cx);
    -#ifdef ARCH_APICTIMER_STOPS_ON_C3
    - /* Some AMD systems fake C3 as C2, but still
    - have timer troubles */
    - if (cx->valid &&
    - boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
    - timer_broadcast++;
    -#endif
    + if (cx->valid)
    + acpi_timer_check_state(i, pr, cx);
    break;

    case ACPI_STATE_C3:
    acpi_processor_power_verify_c3(pr, cx);
    -#ifdef ARCH_APICTIMER_STOPS_ON_C3
    if (cx->valid)
    - timer_broadcast++;
    -#endif
    + acpi_timer_check_state(i, pr, cx);
    break;
    }

    @@ -950,10 +982,7 @@ static int acpi_processor_power_verify(s
    working++;
    }

    -#ifdef ARCH_APICTIMER_STOPS_ON_C3
    - if (timer_broadcast)
    - on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
    -#endif
    + acpi_propagate_timer_broadcast(pr);

    return (working);
    }
    diff -puN include/acpi/processor.h~acpi-keep-track-of-timer-broadcast include/acpi/processor.h
    --- a/include/acpi/processor.h~acpi-keep-track-of-timer-broadcast
    +++ a/include/acpi/processor.h
    @@ -79,6 +79,7 @@ struct acpi_processor_power {
    u32 bm_activity;
    int count;
    struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
    + int timer_broadcast_on_state;
    };

    /* Performance Management */
    _
    --

    -
    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: 2006-11-10 00:49    [W:0.024 / U:1.144 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site