Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6489412imu; Mon, 21 Jan 2019 09:45:17 -0800 (PST) X-Google-Smtp-Source: ALg8bN6V4Dq1/UBHo1st+cz1PuWONgRiHIYngl2agjyd2HTga94C6Gc1OPRTXT3FglTDsM1dPvoT X-Received: by 2002:a17:902:ab84:: with SMTP id f4mr30311456plr.207.1548092716974; Mon, 21 Jan 2019 09:45:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548092716; cv=none; d=google.com; s=arc-20160816; b=GxlQRw/UpcMOpBQNTC3pQODArbX/Qt48mjMWcvoVQk3a1oVk680JmN7Pwt7ccphpsT /yYc3/AVgfgUZLZkZsYXair9sRk302woyNv74zJsTRBJNVUHwsxdPMOsyJxnHPlmPCXj 7NY0FtTqFmRvCVVk/EQnuHJtnKC5om1Sz3SnNRCLCSYTtMCwHi+w6i3f/xsTQSZNoLF1 ReS+L4eIgAPbJeGpS17aJhHAPyeOP2SwMNhrL25UE0jLmGOHp7BmiE/NHRbxDOLaodMd Xyyfi3hUUvZUSDeB+kn0gwCW20UIfUGKe7jwIjXHBklSy0jj3ne3qxPZWQpa27u4Z7kz Q9Yg== 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=BvaEORAmuWSzID7o6vf8zI8PBOEpqDPHoqVpDewB9Qg=; b=uBcGSLofl+RXNCzx8XxgARTFq0NiklSlexslSAVMb3dZiHFw4F2DNAbmL7T+Cr8me7 Bpng6GcwIQySR76eaTgioLc9H/Os2CWdHoneFoB3khkRQqOsGtiSEvto4mkQ7ZMl2Uqi SMMxbpEql5OTpN+2HjSmGu1KY/uBPHhz3c0M8fzWJPJ1Ro0KiNQ/aS0PvJdViv2Syv7o 33V6cO70T5s47CQE1uP2joREDgqYMN0AjvEIT3tsbh1AVybkU5j7LY7RF91V1MC0v0ZM ajmS3lNNIW98PB4EgvSqgXbqeE7QA9JjrAqXMJz7HgnHHxEJ5ZRdAFq9ZLyeWSM9c9YB ta/g== 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 4si13201134pfg.280.2019.01.21.09.45.01; Mon, 21 Jan 2019 09:45:16 -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 S1728296AbfAURnG (ORCPT + 99 others); Mon, 21 Jan 2019 12:43:06 -0500 Received: from smtp2.provo.novell.com ([137.65.250.81]:60484 "EHLO smtp2.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726003AbfAURnG (ORCPT ); Mon, 21 Jan 2019 12:43:06 -0500 Received: from localhost.localdomain (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by smtp2.provo.novell.com with ESMTP (TLS encrypted); Mon, 21 Jan 2019 10:42:52 -0700 From: Davidlohr Bueso To: akpm@linux-foundation.org Cc: dledford@redhat.com, jgg@mellanox.com, jack@suse.de, 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: do not use mmap_sem Date: Mon, 21 Jan 2019 09:42:17 -0800 Message-Id: <20190121174220.10583-4-dave@stgolabs.net> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190121174220.10583-1-dave@stgolabs.net> References: <20190121174220.10583-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(). By using gup_fast() and letting the mm handle the lock if needed, we can no longer rely on the semaphore and simplify the whole thing as the pinning is decoupled from the lock. 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 | 67 ++++++++++-------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index 602387bf98e7..e4114aad4a2f 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(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,40 @@ 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 (locked > lock_limit && !capable(CAP_IPC_LOCK)) { + ret = -ENOMEM; + goto bail; + } - up_write(¤t->mm->mmap_sem); + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages_fast(start_page + got * PAGE_SIZE, + num_pages - got, + FOLL_WRITE | FOLL_FORCE, + p + got); + if (ret < 0) + goto bail_release; + } + 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) { + if (current->mm) { /* during close after signal, mm can be NULL */ atomic64_sub(num_pages, ¤t->mm->pinned_vm); - up_write(¤t->mm->mmap_sem); } } -- 2.16.4