linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Doug Ledford <dledford@redhat.com>
To: Davidlohr Bueso <dave@stgolabs.net>,
	roland@purestorage.com, linux-rdma@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Davidlohr Bueso <dbueso@suse.de>
Subject: Re: [PATCH] IB/mthca: Fix how mthca_map_user_db() calls gup
Date: Thu, 25 Jan 2018 11:34:23 -0500	[thread overview]
Message-ID: <1516898063.27592.136.camel@redhat.com> (raw)
In-Reply-To: <20180123205459.432-1-dave@stgolabs.net>

[-- Attachment #1: Type: text/plain, Size: 3281 bytes --]

On Tue, 2018-01-23 at 12:54 -0800, Davidlohr Bueso wrote:
> mthca_map_user_db() has two problems regarding the call to
> get_user_pages():
> 
> (i) It is not done under mmap_sem.
> 
> (ii) It is done under the db_table mutex, which protects all
> database related operations. Should any of these be called
> under mmap_sem, we get an ABBA deadlock. In addition, gup can
> be performance intensive, which could contend other mapping/
> unmapping ops.
> 
> To fix this, we can drop the mutex while doing a gup_fast(),
> once done, recheck to see the page was mapped while we didn't
> hold the mutex, and exit out with the corresponding housekeeping.
> 
> Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
> Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
> ---
> 
> - Compile tested only.

Jason and I talked about this offline a bit.  We're concerned about
taking a patch like this into an ancient, unmaintained, but working
driver.  Especially when it's only compile tested.  I have mthca
hardware on hand and I can test it, but in this case, testing your patch
would require triggering a race condition that we really don't have a
way to test.

> - Should I be wrong about no callers already holding mmap_sem,
>   I still think calling gup without the mutex makes sense for
>   improved paralellism. Now, if callers can hold the mmap_sem,
>   it's wrong to do copy_from_user right before calling mthca_map_user_db.

So, if I understand you correctly, we (well, you and Al would be more
correct, we haven't looked into the situation yet, so Mellanox people
that worked on this in the day might now, or someone taking the time to
research it could find out) don't have a clear understanding of all the
conditions this function is called under, and so we actually don't know
what the best way forward is to fix it?

> 
>  drivers/infiniband/hw/mthca/mthca_memfree.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
> index c6fe89d79248..046871878a02 100644
> --- a/drivers/infiniband/hw/mthca/mthca_memfree.c
> +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
> @@ -472,9 +472,27 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
>  		goto out;
>  	}
>  
> -	ret = get_user_pages(uaddr & PAGE_MASK, 1, FOLL_WRITE, pages, NULL);
> +	mutex_unlock(&db_tab->mutex);
> +
> +	ret = get_user_pages_fast(uaddr & PAGE_MASK, 1, FOLL_WRITE, pages);
>  	if (ret < 0)
> +		return ret;
> +
> +	mutex_lock(&db_tab->mutex);
> +
> +	if (db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE ||
> +	    (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr)) {
> +		put_page(pages[0]);
> +		ret = -EINVAL;
>  		goto out;
> +	}
> +
> +	/* page was already mapped by another task while we were doing gup */
> +	if (db_tab->page[i].refcount) {
> +		put_page(pages[0]);
> +		++db_tab->page[i].refcount;
> +		goto out;
> +	}
>  
>  	sg_set_page(&db_tab->page[i].mem, pages[0], MTHCA_ICM_PAGE_SIZE,
>  			uaddr & ~PAGE_MASK);

-- 
Doug Ledford <dledford@redhat.com>
    GPG KeyID: B826A3330E572FDD
    Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2018-01-25 16:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-23 20:54 [PATCH] IB/mthca: Fix how mthca_map_user_db() calls gup Davidlohr Bueso
2018-01-25 16:34 ` Doug Ledford [this message]
2018-01-25 17:50   ` Jason Gunthorpe
2018-01-25 18:06     ` Doug Ledford
2018-01-25 18:53       ` Jason Gunthorpe
2018-01-25 19:27         ` Davidlohr Bueso
2018-01-26 15:44           ` Doug Ledford

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=1516898063.27592.136.camel@redhat.com \
    --to=dledford@redhat.com \
    --cc=dave@stgolabs.net \
    --cc=dbueso@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=roland@purestorage.com \
    /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 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).