Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp3533981pxp; Tue, 8 Mar 2022 16:50:20 -0800 (PST) X-Google-Smtp-Source: ABdhPJzAgIHz5GPMl32yVyvm1yqvV7bXkIj5UgEebB12BQgMuy3XvrfpEZI8s8nEA3TMvG3nScm+ X-Received: by 2002:a17:90a:6542:b0:1bd:149f:1c29 with SMTP id f2-20020a17090a654200b001bd149f1c29mr7572769pjs.240.1646787020230; Tue, 08 Mar 2022 16:50:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646787020; cv=none; d=google.com; s=arc-20160816; b=UsTMK5s1qSxeB+7Z+hCDO4aaKEbIpPOH7VdRfbP2LJKHwhegTcal0o5x0twtnx9Mq8 PZexlQyxfqFhhL2+Z2gGOJFY+hhQqokgKLt3rNwZaR9BdGpwSlMfZb3HDerRMMKfP1uo A9p/ATf+jphzb6C8v4EiOD8vIe/+B264O0XbLBtxQVlD2JAEfyEr/gExq+SQvB5bj4oy r9Lpfayv3RqUUDEB58aIfJa7mazFKX/gDSxqLBtgVQsPH5uLgDPJs9AqYScplClBdDzD EPVxwxOvMGju48xlx4450ex0FMvpXIeQ+WKQW9vVqLsih5FY6WC1deRUxSDByNYQtUJN x6zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qJ1qd/yJEkfG7Q+dEgEOQ8X+XaxWGRxyUflZLqtQESE=; b=IFUxUbr791q9ALd6d+KEb2Z/t6FOPg0lTpbcuvdgChnYmPg1aa8rwAiiJSlKC8xIwW QpTJf2lZ/MP1FGTq4Tcxii7NKE6hUQwjnig6Z9OGuIejwPANXzmLve/9dYNZBke9pzbz cWzvVCwgjv84QRwa9IrHeR7PjQ8oF0wPN65SuTDzwStg27m8tOBjLu0End+vBICEA3gG s+n9JgjVd0VEqWYksvrDrBzMIxWaK8Onmod8mWNQdxCOsf5UGwoDWABpW5vIjAJrXEeE L9KrCW1U6mREr6mkXTJp39j0Mr4Kvo2vnIc3RndeSYyYgOcUEkw1liGu6Jtsg/Us6en6 Kfqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=n2wE6EF0; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id m6-20020a17090a668600b001bd14e01fb3si502531pjj.161.2022.03.08.16.50.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 16:50:20 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=n2wE6EF0; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D1E9BDBD13; Tue, 8 Mar 2022 16:02:15 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234656AbiCGKc6 (ORCPT + 99 others); Mon, 7 Mar 2022 05:32:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242063AbiCGKLN (ORCPT ); Mon, 7 Mar 2022 05:11:13 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C16A886E06; Mon, 7 Mar 2022 01:54:19 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CDA2760A27; Mon, 7 Mar 2022 09:54:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5DFBC340F3; Mon, 7 Mar 2022 09:54:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1646646854; bh=jZhJUgnC00Oi4NxwevCHNXIQrXbw0XYFCaL4YrnILQw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n2wE6EF0YTP/DSpmC8gqswD7PGylnjwqu7qDlXDNh3AscQ3JYnM8nyeZ7remSygBG EWiZog8EAfN7dRDA6WYiSSwYnrMqQoJ70CSPYZ0t21pTD1LqnMJ75dVwOvmR3oZmAR LtyvX7Ol0LnyFZIOjqPWdHexwA2rIO8K16NOiUUI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hugh Dickins , Zeal Robot , wangyong , Mike Kravetz , "Matthew Wilcox (Oracle)" , CGEL ZTE , "Kirill A. Shutemov" , Song Liu , Yang Yang , Andrew Morton , Linus Torvalds Subject: [PATCH 5.16 116/186] memfd: fix F_SEAL_WRITE after shmem huge page allocated Date: Mon, 7 Mar 2022 10:19:14 +0100 Message-Id: <20220307091657.321646178@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220307091654.092878898@linuxfoundation.org> References: <20220307091654.092878898@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Hugh Dickins commit f2b277c4d1c63a85127e8aa2588e9cc3bd21cb99 upstream. Wangyong reports: after enabling tmpfs filesystem to support transparent hugepage with the following command: echo always > /sys/kernel/mm/transparent_hugepage/shmem_enabled the docker program tries to add F_SEAL_WRITE through the following command, but it fails unexpectedly with errno EBUSY: fcntl(5, F_ADD_SEALS, F_SEAL_WRITE) = -1. That is because memfd_tag_pins() and memfd_wait_for_pins() were never updated for shmem huge pages: checking page_mapcount() against page_count() is hopeless on THP subpages - they need to check total_mapcount() against page_count() on THP heads only. Make memfd_tag_pins() (compared > 1) as strict as memfd_wait_for_pins() (compared != 1): either can be justified, but given the non-atomic total_mapcount() calculation, it is better now to be strict. Bear in mind that total_mapcount() itself scans all of the THP subpages, when choosing to take an XA_CHECK_SCHED latency break. Also fix the unlikely xa_is_value() case in memfd_wait_for_pins(): if a page has been swapped out since memfd_tag_pins(), then its refcount must have fallen, and so it can safely be untagged. Link: https://lkml.kernel.org/r/a4f79248-df75-2c8c-3df-ba3317ccb5da@google.com Signed-off-by: Hugh Dickins Reported-by: Zeal Robot Reported-by: wangyong Cc: Mike Kravetz Cc: Matthew Wilcox (Oracle) Cc: CGEL ZTE Cc: Kirill A. Shutemov Cc: Song Liu Cc: Yang Yang Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- mm/memfd.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) --- a/mm/memfd.c +++ b/mm/memfd.c @@ -31,20 +31,28 @@ static void memfd_tag_pins(struct xa_state *xas) { struct page *page; - unsigned int tagged = 0; + int latency = 0; + int cache_count; lru_add_drain(); xas_lock_irq(xas); xas_for_each(xas, page, ULONG_MAX) { - if (xa_is_value(page)) - continue; - page = find_subpage(page, xas->xa_index); - if (page_count(page) - page_mapcount(page) > 1) + cache_count = 1; + if (!xa_is_value(page) && + PageTransHuge(page) && !PageHuge(page)) + cache_count = HPAGE_PMD_NR; + + if (!xa_is_value(page) && + page_count(page) - total_mapcount(page) != cache_count) xas_set_mark(xas, MEMFD_TAG_PINNED); + if (cache_count != 1) + xas_set(xas, page->index + cache_count); - if (++tagged % XA_CHECK_SCHED) + latency += cache_count; + if (latency < XA_CHECK_SCHED) continue; + latency = 0; xas_pause(xas); xas_unlock_irq(xas); @@ -73,7 +81,8 @@ static int memfd_wait_for_pins(struct ad error = 0; for (scan = 0; scan <= LAST_SCAN; scan++) { - unsigned int tagged = 0; + int latency = 0; + int cache_count; if (!xas_marked(&xas, MEMFD_TAG_PINNED)) break; @@ -87,10 +96,14 @@ static int memfd_wait_for_pins(struct ad xas_lock_irq(&xas); xas_for_each_marked(&xas, page, ULONG_MAX, MEMFD_TAG_PINNED) { bool clear = true; - if (xa_is_value(page)) - continue; - page = find_subpage(page, xas.xa_index); - if (page_count(page) - page_mapcount(page) != 1) { + + cache_count = 1; + if (!xa_is_value(page) && + PageTransHuge(page) && !PageHuge(page)) + cache_count = HPAGE_PMD_NR; + + if (!xa_is_value(page) && cache_count != + page_count(page) - total_mapcount(page)) { /* * On the last scan, we clean up all those tags * we inserted; but make a note that we still @@ -103,8 +116,11 @@ static int memfd_wait_for_pins(struct ad } if (clear) xas_clear_mark(&xas, MEMFD_TAG_PINNED); - if (++tagged % XA_CHECK_SCHED) + + latency += cache_count; + if (latency < XA_CHECK_SCHED) continue; + latency = 0; xas_pause(&xas); xas_unlock_irq(&xas);