diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-30 19:10:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-30 19:10:19 -0500 |
commit | 5f34fe1cfc1bdd8b4711bbe37421fba4ed0d1ed4 (patch) | |
tree | 85b21c8bb0e53005bd970d648ca093acfd0584a3 /kernel/lockdep.c | |
parent | eca1bf5b4fab56d2feb1572d34d59fcd92ea7df3 (diff) | |
parent | 6638101c1124c19c8a65b1645e4ecd09e0572f3e (diff) |
Merge branch 'core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (63 commits)
stacktrace: provide save_stack_trace_tsk() weak alias
rcu: provide RCU options on non-preempt architectures too
printk: fix discarding message when recursion_bug
futex: clean up futex_(un)lock_pi fault handling
"Tree RCU": scalable classic RCU implementation
futex: rename field in futex_q to clarify single waiter semantics
x86/swiotlb: add default swiotlb_arch_range_needs_mapping
x86/swiotlb: add default phys<->bus conversion
x86: unify pci iommu setup and allow swiotlb to compile for 32 bit
x86: add swiotlb allocation functions
swiotlb: consolidate swiotlb info message printing
swiotlb: support bouncing of HighMem pages
swiotlb: factor out copy to/from device
swiotlb: add arch hook to force mapping
swiotlb: allow architectures to override phys<->bus<->phys conversions
swiotlb: add comment where we handle the overflow of a dma mask on 32 bit
rcu: fix rcutorture behavior during reboot
resources: skip sanity check of busy resources
swiotlb: move some definitions to header
swiotlb: allow architectures to override swiotlb pool allocation
...
Fix up trivial conflicts in
arch/x86/kernel/Makefile
arch/x86/mm/init_32.c
include/linux/hardirq.h
as per Ingo's suggestions.
Diffstat (limited to 'kernel/lockdep.c')
-rw-r--r-- | kernel/lockdep.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 74b1878b8bb8..06b0c3568f0b 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -137,16 +137,16 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) | |||
137 | #ifdef CONFIG_LOCK_STAT | 137 | #ifdef CONFIG_LOCK_STAT |
138 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); | 138 | static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); |
139 | 139 | ||
140 | static int lock_contention_point(struct lock_class *class, unsigned long ip) | 140 | static int lock_point(unsigned long points[], unsigned long ip) |
141 | { | 141 | { |
142 | int i; | 142 | int i; |
143 | 143 | ||
144 | for (i = 0; i < ARRAY_SIZE(class->contention_point); i++) { | 144 | for (i = 0; i < LOCKSTAT_POINTS; i++) { |
145 | if (class->contention_point[i] == 0) { | 145 | if (points[i] == 0) { |
146 | class->contention_point[i] = ip; | 146 | points[i] = ip; |
147 | break; | 147 | break; |
148 | } | 148 | } |
149 | if (class->contention_point[i] == ip) | 149 | if (points[i] == ip) |
150 | break; | 150 | break; |
151 | } | 151 | } |
152 | 152 | ||
@@ -186,6 +186,9 @@ struct lock_class_stats lock_stats(struct lock_class *class) | |||
186 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) | 186 | for (i = 0; i < ARRAY_SIZE(stats.contention_point); i++) |
187 | stats.contention_point[i] += pcs->contention_point[i]; | 187 | stats.contention_point[i] += pcs->contention_point[i]; |
188 | 188 | ||
189 | for (i = 0; i < ARRAY_SIZE(stats.contending_point); i++) | ||
190 | stats.contending_point[i] += pcs->contending_point[i]; | ||
191 | |||
189 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); | 192 | lock_time_add(&pcs->read_waittime, &stats.read_waittime); |
190 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); | 193 | lock_time_add(&pcs->write_waittime, &stats.write_waittime); |
191 | 194 | ||
@@ -210,6 +213,7 @@ void clear_lock_stats(struct lock_class *class) | |||
210 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); | 213 | memset(cpu_stats, 0, sizeof(struct lock_class_stats)); |
211 | } | 214 | } |
212 | memset(class->contention_point, 0, sizeof(class->contention_point)); | 215 | memset(class->contention_point, 0, sizeof(class->contention_point)); |
216 | memset(class->contending_point, 0, sizeof(class->contending_point)); | ||
213 | } | 217 | } |
214 | 218 | ||
215 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) | 219 | static struct lock_class_stats *get_lock_stats(struct lock_class *class) |
@@ -288,14 +292,12 @@ void lockdep_off(void) | |||
288 | { | 292 | { |
289 | current->lockdep_recursion++; | 293 | current->lockdep_recursion++; |
290 | } | 294 | } |
291 | |||
292 | EXPORT_SYMBOL(lockdep_off); | 295 | EXPORT_SYMBOL(lockdep_off); |
293 | 296 | ||
294 | void lockdep_on(void) | 297 | void lockdep_on(void) |
295 | { | 298 | { |
296 | current->lockdep_recursion--; | 299 | current->lockdep_recursion--; |
297 | } | 300 | } |
298 | |||
299 | EXPORT_SYMBOL(lockdep_on); | 301 | EXPORT_SYMBOL(lockdep_on); |
300 | 302 | ||
301 | /* | 303 | /* |
@@ -577,7 +579,8 @@ static void print_lock_class_header(struct lock_class *class, int depth) | |||
577 | /* | 579 | /* |
578 | * printk all lock dependencies starting at <entry>: | 580 | * printk all lock dependencies starting at <entry>: |
579 | */ | 581 | */ |
580 | static void print_lock_dependencies(struct lock_class *class, int depth) | 582 | static void __used |
583 | print_lock_dependencies(struct lock_class *class, int depth) | ||
581 | { | 584 | { |
582 | struct lock_list *entry; | 585 | struct lock_list *entry; |
583 | 586 | ||
@@ -2509,7 +2512,6 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name, | |||
2509 | if (subclass) | 2512 | if (subclass) |
2510 | register_lock_class(lock, subclass, 1); | 2513 | register_lock_class(lock, subclass, 1); |
2511 | } | 2514 | } |
2512 | |||
2513 | EXPORT_SYMBOL_GPL(lockdep_init_map); | 2515 | EXPORT_SYMBOL_GPL(lockdep_init_map); |
2514 | 2516 | ||
2515 | /* | 2517 | /* |
@@ -2690,8 +2692,9 @@ static int check_unlock(struct task_struct *curr, struct lockdep_map *lock, | |||
2690 | } | 2692 | } |
2691 | 2693 | ||
2692 | static int | 2694 | static int |
2693 | __lock_set_subclass(struct lockdep_map *lock, | 2695 | __lock_set_class(struct lockdep_map *lock, const char *name, |
2694 | unsigned int subclass, unsigned long ip) | 2696 | struct lock_class_key *key, unsigned int subclass, |
2697 | unsigned long ip) | ||
2695 | { | 2698 | { |
2696 | struct task_struct *curr = current; | 2699 | struct task_struct *curr = current; |
2697 | struct held_lock *hlock, *prev_hlock; | 2700 | struct held_lock *hlock, *prev_hlock; |
@@ -2718,6 +2721,7 @@ __lock_set_subclass(struct lockdep_map *lock, | |||
2718 | return print_unlock_inbalance_bug(curr, lock, ip); | 2721 | return print_unlock_inbalance_bug(curr, lock, ip); |
2719 | 2722 | ||
2720 | found_it: | 2723 | found_it: |
2724 | lockdep_init_map(lock, name, key, 0); | ||
2721 | class = register_lock_class(lock, subclass, 0); | 2725 | class = register_lock_class(lock, subclass, 0); |
2722 | hlock->class_idx = class - lock_classes + 1; | 2726 | hlock->class_idx = class - lock_classes + 1; |
2723 | 2727 | ||
@@ -2902,9 +2906,9 @@ static void check_flags(unsigned long flags) | |||
2902 | #endif | 2906 | #endif |
2903 | } | 2907 | } |
2904 | 2908 | ||
2905 | void | 2909 | void lock_set_class(struct lockdep_map *lock, const char *name, |
2906 | lock_set_subclass(struct lockdep_map *lock, | 2910 | struct lock_class_key *key, unsigned int subclass, |
2907 | unsigned int subclass, unsigned long ip) | 2911 | unsigned long ip) |
2908 | { | 2912 | { |
2909 | unsigned long flags; | 2913 | unsigned long flags; |
2910 | 2914 | ||
@@ -2914,13 +2918,12 @@ lock_set_subclass(struct lockdep_map *lock, | |||
2914 | raw_local_irq_save(flags); | 2918 | raw_local_irq_save(flags); |
2915 | current->lockdep_recursion = 1; | 2919 | current->lockdep_recursion = 1; |
2916 | check_flags(flags); | 2920 | check_flags(flags); |
2917 | if (__lock_set_subclass(lock, subclass, ip)) | 2921 | if (__lock_set_class(lock, name, key, subclass, ip)) |
2918 | check_chain_key(current); | 2922 | check_chain_key(current); |
2919 | current->lockdep_recursion = 0; | 2923 | current->lockdep_recursion = 0; |
2920 | raw_local_irq_restore(flags); | 2924 | raw_local_irq_restore(flags); |
2921 | } | 2925 | } |
2922 | 2926 | EXPORT_SYMBOL_GPL(lock_set_class); | |
2923 | EXPORT_SYMBOL_GPL(lock_set_subclass); | ||
2924 | 2927 | ||
2925 | /* | 2928 | /* |
2926 | * We are not always called with irqs disabled - do that here, | 2929 | * We are not always called with irqs disabled - do that here, |
@@ -2944,7 +2947,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | |||
2944 | current->lockdep_recursion = 0; | 2947 | current->lockdep_recursion = 0; |
2945 | raw_local_irq_restore(flags); | 2948 | raw_local_irq_restore(flags); |
2946 | } | 2949 | } |
2947 | |||
2948 | EXPORT_SYMBOL_GPL(lock_acquire); | 2950 | EXPORT_SYMBOL_GPL(lock_acquire); |
2949 | 2951 | ||
2950 | void lock_release(struct lockdep_map *lock, int nested, | 2952 | void lock_release(struct lockdep_map *lock, int nested, |
@@ -2962,7 +2964,6 @@ void lock_release(struct lockdep_map *lock, int nested, | |||
2962 | current->lockdep_recursion = 0; | 2964 | current->lockdep_recursion = 0; |
2963 | raw_local_irq_restore(flags); | 2965 | raw_local_irq_restore(flags); |
2964 | } | 2966 | } |
2965 | |||
2966 | EXPORT_SYMBOL_GPL(lock_release); | 2967 | EXPORT_SYMBOL_GPL(lock_release); |
2967 | 2968 | ||
2968 | #ifdef CONFIG_LOCK_STAT | 2969 | #ifdef CONFIG_LOCK_STAT |
@@ -3000,7 +3001,7 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3000 | struct held_lock *hlock, *prev_hlock; | 3001 | struct held_lock *hlock, *prev_hlock; |
3001 | struct lock_class_stats *stats; | 3002 | struct lock_class_stats *stats; |
3002 | unsigned int depth; | 3003 | unsigned int depth; |
3003 | int i, point; | 3004 | int i, contention_point, contending_point; |
3004 | 3005 | ||
3005 | depth = curr->lockdep_depth; | 3006 | depth = curr->lockdep_depth; |
3006 | if (DEBUG_LOCKS_WARN_ON(!depth)) | 3007 | if (DEBUG_LOCKS_WARN_ON(!depth)) |
@@ -3024,18 +3025,22 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3024 | found_it: | 3025 | found_it: |
3025 | hlock->waittime_stamp = sched_clock(); | 3026 | hlock->waittime_stamp = sched_clock(); |
3026 | 3027 | ||
3027 | point = lock_contention_point(hlock_class(hlock), ip); | 3028 | contention_point = lock_point(hlock_class(hlock)->contention_point, ip); |
3029 | contending_point = lock_point(hlock_class(hlock)->contending_point, | ||
3030 | lock->ip); | ||
3028 | 3031 | ||
3029 | stats = get_lock_stats(hlock_class(hlock)); | 3032 | stats = get_lock_stats(hlock_class(hlock)); |
3030 | if (point < ARRAY_SIZE(stats->contention_point)) | 3033 | if (contention_point < LOCKSTAT_POINTS) |
3031 | stats->contention_point[point]++; | 3034 | stats->contention_point[contention_point]++; |
3035 | if (contending_point < LOCKSTAT_POINTS) | ||
3036 | stats->contending_point[contending_point]++; | ||
3032 | if (lock->cpu != smp_processor_id()) | 3037 | if (lock->cpu != smp_processor_id()) |
3033 | stats->bounces[bounce_contended + !!hlock->read]++; | 3038 | stats->bounces[bounce_contended + !!hlock->read]++; |
3034 | put_lock_stats(stats); | 3039 | put_lock_stats(stats); |
3035 | } | 3040 | } |
3036 | 3041 | ||
3037 | static void | 3042 | static void |
3038 | __lock_acquired(struct lockdep_map *lock) | 3043 | __lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3039 | { | 3044 | { |
3040 | struct task_struct *curr = current; | 3045 | struct task_struct *curr = current; |
3041 | struct held_lock *hlock, *prev_hlock; | 3046 | struct held_lock *hlock, *prev_hlock; |
@@ -3084,6 +3089,7 @@ found_it: | |||
3084 | put_lock_stats(stats); | 3089 | put_lock_stats(stats); |
3085 | 3090 | ||
3086 | lock->cpu = cpu; | 3091 | lock->cpu = cpu; |
3092 | lock->ip = ip; | ||
3087 | } | 3093 | } |
3088 | 3094 | ||
3089 | void lock_contended(struct lockdep_map *lock, unsigned long ip) | 3095 | void lock_contended(struct lockdep_map *lock, unsigned long ip) |
@@ -3105,7 +3111,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) | |||
3105 | } | 3111 | } |
3106 | EXPORT_SYMBOL_GPL(lock_contended); | 3112 | EXPORT_SYMBOL_GPL(lock_contended); |
3107 | 3113 | ||
3108 | void lock_acquired(struct lockdep_map *lock) | 3114 | void lock_acquired(struct lockdep_map *lock, unsigned long ip) |
3109 | { | 3115 | { |
3110 | unsigned long flags; | 3116 | unsigned long flags; |
3111 | 3117 | ||
@@ -3118,7 +3124,7 @@ void lock_acquired(struct lockdep_map *lock) | |||
3118 | raw_local_irq_save(flags); | 3124 | raw_local_irq_save(flags); |
3119 | check_flags(flags); | 3125 | check_flags(flags); |
3120 | current->lockdep_recursion = 1; | 3126 | current->lockdep_recursion = 1; |
3121 | __lock_acquired(lock); | 3127 | __lock_acquired(lock, ip); |
3122 | current->lockdep_recursion = 0; | 3128 | current->lockdep_recursion = 0; |
3123 | raw_local_irq_restore(flags); | 3129 | raw_local_irq_restore(flags); |
3124 | } | 3130 | } |
@@ -3442,7 +3448,6 @@ retry: | |||
3442 | if (unlock) | 3448 | if (unlock) |
3443 | read_unlock(&tasklist_lock); | 3449 | read_unlock(&tasklist_lock); |
3444 | } | 3450 | } |
3445 | |||
3446 | EXPORT_SYMBOL_GPL(debug_show_all_locks); | 3451 | EXPORT_SYMBOL_GPL(debug_show_all_locks); |
3447 | 3452 | ||
3448 | /* | 3453 | /* |
@@ -3463,7 +3468,6 @@ void debug_show_held_locks(struct task_struct *task) | |||
3463 | { | 3468 | { |
3464 | __debug_show_held_locks(task); | 3469 | __debug_show_held_locks(task); |
3465 | } | 3470 | } |
3466 | |||
3467 | EXPORT_SYMBOL_GPL(debug_show_held_locks); | 3471 | EXPORT_SYMBOL_GPL(debug_show_held_locks); |
3468 | 3472 | ||
3469 | void lockdep_sys_exit(void) | 3473 | void lockdep_sys_exit(void) |