Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp7620586imu; Mon, 3 Dec 2018 16:18:36 -0800 (PST) X-Google-Smtp-Source: AFSGD/XVwCwboH19UEcSdnmVyNTnv7yr5c8Qtr2U0J6NIW/SyKoSHWtr5vob0u9rH1cXtkTZUzyS X-Received: by 2002:a17:902:1a8:: with SMTP id b37-v6mr17968204plb.314.1543882716257; Mon, 03 Dec 2018 16:18:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543882716; cv=none; d=google.com; s=arc-20160816; b=ZaUUTrT8yoZNa4n5i/p/98uB3SnzrWwUGVgBk97hBMEC1QOS1eIFvwvH82QwdoN99Q Z1OOaMmK7MKs7JKUU7iUbeds/CkH3bFoWr3Vw61ZLvIBIQmNuWPdVejSux7mySd5Q5yE myTZD4ejh8IaL7NNPE2L8gDfnW0kyf9/+KOIEytnfbdRq1hUV0vpPcLFqEmzo5X4kXQx OoRi24OzaBSizo6D3zKRNclT7Qy/U9F5fuorOoUbKfQQ79dggUU6NNrDdTDPwC4fvZaI 9qKLFl8TrzXTaLnnFc92gEIf65Etb/uNL0fYCKeXTjjdIpTokG41v0PKQWYA9qgEhBWu JL1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=sPERV01M+H72mDTnW41nW+wbJyCratcfiLxrJGvVtk8=; b=zRkl8DgsZtL2mlMRNThUT4Trtd77AVoEhv/yid+d+QheY+OYmUqBXo8uP5hNe4ewwF a8jScCwdBeSnvJEnCtUOJ9AasJ2UEAT1rYijGuPTE/bnCJJTiJ1AuUFrkSCqecgcm5fX E7Nob9uruFLS53WFi3Gh7gx4X7zgzUsyx9P3FZzeofLt949+TYpiajBFMehP9EmWvJHs NnuqxA7v3XzMzaTJpkJyqhTSYGvrda9s5H/ePM7/fBx8thBWDtFXsQK/e84GzG0sxh9Y lnHrKiihnwOI3ChNr8+fdJ2C78kt1ftdEYjsaixX/C5Lfgn/mjY9dq+Eq6LVIueSEIP1 ekjg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=oFsY5RV7; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a6si14978731plz.316.2018.12.03.16.18.21; Mon, 03 Dec 2018 16:18:36 -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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=oFsY5RV7; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726117AbeLDARe (ORCPT + 99 others); Mon, 3 Dec 2018 19:17:34 -0500 Received: from mail-pf1-f196.google.com ([209.85.210.196]:34431 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726080AbeLDARa (ORCPT ); Mon, 3 Dec 2018 19:17:30 -0500 Received: by mail-pf1-f196.google.com with SMTP id h3so7248380pfg.1; Mon, 03 Dec 2018 16:17:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sPERV01M+H72mDTnW41nW+wbJyCratcfiLxrJGvVtk8=; b=oFsY5RV7l5W14w7mLS1Cdmirye+IFFD7BkKniPTccV9g+ZUK1Y7i+yZ53H5GvWiXz9 bonqQZYJ3iK653f0cOY6pZSyf33iRK7o5QnfiPgU+eglqjDRatwNWtc/TxXQO48hx60z D9yw2Uy5iiFhmDfEA42JWqdu3m/YE6uzgpKNZrD3V3nz056OCN9BkpD4vlqTWAPxOXgP Uh97wVjpjaAcCdvisXL3koVPzVK2h6x30Qx5tR4eRhbUK4ViCxpwaF5zzUeMxhZFs6aF SVl6Xbi4S6AkyMDcizvwRn0NMY7OGbG5eOu7sxqDmZXaT+pzGmNkYnVpheqPshpbYsE9 Bghg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sPERV01M+H72mDTnW41nW+wbJyCratcfiLxrJGvVtk8=; b=cFUvRvq9u1DjAQDhzAI9JgAZgHWXw7HOQYIwWarUDZoD1KWGPnJgY0HJlEtGgSzVeb X9s7KaQTiPp18GAxFUqjleZ0VsL7Eli4893eM5K9A2VI7V3VUaNgRRmz0QKdXLQV4hj1 MgHEhvfN+4e2cwCPUfLytwddl0B8jH0/7eMNGVLf1dkGi9+RjPa8GGtPb8aZYe+Hvkt8 HmXIlYm48F231x7zAEX0Qq2RbFQpbgLqMhaNfKrNFE0PM0nrIfduOS8+wstHgyTZ2afS 62CZjbWwizh9dHjKjChH5ALxuo2RB14HYcnBZE/646/DLuzwCgSs+tk5kSMQErCXPND3 HdZA== X-Gm-Message-State: AA+aEWaL83U9lcO6lkX4YgfcrFCG+Qeble5eI/9pu9CFN9ejqikAAGe4 85/r6PnB8KeP/ZrJ5I058xk= X-Received: by 2002:a62:c101:: with SMTP id i1mr17934515pfg.80.1543882648390; Mon, 03 Dec 2018 16:17:28 -0800 (PST) Received: from blueforge.nvidia.com (searspoint.nvidia.com. [216.228.112.21]) by smtp.gmail.com with ESMTPSA id y12sm21733332pfk.70.2018.12.03.16.17.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Dec 2018 16:17:27 -0800 (PST) From: john.hubbard@gmail.com X-Google-Original-From: jhubbard@nvidia.com To: Andrew Morton , linux-mm@kvack.org Cc: Jan Kara , Tom Talpey , Al Viro , Christian Benvenuti , Christoph Hellwig , Christopher Lameter , Dan Williams , Dennis Dalessandro , Doug Ledford , Jason Gunthorpe , Jerome Glisse , Matthew Wilcox , Michal Hocko , Mike Marciniszyn , Ralph Campbell , LKML , linux-fsdevel@vger.kernel.org, John Hubbard Subject: [PATCH 2/2] infiniband/mm: convert put_page() to put_user_page*() Date: Mon, 3 Dec 2018 16:17:20 -0800 Message-Id: <20181204001720.26138-3-jhubbard@nvidia.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181204001720.26138-1-jhubbard@nvidia.com> References: <20181204001720.26138-1-jhubbard@nvidia.com> MIME-Version: 1.0 X-NVConfidentiality: public Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: John Hubbard For infiniband code that retains pages via get_user_pages*(), release those pages via the new put_user_page(), or put_user_pages*(), instead of put_page() This is a tiny part of the second step of fixing the problem described in [1]. The steps are: 1) Provide put_user_page*() routines, intended to be used for releasing pages that were pinned via get_user_pages*(). 2) Convert all of the call sites for get_user_pages*(), to invoke put_user_page*(), instead of put_page(). This involves dozens of call sites, and will take some time. 3) After (2) is complete, use get_user_pages*() and put_user_page*() to implement tracking of these pages. This tracking will be separate from the existing struct page refcounting. 4) Use the tracking and identification of these pages, to implement special handling (especially in writeback paths) when the pages are backed by a filesystem. Again, [1] provides details as to why that is desirable. [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()" Reviewed-by: Jan Kara Reviewed-by: Dennis Dalessandro Acked-by: Jason Gunthorpe Cc: Doug Ledford Cc: Jason Gunthorpe Cc: Mike Marciniszyn Cc: Dennis Dalessandro Cc: Christian Benvenuti Signed-off-by: John Hubbard --- drivers/infiniband/core/umem.c | 7 ++++--- drivers/infiniband/core/umem_odp.c | 2 +- drivers/infiniband/hw/hfi1/user_pages.c | 11 ++++------- drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++--- drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++++------- drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +++--- drivers/infiniband/hw/usnic/usnic_uiom.c | 7 ++++--- 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index c6144df47ea4..c2898bc7b3b2 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -58,9 +58,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d for_each_sg(umem->sg_head.sgl, sg, umem->npages, i) { page = sg_page(sg); - if (!PageDirty(page) && umem->writable && dirty) - set_page_dirty_lock(page); - put_page(page); + if (umem->writable && dirty) + put_user_pages_dirty_lock(&page, 1); + else + put_user_page(page); } sg_free_table(&umem->sg_head); diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 676c1fd1119d..99715049cd3b 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -659,7 +659,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt, ret = -EFAULT; break; } - put_page(local_page_list[j]); + put_user_page(local_page_list[j]); continue; } diff --git a/drivers/infiniband/hw/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c index e341e6dcc388..99ccc0483711 100644 --- a/drivers/infiniband/hw/hfi1/user_pages.c +++ b/drivers/infiniband/hw/hfi1/user_pages.c @@ -121,13 +121,10 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np void hfi1_release_user_pages(struct mm_struct *mm, struct page **p, size_t npages, bool dirty) { - size_t i; - - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty_lock(p[i]); - put_page(p[i]); - } + if (dirty) + put_user_pages_dirty_lock(p, npages); + else + put_user_pages(p, npages); if (mm) { /* during close after signal, mm can be NULL */ down_write(&mm->mmap_sem); diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index cc9c0c8ccba3..b8b12effd009 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -481,7 +481,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); if (ret < 0) { - put_page(pages[0]); + put_user_page(pages[0]); goto out; } @@ -489,7 +489,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, mthca_uarc_virt(dev, uar, i)); if (ret) { pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(&db_tab->page[i].mem)); + put_user_page(sg_page(&db_tab->page[i].mem)); goto out; } @@ -555,7 +555,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, if (db_tab->page[i].uvirt) { mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1); pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); - put_page(sg_page(&db_tab->page[i].mem)); + put_user_page(sg_page(&db_tab->page[i].mem)); } } diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index 16543d5e80c3..1a5c64c8695f 100644 --- a/drivers/infiniband/hw/qib/qib_user_pages.c +++ b/drivers/infiniband/hw/qib/qib_user_pages.c @@ -40,13 +40,10 @@ static void __qib_release_user_pages(struct page **p, size_t num_pages, int dirty) { - size_t i; - - for (i = 0; i < num_pages; i++) { - if (dirty) - set_page_dirty_lock(p[i]); - put_page(p[i]); - } + if (dirty) + put_user_pages_dirty_lock(p, num_pages); + else + put_user_pages(p, num_pages); } /* diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c index 926f3c8eba69..4a4b802b011f 100644 --- a/drivers/infiniband/hw/qib/qib_user_sdma.c +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -321,7 +321,7 @@ static int qib_user_sdma_page_to_frags(const struct qib_devdata *dd, * the caller can ignore this page. */ if (put) { - put_page(page); + put_user_page(page); } else { /* coalesce case */ kunmap(page); @@ -635,7 +635,7 @@ static void qib_user_sdma_free_pkt_frag(struct device *dev, kunmap(pkt->addr[i].page); if (pkt->addr[i].put_page) - put_page(pkt->addr[i].page); + put_user_page(pkt->addr[i].page); else __free_page(pkt->addr[i].page); } else if (pkt->addr[i].kvaddr) { @@ -710,7 +710,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, /* if error, return all pages not managed by pkt */ free_pages: while (i < j) - put_page(pages[i++]); + put_user_page(pages[i++]); done: return ret; diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c index 49275a548751..2ef8d31dc838 100644 --- a/drivers/infiniband/hw/usnic/usnic_uiom.c +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c @@ -77,9 +77,10 @@ static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty) for_each_sg(chunk->page_list, sg, chunk->nents, i) { page = sg_page(sg); pa = sg_phys(sg); - if (!PageDirty(page) && dirty) - set_page_dirty_lock(page); - put_page(page); + if (dirty) + put_user_pages_dirty_lock(&page, 1); + else + put_user_page(page); usnic_dbg("pa: %pa\n", &pa); } kfree(chunk); -- 2.19.2