* [PATCH 3/8] RDMAVT: Fix synchronization around percpu_ref [not found] ` <20180314194515.1661824-1-tj@kernel.org> @ 2018-03-14 19:45 ` Tejun Heo 2018-03-15 22:24 ` Jason Gunthorpe 0 siblings, 1 reply; 2+ messages in thread From: Tejun Heo @ 2018-03-14 19:45 UTC (permalink / raw) To: torvalds, jannh, paulmck, bcrl, viro, kent.overstreet Cc: security, linux-kernel, kernel-team, Tejun Heo, Mike Marciniszyn, linux-rdma rvt_mregion uses percpu_ref for reference counting and RCU to protect accesses from lkey_table. When a rvt_mregion needs to be freed, it first gets unregistered from lkey_table and then rvt_check_refs() is called to wait for in-flight usages before the rvt_mregion is freed. rvt_check_refs() seems to have a couple issues. * It has a fast exit path which tests percpu_ref_is_zero(). However, a percpu_ref reading zero doesn't mean that the object can be released. In fact, the ->release() callback might not even have started executing yet. Proceeding with freeing can lead to use-after-free. * lkey_table is RCU protected but there is no RCU grace period in the free path. percpu_ref uses RCU internally but it's sched-RCU whose grace periods are different from regular RCU. Also, it generally isn't a good idea to depend on internal behaviors like this. To address the above issues, this patch removes the fast exit and adds an explicit synchronize_rcu(). Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Cc: Mike Marciniszyn <mike.marciniszyn@intel.com> Cc: linux-rdma@vger.kernel.org Cc: Linus Torvalds <torvalds@linux-foundation.org> --- drivers/infiniband/sw/rdmavt/mr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 1b2e536..cc429b5 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c @@ -489,11 +489,13 @@ static int rvt_check_refs(struct rvt_mregion *mr, const char *t) unsigned long timeout; struct rvt_dev_info *rdi = ib_to_rvt(mr->pd->device); - if (percpu_ref_is_zero(&mr->refcount)) - return 0; - /* avoid dma mr */ - if (mr->lkey) + if (mr->lkey) { + /* avoid dma mr */ rvt_dereg_clean_qps(mr); + /* @mr was indexed on rcu protected @lkey_table */ + synchronize_rcu(); + } + timeout = wait_for_completion_timeout(&mr->comp, 5 * HZ); if (!timeout) { rvt_pr_err(rdi, -- 2.9.5 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 3/8] RDMAVT: Fix synchronization around percpu_ref 2018-03-14 19:45 ` [PATCH 3/8] RDMAVT: Fix synchronization around percpu_ref Tejun Heo @ 2018-03-15 22:24 ` Jason Gunthorpe 0 siblings, 0 replies; 2+ messages in thread From: Jason Gunthorpe @ 2018-03-15 22:24 UTC (permalink / raw) To: Tejun Heo Cc: torvalds, jannh, paulmck, bcrl, viro, kent.overstreet, security, linux-kernel, kernel-team, Mike Marciniszyn, linux-rdma On Wed, Mar 14, 2018 at 12:45:10PM -0700, Tejun Heo wrote: > rvt_mregion uses percpu_ref for reference counting and RCU to protect > accesses from lkey_table. When a rvt_mregion needs to be freed, it > first gets unregistered from lkey_table and then rvt_check_refs() is > called to wait for in-flight usages before the rvt_mregion is freed. > > rvt_check_refs() seems to have a couple issues. > > * It has a fast exit path which tests percpu_ref_is_zero(). However, > a percpu_ref reading zero doesn't mean that the object can be > released. In fact, the ->release() callback might not even have > started executing yet. Proceeding with freeing can lead to > use-after-free. > > * lkey_table is RCU protected but there is no RCU grace period in the > free path. percpu_ref uses RCU internally but it's sched-RCU whose > grace periods are different from regular RCU. Also, it generally > isn't a good idea to depend on internal behaviors like this. > > To address the above issues, this patch removes the fast exit and adds > an explicit synchronize_rcu(). > > Signed-off-by: Tejun Heo <tj@kernel.org> > Acked-by: Dennis Dalessandro <dennis.dalessandro@intel.com> > Cc: Mike Marciniszyn <mike.marciniszyn@intel.com> > Cc: linux-rdma@vger.kernel.org > Cc: Linus Torvalds <torvalds@linux-foundation.org> > drivers/infiniband/sw/rdmavt/mr.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) Applied to rdma for-next Thanks, Jason ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-03-15 22:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20180314194205.1651587-1-tj@kernel.org>
[not found] ` <20180314194515.1661824-1-tj@kernel.org>
2018-03-14 19:45 ` [PATCH 3/8] RDMAVT: Fix synchronization around percpu_ref Tejun Heo
2018-03-15 22:24 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).