X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=include%2Flinux%2Flockdep.h;h=498bfbd3b4e1acfdd0ba200e21e6a91c3eab2e3f;hb=4b32d0a4e9ec07808a5c406a416c6576c986b047;hp=80ec7a4dbc989474ead6b518a490643dbdf9c3cf;hpb=fbb9ce9530fd9b66096d5187fa6a115d16d9746c;p=deliverable%2Flinux.git diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 80ec7a4dbc98..3d3386b88b6a 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -1,20 +1,24 @@ /* * Runtime locking correctness validator * - * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar + * Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar + * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra * * see Documentation/lockdep-design.txt for more details. */ #ifndef __LINUX_LOCKDEP_H #define __LINUX_LOCKDEP_H +struct task_struct; +struct lockdep_map; + +#ifdef CONFIG_LOCKDEP + #include #include #include #include -#ifdef CONFIG_LOCKDEP - /* * Lock-class usage-state bits: */ @@ -112,15 +116,39 @@ struct lock_class { const char *name; int name_version; + +#ifdef CONFIG_LOCK_STAT + unsigned long contention_point[4]; +#endif +}; + +#ifdef CONFIG_LOCK_STAT +struct lock_time { + s64 min; + s64 max; + s64 total; + unsigned long nr; +}; + +struct lock_class_stats { + unsigned long contention_point[4]; + struct lock_time read_waittime; + struct lock_time write_waittime; + struct lock_time read_holdtime; + struct lock_time write_holdtime; }; +struct lock_class_stats lock_stats(struct lock_class *class); +void clear_lock_stats(struct lock_class *class); +#endif + /* * Map the lock object (the lock instance) to the lock-class object. * This is embedded into specific lock instances: */ struct lockdep_map { struct lock_class_key *key; - struct lock_class *class[MAX_LOCKDEP_SUBCLASSES]; + struct lock_class *class_cache; const char *name; }; @@ -132,6 +160,7 @@ struct lock_list { struct list_head entry; struct lock_class *class; struct stack_trace trace; + int distance; }; /* @@ -162,6 +191,10 @@ struct held_lock { unsigned long acquire_ip; struct lockdep_map *instance; +#ifdef CONFIG_LOCK_STAT + u64 waittime_stamp; + u64 holdtime_stamp; +#endif /* * The lock-stack is unified in that the lock chains of interrupt * contexts nest ontop of process context chains, but we 'separate' @@ -193,7 +226,6 @@ extern void lockdep_free_key_range(void *start, unsigned long size); extern void lockdep_off(void); extern void lockdep_on(void); -extern int lockdep_internal(void); /* * These methods are used by specific locking variants (spinlocks, @@ -202,7 +234,7 @@ extern int lockdep_internal(void); */ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, - struct lock_class_key *key); + struct lock_class_key *key, int subclass); /* * Reinitialize a lock key - for cases where there is special locking or @@ -211,9 +243,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, * or they are too narrow (they suffer from a false class-split): */ #define lockdep_set_class(lock, key) \ - lockdep_init_map(&(lock)->dep_map, #key, key) + lockdep_init_map(&(lock)->dep_map, #key, key, 0) #define lockdep_set_class_and_name(lock, key, name) \ - lockdep_init_map(&(lock)->dep_map, name, key) + lockdep_init_map(&(lock)->dep_map, name, key, 0) +#define lockdep_set_class_and_subclass(lock, key, sub) \ + lockdep_init_map(&(lock)->dep_map, #key, key, sub) +#define lockdep_set_subclass(lock, sub) \ + lockdep_init_map(&(lock)->dep_map, #lock, \ + (lock)->dep_map.key, sub) /* * Acquire a lock. @@ -238,6 +275,8 @@ extern void lock_release(struct lockdep_map *lock, int nested, # define INIT_LOCKDEP .lockdep_recursion = 0, +#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) + #else /* !LOCKDEP */ static inline void lockdep_off(void) @@ -248,19 +287,18 @@ static inline void lockdep_on(void) { } -static inline int lockdep_internal(void) -{ - return 0; -} - # define lock_acquire(l, s, t, r, c, i) do { } while (0) # define lock_release(l, n, i) do { } while (0) # define lockdep_init() do { } while (0) # define lockdep_info() do { } while (0) -# define lockdep_init_map(lock, name, key) do { (void)(key); } while (0) +# define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0) # define lockdep_set_class(lock, key) do { (void)(key); } while (0) # define lockdep_set_class_and_name(lock, key, name) \ do { (void)(key); } while (0) +#define lockdep_set_class_and_subclass(lock, key, sub) \ + do { (void)(key); } while (0) +#define lockdep_set_subclass(lock, sub) do { } while (0) + # define INIT_LOCKDEP # define lockdep_reset() do { debug_locks = 1; } while (0) # define lockdep_free_key_range(start, size) do { } while (0) @@ -268,14 +306,57 @@ static inline int lockdep_internal(void) * The class key takes no space if lockdep is disabled: */ struct lock_class_key { }; + +#define lockdep_depth(tsk) (0) + #endif /* !LOCKDEP */ +#ifdef CONFIG_LOCK_STAT + +extern void lock_contended(struct lockdep_map *lock, unsigned long ip); +extern void lock_acquired(struct lockdep_map *lock); + +#define LOCK_CONTENDED(_lock, try, lock) \ +do { \ + if (!try(_lock)) { \ + lock_contended(&(_lock)->dep_map, _RET_IP_); \ + lock(_lock); \ + lock_acquired(&(_lock)->dep_map); \ + } \ +} while (0) + +#else /* CONFIG_LOCK_STAT */ + +#define lock_contended(lockdep_map, ip) do {} while (0) +#define lock_acquired(lockdep_map) do {} while (0) + +#define LOCK_CONTENDED(_lock, try, lock) \ + lock(_lock) + +#endif /* CONFIG_LOCK_STAT */ + +#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS) +extern void early_init_irq_lock_class(void); +#else +static inline void early_init_irq_lock_class(void) +{ +} +#endif + #ifdef CONFIG_TRACE_IRQFLAGS extern void early_boot_irqs_off(void); extern void early_boot_irqs_on(void); +extern void print_irqtrace_events(struct task_struct *curr); #else -# define early_boot_irqs_off() do { } while (0) -# define early_boot_irqs_on() do { } while (0) +static inline void early_boot_irqs_off(void) +{ +} +static inline void early_boot_irqs_on(void) +{ +} +static inline void print_irqtrace_events(struct task_struct *curr) +{ +} #endif /*