Commit 64efade1 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Linus Torvalds

[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: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: default avatarOleg Nesterov <oleg@tv-sign.ru>
Cc: Balbir Singh <balbir@in.ibm.com>
Cc: Shailabh Nagar <nagar@watson.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e5b9a335
...@@ -66,6 +66,7 @@ static void delayacct_end(struct timespec *start, struct timespec *end, ...@@ -66,6 +66,7 @@ static void delayacct_end(struct timespec *start, struct timespec *end,
{ {
struct timespec ts; struct timespec ts;
s64 ns; s64 ns;
unsigned long flags;
do_posix_clock_monotonic_gettime(end); do_posix_clock_monotonic_gettime(end);
ts = timespec_sub(*end, *start); ts = timespec_sub(*end, *start);
...@@ -73,10 +74,10 @@ static void delayacct_end(struct timespec *start, struct timespec *end, ...@@ -73,10 +74,10 @@ static void delayacct_end(struct timespec *start, struct timespec *end,
if (ns < 0) if (ns < 0)
return; return;
spin_lock(&current->delays->lock); spin_lock_irqsave(&current->delays->lock, flags);
*total += ns; *total += ns;
(*count)++; (*count)++;
spin_unlock(&current->delays->lock); spin_unlock_irqrestore(&current->delays->lock, flags);
} }
void __delayacct_blkio_start(void) void __delayacct_blkio_start(void)
...@@ -104,6 +105,7 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) ...@@ -104,6 +105,7 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
s64 tmp; s64 tmp;
struct timespec ts; struct timespec ts;
unsigned long t1,t2,t3; unsigned long t1,t2,t3;
unsigned long flags;
/* Though tsk->delays accessed later, early exit avoids /* Though tsk->delays accessed later, early exit avoids
* unnecessary returning of other data * unnecessary returning of other data
...@@ -136,14 +138,14 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) ...@@ -136,14 +138,14 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
/* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */ /* zero XXX_total, non-zero XXX_count implies XXX stat overflowed */
spin_lock(&tsk->delays->lock); spin_lock_irqsave(&tsk->delays->lock, flags);
tmp = d->blkio_delay_total + tsk->delays->blkio_delay; tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp; d->blkio_delay_total = (tmp < d->blkio_delay_total) ? 0 : tmp;
tmp = d->swapin_delay_total + tsk->delays->swapin_delay; tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp; d->swapin_delay_total = (tmp < d->swapin_delay_total) ? 0 : tmp;
d->blkio_count += tsk->delays->blkio_count; d->blkio_count += tsk->delays->blkio_count;
d->swapin_count += tsk->delays->swapin_count; d->swapin_count += tsk->delays->swapin_count;
spin_unlock(&tsk->delays->lock); spin_unlock_irqrestore(&tsk->delays->lock, flags);
done: done:
return 0; return 0;
...@@ -152,11 +154,12 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) ...@@ -152,11 +154,12 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
__u64 __delayacct_blkio_ticks(struct task_struct *tsk) __u64 __delayacct_blkio_ticks(struct task_struct *tsk)
{ {
__u64 ret; __u64 ret;
unsigned long flags;
spin_lock(&tsk->delays->lock); spin_lock_irqsave(&tsk->delays->lock, flags);
ret = nsec_to_clock_t(tsk->delays->blkio_delay + ret = nsec_to_clock_t(tsk->delays->blkio_delay +
tsk->delays->swapin_delay); tsk->delays->swapin_delay);
spin_unlock(&tsk->delays->lock); spin_unlock_irqrestore(&tsk->delays->lock, flags);
return ret; return ret;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment