diff options
Diffstat (limited to 'include/linux')
36 files changed, 988 insertions, 192 deletions
diff --git a/include/linux/completion.h b/include/linux/completion.h index 90663ad217f9..251c41e3ddd5 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h | |||
@@ -21,6 +21,18 @@ struct completion { | |||
21 | #define DECLARE_COMPLETION(work) \ | 21 | #define DECLARE_COMPLETION(work) \ |
22 | struct completion work = COMPLETION_INITIALIZER(work) | 22 | struct completion work = COMPLETION_INITIALIZER(work) |
23 | 23 | ||
24 | /* | ||
25 | * Lockdep needs to run a non-constant initializer for on-stack | ||
26 | * completions - so we use the _ONSTACK() variant for those that | ||
27 | * are on the kernel stack: | ||
28 | */ | ||
29 | #ifdef CONFIG_LOCKDEP | ||
30 | # define DECLARE_COMPLETION_ONSTACK(work) \ | ||
31 | struct completion work = ({ init_completion(&work); work; }) | ||
32 | #else | ||
33 | # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work) | ||
34 | #endif | ||
35 | |||
24 | static inline void init_completion(struct completion *x) | 36 | static inline void init_completion(struct completion *x) |
25 | { | 37 | { |
26 | x->done = 0; | 38 | x->done = 0; |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 0dd1610a94a9..471781ffeab1 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -114,6 +114,18 @@ struct dentry { | |||
114 | unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ | 114 | unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ |
115 | }; | 115 | }; |
116 | 116 | ||
117 | /* | ||
118 | * dentry->d_lock spinlock nesting subclasses: | ||
119 | * | ||
120 | * 0: normal | ||
121 | * 1: nested | ||
122 | */ | ||
123 | enum dentry_d_lock_class | ||
124 | { | ||
125 | DENTRY_D_LOCK_NORMAL, /* implicitly used by plain spin_lock() APIs. */ | ||
126 | DENTRY_D_LOCK_NESTED | ||
127 | }; | ||
128 | |||
117 | struct dentry_operations { | 129 | struct dentry_operations { |
118 | int (*d_revalidate)(struct dentry *, struct nameidata *); | 130 | int (*d_revalidate)(struct dentry *, struct nameidata *); |
119 | int (*d_hash) (struct dentry *, struct qstr *); | 131 | int (*d_hash) (struct dentry *, struct qstr *); |
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h new file mode 100644 index 000000000000..6a7047851e48 --- /dev/null +++ b/include/linux/debug_locks.h | |||
@@ -0,0 +1,69 @@ | |||
1 | #ifndef __LINUX_DEBUG_LOCKING_H | ||
2 | #define __LINUX_DEBUG_LOCKING_H | ||
3 | |||
4 | extern int debug_locks; | ||
5 | extern int debug_locks_silent; | ||
6 | |||
7 | /* | ||
8 | * Generic 'turn off all lock debugging' function: | ||
9 | */ | ||
10 | extern int debug_locks_off(void); | ||
11 | |||
12 | /* | ||
13 | * In the debug case we carry the caller's instruction pointer into | ||
14 | * other functions, but we dont want the function argument overhead | ||
15 | * in the nondebug case - hence these macros: | ||
16 | */ | ||
17 | #define _RET_IP_ (unsigned long)__builtin_return_address(0) | ||
18 | #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) | ||
19 | |||
20 | #define DEBUG_LOCKS_WARN_ON(c) \ | ||
21 | ({ \ | ||
22 | int __ret = 0; \ | ||
23 | \ | ||
24 | if (unlikely(c)) { \ | ||
25 | if (debug_locks_off()) \ | ||
26 | WARN_ON(1); \ | ||
27 | __ret = 1; \ | ||
28 | } \ | ||
29 | __ret; \ | ||
30 | }) | ||
31 | |||
32 | #ifdef CONFIG_SMP | ||
33 | # define SMP_DEBUG_LOCKS_WARN_ON(c) DEBUG_LOCKS_WARN_ON(c) | ||
34 | #else | ||
35 | # define SMP_DEBUG_LOCKS_WARN_ON(c) do { } while (0) | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_DEBUG_LOCKING_API_SELFTESTS | ||
39 | extern void locking_selftest(void); | ||
40 | #else | ||
41 | # define locking_selftest() do { } while (0) | ||
42 | #endif | ||
43 | |||
44 | #ifdef CONFIG_LOCKDEP | ||
45 | extern void debug_show_all_locks(void); | ||
46 | extern void debug_show_held_locks(struct task_struct *task); | ||
47 | extern void debug_check_no_locks_freed(const void *from, unsigned long len); | ||
48 | extern void debug_check_no_locks_held(struct task_struct *task); | ||
49 | #else | ||
50 | static inline void debug_show_all_locks(void) | ||
51 | { | ||
52 | } | ||
53 | |||
54 | static inline void debug_show_held_locks(struct task_struct *task) | ||
55 | { | ||
56 | } | ||
57 | |||
58 | static inline void | ||
59 | debug_check_no_locks_freed(const void *from, unsigned long len) | ||
60 | { | ||
61 | } | ||
62 | |||
63 | static inline void | ||
64 | debug_check_no_locks_held(struct task_struct *task) | ||
65 | { | ||
66 | } | ||
67 | #endif | ||
68 | |||
69 | #endif | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index e04a5cfe874f..134b32068246 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -436,6 +436,21 @@ struct block_device { | |||
436 | }; | 436 | }; |
437 | 437 | ||
438 | /* | 438 | /* |
439 | * bdev->bd_mutex nesting subclasses for the lock validator: | ||
440 | * | ||
441 | * 0: normal | ||
442 | * 1: 'whole' | ||
443 | * 2: 'partition' | ||
444 | */ | ||
445 | enum bdev_bd_mutex_lock_class | ||
446 | { | ||
447 | BD_MUTEX_NORMAL, | ||
448 | BD_MUTEX_WHOLE, | ||
449 | BD_MUTEX_PARTITION | ||
450 | }; | ||
451 | |||
452 | |||
453 | /* | ||
439 | * Radix-tree tags, for tagging dirty and writeback pages within the pagecache | 454 | * Radix-tree tags, for tagging dirty and writeback pages within the pagecache |
440 | * radix trees | 455 | * radix trees |
441 | */ | 456 | */ |
@@ -543,6 +558,25 @@ struct inode { | |||
543 | }; | 558 | }; |
544 | 559 | ||
545 | /* | 560 | /* |
561 | * inode->i_mutex nesting subclasses for the lock validator: | ||
562 | * | ||
563 | * 0: the object of the current VFS operation | ||
564 | * 1: parent | ||
565 | * 2: child/target | ||
566 | * 3: quota file | ||
567 | * | ||
568 | * The locking order between these classes is | ||
569 | * parent -> child -> normal -> quota | ||
570 | */ | ||
571 | enum inode_i_mutex_lock_class | ||
572 | { | ||
573 | I_MUTEX_NORMAL, | ||
574 | I_MUTEX_PARENT, | ||
575 | I_MUTEX_CHILD, | ||
576 | I_MUTEX_QUOTA | ||
577 | }; | ||
578 | |||
579 | /* | ||
546 | * NOTE: in a 32bit arch with a preemptable kernel and | 580 | * NOTE: in a 32bit arch with a preemptable kernel and |
547 | * an UP compile the i_size_read/write must be atomic | 581 | * an UP compile the i_size_read/write must be atomic |
548 | * with respect to the local cpu (unlike with preempt disabled), | 582 | * with respect to the local cpu (unlike with preempt disabled), |
@@ -1276,6 +1310,8 @@ struct file_system_type { | |||
1276 | struct module *owner; | 1310 | struct module *owner; |
1277 | struct file_system_type * next; | 1311 | struct file_system_type * next; |
1278 | struct list_head fs_supers; | 1312 | struct list_head fs_supers; |
1313 | struct lock_class_key s_lock_key; | ||
1314 | struct lock_class_key s_umount_key; | ||
1279 | }; | 1315 | }; |
1280 | 1316 | ||
1281 | extern int get_sb_bdev(struct file_system_type *fs_type, | 1317 | extern int get_sb_bdev(struct file_system_type *fs_type, |
@@ -1404,6 +1440,7 @@ extern void bd_set_size(struct block_device *, loff_t size); | |||
1404 | extern void bd_forget(struct inode *inode); | 1440 | extern void bd_forget(struct inode *inode); |
1405 | extern void bdput(struct block_device *); | 1441 | extern void bdput(struct block_device *); |
1406 | extern struct block_device *open_by_devnum(dev_t, unsigned); | 1442 | extern struct block_device *open_by_devnum(dev_t, unsigned); |
1443 | extern struct block_device *open_partition_by_devnum(dev_t, unsigned); | ||
1407 | extern const struct file_operations def_blk_fops; | 1444 | extern const struct file_operations def_blk_fops; |
1408 | extern const struct address_space_operations def_blk_aops; | 1445 | extern const struct address_space_operations def_blk_aops; |
1409 | extern const struct file_operations def_chr_fops; | 1446 | extern const struct file_operations def_chr_fops; |
@@ -1414,6 +1451,7 @@ extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); | |||
1414 | extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); | 1451 | extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); |
1415 | extern int blkdev_get(struct block_device *, mode_t, unsigned); | 1452 | extern int blkdev_get(struct block_device *, mode_t, unsigned); |
1416 | extern int blkdev_put(struct block_device *); | 1453 | extern int blkdev_put(struct block_device *); |
1454 | extern int blkdev_put_partition(struct block_device *); | ||
1417 | extern int bd_claim(struct block_device *, void *); | 1455 | extern int bd_claim(struct block_device *, void *); |
1418 | extern void bd_release(struct block_device *); | 1456 | extern void bd_release(struct block_device *); |
1419 | #ifdef CONFIG_SYSFS | 1457 | #ifdef CONFIG_SYSFS |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 114ae583cca9..50d8b5744cf6 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/preempt.h> | 4 | #include <linux/preempt.h> |
5 | #include <linux/smp_lock.h> | 5 | #include <linux/smp_lock.h> |
6 | #include <linux/lockdep.h> | ||
6 | #include <asm/hardirq.h> | 7 | #include <asm/hardirq.h> |
7 | #include <asm/system.h> | 8 | #include <asm/system.h> |
8 | 9 | ||
@@ -86,9 +87,6 @@ extern void synchronize_irq(unsigned int irq); | |||
86 | # define synchronize_irq(irq) barrier() | 87 | # define synchronize_irq(irq) barrier() |
87 | #endif | 88 | #endif |
88 | 89 | ||
89 | #define nmi_enter() irq_enter() | ||
90 | #define nmi_exit() sub_preempt_count(HARDIRQ_OFFSET) | ||
91 | |||
92 | struct task_struct; | 90 | struct task_struct; |
93 | 91 | ||
94 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 92 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -97,12 +95,35 @@ static inline void account_system_vtime(struct task_struct *tsk) | |||
97 | } | 95 | } |
98 | #endif | 96 | #endif |
99 | 97 | ||
98 | /* | ||
99 | * It is safe to do non-atomic ops on ->hardirq_context, | ||
100 | * because NMI handlers may not preempt and the ops are | ||
101 | * always balanced, so the interrupted value of ->hardirq_context | ||
102 | * will always be restored. | ||
103 | */ | ||
100 | #define irq_enter() \ | 104 | #define irq_enter() \ |
101 | do { \ | 105 | do { \ |
102 | account_system_vtime(current); \ | 106 | account_system_vtime(current); \ |
103 | add_preempt_count(HARDIRQ_OFFSET); \ | 107 | add_preempt_count(HARDIRQ_OFFSET); \ |
108 | trace_hardirq_enter(); \ | ||
109 | } while (0) | ||
110 | |||
111 | /* | ||
112 | * Exit irq context without processing softirqs: | ||
113 | */ | ||
114 | #define __irq_exit() \ | ||
115 | do { \ | ||
116 | trace_hardirq_exit(); \ | ||
117 | account_system_vtime(current); \ | ||
118 | sub_preempt_count(HARDIRQ_OFFSET); \ | ||
104 | } while (0) | 119 | } while (0) |
105 | 120 | ||
121 | /* | ||
122 | * Exit irq context and process softirqs if needed: | ||
123 | */ | ||
106 | extern void irq_exit(void); | 124 | extern void irq_exit(void); |
107 | 125 | ||
126 | #define nmi_enter() do { lockdep_off(); irq_enter(); } while (0) | ||
127 | #define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) | ||
128 | |||
108 | #endif /* LINUX_HARDIRQ_H */ | 129 | #endif /* LINUX_HARDIRQ_H */ |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 07d7305f131e..e4bccbcc2750 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -91,6 +91,7 @@ struct hrtimer_base { | |||
91 | ktime_t (*get_softirq_time)(void); | 91 | ktime_t (*get_softirq_time)(void); |
92 | struct hrtimer *curr_timer; | 92 | struct hrtimer *curr_timer; |
93 | ktime_t softirq_time; | 93 | ktime_t softirq_time; |
94 | struct lock_class_key lock_key; | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | /* | 97 | /* |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 285316c836b5..dc7abef10965 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1359,7 +1359,7 @@ extern struct semaphore ide_cfg_sem; | |||
1359 | * ide_drive_t->hwif: constant, no locking | 1359 | * ide_drive_t->hwif: constant, no locking |
1360 | */ | 1360 | */ |
1361 | 1361 | ||
1362 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable(); } while (0) | 1362 | #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) |
1363 | 1363 | ||
1364 | extern struct bus_type ide_bus_type; | 1364 | extern struct bus_type ide_bus_type; |
1365 | 1365 | ||
diff --git a/include/linux/idr.h b/include/linux/idr.h index f559a719dbe8..826803449db7 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h | |||
@@ -66,7 +66,7 @@ struct idr { | |||
66 | .id_free = NULL, \ | 66 | .id_free = NULL, \ |
67 | .layers = 0, \ | 67 | .layers = 0, \ |
68 | .id_free_cnt = 0, \ | 68 | .id_free_cnt = 0, \ |
69 | .lock = SPIN_LOCK_UNLOCKED, \ | 69 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
70 | } | 70 | } |
71 | #define DEFINE_IDR(name) struct idr name = IDR_INIT(name) | 71 | #define DEFINE_IDR(name) struct idr name = IDR_INIT(name) |
72 | 72 | ||
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 3a256957fb56..60aac2cea0cf 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/file.h> | 4 | #include <linux/file.h> |
5 | #include <linux/rcupdate.h> | 5 | #include <linux/rcupdate.h> |
6 | #include <linux/irqflags.h> | ||
7 | #include <linux/lockdep.h> | ||
6 | 8 | ||
7 | #define INIT_FDTABLE \ | 9 | #define INIT_FDTABLE \ |
8 | { \ | 10 | { \ |
@@ -21,7 +23,7 @@ | |||
21 | .count = ATOMIC_INIT(1), \ | 23 | .count = ATOMIC_INIT(1), \ |
22 | .fdt = &init_files.fdtab, \ | 24 | .fdt = &init_files.fdtab, \ |
23 | .fdtab = INIT_FDTABLE, \ | 25 | .fdtab = INIT_FDTABLE, \ |
24 | .file_lock = SPIN_LOCK_UNLOCKED, \ | 26 | .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), \ |
25 | .next_fd = 0, \ | 27 | .next_fd = 0, \ |
26 | .close_on_exec_init = { { 0, } }, \ | 28 | .close_on_exec_init = { { 0, } }, \ |
27 | .open_fds_init = { { 0, } }, \ | 29 | .open_fds_init = { { 0, } }, \ |
@@ -36,7 +38,7 @@ | |||
36 | .user_id = 0, \ | 38 | .user_id = 0, \ |
37 | .next = NULL, \ | 39 | .next = NULL, \ |
38 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait), \ | 40 | .wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait), \ |
39 | .ctx_lock = SPIN_LOCK_UNLOCKED, \ | 41 | .ctx_lock = __SPIN_LOCK_UNLOCKED(name.ctx_lock), \ |
40 | .reqs_active = 0U, \ | 42 | .reqs_active = 0U, \ |
41 | .max_reqs = ~0U, \ | 43 | .max_reqs = ~0U, \ |
42 | } | 44 | } |
@@ -48,7 +50,7 @@ | |||
48 | .mm_users = ATOMIC_INIT(2), \ | 50 | .mm_users = ATOMIC_INIT(2), \ |
49 | .mm_count = ATOMIC_INIT(1), \ | 51 | .mm_count = ATOMIC_INIT(1), \ |
50 | .mmap_sem = __RWSEM_INITIALIZER(name.mmap_sem), \ | 52 | .mmap_sem = __RWSEM_INITIALIZER(name.mmap_sem), \ |
51 | .page_table_lock = SPIN_LOCK_UNLOCKED, \ | 53 | .page_table_lock = __SPIN_LOCK_UNLOCKED(name.page_table_lock), \ |
52 | .mmlist = LIST_HEAD_INIT(name.mmlist), \ | 54 | .mmlist = LIST_HEAD_INIT(name.mmlist), \ |
53 | .cpu_vm_mask = CPU_MASK_ALL, \ | 55 | .cpu_vm_mask = CPU_MASK_ALL, \ |
54 | } | 56 | } |
@@ -69,7 +71,7 @@ | |||
69 | #define INIT_SIGHAND(sighand) { \ | 71 | #define INIT_SIGHAND(sighand) { \ |
70 | .count = ATOMIC_INIT(1), \ | 72 | .count = ATOMIC_INIT(1), \ |
71 | .action = { { { .sa_handler = NULL, } }, }, \ | 73 | .action = { { { .sa_handler = NULL, } }, }, \ |
72 | .siglock = SPIN_LOCK_UNLOCKED, \ | 74 | .siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \ |
73 | } | 75 | } |
74 | 76 | ||
75 | extern struct group_info init_groups; | 77 | extern struct group_info init_groups; |
@@ -119,12 +121,13 @@ extern struct group_info init_groups; | |||
119 | .list = LIST_HEAD_INIT(tsk.pending.list), \ | 121 | .list = LIST_HEAD_INIT(tsk.pending.list), \ |
120 | .signal = {{0}}}, \ | 122 | .signal = {{0}}}, \ |
121 | .blocked = {{0}}, \ | 123 | .blocked = {{0}}, \ |
122 | .alloc_lock = SPIN_LOCK_UNLOCKED, \ | 124 | .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ |
123 | .journal_info = NULL, \ | 125 | .journal_info = NULL, \ |
124 | .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ | 126 | .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ |
125 | .fs_excl = ATOMIC_INIT(0), \ | 127 | .fs_excl = ATOMIC_INIT(0), \ |
126 | .pi_lock = SPIN_LOCK_UNLOCKED, \ | 128 | .pi_lock = SPIN_LOCK_UNLOCKED, \ |
127 | INIT_RT_MUTEXES(tsk) \ | 129 | INIT_TRACE_IRQFLAGS \ |
130 | INIT_LOCKDEP \ | ||
128 | } | 131 | } |
129 | 132 | ||
130 | 133 | ||
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index da3e0dbe61d4..d5afee95fd43 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/irqreturn.h> | 10 | #include <linux/irqreturn.h> |
11 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/irqflags.h> | ||
13 | #include <asm/atomic.h> | 14 | #include <asm/atomic.h> |
14 | #include <asm/ptrace.h> | 15 | #include <asm/ptrace.h> |
15 | #include <asm/system.h> | 16 | #include <asm/system.h> |
@@ -80,12 +81,64 @@ extern int request_irq(unsigned int, | |||
80 | unsigned long, const char *, void *); | 81 | unsigned long, const char *, void *); |
81 | extern void free_irq(unsigned int, void *); | 82 | extern void free_irq(unsigned int, void *); |
82 | 83 | ||
84 | /* | ||
85 | * On lockdep we dont want to enable hardirqs in hardirq | ||
86 | * context. Use local_irq_enable_in_hardirq() to annotate | ||
87 | * kernel code that has to do this nevertheless (pretty much | ||
88 | * the only valid case is for old/broken hardware that is | ||
89 | * insanely slow). | ||
90 | * | ||
91 | * NOTE: in theory this might break fragile code that relies | ||
92 | * on hardirq delivery - in practice we dont seem to have such | ||
93 | * places left. So the only effect should be slightly increased | ||
94 | * irqs-off latencies. | ||
95 | */ | ||
96 | #ifdef CONFIG_LOCKDEP | ||
97 | # define local_irq_enable_in_hardirq() do { } while (0) | ||
98 | #else | ||
99 | # define local_irq_enable_in_hardirq() local_irq_enable() | ||
100 | #endif | ||
83 | 101 | ||
84 | #ifdef CONFIG_GENERIC_HARDIRQS | 102 | #ifdef CONFIG_GENERIC_HARDIRQS |
85 | extern void disable_irq_nosync(unsigned int irq); | 103 | extern void disable_irq_nosync(unsigned int irq); |
86 | extern void disable_irq(unsigned int irq); | 104 | extern void disable_irq(unsigned int irq); |
87 | extern void enable_irq(unsigned int irq); | 105 | extern void enable_irq(unsigned int irq); |
88 | 106 | ||
107 | /* | ||
108 | * Special lockdep variants of irq disabling/enabling. | ||
109 | * These should be used for locking constructs that | ||
110 | * know that a particular irq context which is disabled, | ||
111 | * and which is the only irq-context user of a lock, | ||
112 | * that it's safe to take the lock in the irq-disabled | ||
113 | * section without disabling hardirqs. | ||
114 | * | ||
115 | * On !CONFIG_LOCKDEP they are equivalent to the normal | ||
116 | * irq disable/enable methods. | ||
117 | */ | ||
118 | static inline void disable_irq_nosync_lockdep(unsigned int irq) | ||
119 | { | ||
120 | disable_irq_nosync(irq); | ||
121 | #ifdef CONFIG_LOCKDEP | ||
122 | local_irq_disable(); | ||
123 | #endif | ||
124 | } | ||
125 | |||
126 | static inline void disable_irq_lockdep(unsigned int irq) | ||
127 | { | ||
128 | disable_irq(irq); | ||
129 | #ifdef CONFIG_LOCKDEP | ||
130 | local_irq_disable(); | ||
131 | #endif | ||
132 | } | ||
133 | |||
134 | static inline void enable_irq_lockdep(unsigned int irq) | ||
135 | { | ||
136 | #ifdef CONFIG_LOCKDEP | ||
137 | local_irq_enable(); | ||
138 | #endif | ||
139 | enable_irq(irq); | ||
140 | } | ||
141 | |||
89 | /* IRQ wakeup (PM) control: */ | 142 | /* IRQ wakeup (PM) control: */ |
90 | extern int set_irq_wake(unsigned int irq, unsigned int on); | 143 | extern int set_irq_wake(unsigned int irq, unsigned int on); |
91 | 144 | ||
@@ -99,7 +152,19 @@ static inline int disable_irq_wake(unsigned int irq) | |||
99 | return set_irq_wake(irq, 0); | 152 | return set_irq_wake(irq, 0); |
100 | } | 153 | } |
101 | 154 | ||
102 | #endif | 155 | #else /* !CONFIG_GENERIC_HARDIRQS */ |
156 | /* | ||
157 | * NOTE: non-genirq architectures, if they want to support the lock | ||
158 | * validator need to define the methods below in their asm/irq.h | ||
159 | * files, under an #ifdef CONFIG_LOCKDEP section. | ||
160 | */ | ||
161 | # ifndef CONFIG_LOCKDEP | ||
162 | # define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq) | ||
163 | # define disable_irq_lockdep(irq) disable_irq(irq) | ||
164 | # define enable_irq_lockdep(irq) enable_irq(irq) | ||
165 | # endif | ||
166 | |||
167 | #endif /* CONFIG_GENERIC_HARDIRQS */ | ||
103 | 168 | ||
104 | #ifndef __ARCH_SET_SOFTIRQ_PENDING | 169 | #ifndef __ARCH_SET_SOFTIRQ_PENDING |
105 | #define set_softirq_pending(x) (local_softirq_pending() = (x)) | 170 | #define set_softirq_pending(x) (local_softirq_pending() = (x)) |
@@ -135,13 +200,11 @@ static inline void __deprecated save_and_cli(unsigned long *x) | |||
135 | #define save_and_cli(x) save_and_cli(&x) | 200 | #define save_and_cli(x) save_and_cli(&x) |
136 | #endif /* CONFIG_SMP */ | 201 | #endif /* CONFIG_SMP */ |
137 | 202 | ||
138 | /* SoftIRQ primitives. */ | 203 | extern void local_bh_disable(void); |
139 | #define local_bh_disable() \ | 204 | extern void __local_bh_enable(void); |
140 | do { add_preempt_count(SOFTIRQ_OFFSET); barrier(); } while (0) | 205 | extern void _local_bh_enable(void); |
141 | #define __local_bh_enable() \ | ||
142 | do { barrier(); sub_preempt_count(SOFTIRQ_OFFSET); } while (0) | ||
143 | |||
144 | extern void local_bh_enable(void); | 206 | extern void local_bh_enable(void); |
207 | extern void local_bh_enable_ip(unsigned long ip); | ||
145 | 208 | ||
146 | /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high | 209 | /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high |
147 | frequency threaded job scheduling. For almost all the purposes | 210 | frequency threaded job scheduling. For almost all the purposes |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 87a9fc039b47..5612dfeeae50 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -55,6 +55,7 @@ struct resource_list { | |||
55 | #define IORESOURCE_IRQ_LOWEDGE (1<<1) | 55 | #define IORESOURCE_IRQ_LOWEDGE (1<<1) |
56 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) | 56 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) |
57 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) | 57 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) |
58 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) | ||
58 | 59 | ||
59 | /* ISA PnP DMA specific bits (IORESOURCE_BITS) */ | 60 | /* ISA PnP DMA specific bits (IORESOURCE_BITS) */ |
60 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) | 61 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) |
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h new file mode 100644 index 000000000000..412e025bc5c7 --- /dev/null +++ b/include/linux/irqflags.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * include/linux/irqflags.h | ||
3 | * | ||
4 | * IRQ flags tracing: follow the state of the hardirq and softirq flags and | ||
5 | * provide callbacks for transitions between ON and OFF states. | ||
6 | * | ||
7 | * This file gets included from lowlevel asm headers too, to provide | ||
8 | * wrapped versions of the local_irq_*() APIs, based on the | ||
9 | * raw_local_irq_*() macros from the lowlevel headers. | ||
10 | */ | ||
11 | #ifndef _LINUX_TRACE_IRQFLAGS_H | ||
12 | #define _LINUX_TRACE_IRQFLAGS_H | ||
13 | |||
14 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
15 | extern void trace_hardirqs_on(void); | ||
16 | extern void trace_hardirqs_off(void); | ||
17 | extern void trace_softirqs_on(unsigned long ip); | ||
18 | extern void trace_softirqs_off(unsigned long ip); | ||
19 | # define trace_hardirq_context(p) ((p)->hardirq_context) | ||
20 | # define trace_softirq_context(p) ((p)->softirq_context) | ||
21 | # define trace_hardirqs_enabled(p) ((p)->hardirqs_enabled) | ||
22 | # define trace_softirqs_enabled(p) ((p)->softirqs_enabled) | ||
23 | # define trace_hardirq_enter() do { current->hardirq_context++; } while (0) | ||
24 | # define trace_hardirq_exit() do { current->hardirq_context--; } while (0) | ||
25 | # define trace_softirq_enter() do { current->softirq_context++; } while (0) | ||
26 | # define trace_softirq_exit() do { current->softirq_context--; } while (0) | ||
27 | # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, | ||
28 | #else | ||
29 | # define trace_hardirqs_on() do { } while (0) | ||
30 | # define trace_hardirqs_off() do { } while (0) | ||
31 | # define trace_softirqs_on(ip) do { } while (0) | ||
32 | # define trace_softirqs_off(ip) do { } while (0) | ||
33 | # define trace_hardirq_context(p) 0 | ||
34 | # define trace_softirq_context(p) 0 | ||
35 | # define trace_hardirqs_enabled(p) 0 | ||
36 | # define trace_softirqs_enabled(p) 0 | ||
37 | # define trace_hardirq_enter() do { } while (0) | ||
38 | # define trace_hardirq_exit() do { } while (0) | ||
39 | # define trace_softirq_enter() do { } while (0) | ||
40 | # define trace_softirq_exit() do { } while (0) | ||
41 | # define INIT_TRACE_IRQFLAGS | ||
42 | #endif | ||
43 | |||
44 | #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT | ||
45 | |||
46 | #include <asm/irqflags.h> | ||
47 | |||
48 | #define local_irq_enable() \ | ||
49 | do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0) | ||
50 | #define local_irq_disable() \ | ||
51 | do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0) | ||
52 | #define local_irq_save(flags) \ | ||
53 | do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0) | ||
54 | |||
55 | #define local_irq_restore(flags) \ | ||
56 | do { \ | ||
57 | if (raw_irqs_disabled_flags(flags)) { \ | ||
58 | raw_local_irq_restore(flags); \ | ||
59 | trace_hardirqs_off(); \ | ||
60 | } else { \ | ||
61 | trace_hardirqs_on(); \ | ||
62 | raw_local_irq_restore(flags); \ | ||
63 | } \ | ||
64 | } while (0) | ||
65 | #else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */ | ||
66 | /* | ||
67 | * The local_irq_*() APIs are equal to the raw_local_irq*() | ||
68 | * if !TRACE_IRQFLAGS. | ||
69 | */ | ||
70 | # define raw_local_irq_disable() local_irq_disable() | ||
71 | # define raw_local_irq_enable() local_irq_enable() | ||
72 | # define raw_local_irq_save(flags) local_irq_save(flags) | ||
73 | # define raw_local_irq_restore(flags) local_irq_restore(flags) | ||
74 | #endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ | ||
75 | |||
76 | #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT | ||
77 | #define safe_halt() \ | ||
78 | do { \ | ||
79 | trace_hardirqs_on(); \ | ||
80 | raw_safe_halt(); \ | ||
81 | } while (0) | ||
82 | |||
83 | #define local_save_flags(flags) raw_local_save_flags(flags) | ||
84 | |||
85 | #define irqs_disabled() \ | ||
86 | ({ \ | ||
87 | unsigned long flags; \ | ||
88 | \ | ||
89 | raw_local_save_flags(flags); \ | ||
90 | raw_irqs_disabled_flags(flags); \ | ||
91 | }) | ||
92 | |||
93 | #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) | ||
94 | #endif /* CONFIG_X86 */ | ||
95 | |||
96 | #endif | ||
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 54e2549f96ba..849043ce4ed6 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h | |||
@@ -57,10 +57,25 @@ do { \ | |||
57 | #define print_fn_descriptor_symbol(fmt, addr) print_symbol(fmt, addr) | 57 | #define print_fn_descriptor_symbol(fmt, addr) print_symbol(fmt, addr) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | #define print_symbol(fmt, addr) \ | 60 | static inline void print_symbol(const char *fmt, unsigned long addr) |
61 | do { \ | 61 | { |
62 | __check_printsym_format(fmt, ""); \ | 62 | __check_printsym_format(fmt, ""); |
63 | __print_symbol(fmt, addr); \ | 63 | __print_symbol(fmt, (unsigned long) |
64 | __builtin_extract_return_addr((void *)addr)); | ||
65 | } | ||
66 | |||
67 | #ifndef CONFIG_64BIT | ||
68 | #define print_ip_sym(ip) \ | ||
69 | do { \ | ||
70 | printk("[<%08lx>]", ip); \ | ||
71 | print_symbol(" %s\n", ip); \ | ||
64 | } while(0) | 72 | } while(0) |
73 | #else | ||
74 | #define print_ip_sym(ip) \ | ||
75 | do { \ | ||
76 | printk("[<%016lx>]", ip); \ | ||
77 | print_symbol(" %s\n", ip); \ | ||
78 | } while(0) | ||
79 | #endif | ||
65 | 80 | ||
66 | #endif /*_LINUX_KALLSYMS_H*/ | 81 | #endif /*_LINUX_KALLSYMS_H*/ |
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h new file mode 100644 index 000000000000..316e0fb8d7b1 --- /dev/null +++ b/include/linux/lockdep.h | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | * Runtime locking correctness validator | ||
3 | * | ||
4 | * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
5 | * | ||
6 | * see Documentation/lockdep-design.txt for more details. | ||
7 | */ | ||
8 | #ifndef __LINUX_LOCKDEP_H | ||
9 | #define __LINUX_LOCKDEP_H | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <linux/list.h> | ||
13 | #include <linux/debug_locks.h> | ||
14 | #include <linux/stacktrace.h> | ||
15 | |||
16 | #ifdef CONFIG_LOCKDEP | ||
17 | |||
18 | /* | ||
19 | * Lock-class usage-state bits: | ||
20 | */ | ||
21 | enum lock_usage_bit | ||
22 | { | ||
23 | LOCK_USED = 0, | ||
24 | LOCK_USED_IN_HARDIRQ, | ||
25 | LOCK_USED_IN_SOFTIRQ, | ||
26 | LOCK_ENABLED_SOFTIRQS, | ||
27 | LOCK_ENABLED_HARDIRQS, | ||
28 | LOCK_USED_IN_HARDIRQ_READ, | ||
29 | LOCK_USED_IN_SOFTIRQ_READ, | ||
30 | LOCK_ENABLED_SOFTIRQS_READ, | ||
31 | LOCK_ENABLED_HARDIRQS_READ, | ||
32 | LOCK_USAGE_STATES | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * Usage-state bitmasks: | ||
37 | */ | ||
38 | #define LOCKF_USED (1 << LOCK_USED) | ||
39 | #define LOCKF_USED_IN_HARDIRQ (1 << LOCK_USED_IN_HARDIRQ) | ||
40 | #define LOCKF_USED_IN_SOFTIRQ (1 << LOCK_USED_IN_SOFTIRQ) | ||
41 | #define LOCKF_ENABLED_HARDIRQS (1 << LOCK_ENABLED_HARDIRQS) | ||
42 | #define LOCKF_ENABLED_SOFTIRQS (1 << LOCK_ENABLED_SOFTIRQS) | ||
43 | |||
44 | #define LOCKF_ENABLED_IRQS (LOCKF_ENABLED_HARDIRQS | LOCKF_ENABLED_SOFTIRQS) | ||
45 | #define LOCKF_USED_IN_IRQ (LOCKF_USED_IN_HARDIRQ | LOCKF_USED_IN_SOFTIRQ) | ||
46 | |||
47 | #define LOCKF_USED_IN_HARDIRQ_READ (1 << LOCK_USED_IN_HARDIRQ_READ) | ||
48 | #define LOCKF_USED_IN_SOFTIRQ_READ (1 << LOCK_USED_IN_SOFTIRQ_READ) | ||
49 | #define LOCKF_ENABLED_HARDIRQS_READ (1 << LOCK_ENABLED_HARDIRQS_READ) | ||
50 | #define LOCKF_ENABLED_SOFTIRQS_READ (1 << LOCK_ENABLED_SOFTIRQS_READ) | ||
51 | |||
52 | #define LOCKF_ENABLED_IRQS_READ \ | ||
53 | (LOCKF_ENABLED_HARDIRQS_READ | LOCKF_ENABLED_SOFTIRQS_READ) | ||
54 | #define LOCKF_USED_IN_IRQ_READ \ | ||
55 | (LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ) | ||
56 | |||
57 | #define MAX_LOCKDEP_SUBCLASSES 8UL | ||
58 | |||
59 | /* | ||
60 | * Lock-classes are keyed via unique addresses, by embedding the | ||
61 | * lockclass-key into the kernel (or module) .data section. (For | ||
62 | * static locks we use the lock address itself as the key.) | ||
63 | */ | ||
64 | struct lockdep_subclass_key { | ||
65 | char __one_byte; | ||
66 | } __attribute__ ((__packed__)); | ||
67 | |||
68 | struct lock_class_key { | ||
69 | struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; | ||
70 | }; | ||
71 | |||
72 | /* | ||
73 | * The lock-class itself: | ||
74 | */ | ||
75 | struct lock_class { | ||
76 | /* | ||
77 | * class-hash: | ||
78 | */ | ||
79 | struct list_head hash_entry; | ||
80 | |||
81 | /* | ||
82 | * global list of all lock-classes: | ||
83 | */ | ||
84 | struct list_head lock_entry; | ||
85 | |||
86 | struct lockdep_subclass_key *key; | ||
87 | unsigned int subclass; | ||
88 | |||
89 | /* | ||
90 | * IRQ/softirq usage tracking bits: | ||
91 | */ | ||
92 | unsigned long usage_mask; | ||
93 | struct stack_trace usage_traces[LOCK_USAGE_STATES]; | ||
94 | |||
95 | /* | ||
96 | * These fields represent a directed graph of lock dependencies, | ||
97 | * to every node we attach a list of "forward" and a list of | ||
98 | * "backward" graph nodes. | ||
99 | */ | ||
100 | struct list_head locks_after, locks_before; | ||
101 | |||
102 | /* | ||
103 | * Generation counter, when doing certain classes of graph walking, | ||
104 | * to ensure that we check one node only once: | ||
105 | */ | ||
106 | unsigned int version; | ||
107 | |||
108 | /* | ||
109 | * Statistics counter: | ||
110 | */ | ||
111 | unsigned long ops; | ||
112 | |||
113 | const char *name; | ||
114 | int name_version; | ||
115 | }; | ||
116 | |||
117 | /* | ||
118 | * Map the lock object (the lock instance) to the lock-class object. | ||
119 | * This is embedded into specific lock instances: | ||
120 | */ | ||
121 | struct lockdep_map { | ||
122 | struct lock_class_key *key; | ||
123 | struct lock_class *class[MAX_LOCKDEP_SUBCLASSES]; | ||
124 | const char *name; | ||
125 | }; | ||
126 | |||
127 | /* | ||
128 | * Every lock has a list of other locks that were taken after it. | ||
129 | * We only grow the list, never remove from it: | ||
130 | */ | ||
131 | struct lock_list { | ||
132 | struct list_head entry; | ||
133 | struct lock_class *class; | ||
134 | struct stack_trace trace; | ||
135 | }; | ||
136 | |||
137 | /* | ||
138 | * We record lock dependency chains, so that we can cache them: | ||
139 | */ | ||
140 | struct lock_chain { | ||
141 | struct list_head entry; | ||
142 | u64 chain_key; | ||
143 | }; | ||
144 | |||
145 | struct held_lock { | ||
146 | /* | ||
147 | * One-way hash of the dependency chain up to this point. We | ||
148 | * hash the hashes step by step as the dependency chain grows. | ||
149 | * | ||
150 | * We use it for dependency-caching and we skip detection | ||
151 | * passes and dependency-updates if there is a cache-hit, so | ||
152 | * it is absolutely critical for 100% coverage of the validator | ||
153 | * to have a unique key value for every unique dependency path | ||
154 | * that can occur in the system, to make a unique hash value | ||
155 | * as likely as possible - hence the 64-bit width. | ||
156 | * | ||
157 | * The task struct holds the current hash value (initialized | ||
158 | * with zero), here we store the previous hash value: | ||
159 | */ | ||
160 | u64 prev_chain_key; | ||
161 | struct lock_class *class; | ||
162 | unsigned long acquire_ip; | ||
163 | struct lockdep_map *instance; | ||
164 | |||
165 | /* | ||
166 | * The lock-stack is unified in that the lock chains of interrupt | ||
167 | * contexts nest ontop of process context chains, but we 'separate' | ||
168 | * the hashes by starting with 0 if we cross into an interrupt | ||
169 | * context, and we also keep do not add cross-context lock | ||
170 | * dependencies - the lock usage graph walking covers that area | ||
171 | * anyway, and we'd just unnecessarily increase the number of | ||
172 | * dependencies otherwise. [Note: hardirq and softirq contexts | ||
173 | * are separated from each other too.] | ||
174 | * | ||
175 | * The following field is used to detect when we cross into an | ||
176 | * interrupt context: | ||
177 | */ | ||
178 | int irq_context; | ||
179 | int trylock; | ||
180 | int read; | ||
181 | int check; | ||
182 | int hardirqs_off; | ||
183 | }; | ||
184 | |||
185 | /* | ||
186 | * Initialization, self-test and debugging-output methods: | ||
187 | */ | ||
188 | extern void lockdep_init(void); | ||
189 | extern void lockdep_info(void); | ||
190 | extern void lockdep_reset(void); | ||
191 | extern void lockdep_reset_lock(struct lockdep_map *lock); | ||
192 | extern void lockdep_free_key_range(void *start, unsigned long size); | ||
193 | |||
194 | extern void lockdep_off(void); | ||
195 | extern void lockdep_on(void); | ||
196 | extern int lockdep_internal(void); | ||
197 | |||
198 | /* | ||
199 | * These methods are used by specific locking variants (spinlocks, | ||
200 | * rwlocks, mutexes and rwsems) to pass init/acquire/release events | ||
201 | * to lockdep: | ||
202 | */ | ||
203 | |||
204 | extern void lockdep_init_map(struct lockdep_map *lock, const char *name, | ||
205 | struct lock_class_key *key); | ||
206 | |||
207 | /* | ||
208 | * Reinitialize a lock key - for cases where there is special locking or | ||
209 | * special initialization of locks so that the validator gets the scope | ||
210 | * of dependencies wrong: they are either too broad (they need a class-split) | ||
211 | * or they are too narrow (they suffer from a false class-split): | ||
212 | */ | ||
213 | #define lockdep_set_class(lock, key) \ | ||
214 | lockdep_init_map(&(lock)->dep_map, #key, key) | ||
215 | #define lockdep_set_class_and_name(lock, key, name) \ | ||
216 | lockdep_init_map(&(lock)->dep_map, name, key) | ||
217 | |||
218 | /* | ||
219 | * Acquire a lock. | ||
220 | * | ||
221 | * Values for "read": | ||
222 | * | ||
223 | * 0: exclusive (write) acquire | ||
224 | * 1: read-acquire (no recursion allowed) | ||
225 | * 2: read-acquire with same-instance recursion allowed | ||
226 | * | ||
227 | * Values for check: | ||
228 | * | ||
229 | * 0: disabled | ||
230 | * 1: simple checks (freeing, held-at-exit-time, etc.) | ||
231 | * 2: full validation | ||
232 | */ | ||
233 | extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass, | ||
234 | int trylock, int read, int check, unsigned long ip); | ||
235 | |||
236 | extern void lock_release(struct lockdep_map *lock, int nested, | ||
237 | unsigned long ip); | ||
238 | |||
239 | # define INIT_LOCKDEP .lockdep_recursion = 0, | ||
240 | |||
241 | #else /* !LOCKDEP */ | ||
242 | |||
243 | static inline void lockdep_off(void) | ||
244 | { | ||
245 | } | ||
246 | |||
247 | static inline void lockdep_on(void) | ||
248 | { | ||
249 | } | ||
250 | |||
251 | static inline int lockdep_internal(void) | ||
252 | { | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | # define lock_acquire(l, s, t, r, c, i) do { } while (0) | ||
257 | # define lock_release(l, n, i) do { } while (0) | ||
258 | # define lockdep_init() do { } while (0) | ||
259 | # define lockdep_info() do { } while (0) | ||
260 | # define lockdep_init_map(lock, name, key) do { (void)(key); } while (0) | ||
261 | # define lockdep_set_class(lock, key) do { (void)(key); } while (0) | ||
262 | # define lockdep_set_class_and_name(lock, key, name) \ | ||
263 | do { (void)(key); } while (0) | ||
264 | # define INIT_LOCKDEP | ||
265 | # define lockdep_reset() do { debug_locks = 1; } while (0) | ||
266 | # define lockdep_free_key_range(start, size) do { } while (0) | ||
267 | /* | ||
268 | * The class key takes no space if lockdep is disabled: | ||
269 | */ | ||
270 | struct lock_class_key { }; | ||
271 | #endif /* !LOCKDEP */ | ||
272 | |||
273 | #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS) | ||
274 | extern void early_init_irq_lock_class(void); | ||
275 | #else | ||
276 | # define early_init_irq_lock_class() do { } while (0) | ||
277 | #endif | ||
278 | |||
279 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
280 | extern void early_boot_irqs_off(void); | ||
281 | extern void early_boot_irqs_on(void); | ||
282 | #else | ||
283 | # define early_boot_irqs_off() do { } while (0) | ||
284 | # define early_boot_irqs_on() do { } while (0) | ||
285 | #endif | ||
286 | |||
287 | /* | ||
288 | * For trivial one-depth nesting of a lock-class, the following | ||
289 | * global define can be used. (Subsystems with multiple levels | ||
290 | * of nesting should define their own lock-nesting subclasses.) | ||
291 | */ | ||
292 | #define SINGLE_DEPTH_NESTING 1 | ||
293 | |||
294 | /* | ||
295 | * Map the dependency ops to NOP or to real lockdep ops, depending | ||
296 | * on the per lock-class debug mode: | ||
297 | */ | ||
298 | |||
299 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
300 | # ifdef CONFIG_PROVE_LOCKING | ||
301 | # define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, i) | ||
302 | # else | ||
303 | # define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, i) | ||
304 | # endif | ||
305 | # define spin_release(l, n, i) lock_release(l, n, i) | ||
306 | #else | ||
307 | # define spin_acquire(l, s, t, i) do { } while (0) | ||
308 | # define spin_release(l, n, i) do { } while (0) | ||
309 | #endif | ||
310 | |||
311 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
312 | # ifdef CONFIG_PROVE_LOCKING | ||
313 | # define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, i) | ||
314 | # define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 2, i) | ||
315 | # else | ||
316 | # define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, i) | ||
317 | # define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 1, i) | ||
318 | # endif | ||
319 | # define rwlock_release(l, n, i) lock_release(l, n, i) | ||
320 | #else | ||
321 | # define rwlock_acquire(l, s, t, i) do { } while (0) | ||
322 | # define rwlock_acquire_read(l, s, t, i) do { } while (0) | ||
323 | # define rwlock_release(l, n, i) do { } while (0) | ||
324 | #endif | ||
325 | |||
326 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
327 | # ifdef CONFIG_PROVE_LOCKING | ||
328 | # define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, i) | ||
329 | # else | ||
330 | # define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, i) | ||
331 | # endif | ||
332 | # define mutex_release(l, n, i) lock_release(l, n, i) | ||
333 | #else | ||
334 | # define mutex_acquire(l, s, t, i) do { } while (0) | ||
335 | # define mutex_release(l, n, i) do { } while (0) | ||
336 | #endif | ||
337 | |||
338 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
339 | # ifdef CONFIG_PROVE_LOCKING | ||
340 | # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, i) | ||
341 | # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, i) | ||
342 | # else | ||
343 | # define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, i) | ||
344 | # define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, i) | ||
345 | # endif | ||
346 | # define rwsem_release(l, n, i) lock_release(l, n, i) | ||
347 | #else | ||
348 | # define rwsem_acquire(l, s, t, i) do { } while (0) | ||
349 | # define rwsem_acquire_read(l, s, t, i) do { } while (0) | ||
350 | # define rwsem_release(l, n, i) do { } while (0) | ||
351 | #endif | ||
352 | |||
353 | #endif /* __LINUX_LOCKDEP_H */ | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index 75179529e399..990957e0929f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/prio_tree.h> | 14 | #include <linux/prio_tree.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
17 | #include <linux/debug_locks.h> | ||
17 | 18 | ||
18 | struct mempolicy; | 19 | struct mempolicy; |
19 | struct anon_vma; | 20 | struct anon_vma; |
@@ -1034,13 +1035,6 @@ static inline void vm_stat_account(struct mm_struct *mm, | |||
1034 | } | 1035 | } |
1035 | #endif /* CONFIG_PROC_FS */ | 1036 | #endif /* CONFIG_PROC_FS */ |
1036 | 1037 | ||
1037 | static inline void | ||
1038 | debug_check_no_locks_freed(const void *from, unsigned long len) | ||
1039 | { | ||
1040 | mutex_debug_check_no_locks_freed(from, len); | ||
1041 | rt_mutex_debug_check_no_locks_freed(from, len); | ||
1042 | } | ||
1043 | |||
1044 | #ifndef CONFIG_DEBUG_PAGEALLOC | 1038 | #ifndef CONFIG_DEBUG_PAGEALLOC |
1045 | static inline void | 1039 | static inline void |
1046 | kernel_map_pages(struct page *page, int numpages, int enable) | 1040 | kernel_map_pages(struct page *page, int numpages, int enable) |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 27e748eb72b0..656b588a9f96 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -150,6 +150,10 @@ struct zone { | |||
150 | unsigned long lowmem_reserve[MAX_NR_ZONES]; | 150 | unsigned long lowmem_reserve[MAX_NR_ZONES]; |
151 | 151 | ||
152 | #ifdef CONFIG_NUMA | 152 | #ifdef CONFIG_NUMA |
153 | /* | ||
154 | * zone reclaim becomes active if more unmapped pages exist. | ||
155 | */ | ||
156 | unsigned long min_unmapped_ratio; | ||
153 | struct per_cpu_pageset *pageset[NR_CPUS]; | 157 | struct per_cpu_pageset *pageset[NR_CPUS]; |
154 | #else | 158 | #else |
155 | struct per_cpu_pageset pageset[NR_CPUS]; | 159 | struct per_cpu_pageset pageset[NR_CPUS]; |
@@ -414,6 +418,8 @@ int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *, | |||
414 | void __user *, size_t *, loff_t *); | 418 | void __user *, size_t *, loff_t *); |
415 | int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, struct file *, | 419 | int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, struct file *, |
416 | void __user *, size_t *, loff_t *); | 420 | void __user *, size_t *, loff_t *); |
421 | int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int, | ||
422 | struct file *, void __user *, size_t *, loff_t *); | ||
417 | 423 | ||
418 | #include <linux/topology.h> | 424 | #include <linux/topology.h> |
419 | /* Returns the number of the current Node. */ | 425 | /* Returns the number of the current Node. */ |
diff --git a/include/linux/module.h b/include/linux/module.h index 9e9dc7c24d95..d06c74fb8c26 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -358,6 +358,7 @@ static inline int module_is_live(struct module *mod) | |||
358 | /* Is this address in a module? (second is with no locks, for oops) */ | 358 | /* Is this address in a module? (second is with no locks, for oops) */ |
359 | struct module *module_text_address(unsigned long addr); | 359 | struct module *module_text_address(unsigned long addr); |
360 | struct module *__module_text_address(unsigned long addr); | 360 | struct module *__module_text_address(unsigned long addr); |
361 | int is_module_address(unsigned long addr); | ||
361 | 362 | ||
362 | /* Returns module and fills in value, defined and namebuf, or NULL if | 363 | /* Returns module and fills in value, defined and namebuf, or NULL if |
363 | symnum out of range. */ | 364 | symnum out of range. */ |
@@ -496,6 +497,11 @@ static inline struct module *__module_text_address(unsigned long addr) | |||
496 | return NULL; | 497 | return NULL; |
497 | } | 498 | } |
498 | 499 | ||
500 | static inline int is_module_address(unsigned long addr) | ||
501 | { | ||
502 | return 0; | ||
503 | } | ||
504 | |||
499 | /* Get/put a kernel symbol (calls should be symmetric) */ | 505 | /* Get/put a kernel symbol (calls should be symmetric) */ |
500 | #define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) | 506 | #define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) |
501 | #define symbol_put(x) do { } while(0) | 507 | #define symbol_put(x) do { } while(0) |
diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h index 8b5769f00467..2537285e1064 100644 --- a/include/linux/mutex-debug.h +++ b/include/linux/mutex-debug.h | |||
@@ -2,22 +2,22 @@ | |||
2 | #define __LINUX_MUTEX_DEBUG_H | 2 | #define __LINUX_MUTEX_DEBUG_H |
3 | 3 | ||
4 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
5 | #include <linux/lockdep.h> | ||
5 | 6 | ||
6 | /* | 7 | /* |
7 | * Mutexes - debugging helpers: | 8 | * Mutexes - debugging helpers: |
8 | */ | 9 | */ |
9 | 10 | ||
10 | #define __DEBUG_MUTEX_INITIALIZER(lockname) \ | 11 | #define __DEBUG_MUTEX_INITIALIZER(lockname) \ |
11 | , .held_list = LIST_HEAD_INIT(lockname.held_list), \ | 12 | , .magic = &lockname |
12 | .name = #lockname , .magic = &lockname | ||
13 | 13 | ||
14 | #define mutex_init(sem) __mutex_init(sem, __FUNCTION__) | 14 | #define mutex_init(mutex) \ |
15 | do { \ | ||
16 | static struct lock_class_key __key; \ | ||
17 | \ | ||
18 | __mutex_init((mutex), #mutex, &__key); \ | ||
19 | } while (0) | ||
15 | 20 | ||
16 | extern void FASTCALL(mutex_destroy(struct mutex *lock)); | 21 | extern void FASTCALL(mutex_destroy(struct mutex *lock)); |
17 | 22 | ||
18 | extern void mutex_debug_show_all_locks(void); | ||
19 | extern void mutex_debug_show_held_locks(struct task_struct *filter); | ||
20 | extern void mutex_debug_check_no_locks_held(struct task_struct *task); | ||
21 | extern void mutex_debug_check_no_locks_freed(const void *from, unsigned long len); | ||
22 | |||
23 | #endif | 23 | #endif |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index f1ac507fa20d..27c48daa3183 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include <linux/spinlock_types.h> | 14 | #include <linux/spinlock_types.h> |
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <linux/lockdep.h> | ||
16 | 17 | ||
17 | #include <asm/atomic.h> | 18 | #include <asm/atomic.h> |
18 | 19 | ||
@@ -50,11 +51,12 @@ struct mutex { | |||
50 | struct list_head wait_list; | 51 | struct list_head wait_list; |
51 | #ifdef CONFIG_DEBUG_MUTEXES | 52 | #ifdef CONFIG_DEBUG_MUTEXES |
52 | struct thread_info *owner; | 53 | struct thread_info *owner; |
53 | struct list_head held_list; | ||
54 | unsigned long acquire_ip; | ||
55 | const char *name; | 54 | const char *name; |
56 | void *magic; | 55 | void *magic; |
57 | #endif | 56 | #endif |
57 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
58 | struct lockdep_map dep_map; | ||
59 | #endif | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | /* | 62 | /* |
@@ -74,24 +76,34 @@ struct mutex_waiter { | |||
74 | # include <linux/mutex-debug.h> | 76 | # include <linux/mutex-debug.h> |
75 | #else | 77 | #else |
76 | # define __DEBUG_MUTEX_INITIALIZER(lockname) | 78 | # define __DEBUG_MUTEX_INITIALIZER(lockname) |
77 | # define mutex_init(mutex) __mutex_init(mutex, NULL) | 79 | # define mutex_init(mutex) \ |
80 | do { \ | ||
81 | static struct lock_class_key __key; \ | ||
82 | \ | ||
83 | __mutex_init((mutex), #mutex, &__key); \ | ||
84 | } while (0) | ||
78 | # define mutex_destroy(mutex) do { } while (0) | 85 | # define mutex_destroy(mutex) do { } while (0) |
79 | # define mutex_debug_show_all_locks() do { } while (0) | 86 | #endif |
80 | # define mutex_debug_show_held_locks(p) do { } while (0) | 87 | |
81 | # define mutex_debug_check_no_locks_held(task) do { } while (0) | 88 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
82 | # define mutex_debug_check_no_locks_freed(from, len) do { } while (0) | 89 | # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ |
90 | , .dep_map = { .name = #lockname } | ||
91 | #else | ||
92 | # define __DEP_MAP_MUTEX_INITIALIZER(lockname) | ||
83 | #endif | 93 | #endif |
84 | 94 | ||
85 | #define __MUTEX_INITIALIZER(lockname) \ | 95 | #define __MUTEX_INITIALIZER(lockname) \ |
86 | { .count = ATOMIC_INIT(1) \ | 96 | { .count = ATOMIC_INIT(1) \ |
87 | , .wait_lock = SPIN_LOCK_UNLOCKED \ | 97 | , .wait_lock = SPIN_LOCK_UNLOCKED \ |
88 | , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \ | 98 | , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \ |
89 | __DEBUG_MUTEX_INITIALIZER(lockname) } | 99 | __DEBUG_MUTEX_INITIALIZER(lockname) \ |
100 | __DEP_MAP_MUTEX_INITIALIZER(lockname) } | ||
90 | 101 | ||
91 | #define DEFINE_MUTEX(mutexname) \ | 102 | #define DEFINE_MUTEX(mutexname) \ |
92 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) | 103 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) |
93 | 104 | ||
94 | extern void fastcall __mutex_init(struct mutex *lock, const char *name); | 105 | extern void __mutex_init(struct mutex *lock, const char *name, |
106 | struct lock_class_key *key); | ||
95 | 107 | ||
96 | /*** | 108 | /*** |
97 | * mutex_is_locked - is the mutex locked | 109 | * mutex_is_locked - is the mutex locked |
@@ -110,6 +122,13 @@ static inline int fastcall mutex_is_locked(struct mutex *lock) | |||
110 | */ | 122 | */ |
111 | extern void fastcall mutex_lock(struct mutex *lock); | 123 | extern void fastcall mutex_lock(struct mutex *lock); |
112 | extern int fastcall mutex_lock_interruptible(struct mutex *lock); | 124 | extern int fastcall mutex_lock_interruptible(struct mutex *lock); |
125 | |||
126 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
127 | extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass); | ||
128 | #else | ||
129 | # define mutex_lock_nested(lock, subclass) mutex_lock(lock) | ||
130 | #endif | ||
131 | |||
113 | /* | 132 | /* |
114 | * NOTE: mutex_trylock() follows the spin_trylock() convention, | 133 | * NOTE: mutex_trylock() follows the spin_trylock() convention, |
115 | * not the down_trylock() convention! | 134 | * not the down_trylock() convention! |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 51dbab9710c7..7ff386a6ae87 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -65,7 +65,7 @@ struct raw_notifier_head { | |||
65 | } while (0) | 65 | } while (0) |
66 | 66 | ||
67 | #define ATOMIC_NOTIFIER_INIT(name) { \ | 67 | #define ATOMIC_NOTIFIER_INIT(name) { \ |
68 | .lock = SPIN_LOCK_UNLOCKED, \ | 68 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
69 | .head = NULL } | 69 | .head = NULL } |
70 | #define BLOCKING_NOTIFIER_INIT(name) { \ | 70 | #define BLOCKING_NOTIFIER_INIT(name) { \ |
71 | .rwsem = __RWSEM_INITIALIZER((name).rwsem), \ | 71 | .rwsem = __RWSEM_INITIALIZER((name).rwsem), \ |
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index fa4a3b82ba70..5d41dee82f80 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h | |||
@@ -29,8 +29,6 @@ struct rt_mutex { | |||
29 | struct task_struct *owner; | 29 | struct task_struct *owner; |
30 | #ifdef CONFIG_DEBUG_RT_MUTEXES | 30 | #ifdef CONFIG_DEBUG_RT_MUTEXES |
31 | int save_state; | 31 | int save_state; |
32 | struct list_head held_list_entry; | ||
33 | unsigned long acquire_ip; | ||
34 | const char *name, *file; | 32 | const char *name, *file; |
35 | int line; | 33 | int line; |
36 | void *magic; | 34 | void *magic; |
@@ -98,14 +96,6 @@ extern int rt_mutex_trylock(struct rt_mutex *lock); | |||
98 | 96 | ||
99 | extern void rt_mutex_unlock(struct rt_mutex *lock); | 97 | extern void rt_mutex_unlock(struct rt_mutex *lock); |
100 | 98 | ||
101 | #ifdef CONFIG_DEBUG_RT_MUTEXES | ||
102 | # define INIT_RT_MUTEX_DEBUG(tsk) \ | ||
103 | .held_list_head = LIST_HEAD_INIT(tsk.held_list_head), \ | ||
104 | .held_list_lock = SPIN_LOCK_UNLOCKED | ||
105 | #else | ||
106 | # define INIT_RT_MUTEX_DEBUG(tsk) | ||
107 | #endif | ||
108 | |||
109 | #ifdef CONFIG_RT_MUTEXES | 99 | #ifdef CONFIG_RT_MUTEXES |
110 | # define INIT_RT_MUTEXES(tsk) \ | 100 | # define INIT_RT_MUTEXES(tsk) \ |
111 | .pi_waiters = PLIST_HEAD_INIT(tsk.pi_waiters, tsk.pi_lock), \ | 101 | .pi_waiters = PLIST_HEAD_INIT(tsk.pi_waiters, tsk.pi_lock), \ |
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h index f30f805080ae..ae1fcadd598e 100644 --- a/include/linux/rwsem-spinlock.h +++ b/include/linux/rwsem-spinlock.h | |||
@@ -32,30 +32,37 @@ struct rw_semaphore { | |||
32 | __s32 activity; | 32 | __s32 activity; |
33 | spinlock_t wait_lock; | 33 | spinlock_t wait_lock; |
34 | struct list_head wait_list; | 34 | struct list_head wait_list; |
35 | #if RWSEM_DEBUG | 35 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
36 | int debug; | 36 | struct lockdep_map dep_map; |
37 | #endif | 37 | #endif |
38 | }; | 38 | }; |
39 | 39 | ||
40 | /* | 40 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
41 | * initialisation | 41 | # define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } |
42 | */ | ||
43 | #if RWSEM_DEBUG | ||
44 | #define __RWSEM_DEBUG_INIT , 0 | ||
45 | #else | 42 | #else |
46 | #define __RWSEM_DEBUG_INIT /* */ | 43 | # define __RWSEM_DEP_MAP_INIT(lockname) |
47 | #endif | 44 | #endif |
48 | 45 | ||
49 | #define __RWSEM_INITIALIZER(name) \ | 46 | #define __RWSEM_INITIALIZER(name) \ |
50 | { 0, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __RWSEM_DEBUG_INIT } | 47 | { 0, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } |
51 | 48 | ||
52 | #define DECLARE_RWSEM(name) \ | 49 | #define DECLARE_RWSEM(name) \ |
53 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 50 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
54 | 51 | ||
55 | extern void FASTCALL(init_rwsem(struct rw_semaphore *sem)); | 52 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, |
53 | struct lock_class_key *key); | ||
54 | |||
55 | #define init_rwsem(sem) \ | ||
56 | do { \ | ||
57 | static struct lock_class_key __key; \ | ||
58 | \ | ||
59 | __init_rwsem((sem), #sem, &__key); \ | ||
60 | } while (0) | ||
61 | |||
56 | extern void FASTCALL(__down_read(struct rw_semaphore *sem)); | 62 | extern void FASTCALL(__down_read(struct rw_semaphore *sem)); |
57 | extern int FASTCALL(__down_read_trylock(struct rw_semaphore *sem)); | 63 | extern int FASTCALL(__down_read_trylock(struct rw_semaphore *sem)); |
58 | extern void FASTCALL(__down_write(struct rw_semaphore *sem)); | 64 | extern void FASTCALL(__down_write(struct rw_semaphore *sem)); |
65 | extern void FASTCALL(__down_write_nested(struct rw_semaphore *sem, int subclass)); | ||
59 | extern int FASTCALL(__down_write_trylock(struct rw_semaphore *sem)); | 66 | extern int FASTCALL(__down_write_trylock(struct rw_semaphore *sem)); |
60 | extern void FASTCALL(__up_read(struct rw_semaphore *sem)); | 67 | extern void FASTCALL(__up_read(struct rw_semaphore *sem)); |
61 | extern void FASTCALL(__up_write(struct rw_semaphore *sem)); | 68 | extern void FASTCALL(__up_write(struct rw_semaphore *sem)); |
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index f99fe90732ab..658afb37c3f5 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h | |||
@@ -9,8 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/linkage.h> | 10 | #include <linux/linkage.h> |
11 | 11 | ||
12 | #define RWSEM_DEBUG 0 | ||
13 | |||
14 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
15 | 13 | ||
16 | #include <linux/types.h> | 14 | #include <linux/types.h> |
@@ -26,89 +24,58 @@ struct rw_semaphore; | |||
26 | #include <asm/rwsem.h> /* use an arch-specific implementation */ | 24 | #include <asm/rwsem.h> /* use an arch-specific implementation */ |
27 | #endif | 25 | #endif |
28 | 26 | ||
29 | #ifndef rwsemtrace | ||
30 | #if RWSEM_DEBUG | ||
31 | extern void FASTCALL(rwsemtrace(struct rw_semaphore *sem, const char *str)); | ||
32 | #else | ||
33 | #define rwsemtrace(SEM,FMT) | ||
34 | #endif | ||
35 | #endif | ||
36 | |||
37 | /* | 27 | /* |
38 | * lock for reading | 28 | * lock for reading |
39 | */ | 29 | */ |
40 | static inline void down_read(struct rw_semaphore *sem) | 30 | extern void down_read(struct rw_semaphore *sem); |
41 | { | ||
42 | might_sleep(); | ||
43 | rwsemtrace(sem,"Entering down_read"); | ||
44 | __down_read(sem); | ||
45 | rwsemtrace(sem,"Leaving down_read"); | ||
46 | } | ||
47 | 31 | ||
48 | /* | 32 | /* |
49 | * trylock for reading -- returns 1 if successful, 0 if contention | 33 | * trylock for reading -- returns 1 if successful, 0 if contention |
50 | */ | 34 | */ |
51 | static inline int down_read_trylock(struct rw_semaphore *sem) | 35 | extern int down_read_trylock(struct rw_semaphore *sem); |
52 | { | ||
53 | int ret; | ||
54 | rwsemtrace(sem,"Entering down_read_trylock"); | ||
55 | ret = __down_read_trylock(sem); | ||
56 | rwsemtrace(sem,"Leaving down_read_trylock"); | ||
57 | return ret; | ||
58 | } | ||
59 | 36 | ||
60 | /* | 37 | /* |
61 | * lock for writing | 38 | * lock for writing |
62 | */ | 39 | */ |
63 | static inline void down_write(struct rw_semaphore *sem) | 40 | extern void down_write(struct rw_semaphore *sem); |
64 | { | ||
65 | might_sleep(); | ||
66 | rwsemtrace(sem,"Entering down_write"); | ||
67 | __down_write(sem); | ||
68 | rwsemtrace(sem,"Leaving down_write"); | ||
69 | } | ||
70 | 41 | ||
71 | /* | 42 | /* |
72 | * trylock for writing -- returns 1 if successful, 0 if contention | 43 | * trylock for writing -- returns 1 if successful, 0 if contention |
73 | */ | 44 | */ |
74 | static inline int down_write_trylock(struct rw_semaphore *sem) | 45 | extern int down_write_trylock(struct rw_semaphore *sem); |
75 | { | ||
76 | int ret; | ||
77 | rwsemtrace(sem,"Entering down_write_trylock"); | ||
78 | ret = __down_write_trylock(sem); | ||
79 | rwsemtrace(sem,"Leaving down_write_trylock"); | ||
80 | return ret; | ||
81 | } | ||
82 | 46 | ||
83 | /* | 47 | /* |
84 | * release a read lock | 48 | * release a read lock |
85 | */ | 49 | */ |
86 | static inline void up_read(struct rw_semaphore *sem) | 50 | extern void up_read(struct rw_semaphore *sem); |
87 | { | ||
88 | rwsemtrace(sem,"Entering up_read"); | ||
89 | __up_read(sem); | ||
90 | rwsemtrace(sem,"Leaving up_read"); | ||
91 | } | ||
92 | 51 | ||
93 | /* | 52 | /* |
94 | * release a write lock | 53 | * release a write lock |
95 | */ | 54 | */ |
96 | static inline void up_write(struct rw_semaphore *sem) | 55 | extern void up_write(struct rw_semaphore *sem); |
97 | { | ||
98 | rwsemtrace(sem,"Entering up_write"); | ||
99 | __up_write(sem); | ||
100 | rwsemtrace(sem,"Leaving up_write"); | ||
101 | } | ||
102 | 56 | ||
103 | /* | 57 | /* |
104 | * downgrade write lock to read lock | 58 | * downgrade write lock to read lock |
105 | */ | 59 | */ |
106 | static inline void downgrade_write(struct rw_semaphore *sem) | 60 | extern void downgrade_write(struct rw_semaphore *sem); |
107 | { | 61 | |
108 | rwsemtrace(sem,"Entering downgrade_write"); | 62 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
109 | __downgrade_write(sem); | 63 | /* |
110 | rwsemtrace(sem,"Leaving downgrade_write"); | 64 | * nested locking: |
111 | } | 65 | */ |
66 | extern void down_read_nested(struct rw_semaphore *sem, int subclass); | ||
67 | extern void down_write_nested(struct rw_semaphore *sem, int subclass); | ||
68 | /* | ||
69 | * Take/release a lock when not the owner will release it: | ||
70 | */ | ||
71 | extern void down_read_non_owner(struct rw_semaphore *sem); | ||
72 | extern void up_read_non_owner(struct rw_semaphore *sem); | ||
73 | #else | ||
74 | # define down_read_nested(sem, subclass) down_read(sem) | ||
75 | # define down_write_nested(sem, subclass) down_write(sem) | ||
76 | # define down_read_non_owner(sem) down_read(sem) | ||
77 | # define up_read_non_owner(sem) up_read(sem) | ||
78 | #endif | ||
112 | 79 | ||
113 | #endif /* __KERNEL__ */ | 80 | #endif /* __KERNEL__ */ |
114 | #endif /* _LINUX_RWSEM_H */ | 81 | #endif /* _LINUX_RWSEM_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index aaf723308ed4..1c876e27ff93 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -184,11 +184,11 @@ extern unsigned long weighted_cpuload(const int cpu); | |||
184 | extern rwlock_t tasklist_lock; | 184 | extern rwlock_t tasklist_lock; |
185 | extern spinlock_t mmlist_lock; | 185 | extern spinlock_t mmlist_lock; |
186 | 186 | ||
187 | typedef struct task_struct task_t; | 187 | struct task_struct; |
188 | 188 | ||
189 | extern void sched_init(void); | 189 | extern void sched_init(void); |
190 | extern void sched_init_smp(void); | 190 | extern void sched_init_smp(void); |
191 | extern void init_idle(task_t *idle, int cpu); | 191 | extern void init_idle(struct task_struct *idle, int cpu); |
192 | 192 | ||
193 | extern cpumask_t nohz_cpu_mask; | 193 | extern cpumask_t nohz_cpu_mask; |
194 | 194 | ||
@@ -383,7 +383,7 @@ struct signal_struct { | |||
383 | wait_queue_head_t wait_chldexit; /* for wait4() */ | 383 | wait_queue_head_t wait_chldexit; /* for wait4() */ |
384 | 384 | ||
385 | /* current thread group signal load-balancing target: */ | 385 | /* current thread group signal load-balancing target: */ |
386 | task_t *curr_target; | 386 | struct task_struct *curr_target; |
387 | 387 | ||
388 | /* shared signal handling: */ | 388 | /* shared signal handling: */ |
389 | struct sigpending shared_pending; | 389 | struct sigpending shared_pending; |
@@ -534,7 +534,6 @@ extern struct user_struct *find_user(uid_t); | |||
534 | extern struct user_struct root_user; | 534 | extern struct user_struct root_user; |
535 | #define INIT_USER (&root_user) | 535 | #define INIT_USER (&root_user) |
536 | 536 | ||
537 | typedef struct prio_array prio_array_t; | ||
538 | struct backing_dev_info; | 537 | struct backing_dev_info; |
539 | struct reclaim_state; | 538 | struct reclaim_state; |
540 | 539 | ||
@@ -699,7 +698,7 @@ extern int groups_search(struct group_info *group_info, gid_t grp); | |||
699 | ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) | 698 | ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) |
700 | 699 | ||
701 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK | 700 | #ifdef ARCH_HAS_PREFETCH_SWITCH_STACK |
702 | extern void prefetch_stack(struct task_struct*); | 701 | extern void prefetch_stack(struct task_struct *t); |
703 | #else | 702 | #else |
704 | static inline void prefetch_stack(struct task_struct *t) { } | 703 | static inline void prefetch_stack(struct task_struct *t) { } |
705 | #endif | 704 | #endif |
@@ -715,6 +714,8 @@ enum sleep_type { | |||
715 | SLEEP_INTERRUPTED, | 714 | SLEEP_INTERRUPTED, |
716 | }; | 715 | }; |
717 | 716 | ||
717 | struct prio_array; | ||
718 | |||
718 | struct task_struct { | 719 | struct task_struct { |
719 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ | 720 | volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ |
720 | struct thread_info *thread_info; | 721 | struct thread_info *thread_info; |
@@ -732,7 +733,7 @@ struct task_struct { | |||
732 | int load_weight; /* for niceness load balancing purposes */ | 733 | int load_weight; /* for niceness load balancing purposes */ |
733 | int prio, static_prio, normal_prio; | 734 | int prio, static_prio, normal_prio; |
734 | struct list_head run_list; | 735 | struct list_head run_list; |
735 | prio_array_t *array; | 736 | struct prio_array *array; |
736 | 737 | ||
737 | unsigned short ioprio; | 738 | unsigned short ioprio; |
738 | unsigned int btrace_seq; | 739 | unsigned int btrace_seq; |
@@ -865,16 +866,34 @@ struct task_struct { | |||
865 | struct plist_head pi_waiters; | 866 | struct plist_head pi_waiters; |
866 | /* Deadlock detection and priority inheritance handling */ | 867 | /* Deadlock detection and priority inheritance handling */ |
867 | struct rt_mutex_waiter *pi_blocked_on; | 868 | struct rt_mutex_waiter *pi_blocked_on; |
868 | # ifdef CONFIG_DEBUG_RT_MUTEXES | ||
869 | spinlock_t held_list_lock; | ||
870 | struct list_head held_list_head; | ||
871 | # endif | ||
872 | #endif | 869 | #endif |
873 | 870 | ||
874 | #ifdef CONFIG_DEBUG_MUTEXES | 871 | #ifdef CONFIG_DEBUG_MUTEXES |
875 | /* mutex deadlock detection */ | 872 | /* mutex deadlock detection */ |
876 | struct mutex_waiter *blocked_on; | 873 | struct mutex_waiter *blocked_on; |
877 | #endif | 874 | #endif |
875 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
876 | unsigned int irq_events; | ||
877 | int hardirqs_enabled; | ||
878 | unsigned long hardirq_enable_ip; | ||
879 | unsigned int hardirq_enable_event; | ||
880 | unsigned long hardirq_disable_ip; | ||
881 | unsigned int hardirq_disable_event; | ||
882 | int softirqs_enabled; | ||
883 | unsigned long softirq_disable_ip; | ||
884 | unsigned int softirq_disable_event; | ||
885 | unsigned long softirq_enable_ip; | ||
886 | unsigned int softirq_enable_event; | ||
887 | int hardirq_context; | ||
888 | int softirq_context; | ||
889 | #endif | ||
890 | #ifdef CONFIG_LOCKDEP | ||
891 | # define MAX_LOCK_DEPTH 30UL | ||
892 | u64 curr_chain_key; | ||
893 | int lockdep_depth; | ||
894 | struct held_lock held_locks[MAX_LOCK_DEPTH]; | ||
895 | unsigned int lockdep_recursion; | ||
896 | #endif | ||
878 | 897 | ||
879 | /* journalling filesystem info */ | 898 | /* journalling filesystem info */ |
880 | void *journal_info; | 899 | void *journal_info; |
@@ -1013,9 +1032,9 @@ static inline void put_task_struct(struct task_struct *t) | |||
1013 | #define used_math() tsk_used_math(current) | 1032 | #define used_math() tsk_used_math(current) |
1014 | 1033 | ||
1015 | #ifdef CONFIG_SMP | 1034 | #ifdef CONFIG_SMP |
1016 | extern int set_cpus_allowed(task_t *p, cpumask_t new_mask); | 1035 | extern int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask); |
1017 | #else | 1036 | #else |
1018 | static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask) | 1037 | static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) |
1019 | { | 1038 | { |
1020 | if (!cpu_isset(0, new_mask)) | 1039 | if (!cpu_isset(0, new_mask)) |
1021 | return -EINVAL; | 1040 | return -EINVAL; |
@@ -1024,7 +1043,8 @@ static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask) | |||
1024 | #endif | 1043 | #endif |
1025 | 1044 | ||
1026 | extern unsigned long long sched_clock(void); | 1045 | extern unsigned long long sched_clock(void); |
1027 | extern unsigned long long current_sched_time(const task_t *current_task); | 1046 | extern unsigned long long |
1047 | current_sched_time(const struct task_struct *current_task); | ||
1028 | 1048 | ||
1029 | /* sched_exec is called by processes performing an exec */ | 1049 | /* sched_exec is called by processes performing an exec */ |
1030 | #ifdef CONFIG_SMP | 1050 | #ifdef CONFIG_SMP |
@@ -1042,27 +1062,27 @@ static inline void idle_task_exit(void) {} | |||
1042 | extern void sched_idle_next(void); | 1062 | extern void sched_idle_next(void); |
1043 | 1063 | ||
1044 | #ifdef CONFIG_RT_MUTEXES | 1064 | #ifdef CONFIG_RT_MUTEXES |
1045 | extern int rt_mutex_getprio(task_t *p); | 1065 | extern int rt_mutex_getprio(struct task_struct *p); |
1046 | extern void rt_mutex_setprio(task_t *p, int prio); | 1066 | extern void rt_mutex_setprio(struct task_struct *p, int prio); |
1047 | extern void rt_mutex_adjust_pi(task_t *p); | 1067 | extern void rt_mutex_adjust_pi(struct task_struct *p); |
1048 | #else | 1068 | #else |
1049 | static inline int rt_mutex_getprio(task_t *p) | 1069 | static inline int rt_mutex_getprio(struct task_struct *p) |
1050 | { | 1070 | { |
1051 | return p->normal_prio; | 1071 | return p->normal_prio; |
1052 | } | 1072 | } |
1053 | # define rt_mutex_adjust_pi(p) do { } while (0) | 1073 | # define rt_mutex_adjust_pi(p) do { } while (0) |
1054 | #endif | 1074 | #endif |
1055 | 1075 | ||
1056 | extern void set_user_nice(task_t *p, long nice); | 1076 | extern void set_user_nice(struct task_struct *p, long nice); |
1057 | extern int task_prio(const task_t *p); | 1077 | extern int task_prio(const struct task_struct *p); |
1058 | extern int task_nice(const task_t *p); | 1078 | extern int task_nice(const struct task_struct *p); |
1059 | extern int can_nice(const task_t *p, const int nice); | 1079 | extern int can_nice(const struct task_struct *p, const int nice); |
1060 | extern int task_curr(const task_t *p); | 1080 | extern int task_curr(const struct task_struct *p); |
1061 | extern int idle_cpu(int cpu); | 1081 | extern int idle_cpu(int cpu); |
1062 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); | 1082 | extern int sched_setscheduler(struct task_struct *, int, struct sched_param *); |
1063 | extern task_t *idle_task(int cpu); | 1083 | extern struct task_struct *idle_task(int cpu); |
1064 | extern task_t *curr_task(int cpu); | 1084 | extern struct task_struct *curr_task(int cpu); |
1065 | extern void set_curr_task(int cpu, task_t *p); | 1085 | extern void set_curr_task(int cpu, struct task_struct *p); |
1066 | 1086 | ||
1067 | void yield(void); | 1087 | void yield(void); |
1068 | 1088 | ||
@@ -1119,8 +1139,8 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, | |||
1119 | #else | 1139 | #else |
1120 | static inline void kick_process(struct task_struct *tsk) { } | 1140 | static inline void kick_process(struct task_struct *tsk) { } |
1121 | #endif | 1141 | #endif |
1122 | extern void FASTCALL(sched_fork(task_t * p, int clone_flags)); | 1142 | extern void FASTCALL(sched_fork(struct task_struct * p, int clone_flags)); |
1123 | extern void FASTCALL(sched_exit(task_t * p)); | 1143 | extern void FASTCALL(sched_exit(struct task_struct * p)); |
1124 | 1144 | ||
1125 | extern int in_group_p(gid_t); | 1145 | extern int in_group_p(gid_t); |
1126 | extern int in_egroup_p(gid_t); | 1146 | extern int in_egroup_p(gid_t); |
@@ -1225,17 +1245,17 @@ extern NORET_TYPE void do_group_exit(int); | |||
1225 | extern void daemonize(const char *, ...); | 1245 | extern void daemonize(const char *, ...); |
1226 | extern int allow_signal(int); | 1246 | extern int allow_signal(int); |
1227 | extern int disallow_signal(int); | 1247 | extern int disallow_signal(int); |
1228 | extern task_t *child_reaper; | 1248 | extern struct task_struct *child_reaper; |
1229 | 1249 | ||
1230 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); | 1250 | extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *); |
1231 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); | 1251 | extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); |
1232 | task_t *fork_idle(int); | 1252 | struct task_struct *fork_idle(int); |
1233 | 1253 | ||
1234 | extern void set_task_comm(struct task_struct *tsk, char *from); | 1254 | extern void set_task_comm(struct task_struct *tsk, char *from); |
1235 | extern void get_task_comm(char *to, struct task_struct *tsk); | 1255 | extern void get_task_comm(char *to, struct task_struct *tsk); |
1236 | 1256 | ||
1237 | #ifdef CONFIG_SMP | 1257 | #ifdef CONFIG_SMP |
1238 | extern void wait_task_inactive(task_t * p); | 1258 | extern void wait_task_inactive(struct task_struct * p); |
1239 | #else | 1259 | #else |
1240 | #define wait_task_inactive(p) do { } while (0) | 1260 | #define wait_task_inactive(p) do { } while (0) |
1241 | #endif | 1261 | #endif |
@@ -1261,13 +1281,13 @@ extern void wait_task_inactive(task_t * p); | |||
1261 | /* de_thread depends on thread_group_leader not being a pid based check */ | 1281 | /* de_thread depends on thread_group_leader not being a pid based check */ |
1262 | #define thread_group_leader(p) (p == p->group_leader) | 1282 | #define thread_group_leader(p) (p == p->group_leader) |
1263 | 1283 | ||
1264 | static inline task_t *next_thread(const task_t *p) | 1284 | static inline struct task_struct *next_thread(const struct task_struct *p) |
1265 | { | 1285 | { |
1266 | return list_entry(rcu_dereference(p->thread_group.next), | 1286 | return list_entry(rcu_dereference(p->thread_group.next), |
1267 | task_t, thread_group); | 1287 | struct task_struct, thread_group); |
1268 | } | 1288 | } |
1269 | 1289 | ||
1270 | static inline int thread_group_empty(task_t *p) | 1290 | static inline int thread_group_empty(struct task_struct *p) |
1271 | { | 1291 | { |
1272 | return list_empty(&p->thread_group); | 1292 | return list_empty(&p->thread_group); |
1273 | } | 1293 | } |
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index 7bc5c7c12b54..46000936f8f1 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h | |||
@@ -38,9 +38,17 @@ typedef struct { | |||
38 | * These macros triggered gcc-3.x compile-time problems. We think these are | 38 | * These macros triggered gcc-3.x compile-time problems. We think these are |
39 | * OK now. Be cautious. | 39 | * OK now. Be cautious. |
40 | */ | 40 | */ |
41 | #define SEQLOCK_UNLOCKED { 0, SPIN_LOCK_UNLOCKED } | 41 | #define __SEQLOCK_UNLOCKED(lockname) \ |
42 | #define seqlock_init(x) do { *(x) = (seqlock_t) SEQLOCK_UNLOCKED; } while (0) | 42 | { 0, __SPIN_LOCK_UNLOCKED(lockname) } |
43 | 43 | ||
44 | #define SEQLOCK_UNLOCKED \ | ||
45 | __SEQLOCK_UNLOCKED(old_style_seqlock_init) | ||
46 | |||
47 | #define seqlock_init(x) \ | ||
48 | do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); } while (0) | ||
49 | |||
50 | #define DEFINE_SEQLOCK(x) \ | ||
51 | seqlock_t x = __SEQLOCK_UNLOCKED(x) | ||
44 | 52 | ||
45 | /* Lock out other writers and update the count. | 53 | /* Lock out other writers and update the count. |
46 | * Acts like a normal spin_lock/unlock. | 54 | * Acts like a normal spin_lock/unlock. |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 57d7d4965f9a..3597b4f14389 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -604,9 +604,12 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) | |||
604 | return list_->qlen; | 604 | return list_->qlen; |
605 | } | 605 | } |
606 | 606 | ||
607 | extern struct lock_class_key skb_queue_lock_key; | ||
608 | |||
607 | static inline void skb_queue_head_init(struct sk_buff_head *list) | 609 | static inline void skb_queue_head_init(struct sk_buff_head *list) |
608 | { | 610 | { |
609 | spin_lock_init(&list->lock); | 611 | spin_lock_init(&list->lock); |
612 | lockdep_set_class(&list->lock, &skb_queue_lock_key); | ||
610 | list->prev = list->next = (struct sk_buff *)list; | 613 | list->prev = list->next = (struct sk_buff *)list; |
611 | list->qlen = 0; | 614 | list->qlen = 0; |
612 | } | 615 | } |
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index ae23beef9cc9..31473db92d3b 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h | |||
@@ -82,14 +82,40 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); | |||
82 | /* | 82 | /* |
83 | * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): | 83 | * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): |
84 | */ | 84 | */ |
85 | #if defined(CONFIG_SMP) | 85 | #ifdef CONFIG_SMP |
86 | # include <asm/spinlock.h> | 86 | # include <asm/spinlock.h> |
87 | #else | 87 | #else |
88 | # include <linux/spinlock_up.h> | 88 | # include <linux/spinlock_up.h> |
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | #define spin_lock_init(lock) do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0) | 91 | #ifdef CONFIG_DEBUG_SPINLOCK |
92 | #define rwlock_init(lock) do { *(lock) = RW_LOCK_UNLOCKED; } while (0) | 92 | extern void __spin_lock_init(spinlock_t *lock, const char *name, |
93 | struct lock_class_key *key); | ||
94 | # define spin_lock_init(lock) \ | ||
95 | do { \ | ||
96 | static struct lock_class_key __key; \ | ||
97 | \ | ||
98 | __spin_lock_init((lock), #lock, &__key); \ | ||
99 | } while (0) | ||
100 | |||
101 | #else | ||
102 | # define spin_lock_init(lock) \ | ||
103 | do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0) | ||
104 | #endif | ||
105 | |||
106 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
107 | extern void __rwlock_init(rwlock_t *lock, const char *name, | ||
108 | struct lock_class_key *key); | ||
109 | # define rwlock_init(lock) \ | ||
110 | do { \ | ||
111 | static struct lock_class_key __key; \ | ||
112 | \ | ||
113 | __rwlock_init((lock), #lock, &__key); \ | ||
114 | } while (0) | ||
115 | #else | ||
116 | # define rwlock_init(lock) \ | ||
117 | do { *(lock) = RW_LOCK_UNLOCKED; } while (0) | ||
118 | #endif | ||
93 | 119 | ||
94 | #define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) | 120 | #define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) |
95 | 121 | ||
@@ -113,7 +139,6 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); | |||
113 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) | 139 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) |
114 | extern int _raw_spin_trylock(spinlock_t *lock); | 140 | extern int _raw_spin_trylock(spinlock_t *lock); |
115 | extern void _raw_spin_unlock(spinlock_t *lock); | 141 | extern void _raw_spin_unlock(spinlock_t *lock); |
116 | |||
117 | extern void _raw_read_lock(rwlock_t *lock); | 142 | extern void _raw_read_lock(rwlock_t *lock); |
118 | extern int _raw_read_trylock(rwlock_t *lock); | 143 | extern int _raw_read_trylock(rwlock_t *lock); |
119 | extern void _raw_read_unlock(rwlock_t *lock); | 144 | extern void _raw_read_unlock(rwlock_t *lock); |
@@ -121,17 +146,17 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); | |||
121 | extern int _raw_write_trylock(rwlock_t *lock); | 146 | extern int _raw_write_trylock(rwlock_t *lock); |
122 | extern void _raw_write_unlock(rwlock_t *lock); | 147 | extern void _raw_write_unlock(rwlock_t *lock); |
123 | #else | 148 | #else |
124 | # define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) | ||
125 | # define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) | ||
126 | # define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) | 149 | # define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) |
127 | # define _raw_spin_lock_flags(lock, flags) \ | 150 | # define _raw_spin_lock_flags(lock, flags) \ |
128 | __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) | 151 | __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) |
152 | # define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) | ||
153 | # define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) | ||
129 | # define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) | 154 | # define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) |
130 | # define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) | ||
131 | # define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) | ||
132 | # define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) | ||
133 | # define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) | 155 | # define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) |
156 | # define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) | ||
157 | # define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) | ||
134 | # define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) | 158 | # define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) |
159 | # define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) | ||
135 | #endif | 160 | #endif |
136 | 161 | ||
137 | #define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) | 162 | #define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) |
@@ -147,6 +172,13 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); | |||
147 | #define write_trylock(lock) __cond_lock(_write_trylock(lock)) | 172 | #define write_trylock(lock) __cond_lock(_write_trylock(lock)) |
148 | 173 | ||
149 | #define spin_lock(lock) _spin_lock(lock) | 174 | #define spin_lock(lock) _spin_lock(lock) |
175 | |||
176 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
177 | # define spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) | ||
178 | #else | ||
179 | # define spin_lock_nested(lock, subclass) _spin_lock(lock) | ||
180 | #endif | ||
181 | |||
150 | #define write_lock(lock) _write_lock(lock) | 182 | #define write_lock(lock) _write_lock(lock) |
151 | #define read_lock(lock) _read_lock(lock) | 183 | #define read_lock(lock) _read_lock(lock) |
152 | 184 | ||
@@ -172,21 +204,18 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); | |||
172 | /* | 204 | /* |
173 | * We inline the unlock functions in the nondebug case: | 205 | * We inline the unlock functions in the nondebug case: |
174 | */ | 206 | */ |
175 | #if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) | 207 | #if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || \ |
208 | !defined(CONFIG_SMP) | ||
176 | # define spin_unlock(lock) _spin_unlock(lock) | 209 | # define spin_unlock(lock) _spin_unlock(lock) |
177 | # define read_unlock(lock) _read_unlock(lock) | 210 | # define read_unlock(lock) _read_unlock(lock) |
178 | # define write_unlock(lock) _write_unlock(lock) | 211 | # define write_unlock(lock) _write_unlock(lock) |
179 | #else | ||
180 | # define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) | ||
181 | # define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock) | ||
182 | # define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock) | ||
183 | #endif | ||
184 | |||
185 | #if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP) | ||
186 | # define spin_unlock_irq(lock) _spin_unlock_irq(lock) | 212 | # define spin_unlock_irq(lock) _spin_unlock_irq(lock) |
187 | # define read_unlock_irq(lock) _read_unlock_irq(lock) | 213 | # define read_unlock_irq(lock) _read_unlock_irq(lock) |
188 | # define write_unlock_irq(lock) _write_unlock_irq(lock) | 214 | # define write_unlock_irq(lock) _write_unlock_irq(lock) |
189 | #else | 215 | #else |
216 | # define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) | ||
217 | # define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock) | ||
218 | # define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock) | ||
190 | # define spin_unlock_irq(lock) \ | 219 | # define spin_unlock_irq(lock) \ |
191 | do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0) | 220 | do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0) |
192 | # define read_unlock_irq(lock) \ | 221 | # define read_unlock_irq(lock) \ |
diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 78e6989ffb54..b2c4f8299464 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h | |||
@@ -20,6 +20,8 @@ int in_lock_functions(unsigned long addr); | |||
20 | #define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) | 20 | #define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) |
21 | 21 | ||
22 | void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t); | 22 | void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t); |
23 | void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass) | ||
24 | __acquires(spinlock_t); | ||
23 | void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t); | 25 | void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t); |
24 | void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t); | 26 | void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t); |
25 | void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t); | 27 | void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t); |
diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h index cd81cee566f4..67faa044c5f5 100644 --- a/include/linux/spinlock_api_up.h +++ b/include/linux/spinlock_api_up.h | |||
@@ -49,6 +49,7 @@ | |||
49 | do { local_irq_restore(flags); __UNLOCK(lock); } while (0) | 49 | do { local_irq_restore(flags); __UNLOCK(lock); } while (0) |
50 | 50 | ||
51 | #define _spin_lock(lock) __LOCK(lock) | 51 | #define _spin_lock(lock) __LOCK(lock) |
52 | #define _spin_lock_nested(lock, subclass) __LOCK(lock) | ||
52 | #define _read_lock(lock) __LOCK(lock) | 53 | #define _read_lock(lock) __LOCK(lock) |
53 | #define _write_lock(lock) __LOCK(lock) | 54 | #define _write_lock(lock) __LOCK(lock) |
54 | #define _spin_lock_bh(lock) __LOCK_BH(lock) | 55 | #define _spin_lock_bh(lock) __LOCK_BH(lock) |
diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index 9cb51e070390..dc5fb69e4de9 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h | |||
@@ -9,6 +9,8 @@ | |||
9 | * Released under the General Public License (GPL). | 9 | * Released under the General Public License (GPL). |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/lockdep.h> | ||
13 | |||
12 | #if defined(CONFIG_SMP) | 14 | #if defined(CONFIG_SMP) |
13 | # include <asm/spinlock_types.h> | 15 | # include <asm/spinlock_types.h> |
14 | #else | 16 | #else |
@@ -24,6 +26,9 @@ typedef struct { | |||
24 | unsigned int magic, owner_cpu; | 26 | unsigned int magic, owner_cpu; |
25 | void *owner; | 27 | void *owner; |
26 | #endif | 28 | #endif |
29 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
30 | struct lockdep_map dep_map; | ||
31 | #endif | ||
27 | } spinlock_t; | 32 | } spinlock_t; |
28 | 33 | ||
29 | #define SPINLOCK_MAGIC 0xdead4ead | 34 | #define SPINLOCK_MAGIC 0xdead4ead |
@@ -37,31 +42,53 @@ typedef struct { | |||
37 | unsigned int magic, owner_cpu; | 42 | unsigned int magic, owner_cpu; |
38 | void *owner; | 43 | void *owner; |
39 | #endif | 44 | #endif |
45 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
46 | struct lockdep_map dep_map; | ||
47 | #endif | ||
40 | } rwlock_t; | 48 | } rwlock_t; |
41 | 49 | ||
42 | #define RWLOCK_MAGIC 0xdeaf1eed | 50 | #define RWLOCK_MAGIC 0xdeaf1eed |
43 | 51 | ||
44 | #define SPINLOCK_OWNER_INIT ((void *)-1L) | 52 | #define SPINLOCK_OWNER_INIT ((void *)-1L) |
45 | 53 | ||
54 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
55 | # define SPIN_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } | ||
56 | #else | ||
57 | # define SPIN_DEP_MAP_INIT(lockname) | ||
58 | #endif | ||
59 | |||
60 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
61 | # define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } | ||
62 | #else | ||
63 | # define RW_DEP_MAP_INIT(lockname) | ||
64 | #endif | ||
65 | |||
46 | #ifdef CONFIG_DEBUG_SPINLOCK | 66 | #ifdef CONFIG_DEBUG_SPINLOCK |
47 | # define SPIN_LOCK_UNLOCKED \ | 67 | # define __SPIN_LOCK_UNLOCKED(lockname) \ |
48 | (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ | 68 | (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ |
49 | .magic = SPINLOCK_MAGIC, \ | 69 | .magic = SPINLOCK_MAGIC, \ |
50 | .owner = SPINLOCK_OWNER_INIT, \ | 70 | .owner = SPINLOCK_OWNER_INIT, \ |
51 | .owner_cpu = -1 } | 71 | .owner_cpu = -1, \ |
52 | #define RW_LOCK_UNLOCKED \ | 72 | SPIN_DEP_MAP_INIT(lockname) } |
73 | #define __RW_LOCK_UNLOCKED(lockname) \ | ||
53 | (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ | 74 | (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ |
54 | .magic = RWLOCK_MAGIC, \ | 75 | .magic = RWLOCK_MAGIC, \ |
55 | .owner = SPINLOCK_OWNER_INIT, \ | 76 | .owner = SPINLOCK_OWNER_INIT, \ |
56 | .owner_cpu = -1 } | 77 | .owner_cpu = -1, \ |
78 | RW_DEP_MAP_INIT(lockname) } | ||
57 | #else | 79 | #else |
58 | # define SPIN_LOCK_UNLOCKED \ | 80 | # define __SPIN_LOCK_UNLOCKED(lockname) \ |
59 | (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED } | 81 | (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \ |
60 | #define RW_LOCK_UNLOCKED \ | 82 | SPIN_DEP_MAP_INIT(lockname) } |
61 | (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED } | 83 | #define __RW_LOCK_UNLOCKED(lockname) \ |
84 | (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \ | ||
85 | RW_DEP_MAP_INIT(lockname) } | ||
62 | #endif | 86 | #endif |
63 | 87 | ||
64 | #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED | 88 | #define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init) |
65 | #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED | 89 | #define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init) |
90 | |||
91 | #define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) | ||
92 | #define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x) | ||
66 | 93 | ||
67 | #endif /* __LINUX_SPINLOCK_TYPES_H */ | 94 | #endif /* __LINUX_SPINLOCK_TYPES_H */ |
diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h index 04135b0e198e..27644af20b7c 100644 --- a/include/linux/spinlock_types_up.h +++ b/include/linux/spinlock_types_up.h | |||
@@ -12,10 +12,14 @@ | |||
12 | * Released under the General Public License (GPL). | 12 | * Released under the General Public License (GPL). |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifdef CONFIG_DEBUG_SPINLOCK | 15 | #if defined(CONFIG_DEBUG_SPINLOCK) || \ |
16 | defined(CONFIG_DEBUG_LOCK_ALLOC) | ||
16 | 17 | ||
17 | typedef struct { | 18 | typedef struct { |
18 | volatile unsigned int slock; | 19 | volatile unsigned int slock; |
20 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
21 | struct lockdep_map dep_map; | ||
22 | #endif | ||
19 | } raw_spinlock_t; | 23 | } raw_spinlock_t; |
20 | 24 | ||
21 | #define __RAW_SPIN_LOCK_UNLOCKED { 1 } | 25 | #define __RAW_SPIN_LOCK_UNLOCKED { 1 } |
@@ -30,6 +34,9 @@ typedef struct { } raw_spinlock_t; | |||
30 | 34 | ||
31 | typedef struct { | 35 | typedef struct { |
32 | /* no debug version on UP */ | 36 | /* no debug version on UP */ |
37 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
38 | struct lockdep_map dep_map; | ||
39 | #endif | ||
33 | } raw_rwlock_t; | 40 | } raw_rwlock_t; |
34 | 41 | ||
35 | #define __RAW_RW_LOCK_UNLOCKED { } | 42 | #define __RAW_RW_LOCK_UNLOCKED { } |
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index 31accf2f0b13..ea54c4c9a4ec 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h | |||
@@ -18,7 +18,6 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #ifdef CONFIG_DEBUG_SPINLOCK | 20 | #ifdef CONFIG_DEBUG_SPINLOCK |
21 | |||
22 | #define __raw_spin_is_locked(x) ((x)->slock == 0) | 21 | #define __raw_spin_is_locked(x) ((x)->slock == 0) |
23 | 22 | ||
24 | static inline void __raw_spin_lock(raw_spinlock_t *lock) | 23 | static inline void __raw_spin_lock(raw_spinlock_t *lock) |
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h new file mode 100644 index 000000000000..9cc81e572224 --- /dev/null +++ b/include/linux/stacktrace.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef __LINUX_STACKTRACE_H | ||
2 | #define __LINUX_STACKTRACE_H | ||
3 | |||
4 | #ifdef CONFIG_STACKTRACE | ||
5 | struct stack_trace { | ||
6 | unsigned int nr_entries, max_entries; | ||
7 | unsigned long *entries; | ||
8 | }; | ||
9 | |||
10 | extern void save_stack_trace(struct stack_trace *trace, | ||
11 | struct task_struct *task, int all_contexts, | ||
12 | unsigned int skip); | ||
13 | |||
14 | extern void print_stack_trace(struct stack_trace *trace, int spaces); | ||
15 | #else | ||
16 | # define save_stack_trace(trace, task, all, skip) do { } while (0) | ||
17 | # define print_stack_trace(trace) do { } while (0) | ||
18 | #endif | ||
19 | |||
20 | #endif | ||
diff --git a/include/linux/swap.h b/include/linux/swap.h index cf6ca6e377bd..5e59184c9096 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -189,6 +189,7 @@ extern long vm_total_pages; | |||
189 | 189 | ||
190 | #ifdef CONFIG_NUMA | 190 | #ifdef CONFIG_NUMA |
191 | extern int zone_reclaim_mode; | 191 | extern int zone_reclaim_mode; |
192 | extern int sysctl_min_unmapped_ratio; | ||
192 | extern int zone_reclaim(struct zone *, gfp_t, unsigned int); | 193 | extern int zone_reclaim(struct zone *, gfp_t, unsigned int); |
193 | #else | 194 | #else |
194 | #define zone_reclaim_mode 0 | 195 | #define zone_reclaim_mode 0 |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 46e4d8f2771f..e4b1a4d4dcf3 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -188,7 +188,7 @@ enum | |||
188 | VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */ | 188 | VM_DROP_PAGECACHE=29, /* int: nuke lots of pagecache */ |
189 | VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */ | 189 | VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */ |
190 | VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */ | 190 | VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */ |
191 | VM_ZONE_RECLAIM_INTERVAL=32, /* time period to wait after reclaim failure */ | 191 | VM_MIN_UNMAPPED=32, /* Set min percent of unmapped pages */ |
192 | VM_PANIC_ON_OOM=33, /* panic at out-of-memory */ | 192 | VM_PANIC_ON_OOM=33, /* panic at out-of-memory */ |
193 | VM_VDSO_ENABLED=34, /* map VDSO into new processes? */ | 193 | VM_VDSO_ENABLED=34, /* map VDSO into new processes? */ |
194 | }; | 194 | }; |
diff --git a/include/linux/wait.h b/include/linux/wait.h index 544e855c7c02..794be7af58ae 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -68,7 +68,7 @@ struct task_struct; | |||
68 | wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) | 68 | wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) |
69 | 69 | ||
70 | #define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ | 70 | #define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ |
71 | .lock = SPIN_LOCK_UNLOCKED, \ | 71 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
72 | .task_list = { &(name).task_list, &(name).task_list } } | 72 | .task_list = { &(name).task_list, &(name).task_list } } |
73 | 73 | ||
74 | #define DECLARE_WAIT_QUEUE_HEAD(name) \ | 74 | #define DECLARE_WAIT_QUEUE_HEAD(name) \ |
@@ -77,9 +77,15 @@ struct task_struct; | |||
77 | #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ | 77 | #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ |
78 | { .flags = word, .bit_nr = bit, } | 78 | { .flags = word, .bit_nr = bit, } |
79 | 79 | ||
80 | /* | ||
81 | * lockdep: we want one lock-class for all waitqueue locks. | ||
82 | */ | ||
83 | extern struct lock_class_key waitqueue_lock_key; | ||
84 | |||
80 | static inline void init_waitqueue_head(wait_queue_head_t *q) | 85 | static inline void init_waitqueue_head(wait_queue_head_t *q) |
81 | { | 86 | { |
82 | spin_lock_init(&q->lock); | 87 | spin_lock_init(&q->lock); |
88 | lockdep_set_class(&q->lock, &waitqueue_lock_key); | ||
83 | INIT_LIST_HEAD(&q->task_list); | 89 | INIT_LIST_HEAD(&q->task_list); |
84 | } | 90 | } |
85 | 91 | ||