lkml.org 
[lkml]   [2006]   [Nov]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [patch] cpufreq: mark cpufreq_tsc() as core_initcall_sync


    On Thu, 16 Nov 2006, Thomas Gleixner wrote:
    >
    > Here is the i386/sparc fixup

    Gag me with a volvo.

    This is disgusting, but I would actually prefer the following version over
    the patches I've seen, because

    - it doesn't end up having any architecture-specific parts

    - it doesn't use the new "xxx_sync()" thing that I'm not even sure we
    should be using.

    - it makes it clear that this should be fixed, preferably by just having
    some way to initialize SRCU structs staticalyl. If we get that, the fix
    is to just replace the horrible "initialize by hand" with a static
    initializer once and for all.

    Hmm?

    Totally untested, but it compiles and it _looks_ sane. The overhead of the
    function call should be minimal, once things are initialized.

    Paul, it would be _really_ nice to have some way to just initialize that
    SRCU thing statically. This kind of crud is just crazy.

    Comments?

    Linus

    ----
    diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
    index 86e69b7..02326b2 100644
    --- a/drivers/cpufreq/cpufreq.c
    +++ b/drivers/cpufreq/cpufreq.c
    @@ -52,14 +52,39 @@ static void handle_update(void *data);
    * The mutex locks both lists.
    */
    static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
    -static struct srcu_notifier_head cpufreq_transition_notifier_list;

    -static int __init init_cpufreq_transition_notifier_list(void)
    +/*
    + * This is horribly horribly ugly.
    + *
    + * We really want to initialize the transition notifier list
    + * statically and just once, but there is no static way to
    + * initialize a srcu lock, so we instead make up all this nasty
    + * infrastructure to make sure it's initialized when we use it.
    + *
    + * Bleaargh.
    + */
    +static struct srcu_notifier_head *cpufreq_transition_notifier_list(void)
    {
    - srcu_init_notifier_head(&cpufreq_transition_notifier_list);
    - return 0;
    + static struct srcu_notifier_head *initialized;
    + struct srcu_notifier_head *ret;
    +
    + ret = initialized;
    + if (!ret) {
    + static DEFINE_MUTEX(init_lock);
    +
    + mutex_lock(&init_lock);
    + ret = initialized;
    + if (!ret) {
    + static struct srcu_notifier_head list_head;
    + ret = &list_head;
    + srcu_init_notifier_head(ret);
    + smp_wmb();
    + initialized = ret;
    + }
    + mutex_unlock(&init_lock);
    + }
    + return ret;
    }
    -core_initcall(init_cpufreq_transition_notifier_list);

    static LIST_HEAD(cpufreq_governor_list);
    static DEFINE_MUTEX (cpufreq_governor_mutex);
    @@ -268,14 +293,14 @@ void cpufreq_notify_transition(struct cp
    freqs->old = policy->cur;
    }
    }
    - srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
    + srcu_notifier_call_chain(cpufreq_transition_notifier_list(),
    CPUFREQ_PRECHANGE, freqs);
    adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
    break;

    case CPUFREQ_POSTCHANGE:
    adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
    - srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
    + srcu_notifier_call_chain(cpufreq_transition_notifier_list(),
    CPUFREQ_POSTCHANGE, freqs);
    if (likely(policy) && likely(policy->cpu == freqs->cpu))
    policy->cur = freqs->new;
    @@ -1055,7 +1080,7 @@ static int cpufreq_suspend(struct sys_de
    freqs.old = cpu_policy->cur;
    freqs.new = cur_freq;

    - srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
    + srcu_notifier_call_chain(cpufreq_transition_notifier_list(),
    CPUFREQ_SUSPENDCHANGE, &freqs);
    adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);

    @@ -1137,7 +1162,7 @@ static int cpufreq_resume(struct sys_dev
    freqs.new = cur_freq;

    srcu_notifier_call_chain(
    - &cpufreq_transition_notifier_list,
    + cpufreq_transition_notifier_list(),
    CPUFREQ_RESUMECHANGE, &freqs);
    adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);

    @@ -1183,7 +1208,7 @@ int cpufreq_register_notifier(struct not
    switch (list) {
    case CPUFREQ_TRANSITION_NOTIFIER:
    ret = srcu_notifier_chain_register(
    - &cpufreq_transition_notifier_list, nb);
    + cpufreq_transition_notifier_list(), nb);
    break;
    case CPUFREQ_POLICY_NOTIFIER:
    ret = blocking_notifier_chain_register(
    @@ -1215,7 +1240,7 @@ int cpufreq_unregister_notifier(struct n
    switch (list) {
    case CPUFREQ_TRANSITION_NOTIFIER:
    ret = srcu_notifier_chain_unregister(
    - &cpufreq_transition_notifier_list, nb);
    + cpufreq_transition_notifier_list(), nb);
    break;
    case CPUFREQ_POLICY_NOTIFIER:
    ret = blocking_notifier_chain_unregister(
    -
    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: 2009-11-18 23:46    [W:0.053 / U:0.824 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site