diff options
author | Jens Axboe <axboe@fb.com> | 2017-05-09 13:39:56 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-05-10 09:40:18 -0400 |
commit | d3738123986954ba3abbd96b595f5176b50c3f5d (patch) | |
tree | 67770332a697a8496a60c75ca8583dec06b3ceda | |
parent | 340ff3216799a947fe0b07bed8f0409ffc716be9 (diff) |
blk-stat: don't use this_cpu_ptr() in a preemptable section
If PREEMPT_RCU is enabled, rcu_read_lock() isn't strong enough
for us to use this_cpu_ptr() in that section. Use the safer
get/put_cpu_ptr() variants instead.
Reported-by: Mike Galbraith <efault@gmx.de>
Fixes: 34dbad5d26e2 ("blk-stat: convert to callback-based statistics reporting")
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-stat.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/block/blk-stat.c b/block/blk-stat.c index 6c2f40940439..c52356d90fe3 100644 --- a/block/blk-stat.c +++ b/block/blk-stat.c | |||
@@ -96,13 +96,16 @@ void blk_stat_add(struct request *rq) | |||
96 | 96 | ||
97 | rcu_read_lock(); | 97 | rcu_read_lock(); |
98 | list_for_each_entry_rcu(cb, &q->stats->callbacks, list) { | 98 | list_for_each_entry_rcu(cb, &q->stats->callbacks, list) { |
99 | if (blk_stat_is_active(cb)) { | 99 | if (!blk_stat_is_active(cb)) |
100 | bucket = cb->bucket_fn(rq); | 100 | continue; |
101 | if (bucket < 0) | 101 | |
102 | continue; | 102 | bucket = cb->bucket_fn(rq); |
103 | stat = &this_cpu_ptr(cb->cpu_stat)[bucket]; | 103 | if (bucket < 0) |
104 | __blk_stat_add(stat, value); | 104 | continue; |
105 | } | 105 | |
106 | stat = &get_cpu_ptr(cb->cpu_stat)[bucket]; | ||
107 | __blk_stat_add(stat, value); | ||
108 | put_cpu_ptr(cb->cpu_stat); | ||
106 | } | 109 | } |
107 | rcu_read_unlock(); | 110 | rcu_read_unlock(); |
108 | } | 111 | } |