From: Douglas Miller <dougmill@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org, Christoph Lameter <cl@linux.com>,
Tejun Heo <tj@kernel.org>
Cc: linux-block@vger.kernel.org,
Douglas Miller <dougmill@linux.vnet.ibm.com>,
Guilherme Piccoli <gpiccoli@br.ibm.com>
Subject: [PATCH 1/1] percpu-refcount: fix reference leak during percpu-atomic transition
Date: Fri, 27 Jan 2017 14:59:08 -0600 [thread overview]
Message-ID: <1485550748-28075-1-git-send-email-dougmill@linux.vnet.ibm.com> (raw)
percpu_ref_tryget() and percpu_ref_tryget_live() should return
"true" IFF they acquire a reference. But the return value from
atomic_long_inc_not_zero() is a long and may have high bits set,
e.g. PERCPU_COUNT_BIAS, and the return value of the tryget routines
is bool so the reference may actually be acquired but the routines
return "false" which results in a reference leak since the caller
assumes it does not need to do a corresponding percpu_ref_put().
This was seen when performing CPU hotplug during I/O, as hangs in
blk_mq_freeze_queue_wait where percpu_ref_kill (blk_mq_freeze_queue_start)
raced with percpu_ref_tryget (blk_mq_timeout_work).
Sample stack trace:
__switch_to+0x2c0/0x450
__schedule+0x2f8/0x970
schedule+0x48/0xc0
blk_mq_freeze_queue_wait+0x94/0x120
blk_mq_queue_reinit_work+0xb8/0x180
blk_mq_queue_reinit_prepare+0x84/0xa0
cpuhp_invoke_callback+0x17c/0x600
cpuhp_up_callbacks+0x58/0x150
_cpu_up+0xf0/0x1c0
do_cpu_up+0x120/0x150
cpu_subsys_online+0x64/0xe0
device_online+0xb4/0x120
online_store+0xb4/0xc0
dev_attr_store+0x68/0xa0
sysfs_kf_write+0x80/0xb0
kernfs_fop_write+0x17c/0x250
__vfs_write+0x6c/0x1e0
vfs_write+0xd0/0x270
SyS_write+0x6c/0x110
system_call+0x38/0xe0
Examination of the queue showed a single reference (no PERCPU_COUNT_BIAS,
and __PERCPU_REF_DEAD, __PERCPU_REF_ATOMIC set) and no requests.
However, conditions at the time of the race are count of PERCPU_COUNT_BIAS + 0
and __PERCPU_REF_DEAD and __PERCPU_REF_ATOMIC set.
The fix is to make the tryget routines return an actual boolean instead
of the atomic long result truncated to a bool.
Fixes: e625305b3907 percpu-refcount: make percpu_ref based on longs instead of ints
Link: https://bugzilla.kernel.org/show_bug.cgi?id=190751
Signed-off-by: Douglas Miller <dougmill@linux.vnet.ibm.com>
---
include/linux/percpu-refcount.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h
index 1c7eec0..88dc96b 100644
--- a/include/linux/percpu-refcount.h
+++ b/include/linux/percpu-refcount.h
@@ -212,7 +212,7 @@ static inline bool percpu_ref_tryget(struct percpu_ref *ref)
this_cpu_inc(*percpu_count);
ret = true;
} else {
- ret = atomic_long_inc_not_zero(&ref->count);
+ ret = (atomic_long_inc_not_zero(&ref->count) != 0);
}
rcu_read_unlock_sched();
@@ -246,7 +246,7 @@ static inline bool percpu_ref_tryget_live(struct percpu_ref *ref)
this_cpu_inc(*percpu_count);
ret = true;
} else if (!(ref->percpu_count_ptr & __PERCPU_REF_DEAD)) {
- ret = atomic_long_inc_not_zero(&ref->count);
+ ret = (atomic_long_inc_not_zero(&ref->count) != 0);
}
rcu_read_unlock_sched();
--
1.7.1
next reply other threads:[~2017-01-27 20:59 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-27 20:59 Douglas Miller [this message]
2017-01-27 21:39 ` [PATCH 1/1] percpu-refcount: fix reference leak during percpu-atomic transition Douglas Miller
2017-01-27 22:09 ` Tejun Heo
2017-01-27 22:14 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1485550748-28075-1-git-send-email-dougmill@linux.vnet.ibm.com \
--to=dougmill@linux.vnet.ibm.com \
--cc=cl@linux.com \
--cc=gpiccoli@br.ibm.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.