Re: [PATCH] RCU: don't turn off lockdep when find suspicious rcu_dereference_check() usage

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Paul E. McKenney
Date: Tuesday, April 20, 2010 - 6:52 am

On Tue, Apr 20, 2010 at 08:45:28AM -0400, Miles Lane wrote:

I will be sending a patchset out later today after testing, but
please see below for a sneak preview collapsed into a single patch.

							Thanx, Paul


diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 07db2fe..ec9ab49 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -190,6 +190,15 @@ static inline int rcu_read_lock_sched_held(void)
 
 #ifdef CONFIG_PROVE_RCU
 
+#define __do_rcu_dereference_check(c)					\
+	do {								\
+		static bool __warned;					\
+		if (debug_lockdep_rcu_enabled() && !__warned && !(c)) {	\
+			__warned = true;				\
+			lockdep_rcu_dereference(__FILE__, __LINE__);	\
+		}							\
+	} while (0)
+
 /**
  * rcu_dereference_check - rcu_dereference with debug checking
  * @p: The pointer to read, prior to dereferencing
@@ -219,8 +228,7 @@ static inline int rcu_read_lock_sched_held(void)
  */
 #define rcu_dereference_check(p, c) \
 	({ \
-		if (debug_lockdep_rcu_enabled() && !(c)) \
-			lockdep_rcu_dereference(__FILE__, __LINE__); \
+		__do_rcu_dereference_check(c); \
 		rcu_dereference_raw(p); \
 	})
 
@@ -237,8 +245,7 @@ static inline int rcu_read_lock_sched_held(void)
  */
 #define rcu_dereference_protected(p, c) \
 	({ \
-		if (debug_lockdep_rcu_enabled() && !(c)) \
-			lockdep_rcu_dereference(__FILE__, __LINE__); \
+		__do_rcu_dereference_check(c); \
 		(p); \
 	})
 
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index da5e139..e5c0244 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -205,9 +205,12 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
 	 * No lock is needed, since the task isn't on tasklist yet,
 	 * so it can't be moved to another cgroup, which means the
 	 * freezer won't be removed and will be valid during this
-	 * function call.
+	 * function call.  Nevertheless, apply RCU read-side critical
+	 * section to suppress RCU lockdep false positives.
 	 */
+	rcu_read_lock();
 	freezer = task_freezer(task);
+	rcu_read_unlock();
 
 	/*
 	 * The root cgroup is non-freezable, so we can skip the
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 2594e1c..03dd1fa 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -3801,8 +3801,6 @@ void lockdep_rcu_dereference(const char *file, const int line)
 {
 	struct task_struct *curr = current;
 
-	if (!debug_locks_off())
-		return;
 	printk("\n===================================================\n");
 	printk(  "[ INFO: suspicious rcu_dereference_check() usage. ]\n");
 	printk(  "---------------------------------------------------\n");
diff --git a/kernel/sched.c b/kernel/sched.c
index 6af210a..14c44ec 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -323,6 +323,15 @@ static inline struct task_group *task_group(struct task_struct *p)
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 {
+	/*
+	 * Strictly speaking this rcu_read_lock() is not needed since the
+	 * task_group is tied to the cgroup, which in turn can never go away
+	 * as long as there are tasks attached to it.
+	 *
+	 * However since task_group() uses task_subsys_state() which is an
+	 * rcu_dereference() user, this quiets CONFIG_PROVE_RCU.
+	 */
+	rcu_read_lock();
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
 	p->se.parent = task_group(p)->se[cpu];
@@ -332,6 +341,7 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 	p->rt.rt_rq  = task_group(p)->rt_rq[cpu];
 	p->rt.parent = task_group(p)->rt_se[cpu];
 #endif
+	rcu_read_unlock();
 }
 
 #else
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCH] RCU: don't turn off lockdep when find suspicio ..., Paul E. McKenney, (Tue Apr 20, 6:52 am)
Re: [PATCH] RCU: don't turn off lockdep when find suspicio ..., Eric W. Biederman, (Wed Apr 21, 4:26 pm)
Re: [PATCH] RCU: don't turn off lockdep when find suspicio ..., Paul E. McKenney, (Fri Apr 23, 12:42 pm)
[PATCH v2.6.34-rc5 01/12] rcu: Fix RCU lockdep splat in se ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 02/12] rcu: fix RCU lockdep splat on fr ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 03/12] rcu: leave lockdep enabled after ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 04/12] NFSv4: Fix the locking in nfs_in ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 05/12] NFS: Fix RCU issues in the NFSv4 ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 06/12] KEYS: Fix an RCU warning, Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 07/12] KEYS: Fix an RCU warning in the ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 08/12] cgroup: Fix an RCU warning in cg ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 09/12] cgroup: Fix an RCU warning in al ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 10/12] sched: Fix an RCU warning in pri ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 11/12] cgroup: Check task_lock in task_ ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
[PATCH v2.6.34-rc5 12/12] memcg: css_id() must be called u ..., Paul E. McKenney, (Fri Apr 23, 12:43 pm)
Re: [PATCH] RCU: don't turn off lockdep when find suspicio ..., Eric W. Biederman, (Mon Apr 26, 11:35 am)