diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-15 09:05:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-06-15 09:57:49 -0400 |
| commit | 75f937f24bd9c003dcb9d7d5509f23459f1f6000 (patch) | |
| tree | 859d5ebe9b47b952d13873d7a2a580012682aeb0 /kernel | |
| parent | 613d8602292165f86ba1969784fea01a06d55900 (diff) | |
perf_counter: Fix ctx->mutex vs counter->mutex inversion
Simon triggered a lockdep inversion report about us taking ctx->mutex
vs counter->mutex in inverse orders. Fix that up.
Reported-by: Simon Holm Thøgersen <odie@cs.aau.dk>
Tested-by: Simon Holm Thøgersen <odie@cs.aau.dk>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/perf_counter.c | 34 |
1 files changed, 11 insertions, 23 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index e914daff03b5..109a95723859 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
| @@ -1620,22 +1620,6 @@ static void perf_counter_reset(struct perf_counter *counter) | |||
| 1620 | perf_counter_update_userpage(counter); | 1620 | perf_counter_update_userpage(counter); |
| 1621 | } | 1621 | } |
| 1622 | 1622 | ||
| 1623 | static void perf_counter_for_each_sibling(struct perf_counter *counter, | ||
| 1624 | void (*func)(struct perf_counter *)) | ||
| 1625 | { | ||
| 1626 | struct perf_counter_context *ctx = counter->ctx; | ||
| 1627 | struct perf_counter *sibling; | ||
| 1628 | |||
| 1629 | WARN_ON_ONCE(ctx->parent_ctx); | ||
| 1630 | mutex_lock(&ctx->mutex); | ||
| 1631 | counter = counter->group_leader; | ||
| 1632 | |||
| 1633 | func(counter); | ||
| 1634 | list_for_each_entry(sibling, &counter->sibling_list, list_entry) | ||
| 1635 | func(sibling); | ||
| 1636 | mutex_unlock(&ctx->mutex); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | /* | 1623 | /* |
| 1640 | * Holding the top-level counter's child_mutex means that any | 1624 | * Holding the top-level counter's child_mutex means that any |
| 1641 | * descendant process that has inherited this counter will block | 1625 | * descendant process that has inherited this counter will block |
| @@ -1658,14 +1642,18 @@ static void perf_counter_for_each_child(struct perf_counter *counter, | |||
| 1658 | static void perf_counter_for_each(struct perf_counter *counter, | 1642 | static void perf_counter_for_each(struct perf_counter *counter, |
| 1659 | void (*func)(struct perf_counter *)) | 1643 | void (*func)(struct perf_counter *)) |
| 1660 | { | 1644 | { |
| 1661 | struct perf_counter *child; | 1645 | struct perf_counter_context *ctx = counter->ctx; |
| 1646 | struct perf_counter *sibling; | ||
| 1662 | 1647 | ||
| 1663 | WARN_ON_ONCE(counter->ctx->parent_ctx); | 1648 | WARN_ON_ONCE(ctx->parent_ctx); |
| 1664 | mutex_lock(&counter->child_mutex); | 1649 | mutex_lock(&ctx->mutex); |
| 1665 | perf_counter_for_each_sibling(counter, func); | 1650 | counter = counter->group_leader; |
| 1666 | list_for_each_entry(child, &counter->child_list, child_list) | 1651 | |
| 1667 | perf_counter_for_each_sibling(child, func); | 1652 | perf_counter_for_each_child(counter, func); |
| 1668 | mutex_unlock(&counter->child_mutex); | 1653 | func(counter); |
| 1654 | list_for_each_entry(sibling, &counter->sibling_list, list_entry) | ||
| 1655 | perf_counter_for_each_child(counter, func); | ||
| 1656 | mutex_unlock(&ctx->mutex); | ||
| 1669 | } | 1657 | } |
| 1670 | 1658 | ||
| 1671 | static int perf_counter_period(struct perf_counter *counter, u64 __user *arg) | 1659 | static int perf_counter_period(struct perf_counter *counter, u64 __user *arg) |
