Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp420069imm; Tue, 9 Oct 2018 21:12:41 -0700 (PDT) X-Google-Smtp-Source: ACcGV60uqZz9fRK/5YzbbPSqj9Pjry7q2EX3pbc1yzdWHZOeTJudZ/VVWvMVTmZAXggJJ3IctoKd X-Received: by 2002:a63:a119:: with SMTP id b25-v6mr28121741pgf.186.1539144761043; Tue, 09 Oct 2018 21:12:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539144761; cv=none; d=google.com; s=arc-20160816; b=HEUQU1R+c1rc3BmIdwwuFUbmn0JxB5fQTuGM+GeK+UuQ/ZCKYvDa3cfynX3OdHmAer psk7hQzXxFrdbI4igvNbRC6GzI63pgC2rEPbqGXXPiOZTerV2rll4k2hq8T2OFt2HXDt hz0h89ovurc4u0kbVWB45aA9Hjq0pEbQ9R6H271bm8ZTsukkS3FGvjZ5OdcIAA//SBlA PReiBZeRA5iaqrOIVPv8L4Pw7HKGN9nj/PQYP+STk6iRQUpmMqDcAxzqIAy3k0eBT7J4 vmwCHeKA3kH+tMjQT46e2vhrqVusJ1gAL0Nr/8JNn6awKInunqhX+7nA4VdB2QNWBJlq oa3g== 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=TbmsHWe5H8ma6Tv0sw8/rQINZ8rQuKk0IUgMEK2LUDs=; b=xvKPiiVe8K6ulYp49fTbaAgB4+NHCqA+PNvNwBcopN/AEQRPqGDB/bN2JR2Mf0qzCN IG0BHkv1bTJqj/KagqUIEqQsoYcvBzzH3qlyAx3seH8ZFE7mKzS74QBUOFI7EULB2Dro g5bemnzmwe4CcVwpbgznuDBm7qn7LqHdO3aJZ+KlllMvByRDXNB9uNPPPC9sS3oApIoK GFTIrrL9U5Tm8XUgJOrRtEuzo0o1G//AyqNNK+F9GhXvH/gKUBMmtTDltLylRBcTmDaA zFz+SgQhzPOtEU1RXvSCpgAc1qTclCGfSPdGAdasaMRVVA9TPcqvtxqgBiV7q53cQYWT HzIg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b="A/dSgG++"; 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 d30-v6si23499102pla.200.2018.10.09.21.12.26; Tue, 09 Oct 2018 21:12:41 -0700 (PDT) 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="A/dSgG++"; 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 S1727579AbeJJLcD (ORCPT + 99 others); Wed, 10 Oct 2018 07:32:03 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:41051 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727031AbeJJLcD (ORCPT ); Wed, 10 Oct 2018 07:32:03 -0400 Received: by mail-pg1-f194.google.com with SMTP id 23-v6so1851754pgc.8; Tue, 09 Oct 2018 21:11:51 -0700 (PDT) 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=TbmsHWe5H8ma6Tv0sw8/rQINZ8rQuKk0IUgMEK2LUDs=; b=A/dSgG+++v436Fhj/G3jJw45T/toilPXdJ5ZphfagywceVISvzvBqi6kFE+xRe6cz5 EqWNZFErHhMdeu40XJ3fHWgjxtFFbUP0AJYWAhooU2Wp3nkpFUe/1XgBSMpfZWuZBDst W2jSQxy8L7zF8OHRnIThM9PUDfWh10oFt9uW8u54cb4WYcmBUreCU9mbbZAinnoCDfD9 7gQVc3HJbnT9+pV+R1oyl3rUdRhxP2WcUm1oLtyumbe5mHLafpduiZiOPZIevxNj3PLl Zeio1fpuWEyDpRigax1ekx1gAatmdtXTIssewbbUqtgK0sGDwIFwusZqmC4ttF/EuOEe vZWg== 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=TbmsHWe5H8ma6Tv0sw8/rQINZ8rQuKk0IUgMEK2LUDs=; b=eHJ1Jx+Ewfb12Ga9+F/3+vUqGeioMkPDk7Npx3S14FlmTvTAOTehVGO7LnurhC+jRM bT9TPro66ZzvzrCd7tNWFsIC3Fxt/XQwZ2qiRvLFweA04OCjw7HTe3L5Qw+Uo2dm9JQ4 DQpu0ESi2jJQssXiJuevpi2Lrc7RXG4dx183L9ZJUt7f9a9Ht3WFEzhwMRmzU77zQ6N0 aVsBJ4l9sDJFZsCYm2uJ2SIZpn01MWZF+CcpiHY6LaxpPvSqVX+9w/nQ4QeZowqtfPbf 4PxpzdZmrP7p4RHmectSFagK7koH/CIgFY2MWAjpCMwO82PPkPgtCwyU1Rat8MX1i2+K Pc7Q== X-Gm-Message-State: ABuFfoi15qViqfto5pMU/ooEMYg6ZoiJbRf5n71Fhkc6sCSwYw4mt/9D bIOi2lZ6Bkexxomft0h9zzY= X-Received: by 2002:aa7:83cb:: with SMTP id j11-v6mr33090007pfn.91.1539144705851; Tue, 09 Oct 2018 21:11:45 -0700 (PDT) Received: from blueforge.nvidia.com (searspoint.nvidia.com. [216.228.112.21]) by smtp.gmail.com with ESMTPSA id o133-v6sm50045619pfg.86.2018.10.09.21.11.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Oct 2018 21:11:44 -0700 (PDT) From: john.hubbard@gmail.com X-Google-Original-From: jhubbard@nvidia.com To: Matthew Wilcox , Michal Hocko , Christopher Lameter , Jason Gunthorpe , Dan Williams , Jan Kara Cc: linux-mm@kvack.org, LKML , linux-rdma , linux-fsdevel@vger.kernel.org, John Hubbard , Doug Ledford , Mike Marciniszyn , Dennis Dalessandro , Christian Benvenuti Subject: [PATCH v5 3/3] infiniband/mm: convert put_page() to put_user_page*() Date: Tue, 9 Oct 2018 21:11:34 -0700 Message-Id: <20181010041134.14096-4-jhubbard@nvidia.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010041134.14096-1-jhubbard@nvidia.com> References: <20181010041134.14096-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, any 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 CC: linux-rdma@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: linux-mm@kvack.org 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 a41792dbae1f..7ab7a3a35eb4 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 6ec748eccff7..6227b89cf05c 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -717,7 +717,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, 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 9dd39daa602b..9e3615fd05f7 100644 --- a/drivers/infiniband/hw/usnic/usnic_uiom.c +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c @@ -89,9 +89,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.1