diff mbox

[RFC,04/19] cpufreq: bring data structures close to their locks

Message ID 1452533760-13787-5-git-send-email-juri.lelli@arm.com
State New
Headers show

Commit Message

Juri Lelli Jan. 11, 2016, 5:35 p.m. UTC
Currently it is not easy to figure out which lock/mutex protects which data
structure. Clean things up by moving data structures and their locks/mutexs
closer; also, change comments to document relations further.

Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Juri Lelli <juri.lelli@arm.com>

---
 drivers/cpufreq/cpufreq.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

-- 
2.2.2

Comments

Viresh Kumar Jan. 12, 2016, 9:27 a.m. UTC | #1
On 11-01-16, 23:07, Peter Zijlstra wrote:
> On Mon, Jan 11, 2016 at 05:35:45PM +0000, Juri Lelli wrote:

> > +/**

> > + * Iterate over governors

> > + *

> > + * cpufreq_governor_list is protected by cpufreq_governor_mutex.

> > + */

> > +static LIST_HEAD(cpufreq_governor_list);

> > +static DEFINE_MUTEX(cpufreq_governor_mutex);

> > +#define for_each_governor(__governor)				\

> > +	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)

> 

> So you could stuff the lockdep_assert_held() you later add intididually

> into the for_each_governor macro, impossible to forget that way.


How exactly? I couldn't see how it can be done in a neat and clean
way.

-- 
viresh
Juri Lelli Jan. 12, 2016, 3:26 p.m. UTC | #2
On 12/01/16 12:36, Juri Lelli wrote:
> On 12/01/16 12:58, Peter Zijlstra wrote:

> > On Tue, Jan 12, 2016 at 11:21:25AM +0000, Juri Lelli wrote:

> > > I tried to see if something like for_each_domain() can be done, but here

> > > we use list_for_each_entry() macro. Peter, do you mean something like

> > > the following?

> > > 

> > > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c

> > > index 78b1e2f..1a847a6 100644

> > > --- a/drivers/cpufreq/cpufreq.c

> > > +++ b/drivers/cpufreq/cpufreq.c

> > > @@ -39,6 +39,7 @@

> > >  static LIST_HEAD(cpufreq_governor_list);

> > >  static DEFINE_MUTEX(cpufreq_governor_mutex);

> > >  #define for_each_governor(__governor)				\

> > > +	lockdep_assert_held(&cpufreq_governor_mutex);		\

> > >  	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)

> > 

> > That fails for things like:

> > 

> > 	if (blah)

> > 		for_each_governor(...) {

> > 		}

> > 

> > which looks like valid C -- even though our Coding Style says the if

> > should have { } on.

> > 

> > I was thinking of either open coding the for statement and adding it to

> > the first statement like:

> > 

> > 	#define for_each_governor(__g) \

> > 		for (_g = list_first_entry(&cpufreq_governor_list, typeof(*_g), governor_list, lockdep_assert_held(), \

> > 		     ..... )

> > 

> > Or use something like this:

> > 

> >   lkml.kernel.org/r/20150422154212.GE3007@worktop.Skamania.guest

> > 

> > 	#define for_each_governor(_g) \

> > 		list_for_each_entry(_g, &cpufreq_governor_list, governor_list)

> > 			if (lockdep_assert_held(..), false)

> > 				;

> > 			else

> > 

> > Which should preserve C syntax rules.

> > 

> 

> Oh, nice this! I'll try it.

> 


This second approach doesn't really play well with lockdep_assert_held
definition, right?

However, it seems I could make this work with

 #ifdef CONFIG_LOCKDEP
 #define for_each_governor(__gov)					    \
 	for (__gov = list_first_entry(&cpufreq_governor_list, 		    \
 				      typeof(*__gov), 			    \
 				      governor_list),			    \
 				WARN_ON(debug_locks &&			    \
 				!lockdep_is_held(&cpufreq_governor_mutex)); \
 	     &__gov->governor_list != (&cpufreq_governor_list);		    \
 	     __gov = list_next_entry(__gov, governor_list))
 #else /* !CONFIG_LOCKDEP */
 #define for_each_governor(__gov)					    \
 	list_for_each_entry(__gov, &cpufreq_governor_list, governor_list)
 #endif /* CONFIG_LOCKDEP */

Thanks,

- Juri
diff mbox

Patch

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 2e41356..00a00cd 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -31,7 +31,25 @@ 
 #include <linux/tick.h>
 #include <trace/events/power.h>
 
+/**
+ * Iterate over governors
+ *
+ * cpufreq_governor_list is protected by cpufreq_governor_mutex.
+ */
+static LIST_HEAD(cpufreq_governor_list);
+static DEFINE_MUTEX(cpufreq_governor_mutex);
+#define for_each_governor(__governor)				\
+	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
+
+/**
+ * The "cpufreq driver" - the arch- or hardware-dependent low
+ * level driver of CPUFreq support, and its spinlock (cpufreq_driver_lock).
+ * This lock also protects cpufreq_cpu_data array and cpufreq_policy_list.
+ */
+static struct cpufreq_driver *cpufreq_driver;
+static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
 static LIST_HEAD(cpufreq_policy_list);
+static DEFINE_RWLOCK(cpufreq_driver_lock);
 
 static inline bool policy_is_inactive(struct cpufreq_policy *policy)
 {
@@ -86,21 +104,6 @@  static struct cpufreq_policy *first_policy(bool active)
 #define for_each_inactive_policy(__policy)		\
 	for_each_suitable_policy(__policy, false)
 
-/* Iterate over governors */
-static LIST_HEAD(cpufreq_governor_list);
-#define for_each_governor(__governor)				\
-	list_for_each_entry(__governor, &cpufreq_governor_list, governor_list)
-
-/**
- * The "cpufreq driver" - the arch- or hardware-dependent low
- * level driver of CPUFreq support, and its spinlock. This lock
- * also protects the cpufreq_cpu_data array.
- */
-static struct cpufreq_driver *cpufreq_driver;
-static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
-static DEFINE_RWLOCK(cpufreq_driver_lock);
-static DEFINE_MUTEX(cpufreq_governor_mutex);
-
 /* Flag to suspend/resume CPUFreq governors */
 static bool cpufreq_suspended;