From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29549C4707F for ; Fri, 28 May 2021 00:47:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 022DC610A2 for ; Fri, 28 May 2021 00:46:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234573AbhE1Asc (ORCPT ); Thu, 27 May 2021 20:48:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46756 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229864AbhE1Asb (ORCPT ); Thu, 27 May 2021 20:48:31 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB035C061574 for ; Thu, 27 May 2021 17:46:57 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id m205-20020a25d4d60000b029052a8de1fe41so2351612ybf.23 for ; Thu, 27 May 2021 17:46:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:cc; bh=PlH95++B36nHBbK4Jduk7vzZIY/Sp5eibx3QUHpkfY4=; b=d8JjgOYRm5B+az3o5xuyhJh4s4yOm3NSMPpy9CvUAUdDygC5AmVSotAECzCOWOmOCK MtEFJvT/fk65zwVtYPJ1TEzGWEeN9Ca6yQDjrucYfC5pfTScNpzBQm9l187O49k7+yo8 ncN6n70im6MOOYNAsIho6nIgWGXR0TLfKrJGaggtrh5V7bEZuHwcLrYT207BjNul4F51 VXa+rKxgOFpC4IlNQDcb5aNKTXzQUQpVaEbDaKWn6f2OGeYOMAmdDgqKqetmyUKN3UOd Y+Ky2OCUKLTsa6/W9PbdMpIq6ERJtuNnbcztazqZkEYzAa4/DoW2pq3FSK62fzEusbFu h8uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:cc; bh=PlH95++B36nHBbK4Jduk7vzZIY/Sp5eibx3QUHpkfY4=; b=QRZUSN1czLwLZ8RNbbhbHVHvCFx1EAbNXjNYSWf+YerR4XeGOncKsMAkWnC1MZ7F1H qo3q7pQewGWP4q/oT4QMY9H8vSD6VotbdDLywkir6avzrhVBzNruPApBq5pU6H7QLMKK 1lDx/z4NpkEI38W+fvOREzn5t+AGx9U5EX/V3XS4WvTzbaoqoOLOyz5GbHOuVPhaQnKn 4lQdBAf5SngsA4kh1Z/+kqkm3cesjel0FqpnguCZgCpwyXMLbkgd0W3E7gDun0hqbmtg To5EuuhkvWCtTqa0d1Olrvz+0F6hgJOVk32lFHVVatpMmoGH20TXcuJHUqpUEq3KOZki XXQw== X-Gm-Message-State: AOAM532TxPc9vIrY5yxJN/+Znaj68+MNE/RYWaYQIhd5jKzKGFDmFHFA zE3fVwm8JEyE+kmqCL3Q47r7oKcF6RNi8G4HAQ== X-Google-Smtp-Source: ABdhPJypQIi7OLeQOMkKC8MqPd+cdGydq1CCA7pc+vFNILHmJek6bUDtkR6qrp28z/EouWBP2MGghJ0c3azUecOTpw== X-Received: from almasrymina.svl.corp.google.com ([2620:15c:2cd:202:b35:38bd:7e0f:3b1d]) (user=almasrymina job=sendgmr) by 2002:a25:7a41:: with SMTP id v62mr8586302ybc.225.1622162816966; Thu, 27 May 2021 17:46:56 -0700 (PDT) Date: Thu, 27 May 2021 17:46:49 -0700 Message-Id: <20210528004649.85298-1-almasrymina@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.32.0.rc0.204.g9fa02ecfa5-goog Subject: [PATCH v4] mm, hugetlb: Fix simple resv_huge_pages underflow on UFFDIO_COPY From: Mina Almasry Cc: Mina Almasry , Axel Rasmussen , Peter Xu , linux-mm@kvack.org, Mike Kravetz , Andrew Morton , linux-kernel@vger.kernel.org, stable@vger.kernel.org Content-Type: text/plain; charset="UTF-8" To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The userfaultfd hugetlb tests detect a resv_huge_pages underflow. This happens when hugetlb_mcopy_atomic_pte() is called with !is_continue on an index for which we already have a page in the cache. When this happens, we allocate a second page, double consuming the reservation, and then fail to insert the page into the cache and return -EEXIST. To fix this, we first if there exists a page in the cache which already consumed the reservation, and return -EEXIST immediately if so. There is still a rare condition where we fail to copy the page contents AND race with a call for hugetlb_no_page() for this index and again we will underflow resv_huge_pages. That is fixed in a more complicated patch not targeted for -stable. Test: Hacked the code locally such that resv_huge_pages underflows produce a warning, then: ./tools/testing/selftests/vm/userfaultfd hugetlb_shared 10 2 /tmp/kokonut_test/huge/userfaultfd_test && echo test success ./tools/testing/selftests/vm/userfaultfd hugetlb 10 2 /tmp/kokonut_test/huge/userfaultfd_test && echo test success Both tests succeed and produce no warnings. After the test runs number of free/resv hugepages is correct. Signed-off-by: Mina Almasry Cc: Axel Rasmussen Cc: Peter Xu Cc: linux-mm@kvack.org Cc: Mike Kravetz Cc: Andrew Morton Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org --- mm/hugetlb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ead5d12e0604..76e2a6efc165 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4925,10 +4925,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, if (!page) goto out; } else if (!*pagep) { - ret = -ENOMEM; + /* If a page already exists, then it's UFFDIO_COPY for + * a non-missing case. Return -EEXIST. + */ + if (vm_shared && + hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) { + ret = -EEXIST; + goto out; + } + page = alloc_huge_page(dst_vma, dst_addr, 0); - if (IS_ERR(page)) + if (IS_ERR(page)) { + ret = -ENOMEM; goto out; + } ret = copy_huge_page_from_user(page, (const void __user *) src_addr, -- 2.32.0.rc0.204.g9fa02ecfa5-goog