From patchwork Thu May 25 15:51:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13255404 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7D1DC77B7A for ; Thu, 25 May 2023 15:51:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 46593900003; Thu, 25 May 2023 11:51:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 415C26B0075; Thu, 25 May 2023 11:51:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 28F8A900003; Thu, 25 May 2023 11:51:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 19C616B0074 for ; Thu, 25 May 2023 11:51:20 -0400 (EDT) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id E112B160998 for ; Thu, 25 May 2023 15:51:19 +0000 (UTC) X-FDA: 80829216678.03.DE5B2AD Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf13.hostedemail.com (Postfix) with ESMTP id 2218420013 for ; Thu, 25 May 2023 15:51:17 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=LIL53DOr; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf13.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1685029878; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=VN2ZrpZ7x9fEyIq82GnRy+FAZ1eh7E2WAh2aAKifPL4=; b=z/2ShWDIZ6PFBCDTcEEfBxmzcUKbYxhFopNAHTxFypP/5cNibUCjWRy6do6cDIHnJU4W5f 6QOlJFmDJYSnUwQg3vyPqwIihmmDpa0Ul7AM+PDNTiDBeOG0lwW5r+Rh34O5I3oX3zlDuB rvffJzBYLuqkWhryDZuibEgGBJQ6Psc= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=LIL53DOr; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf13.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1685029878; a=rsa-sha256; cv=none; b=yhtpZiUVkYBWDt5nGl0CTGXqGJXxiCsRa4b+YCGeWuwDQMPA3SNWZKYtBcOCZeDxYPW1L3 XmLYEMDbDAS85CdDWpO3fj/9apDQoy/VwdafzF2GJMujqKZvZFHJuSYgVefK/nUu1otSlj DCwCLI26jZvVaogosVoJA0tyYTzp6zY= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685029877; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VN2ZrpZ7x9fEyIq82GnRy+FAZ1eh7E2WAh2aAKifPL4=; b=LIL53DOrLmOsYXtzVAqCspPRYgBf7HQN6lE48ZklwuwQjinO5ofSGNnfQNiLu3Cp1hl5QD k0dCQAM8wVvoGerdnUQcK8Mm28YZZBOpK+HBnoEdFRYw31U3FAtFka5BuSdh74unbtOmNc TNGEsSzd+cHbnRrP+3IEAy8U6JWh94M= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-554-FDn4oHLSPcWua6K8xvmmRA-1; Thu, 25 May 2023 11:51:11 -0400 X-MC-Unique: FDn4oHLSPcWua6K8xvmmRA-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9B8FF85A5AA; Thu, 25 May 2023 15:51:10 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.39.192.68]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3BEA6492B0A; Thu, 25 May 2023 15:51:08 +0000 (UTC) From: David Howells To: Christoph Hellwig , David Hildenbrand Cc: David Howells , Jens Axboe , Al Viro , Matthew Wilcox , Jan Kara , Jeff Layton , Jason Gunthorpe , Logan Gunthorpe , Hillf Danton , Christian Brauner , Linus Torvalds , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Andrew Morton Subject: [RFC PATCH 1/3] mm: Don't pin ZERO_PAGE in pin_user_pages() Date: Thu, 25 May 2023 16:51:00 +0100 Message-Id: <20230525155102.87353-2-dhowells@redhat.com> In-Reply-To: <20230525155102.87353-1-dhowells@redhat.com> References: <20230525155102.87353-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Rspam-User: X-Stat-Signature: p814jgoxeeeaxnimh3j9idkn5pp347a8 X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 2218420013 X-HE-Tag: 1685029877-267902 X-HE-Meta: U2FsdGVkX18tieu4HxYxmWHhTWRNdMuRJ4EO2rCBS2GF0XwdeCcJdUIt7XFPCQ8q3qwKfwJXpR1/WjmuX26gfRj6vxETSu63xI+4ukmvphLblXMIHG55lupUbbUeeFweuIqTlmBvj7OZJpahpThD/kf4pCKlZf/z/wtfi5IQ7HnhgCg5IQWfD5BEw8psS/L9SokDH5+FQATcUqlbE35jct/P/oy3KYRHNEv2c0iI4kIPzDrmwbdxNeGtkSXxtx3fmbvXmnBngQwNP1L9fy5TOKX9zSV1xmi305XGmPttcMofOllP1E79fi5QVIqIAZYLM5FcvErLW1KmhhzzM8VeV0em/AbvfGAvlCoW55aUdWY6G8RL2f+JQTvHCczP+aUtuUAjWt/wNcth2gvVgmpTSab3c5aZ0N+3lCGBx9eU0sCixoLqeC+vU46PHJ4OI5jY81VZoUEQiA1GxWphtT+tStb55mzDaXREFDLV7FvBxsgRYymt7XF1WszTLBqJAw3Q8SDsEmLnHmOgf1wYDr4WJ2ZlGUYMBq7tfXORpasRauG5flAeCfylciTFkFMG3FqvBOhQLlXMVCWuQQcwuEVM1RCic6CpFBE7fmG55qom8ZHCmqYbtpOyxSLLmdtrpcPd7ks7Kt+74/XiF93V+kX5f02UtgCsB1VYMX9R1og6OJcSdEhgWpP0SQ2DEgP/Y1Phh03MNJ1Qb1Yq3x44cDkWVomwzxEhmREfAyoBu3ku1IaV9uyv/34B4zcloCGZ+xcjZHBhwwf1Wz769FxkutQMPSTNEg5ZiiWhSaDM6IDwiOV8AGn1tgzHGO+wRMxdSOCFKCMyRu0ams8HyJCdYSfssxUlH19b1r8NaqVpOBmCVApmDHlQ5vfik976sPX3zxXC/DMKPLQzYXVPmqXIx8bn7KVHvuCEm/GbU3La2QcokJ1z7MIPExAj6OiBmdHCpdEOgZ7YQ4Qib2qgxSH+st/ Dem0VyWB uLNkSAEqEDb2mpt0w2Itw1iSJpfbDmgWbAF3+P5c/X454rMPYUyhpVOa+Gk84H5BXFDyVAS3zgYFkLVS1Yhlyv1juu88/6SluI4ixr1vDWMjqIYPVhZXObcMfVQ38I2slkJStVR6OGSlHCc3rxJ56eUZoKOE/xDsKJ/CbujDiJz1K9o3/bZomXhxAcUgkzltWDvlSzyP4VoA+DM83HjZoWIDQ3JYHOqEd1PjwA+HJffEk0PdkMuT+Om59udVHLDI2KN610i9ekVEVKLR+ZQgUqNHImODcbcvIUKZfCK6IxkJPV1jA8+yupDa7PwgOIJzxuJj/2BhSPrcaLcfby84C024OCX3SVq9f3y165KjZFWohwZke+VDNCb4lGxhLTcfbwafuC+fOkgz2pE9xN6sZwvZiHhh93fxvj38YP3Aph+SdS5ubE0aLDyTkaeJu1H76OOBmOwr5o5J3o1rXU9I0j4E/rDPxQ8fRq4Z9mRmDjUOIQLdYVvk3sGjfXpG7KRTg9aFUVQCXzlOWE4S6UEGXsrF13H4LdzIQeeqoO8lT45OKdD0jCUh12yp+8rvpR/+SRNu6YABEGTRo2ulKVGUcpUG2/6KK5Sp+Zvkf9b+fN6Vf+JHwkxiDbdcM8hSz2hXUFZQ9yjcZBsCG7YjVUVUFoZGeUpDfCu5J1Cf3l86fCxkF+pZF/nz0khjJUnuWumOtnW4Icu8fVDMsxrQ= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Make pin_user_pages*() leave the ZERO_PAGE unpinned if it extracts a pointer to it from the page tables and make unpin_user_page*() correspondingly ignore the ZERO_PAGE when unpinning. We don't want to risk overrunning the zero page's refcount as we're only allowed ~2 million pins on it - something that userspace can conceivably trigger. Signed-off-by: David Howells cc: Christoph Hellwig cc: David Hildenbrand cc: Andrew Morton cc: Jens Axboe cc: Al Viro cc: Matthew Wilcox cc: Jan Kara cc: Jeff Layton cc: Jason Gunthorpe cc: Logan Gunthorpe cc: Hillf Danton cc: Christian Brauner cc: Linus Torvalds cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org cc: linux-kernel@vger.kernel.org cc: linux-mm@kvack.org --- mm/gup.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/mm/gup.c b/mm/gup.c index bbe416236593..d2662aa8cf01 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -51,7 +51,8 @@ static inline void sanity_check_pinned_pages(struct page **pages, struct page *page = *pages; struct folio *folio = page_folio(page); - if (!folio_test_anon(folio)) + if (page == ZERO_PAGE(0) || + !folio_test_anon(folio)) continue; if (!folio_test_large(folio) || folio_test_hugetlb(folio)) VM_BUG_ON_PAGE(!PageAnonExclusive(&folio->page), page); @@ -131,6 +132,13 @@ struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags) else if (flags & FOLL_PIN) { struct folio *folio; + /* + * Don't take a pin on the zero page - it's not going anywhere + * and it is used in a *lot* of places. + */ + if (page == ZERO_PAGE(0)) + return page_folio(ZERO_PAGE(0)); + /* * Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a * right zone, so fail and let the caller fall back to the slow @@ -180,6 +188,8 @@ struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags) static void gup_put_folio(struct folio *folio, int refs, unsigned int flags) { if (flags & FOLL_PIN) { + if (folio == page_folio(ZERO_PAGE(0))) + return; node_stat_mod_folio(folio, NR_FOLL_PIN_RELEASED, refs); if (folio_test_large(folio)) atomic_sub(refs, &folio->_pincount); @@ -224,6 +234,13 @@ int __must_check try_grab_page(struct page *page, unsigned int flags) if (flags & FOLL_GET) folio_ref_inc(folio); else if (flags & FOLL_PIN) { + /* + * Don't take a pin on the zero page - it's not going anywhere + * and it is used in a *lot* of places. + */ + if (page == ZERO_PAGE(0)) + return 0; + /* * Similar to try_grab_folio(): be sure to *also* * increment the normal page refcount field at least once, @@ -3079,6 +3096,9 @@ EXPORT_SYMBOL_GPL(get_user_pages_fast); * * FOLL_PIN means that the pages must be released via unpin_user_page(). Please * see Documentation/core-api/pin_user_pages.rst for further details. + * + * Note that if the zero_page is amongst the returned pages, it will not have + * pins in it and unpin_user_page() will not remove pins from it. */ int pin_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages) @@ -3161,6 +3181,9 @@ EXPORT_SYMBOL(pin_user_pages); * pin_user_pages_unlocked() is the FOLL_PIN variant of * get_user_pages_unlocked(). Behavior is the same, except that this one sets * FOLL_PIN and rejects FOLL_GET. + * + * Note that if the zero_page is amongst the returned pages, it will not have + * pins in it and unpin_user_page() will not remove pins from it. */ long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, struct page **pages, unsigned int gup_flags) From patchwork Thu May 25 15:51:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13255406 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFD3DC7EE2D for ; Thu, 25 May 2023 15:51:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F3E56280001; Thu, 25 May 2023 11:51:22 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EC6DA6B0075; Thu, 25 May 2023 11:51:22 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B9C45280001; Thu, 25 May 2023 11:51:22 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id A68566B0074 for ; Thu, 25 May 2023 11:51:22 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 248E0C0B98 for ; Thu, 25 May 2023 15:51:22 +0000 (UTC) X-FDA: 80829216804.11.E3660F4 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf19.hostedemail.com (Postfix) with ESMTP id 0E63A1A0025 for ; Thu, 25 May 2023 15:51:18 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b="Fp08mMQ/"; spf=pass (imf19.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1685029879; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=BVMkJArYFah5gI2QNFMxWzaYnawUBl8R91cCRWuGcSI=; b=nqSCu5ogGrUxrjJmdwUJgcfhZTMsKO8ISbzNVVzp7Zo1LS+4n5uuepgFh78lz/+Tl3w0/M /8fg4Qd2trchVe+DGvs5E15faa87tdh4uEOFMhX3gwA/V3b9fBesZh7yXxPIaSmac7NIDr wAu9Ht8a1BS2mPOjfNVbCk6GygZusLs= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1685029879; a=rsa-sha256; cv=none; b=okdCqyiwNgX4Lrf96vVE5xEoq+0zd3RvuJuCoke7atQdyPeyOnvxI4dv4uFxSltlbdgzxu z4aegaRRQf4Jx/J0TlsV8yPJASFgO155IzoFbMgD0QzWprxjQDv6hA2Unn7kbsJPkcEtPM FOMlNqzXfpB2+iwdGaxoWWUggv2krgQ= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b="Fp08mMQ/"; spf=pass (imf19.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685029878; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BVMkJArYFah5gI2QNFMxWzaYnawUBl8R91cCRWuGcSI=; b=Fp08mMQ/g8XkuMXTSaMpNU1r3oiMD+mK4fQUkVIJM2kKjlr0B9/sPlTeaIx1XFvf+8d/fN GKO/N1Wo/J8t38jbYDdBaadqz4OvYjQ3HYsSgFC8pQ5bLB5NCAr291dp0kkESHodSmAMCn IC3/szzm/Fy2teW2aPSdJosFja+hMFo= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-414-ellFKLpmOhqtIg-dAldJeQ-1; Thu, 25 May 2023 11:51:14 -0400 X-MC-Unique: ellFKLpmOhqtIg-dAldJeQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C448238294B6; Thu, 25 May 2023 15:51:13 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.39.192.68]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6EE15407DEC3; Thu, 25 May 2023 15:51:11 +0000 (UTC) From: David Howells To: Christoph Hellwig , David Hildenbrand Cc: David Howells , Jens Axboe , Al Viro , Matthew Wilcox , Jan Kara , Jeff Layton , Jason Gunthorpe , Logan Gunthorpe , Hillf Danton , Christian Brauner , Linus Torvalds , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Andrew Morton Subject: [RFC PATCH 2/3] mm: Provide a function to get an additional pin on a page Date: Thu, 25 May 2023 16:51:01 +0100 Message-Id: <20230525155102.87353-3-dhowells@redhat.com> In-Reply-To: <20230525155102.87353-1-dhowells@redhat.com> References: <20230525155102.87353-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Rspamd-Queue-Id: 0E63A1A0025 X-Rspam-User: X-Stat-Signature: mf4xnz4rghcnjzpz37n7mgz83esttpst X-Rspamd-Server: rspam03 X-HE-Tag: 1685029878-944141 X-HE-Meta: U2FsdGVkX1+FMHRhPLQWO5S09PjmnWLF3kDrY1fDY8pqhoLJCX/72pnf73R/XjS1wyzZzhWnIbRxRa4f7JX/brW8QukND3gXRjkboyaPRBbC6CzyBflEOnkmcwUXCLPGExu9Txr3oYwwUXr4iMHX00leaTSInM+YB9SRFjS9y727c9qu9tPUh5FF3jkhJd9xZi3LTBLO1zEKKqCrTf4Zg6ucdPSIsCGneiMpTnIbFi8/qwY/537xtQbrUkpMHt7E9A3epRz01aWXFLFaLfBuEB4zwuvHcUPvePZ3fLCgVP9VKuTHCLyS7xWSGra2rqARaJYZfhYjEbdo4I3eNFJ1rbo6ulCQLgMVEebtlBNN1vsQXoXvNOeb+gv1L5R2F9a8EIJj4Sq9sW2ytCPurC4AJ7UE0TBbAP5MXrsw+h2sLxqYXlNq6Q1qSR4UtLk5JPtE/gCFxeX+YhDjocMcC48viJR41Toxhy6AjFZurqcG+wsX3MP9dUsH0cnKutWncOlhKJDe9MeEPLJ8Hs3+WvyYfK+gcmSZgzDqW7RimmlgBC0OEaktFmah+XKrHDAhL8dh/oMtbGhBGdrZ3K3KSBxRaj/dV5FoyeTDpT/DfcU6uqjbh5Wooa4sL3vmP+cXXTypjLSrB0sCit+bFYLzghZat7+TGE2GfIZJuIweORcblkyoKMxudHu292wbLCK7XLckxyBzEktoglHtpGaoYA88OYI++uwcJ+EE4aJYyOdKxIBHgHZKaTXftAJHF4NqY6fctProvoUe99BTaOZ1XfXBl17cwHOdQXOtUxSQ0T2W69NKntoSEvVbsLYo9WHhaAv3cS1AsnvyfXVYZ8zIlWuRkFr1JYSJUUPxMne1mgOZAb08H0j099/Z0xzYsmv1rUygceKPia7M3iZh86QoHTB7/ammO46tUfZ0gQ5lz83RvX70ZZJsfwp3LJXe9b3C+shZ7ETj+N3s0tQxAp/9Bd0 6dZV9CTx 7bC1pdg2H1pYQAOwEojH6ol/JRLaFtjp/4GsuF7cAXfI805cc2695T17wSBvDOEzXh0tkHHJVpnW5xVo0Bd8mhZFsrQOTs0T07A6qOH+G/HGATN8RX1cZJoPvHjh3SH0ky66Nc5jJGRDj8bZ670tVF32RfnaOJljcb9OWQCKBHzOcp4sOMNfd6Pvv0ZsrYVvBLK1oj+Bzfg13ZM2LHYL2omUAgjnZ/OZx4hDt5ojkFUbepEamEPHxL3iVyJOOR9/mBodILwqqsASF4srTJNJYXXDa+uOweENyNWKGt6iVnPBqncHZpJxxmARMVkapgjkoPWQWk7awPtOl4ILz9LRykPfLR+AbbCjAt82KMnXmTLDsAiq8HWVSQoKOI4TbiF3JbQFmfQnwEcaSsTsxndr8udN80i6aZhM4MSwwa/1MaRe4g0z1Iy7KIIJQFlQu3QXBAXepFU+ID0d0EVWT5/pdyNotZcgscYFhpS3m6IZTICsCuKUAeQEXvflnFIhHXj42TTx4kTexRdoE1GdwEqPYC+Q3VDDBpoxGhjQJEPpwZBgDzBPVEiKfqgmokg3+S5Mfw9cSgVN51C4nboD2HZPZ10ue3wkRVoMV5bVXBhbOzQDSoD43LLI176yqGURWFRhAkSQFj3WDujgdI2kae3aVlMJv2I52N7Ays9bkRJrG/VxoNKg= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Provide a function to get an additional pin on a page that we already have a pin on. This will be used in fs/direct-io.c when dispatching multiple bios to a page we've extracted from a user-backed iter rather than redoing the extraction. Signed-off-by: David Howells cc: Christoph Hellwig cc: David Hildenbrand cc: Andrew Morton cc: Jens Axboe cc: Al Viro cc: Matthew Wilcox cc: Jan Kara cc: Jeff Layton cc: Jason Gunthorpe cc: Logan Gunthorpe cc: Hillf Danton cc: Christian Brauner cc: Linus Torvalds cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org cc: linux-kernel@vger.kernel.org cc: linux-mm@kvack.org --- include/linux/mm.h | 1 + mm/gup.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 27ce77080c79..931b75dae7ff 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2383,6 +2383,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); int pin_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); +void page_get_additional_pin(struct page *page); int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, diff --git a/mm/gup.c b/mm/gup.c index d2662aa8cf01..b1e55847ca13 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -275,6 +275,35 @@ void unpin_user_page(struct page *page) } EXPORT_SYMBOL(unpin_user_page); +/** + * page_get_additional_pin - Try to get an additional pin on a pinned page + * @page: The page to be pinned + * + * Get an additional pin on a page we already have a pin on. Makes no change + * if the page is the zero_page. + */ +void page_get_additional_pin(struct page *page) +{ + struct folio *folio = page_folio(page); + + if (page == ZERO_PAGE(0)) + return; + + /* + * Similar to try_grab_folio(): be sure to *also* increment the normal + * page refcount field at least once, so that the page really is + * pinned. + */ + if (folio_test_large(folio)) { + WARN_ON_ONCE(atomic_read(&folio->_pincount) < 1); + folio_ref_add(folio, 1); + atomic_add(1, &folio->_pincount); + } else { + WARN_ON_ONCE(folio_ref_count(folio) < GUP_PIN_COUNTING_BIAS); + folio_ref_add(folio, GUP_PIN_COUNTING_BIAS); + } +} + static inline struct folio *gup_folio_range_next(struct page *start, unsigned long npages, unsigned long i, unsigned int *ntails) { From patchwork Thu May 25 15:51:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13255405 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50EFFC77B7E for ; Thu, 25 May 2023 15:51:23 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B9E44280002; Thu, 25 May 2023 11:51:22 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B1A876B0078; Thu, 25 May 2023 11:51:22 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 96F94280001; Thu, 25 May 2023 11:51:22 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 887316B0074 for ; Thu, 25 May 2023 11:51:22 -0400 (EDT) Received: from smtpin09.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 60BA9AE5D4 for ; Thu, 25 May 2023 15:51:22 +0000 (UTC) X-FDA: 80829216804.09.0941FFB Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf11.hostedemail.com (Postfix) with ESMTP id 58FEA40013 for ; Thu, 25 May 2023 15:51:20 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=R9Gr2oQA; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf11.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1685029880; a=rsa-sha256; cv=none; b=rAm5NPC6j1pd38l7kj3MZmXaQanotjlZqwhFbyDN/ZwQK7QgcSLEhzZwd9M4/81JtenAxL TXOwJ/lsyjUsRbpHYS395csRNAFN/emTjexO5NUicN92cSOdh448EXYSuT0yOIJIYhtPAE o+YcBFTLvHnifjqLNL/2t2s9r3xb8j4= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=R9Gr2oQA; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf11.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1685029880; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=pxFfFsuy6kbRVs0LWrBWAlBLaVA5rUY1NByIba8Y/08=; b=EZowuuZ5uDrTVnQ8synmkZSYF7G5tc5Z5ZdD5mp2qW2mtL59ygwfTIYLdmqObu8uNogAnC tfexoBtjmWBTrQ4A+5o1hjdUKGiAjPMd9K3NDdEyCDcw2meGqsvQAEoh1HhA67ud1iEMXH SaZa4uEfltISLSFm1TRbBLR7ceYY/+w= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685029879; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pxFfFsuy6kbRVs0LWrBWAlBLaVA5rUY1NByIba8Y/08=; b=R9Gr2oQALsW8UR9K3V1zdqIvn3jQ9oeABbYhxTcqiuk5SPnQMpXVCjekWrOPy6AZ+DRDnk tJGl+OxqGTvQXyI/iWYjKOKA80SEClKTZ/Nw58aEb5E+br08gY5LMtaPz+99x2V7LwLbwu 6HSMS52s7djNDgwZlxHDR59RcByBwgg= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-601-yKzjrWDzM6Su1Tb4mISqqA-1; Thu, 25 May 2023 11:51:18 -0400 X-MC-Unique: yKzjrWDzM6Su1Tb4mISqqA-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DB73F3C17C65; Thu, 25 May 2023 15:51:16 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.39.192.68]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7BE4C492B0A; Thu, 25 May 2023 15:51:14 +0000 (UTC) From: David Howells To: Christoph Hellwig , David Hildenbrand Cc: David Howells , Jens Axboe , Al Viro , Matthew Wilcox , Jan Kara , Jeff Layton , Jason Gunthorpe , Logan Gunthorpe , Hillf Danton , Christian Brauner , Linus Torvalds , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Andrew Morton Subject: [RFC PATCH 3/3] block: Use iov_iter_extract_pages() and page pinning in direct-io.c Date: Thu, 25 May 2023 16:51:02 +0100 Message-Id: <20230525155102.87353-4-dhowells@redhat.com> In-Reply-To: <20230525155102.87353-1-dhowells@redhat.com> References: <20230525155102.87353-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Rspam-User: X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 58FEA40013 X-Stat-Signature: znw35gqqa8ca1s8h8rcs4n8z8aytq6xz X-HE-Tag: 1685029880-315915 X-HE-Meta: U2FsdGVkX1/Z1Kzhy8VOGgLDZEdWTGc1mStVfupsVvZ29ttu+S935Pg92wgtvucQmJKzwvnqnyda7WVe1fZrfr7c+wDuA0ZnyZRgxDNgn27oG6kvY2cnikcAxSrdPWX+lZekvGYWfTECQKf7tHBQjRAl2ysV+RQCevx8XGQReG3lclvghgqBBTHlY1T9VW0SgjW396FtFFUgujUkbfG8I/u6ti4XDAZ/jGNl6DKqZrs8Cd0MPhw+GSn9HrE46kQnhbapnMkvJfIgFgUG8H2hdl8F1TfJrmEPhCAGDLX2nhyR4cnu+FiHec4F9YfbkuJXOpYvSGkLcW6joy5DLsriTujt4H4Wph7cFVn/YYk8ySq4qF1H4SjEXXRBaw5os1pAxjLFGBZkzXuCroZTIfFd73q0z5yzFiS+WWTotOUbi4XC2yHVtvbG12cxLm/vEQMVGsXg2YWXM9D6Qv5gpqMr+qMbKTpoAEW3xS35VcIEz/2bCIw9HPtECp9VbMlrTCt87f1gVD10JS/O6+tWImyQXaiUjIh4WQNVzxtmWbc5MjJBl2kM1eMRE2vu2vS5LxvjcXaHtwpaHKFbCX+aJFKZ3navlogGPLyrj17ChDRscx3M+mosxfxvLnX5V2D23Oo+Mmu1P5fHpUuars7knJ87wLKCIF0nkZJvjwFeo37X1dtRFCeoaF4Srn8klUueqlEQy0qzmazvXuiTm2J6TI1S+bDnq4jD77Ji4d0n50LHncfN9h1AWixotvmL2apdRtoJFwwVGeEfTQ9vWnhmcHvNjnnh6Fpri20/OMI+MMP11e37so6+PnNHCqdOiFNVu2N/m+QIbBYgGHGXArbofvH8SYbzqZ2Ia6ovWoex0v2gwGbnUEwR/Fieby01hnL21ws6g6MgTDfLOLqRhA4oVcjp68iJ6Aqcb/X7TpSA4g4tpjlC7uXno+QXPgBUktX/URwHFXZVc7WqRt2oV42MW9f f4WHQxNU 7buGT2lVkLrYhn9meUObjYZf74O7EgYsbPBHVqeD3IlE/eMsd17rDlcnDEj8xcTrQAyChhnsCFXiNDBgz2rEE+yBRT/M7EYRQkYn1uLuNPYxweMGef/hiCeQzvw4jJSxuTqjagI1aSUkQxnkhEiQKFcNX3vSfpCF5Azh+44c7hV0LeD3x5YNKM/EqWCpNTmGzw+TgPhWu4wYEO57PM287PrLbZThlcc8hVVEttKzze6JE5asJOSvFToQxsh3q4W6m2gotxjGb24VS8mcgmNZfSoc1/JJDT8RyAhvNA0r10idBKaEUtJ0dzgv+Q5lGcTPxOOtN9IqzGS/Jenrn7lc6l01UUpwX8L7aJzI6pkQYLtjEWGTnj5j4c4USYzoogXtYvLcpRnwALgKNDU2EDnNIZwcllN3dqagPJnomQQ4Xxa4ksFh/ew0OsgIgvryP50sGY9PjKMEaP6LvYNl8wd6gfKpZ9sf4W+rfC/eig8iqRGzzeuFo5otT5ISg48ZCwckuPyS1ef8F8wZs76di/0bVYvobnmkc6YBueG9hDfANUvBB2aewW29raX2w5Yocbhd+hzU24KJtYRav3YU7rbje0C43q3bSdwpIf5tfgLAN/fyiqiKpduFRaUkIpJEIFdVAnMKxj1LoLC1f+kxcQdJJZCUyTSSNeeBFORAa X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Change the old block-based direct-I/O code to use iov_iter_extract_pages() to pin user pages or leave kernel pages unpinned rather than taking refs when submitting bios. This makes use of the preceding patches to not take pins on the zero page (thereby allowing insertion of zero pages in with pinned pages) and to get additional pins on pages, allowing an extracted page to be used in multiple bios without having to re-extract it. Signed-off-by: David Howells cc: Christoph Hellwig cc: David Hildenbrand cc: Andrew Morton cc: Jens Axboe cc: Al Viro cc: Matthew Wilcox cc: Jan Kara cc: Jeff Layton cc: Jason Gunthorpe cc: Logan Gunthorpe cc: Hillf Danton cc: Christian Brauner cc: Linus Torvalds cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org cc: linux-kernel@vger.kernel.org cc: linux-mm@kvack.org --- fs/direct-io.c | 68 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index ad20f3428bab..14049204cac8 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -42,8 +42,8 @@ #include "internal.h" /* - * How many user pages to map in one call to get_user_pages(). This determines - * the size of a structure in the slab cache + * How many user pages to map in one call to iov_iter_extract_pages(). This + * determines the size of a structure in the slab cache */ #define DIO_PAGES 64 @@ -121,12 +121,13 @@ struct dio { struct inode *inode; loff_t i_size; /* i_size when submitted */ dio_iodone_t *end_io; /* IO completion function */ + bool need_unpin; /* T if we need to unpin the pages */ void *private; /* copy from map_bh.b_private */ /* BIO completion state */ spinlock_t bio_lock; /* protects BIO fields below */ - int page_errors; /* errno from get_user_pages() */ + int page_errors; /* err from iov_iter_extract_pages() */ int is_async; /* is IO async ? */ bool defer_completion; /* defer AIO completion to workqueue? */ bool should_dirty; /* if pages should be dirtied */ @@ -165,14 +166,14 @@ static inline unsigned dio_pages_present(struct dio_submit *sdio) */ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio) { + struct page **pages = dio->pages; const enum req_op dio_op = dio->opf & REQ_OP_MASK; ssize_t ret; - ret = iov_iter_get_pages2(sdio->iter, dio->pages, LONG_MAX, DIO_PAGES, - &sdio->from); + ret = iov_iter_extract_pages(sdio->iter, &pages, LONG_MAX, + DIO_PAGES, 0, &sdio->from); if (ret < 0 && sdio->blocks_available && dio_op == REQ_OP_WRITE) { - struct page *page = ZERO_PAGE(0); /* * A memory fault, but the filesystem has some outstanding * mapped blocks. We need to use those blocks up to avoid @@ -180,8 +181,7 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio) */ if (dio->page_errors == 0) dio->page_errors = ret; - get_page(page); - dio->pages[0] = page; + dio->pages[0] = ZERO_PAGE(0); sdio->head = 0; sdio->tail = 1; sdio->from = 0; @@ -201,9 +201,9 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio) /* * Get another userspace page. Returns an ERR_PTR on error. Pages are - * buffered inside the dio so that we can call get_user_pages() against a - * decent number of pages, less frequently. To provide nicer use of the - * L1 cache. + * buffered inside the dio so that we can call iov_iter_extract_pages() + * against a decent number of pages, less frequently. To provide nicer use of + * the L1 cache. */ static inline struct page *dio_get_page(struct dio *dio, struct dio_submit *sdio) @@ -219,6 +219,18 @@ static inline struct page *dio_get_page(struct dio *dio, return dio->pages[sdio->head]; } +static void dio_pin_page(struct dio *dio, struct page *page) +{ + if (dio->need_unpin) + page_get_additional_pin(page); +} + +static void dio_unpin_page(struct dio *dio, struct page *page) +{ + if (dio->need_unpin) + unpin_user_page(page); +} + /* * dio_complete() - called when all DIO BIO I/O has been completed * @@ -444,8 +456,9 @@ static inline void dio_bio_submit(struct dio *dio, struct dio_submit *sdio) */ static inline void dio_cleanup(struct dio *dio, struct dio_submit *sdio) { - while (sdio->head < sdio->tail) - put_page(dio->pages[sdio->head++]); + if (dio->need_unpin) + unpin_user_pages(dio->pages + sdio->head, + sdio->tail - sdio->head); } /* @@ -676,7 +689,7 @@ static inline int dio_new_bio(struct dio *dio, struct dio_submit *sdio, * * Return zero on success. Non-zero means the caller needs to start a new BIO. */ -static inline int dio_bio_add_page(struct dio_submit *sdio) +static inline int dio_bio_add_page(struct dio *dio, struct dio_submit *sdio) { int ret; @@ -688,7 +701,7 @@ static inline int dio_bio_add_page(struct dio_submit *sdio) */ if ((sdio->cur_page_len + sdio->cur_page_offset) == PAGE_SIZE) sdio->pages_in_io--; - get_page(sdio->cur_page); + dio_pin_page(dio, sdio->cur_page); sdio->final_block_in_bio = sdio->cur_page_block + (sdio->cur_page_len >> sdio->blkbits); ret = 0; @@ -743,11 +756,11 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio, goto out; } - if (dio_bio_add_page(sdio) != 0) { + if (dio_bio_add_page(dio, sdio) != 0) { dio_bio_submit(dio, sdio); ret = dio_new_bio(dio, sdio, sdio->cur_page_block, map_bh); if (ret == 0) { - ret = dio_bio_add_page(sdio); + ret = dio_bio_add_page(dio, sdio); BUG_ON(ret != 0); } } @@ -804,13 +817,13 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, */ if (sdio->cur_page) { ret = dio_send_cur_page(dio, sdio, map_bh); - put_page(sdio->cur_page); + dio_unpin_page(dio, sdio->cur_page); sdio->cur_page = NULL; if (ret) return ret; } - get_page(page); /* It is in dio */ + dio_pin_page(dio, page); /* It is in dio */ sdio->cur_page = page; sdio->cur_page_offset = offset; sdio->cur_page_len = len; @@ -825,7 +838,7 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page, ret = dio_send_cur_page(dio, sdio, map_bh); if (sdio->bio) dio_bio_submit(dio, sdio); - put_page(sdio->cur_page); + dio_unpin_page(dio, sdio->cur_page); sdio->cur_page = NULL; } return ret; @@ -926,7 +939,7 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio, ret = get_more_blocks(dio, sdio, map_bh); if (ret) { - put_page(page); + dio_unpin_page(dio, page); goto out; } if (!buffer_mapped(map_bh)) @@ -971,7 +984,7 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio, /* AKPM: eargh, -ENOTBLK is a hack */ if (dio_op == REQ_OP_WRITE) { - put_page(page); + dio_unpin_page(dio, page); return -ENOTBLK; } @@ -984,7 +997,7 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio, if (sdio->block_in_file >= i_size_aligned >> blkbits) { /* We hit eof */ - put_page(page); + dio_unpin_page(dio, page); goto out; } zero_user(page, from, 1 << blkbits); @@ -1024,7 +1037,7 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio, sdio->next_block_for_io, map_bh); if (ret) { - put_page(page); + dio_unpin_page(dio, page); goto out; } sdio->next_block_for_io += this_chunk_blocks; @@ -1039,8 +1052,8 @@ static int do_direct_IO(struct dio *dio, struct dio_submit *sdio, break; } - /* Drop the ref which was taken in get_user_pages() */ - put_page(page); + /* Drop the pin which was taken in get_user_pages() */ + dio_unpin_page(dio, page); } out: return ret; @@ -1135,6 +1148,7 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, /* will be released by direct_io_worker */ inode_lock(inode); } + dio->need_unpin = iov_iter_extract_will_pin(iter); /* Once we sampled i_size check for reads beyond EOF */ dio->i_size = i_size_read(inode); @@ -1259,7 +1273,7 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, ret2 = dio_send_cur_page(dio, &sdio, &map_bh); if (retval == 0) retval = ret2; - put_page(sdio.cur_page); + dio_unpin_page(dio, sdio.cur_page); sdio.cur_page = NULL; } if (sdio.bio)