lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0611161342320.3349@woody.osdl.org>
Date:	Thu, 16 Nov 2006 13:47:48 -0800 (PST)
From:	Linus Torvalds <torvalds@...l.org>
To:	Thomas Gleixner <tglx@...esys.com>
cc:	Ingo Molnar <mingo@...e.hu>,
	Alan Stern <stern@...land.harvard.edu>,
	LKML <linux-kernel@...r.kernel.org>,
	john stultz <johnstul@...ibm.com>,
	David Miller <davem@...emloft.net>,
	Arjan van de Ven <arjan@...radead.org>,
	Andrew Morton <akpm@...l.org>, Andi Kleen <ak@...e.de>,
	"Paul E. McKenney" <paulmck@...ibm.com>
Subject: Re: [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@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ