Received: by 2002:ac0:8c8e:0:0:0:0:0 with SMTP id r14csp901412ima; Wed, 6 Feb 2019 10:09:31 -0800 (PST) X-Google-Smtp-Source: AHgI3IZAakZKBuTZXtxwR0nJ/x10KBxf4d9lVWboyRZ84F58NhxPxHqcsDeq1LvHqDwfd19Xi+t3 X-Received: by 2002:a17:902:f64:: with SMTP id 91mr11950040ply.132.1549476571652; Wed, 06 Feb 2019 10:09:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549476571; cv=none; d=google.com; s=arc-20160816; b=KAFCD4WXHM7VCraIpaN4Y466W4BxUC//Scdf8R18KIXg3K/XnolhlGnQxSZ63+OHJs geRkaeIQUvopqFthPRCaRNljCTFM9wL51VW+JVk2S2IDjfmTXZ5Mp0eRlUTwbjQhAUYj bYNUVbHVDpd4lPq9XHy06UlA9RM6F6I1Gh+9i4F6FCaA4xWdjgMX+wD8/e4Sjw1YVDZE WS3u4KZW2wxNUIUxqzZF4U31Vn+upgDQlFUrKGCir7cnTxvVdWuAcpMR6W8VMG5q7cyI jJ0q+7ECR5v+t4sLUN2sJNIqKWpNgEMS34+wOL9ZW0HXXdREghQ1JQO4BlyvPmKYCVq4 HAqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=S/67tRKTlxOYP+sBkMKRSV2F+ob/jIFmPIustnrAhjE=; b=DWSI0PsTKBjowEYrTXf1xO/reXj/dABc8zwhyscx2xVnX+80QUeMfQSNREc+VnqYVw Smr7b25YRLSJjYDUV3H2XicVTWND3YA9izZKAfSlzzIW6DHsoMfGVVBwZOp8ovlRGNrl XZTot/yKvBRUUS7+N2Mnqm6fuwcJyX2rHSGGyBwWJ0ndd0kRxH5+rcsrW9+SNmUAjWkT tnAmyAKpbBJTc3v4OP9dtUqyvtMET88Ibh8Xe7MC8otnWw1PQELEJ2cqrVekmwSNsYZ1 2jKSyP/PQLvxAmrdr73yKena1WmigRUpGutfHCtZNawNz5fdZlKcxpYROxJ5oeEv6RHU N0BQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 189si6908830pfd.142.2019.02.06.10.09.06; Wed, 06 Feb 2019 10:09:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731011AbfBFSAG (ORCPT + 99 others); Wed, 6 Feb 2019 13:00:06 -0500 Received: from smtp.nue.novell.com ([195.135.221.5]:54017 "EHLO smtp.nue.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730952AbfBFSAF (ORCPT ); Wed, 6 Feb 2019 13:00:05 -0500 Received: from emea4-mta.ukb.novell.com ([10.120.13.87]) by smtp.nue.novell.com with ESMTP (TLS encrypted); Wed, 06 Feb 2019 19:00:03 +0100 Received: from linux-r8p5.suse.de (nwb-a10-snat.microfocus.com [10.120.13.202]) by emea4-mta.ukb.novell.com with ESMTP (TLS encrypted); Wed, 06 Feb 2019 17:59:46 +0000 From: Davidlohr Bueso To: jgg@ziepe.ca, akpm@linux-foundation.org Cc: dledford@redhat.com, jgg@mellanox.com, jack@suse.cz, willy@infradead.org, ira.weiny@intel.com, linux-rdma@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, dave@stgolabs.net, dennis.dalessandro@intel.com, mike.marciniszyn@intel.com, Davidlohr Bueso Subject: [PATCH 3/6] drivers/IB,qib: optimize mmap_sem usage Date: Wed, 6 Feb 2019 09:59:17 -0800 Message-Id: <20190206175920.31082-4-dave@stgolabs.net> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190206175920.31082-1-dave@stgolabs.net> References: <20190206175920.31082-1-dave@stgolabs.net> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The driver uses mmap_sem for both pinned_vm accounting and get_user_pages(). Because rdma drivers might want to use gup_longterm() in the future we still need some sort of mmap_sem serialization (as opposed to removing it entirely by using gup_fast()). Now that pinned_vm is atomic the writer lock can therefore be converted to reader. This also fixes a bug that __qib_get_user_pages was not taking into account the current value of pinned_vm. Cc: dennis.dalessandro@intel.com Cc: mike.marciniszyn@intel.com Reviewed-by: Ira Weiny Signed-off-by: Davidlohr Bueso --- drivers/infiniband/hw/qib/qib_user_pages.c | 73 +++++++++++------------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index c6c81022d313..ef8bcf366ddc 100644 --- a/drivers/infiniband/hw/qib/qib_user_pages.c +++ b/drivers/infiniband/hw/qib/qib_user_pages.c @@ -49,43 +49,6 @@ static void __qib_release_user_pages(struct page **p, size_t num_pages, } } -/* - * Call with current->mm->mmap_sem held. - */ -static int __qib_get_user_pages(unsigned long start_page, size_t num_pages, - struct page **p) -{ - unsigned long lock_limit; - size_t got; - int ret; - - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - - if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) { - ret = -ENOMEM; - goto bail; - } - - for (got = 0; got < num_pages; got += ret) { - ret = get_user_pages_longterm(start_page + got * PAGE_SIZE, - num_pages - got, - FOLL_WRITE | FOLL_FORCE, - p + got, NULL); - if (ret < 0) - goto bail_release; - } - - atomic64_add(num_pages, ¤t->mm->pinned_vm); - - ret = 0; - goto bail; - -bail_release: - __qib_release_user_pages(p, got, 0); -bail: - return ret; -} - /** * qib_map_page - a safety wrapper around pci_map_page() * @@ -137,26 +100,44 @@ int qib_map_page(struct pci_dev *hwdev, struct page *page, dma_addr_t *daddr) int qib_get_user_pages(unsigned long start_page, size_t num_pages, struct page **p) { + unsigned long locked, lock_limit; + size_t got; int ret; - down_write(¤t->mm->mmap_sem); + lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + locked = atomic64_add_return(num_pages, ¤t->mm->pinned_vm); - ret = __qib_get_user_pages(start_page, num_pages, p); + if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) { + ret = -ENOMEM; + goto bail; + } - up_write(¤t->mm->mmap_sem); + down_read(¤t->mm->mmap_sem); + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages_longterm(start_page + got * PAGE_SIZE, + num_pages - got, + FOLL_WRITE | FOLL_FORCE, + p + got, NULL); + if (ret < 0) { + up_read(¤t->mm->mmap_sem); + goto bail_release; + } + } + up_read(¤t->mm->mmap_sem); + return 0; +bail_release: + __qib_release_user_pages(p, got, 0); +bail: + atomic64_sub(num_pages, ¤t->mm->pinned_vm); return ret; } void qib_release_user_pages(struct page **p, size_t num_pages) { - if (current->mm) /* during close after signal, mm can be NULL */ - down_write(¤t->mm->mmap_sem); - __qib_release_user_pages(p, num_pages, 1); - if (current->mm) { + /* during close after signal, mm can be NULL */ + if (current->mm) atomic64_sub(num_pages, ¤t->mm->pinned_vm); - up_write(¤t->mm->mmap_sem); - } } -- 2.16.4