Commit 64efade11cddc4237c1b95ea4ca18af122a7e19e

Authored by Peter Zijlstra
Committed by Linus Torvalds
1 parent e5b9a335fd

[PATCH] lockdep: fix delayacct locking bug

Make the delayacct lock irqsave; this avoids the possible deadlock where
an interrupt is taken while holding the delayacct lock which needs to
take the delayacct lock.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Shailabh Nagar <nagar@watson.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 9 additions and 6 deletions Side-by-side Diff

... ... @@ -66,6 +66,7 @@
66 66 {
67 67 struct timespec ts;
68 68 s64 ns;
  69 + unsigned long flags;
69 70  
70 71 do_posix_clock_monotonic_gettime(end);
71 72 ts = timespec_sub(*end, *start);
72 73  
... ... @@ -73,10 +74,10 @@
73 74 if (ns < 0)
74 75 return;
75 76  
76   - spin_lock(&current->delays->lock);
  77 + spin_lock_irqsave(&current->delays->lock, flags);
77 78 *total += ns;
78 79 (*count)++;
79   - spin_unlock(&current->delays->lock);
  80 + spin_unlock_irqrestore(&current->delays->lock, flags);
80 81 }
81 82  
82 83 void __delayacct_blkio_start(void)
... ... @@ -104,6 +105,7 @@
104 105 s64 tmp;
105 106 struct timespec ts;
106 107 unsigned long t1,t2,t3;
  108 + unsigned long flags;
107 109  
108 110 /* Though tsk->delays accessed later, early exit avoids
109 111 * unnecessary returning of other data
110 112  
... ... @@ -136,14 +138,14 @@
136 138  
137 139 /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
138 140  
139   - spin_lock(&tsk->delays->lock);
  141 + spin_lock_irqsave(&tsk->delays->lock, flags);
140 142 tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
141 143 d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
142 144 tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
143 145 d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
144 146 d->blkio_count += tsk->delays->blkio_count;
145 147 d->swapin_count += tsk->delays->swapin_count;
146   - spin_unlock(&tsk->delays->lock);
  148 + spin_unlock_irqrestore(&tsk->delays->lock, flags);
147 149  
148 150 done:
149 151 return 0;
150 152  
151 153  
... ... @@ -152,11 +154,12 @@
152 154 __u64 __delayacct_blkio_ticks(struct task_struct *tsk)
153 155 {
154 156 __u64 ret;
  157 + unsigned long flags;
155 158  
156   - spin_lock(&tsk->delays->lock);
  159 + spin_lock_irqsave(&tsk->delays->lock, flags);
157 160 ret = nsec_to_clock_t(tsk->delays->blkio_delay +
158 161 tsk->delays->swapin_delay);
159   - spin_unlock(&tsk->delays->lock);
  162 + spin_unlock_irqrestore(&tsk->delays->lock, flags);
160 163 return ret;
161 164 }