[RFC] hrtimer: add lockdep annotation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a lame copy of lockdep map in timer.

Only for thoughts now.

Hillf

--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -124,6 +124,9 @@ struct hrtimer {
 	u8				is_rel;
 	u8				is_soft;
 	u8				is_hard;
+#ifdef CONFIG_LOCKDEP
+	struct lockdep_map		lockdep_map;
+#endif
 };
 
 /**
@@ -369,10 +372,34 @@ static inline void hrtimer_cancel_wait_r
 /* Exported timer functions: */
 
 /* Initialize timers: */
-extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,
-			 enum hrtimer_mode mode);
-extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id,
-				 enum hrtimer_mode mode);
+extern void hrtimer_init_key(struct hrtimer *timer, clockid_t which_clock,
+				 enum hrtimer_mode mode,
+		    const char *name, struct lock_class_key *key);
+extern void hrtimer_init_sleeper_key(struct hrtimer_sleeper *sl, clockid_t clock_id,
+				 enum hrtimer_mode mode,
+		    const char *name, struct lock_class_key *key);
+
+#ifdef CONFIG_LOCKDEP
+#define hrtimer_init(t, c, m)				\
+	do {	static struct lock_class_key __k;	\
+		hrtimer_init_key(t, c, m, #t, &__k);	\
+	} while (0)
+
+#define hrtimer_init_sleeper(s, c, m)				\
+	do {	static struct lock_class_key __k;		\
+		hrtimer_init_sleeper_key(s, c, m, #s, &__k);	\
+	} while (0)
+#else
+#define hrtimer_init(t, c, m)				\
+	do {						\
+		hrtimer_init_key(t, c, m, NULL, NULL);	\
+	} while (0)
+
+#define hrtimer_init_sleeper(s, c, m)				\
+	do {							\
+		hrtimer_init_sleeper_key(s, c, m, NULL, NULL);	\
+	} while (0)
+#endif
 
 #ifdef CONFIG_DEBUG_OBJECTS_TIMERS
 extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock,
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1439,6 +1439,8 @@ int hrtimer_cancel(struct hrtimer *timer
 {
 	int ret;
 
+	lock_map_acquire(&timer->lockdep_map);
+	lock_map_release(&timer->lockdep_map);
 	do {
 		ret = hrtimer_try_to_cancel(timer);
 
@@ -1575,7 +1577,7 @@ static void __hrtimer_init(struct hrtime
 }
 
 /**
- * hrtimer_init - initialize a timer to the given clock
+ * hrtimer_init_key - initialize a timer to the given clock
  * @timer:	the timer to be initialized
  * @clock_id:	the clock to be used
  * @mode:       The modes which are relevant for initialization:
@@ -1586,13 +1588,14 @@ static void __hrtimer_init(struct hrtime
  *              but the PINNED bit is ignored as pinning happens
  *              when the hrtimer is started
  */
-void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
-		  enum hrtimer_mode mode)
+void hrtimer_init_key(struct hrtimer *timer, clockid_t clock_id,
+			enum hrtimer_mode mode,
+			const char *name, struct lock_class_key *key)
 {
 	debug_init(timer, clock_id, mode);
 	__hrtimer_init(timer, clock_id, mode);
+	lockdep_init_map(&timer->lockdep_map, name, key, 0);
 }
-EXPORT_SYMBOL_GPL(hrtimer_init);
 
 /*
  * A timer is active, when it is enqueued into the rbtree or the
@@ -1647,6 +1650,11 @@ static void __run_hrtimer(struct hrtimer
 	enum hrtimer_restart (*fn)(struct hrtimer *);
 	bool expires_in_hardirq;
 	int restart;
+#ifdef CONFIG_LOCKDEP
+	struct lockdep_map lockdep_map;
+
+	lockdep_copy_map(&lockdep_map, &timer->lockdep_map);
+#endif
 
 	lockdep_assert_held(&cpu_base->lock);
 
@@ -1681,9 +1689,11 @@ static void __run_hrtimer(struct hrtimer
 	raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
 	trace_hrtimer_expire_entry(timer, now);
 	expires_in_hardirq = lockdep_hrtimer_enter(timer);
+	lock_map_acquire(&lockdep_map);
 
 	restart = fn(timer);
 
+	lock_map_release(&lockdep_map);
 	lockdep_hrtimer_exit(expires_in_hardirq);
 	trace_hrtimer_expire_exit(timer);
 	raw_spin_lock_irq(&cpu_base->lock);
@@ -1999,19 +2009,19 @@ static void __hrtimer_init_sleeper(struc
 }
 
 /**
- * hrtimer_init_sleeper - initialize sleeper to the given clock
+ * hrtimer_init_sleeper_key - initialize sleeper to the given clock
  * @sl:		sleeper to be initialized
  * @clock_id:	the clock to be used
  * @mode:	timer mode abs/rel
  */
-void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id,
-			  enum hrtimer_mode mode)
+void hrtimer_init_sleeper_key(struct hrtimer_sleeper *sl, clockid_t clock_id,
+				enum hrtimer_mode mode,
+				const char *name, struct lock_class_key *key)
 {
 	debug_init(&sl->timer, clock_id, mode);
 	__hrtimer_init_sleeper(sl, clock_id, mode);
-
+	lockdep_init_map(&sl->timer.lockdep_map, name, key, 0);
 }
-EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
 
 int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts)
 {




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux