Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp1374786imj; Thu, 7 Feb 2019 23:57:52 -0800 (PST) X-Google-Smtp-Source: AHgI3IYgpdCX8f921jF11n1fM6nwUtD39ThiwWZPWGRdoBnJ0rpdsXPGRSX1ifB2JmRjgsXIW0PX X-Received: by 2002:a62:4bcf:: with SMTP id d76mr21627122pfj.170.1549612672703; Thu, 07 Feb 2019 23:57:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549612672; cv=none; d=google.com; s=arc-20160816; b=xVJ64X9fNbCVWq8E9B365P2hZeOMuC/ii6VVLHIJQ6HzQNcCyM76i5Qymg/sx5/usN XUpJst/myhjFkhPKtTqy5527sdfTTSkxeAJyGna05aBrJMge4OgJXz9nS1ed3rEqC5BH S5oHw1g1D05Y5/A2ysLPMYJDdwl10GJiAmbspEkDM2J1znLY413skpFzb5rxOnKgef0s cELa4N5hK1TnFa+qZOkdEop4rIextYxG7r/hBFZSsU1pPUKB9GrwO0R4pO5GAE1bMS4F KmmOuDwEDIbMUSPPgWTR5QrP9/SpaIrKFhfXQQhK6qoxPnlJKuu7HSR5SCvrayoaiR3c 71tw== 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=J2d/n7dMaeGjTEKIDIBTiayW7FnCIDacKxsczsn6v/k=; b=1ES589ROfl8s5wlgpSHafgfWi62suJKlmuUKRGxktU23ztpaQ9oZF0c4h9lgagqeXu lEi1Vg1jtqtz0schNqAuCN5wktbyNzSdJ5lOgGAwLq/6d6g8Yx4/epEcSIffBz4w3SNz YLZh3jajQ6vCqisJgijoBosvBl0P4QJZeULE2U52xn7QG/5kQPJ3KE3a+8FFutrQaaYp SEs+QVf/pS4ns8kktrjex/6zqXGKX0OQQ8MloVbqhvkMrjGEbpKpphNf52VNSlM+V3SU EjeMHd6zJg8TPAZENCcsIx2WCI5f0FJ97pniFr7+g/SP82cF5wKMvu6bX1SyrqsJE0M6 qlAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=I4GdsIz4; 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 q3si1638061plb.200.2019.02.07.23.57.37; Thu, 07 Feb 2019 23:57:52 -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=I4GdsIz4; 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 S1727298AbfBHH5F (ORCPT + 99 others); Fri, 8 Feb 2019 02:57:05 -0500 Received: from mail-pf1-f193.google.com ([209.85.210.193]:34277 "EHLO mail-pf1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727257AbfBHH45 (ORCPT ); Fri, 8 Feb 2019 02:56:57 -0500 Received: by mail-pf1-f193.google.com with SMTP id j18so1315455pfe.1; Thu, 07 Feb 2019 23:56:56 -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=J2d/n7dMaeGjTEKIDIBTiayW7FnCIDacKxsczsn6v/k=; b=I4GdsIz44Gw1ZvdxS8A3KX2aMztLlez48JnFUkyF/acaAc80cF5HhhgrbpoGR2PB+E vP8U4msgbCn1JRQtjFisJFWRt+xNAUMU/ob+jHwE+eyLV8RMqHi1bS2fj1pBgNYUiWra clSIiacqFsl9crG1jF98vOlxCxG1p6wFAjL7/g1xMk/yIy6s+gR6l5+9vCDOOdx4Xz+I AYruW4TVowbQxZCmYY47S19UsD4WvHPvMClC6ZQoh7GC/KFrFfn/1uSc7RX5TAOd5Gg2 Y3KKyAj5lkTr2tHH/EJJ6Uf280tplM9hzxdBlAg5IgcgttR2fxsX+wVOMcstZ4YtxbXf qZ3g== 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=J2d/n7dMaeGjTEKIDIBTiayW7FnCIDacKxsczsn6v/k=; b=F3Fxg1jJSqCo28LB6fjYnTurYKyBgU2w1i1TtTdNrVricwI/DWGnVlNsEEKD/SFuSW U7+T3VbKoWgtpzvD+v/YyaDjLP5cM6HZ1dBaXexSRbdHhtAqqAqYMxhetVnY5i4p2wtR f3qFyuwIQXB/WeKmK1HdJ3iEdlYtDWzETGhBpg3jj2fuQu9upt8ybQkNzlPYwA9buYGZ VHoLIHKpq353EEk8ppfNtTr9b9GfUvQGLGdiHWKYxWeTIouw++cyskLVis8AK/b7QVsJ dsvy1oKTjCDJuVojsB9PtgcPUpW+uWplioSrk4AmDUrdo1DEosSBppBKyRHWN4IylwNv 0RTw== X-Gm-Message-State: AHQUAubz2EwurjTOX+cEFBS62Sz3hEOXvTqOk5iCR8JzSHUcXFuqinAQ gAgsQ+ovrATvL1qcKeBJnzU= X-Received: by 2002:a63:4611:: with SMTP id t17mr9848800pga.119.1549612616425; Thu, 07 Feb 2019 23:56:56 -0800 (PST) Received: from blueforge.nvidia.com (searspoint.nvidia.com. [216.228.112.21]) by smtp.gmail.com with ESMTPSA id h64sm2642610pfc.142.2019.02.07.23.56.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Feb 2019 23:56:55 -0800 (PST) From: john.hubbard@gmail.com X-Google-Original-From: jhubbard@nvidia.com To: Andrew Morton , linux-mm@kvack.org Cc: Al Viro , Christian Benvenuti , Christoph Hellwig , Christopher Lameter , Dan Williams , Dave Chinner , Dennis Dalessandro , Doug Ledford , Jan Kara , Jason Gunthorpe , Jerome Glisse , Matthew Wilcox , Michal Hocko , Mike Rapoport , Mike Marciniszyn , Ralph Campbell , Tom Talpey , LKML , linux-fsdevel@vger.kernel.org, John Hubbard , Jason Gunthorpe Subject: [PATCH 2/2] infiniband/mm: convert put_page() to put_user_page*() Date: Thu, 7 Feb 2019 23:56:49 -0800 Message-Id: <20190208075649.3025-3-jhubbard@nvidia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190208075649.3025-1-jhubbard@nvidia.com> References: <20190208075649.3025-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()" Cc: Doug Ledford Cc: Jason Gunthorpe Cc: Mike Marciniszyn Cc: Dennis Dalessandro Cc: Christian Benvenuti Reviewed-by: Jan Kara Reviewed-by: Dennis Dalessandro Acked-by: Jason Gunthorpe 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 acb882f279cb..d32757c1f77e 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -663,7 +663,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 112d2f38e0de..99108f3dcf01 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 31c523b2a9f5..a1a1ec4adffc 100644 --- a/drivers/infiniband/hw/qib/qib_user_sdma.c +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -320,7 +320,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); @@ -634,7 +634,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) { @@ -709,7 +709,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.20.1