From patchwork Sat Jan 14 13:16:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 13101945 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 265E7C46467 for ; Sat, 14 Jan 2023 13:16:55 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5DFD88E0002; Sat, 14 Jan 2023 08:16:55 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5690F8E0001; Sat, 14 Jan 2023 08:16:55 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3E24B8E0002; Sat, 14 Jan 2023 08:16:55 -0500 (EST) 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 2A8038E0001 for ; Sat, 14 Jan 2023 08:16:55 -0500 (EST) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id C96EB1A0795 for ; Sat, 14 Jan 2023 13:16:54 +0000 (UTC) X-FDA: 80353454748.08.21A2D40 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) by imf30.hostedemail.com (Postfix) with ESMTP id 2A8A880004 for ; Sat, 14 Jan 2023 13:16:52 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=OaPLKp4I; spf=pass (imf30.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.53 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1673702213; 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:references:dkim-signature; bh=xbToiHr9DoIKWP2GgDy4WohTZnzZoHKjsA3gXbib5fo=; b=qBsaCwad9J7OaiInsRyxJA81H2vx3tBvuA1mNSzfzwxM1b+bSuHp5tXaNjicvi7SSs15Rq E6XYNcHeZcCCwZnx/1sUx0fr3jMpzDieSKZD0x3a8Sh0E2tyBPLc2Ej/FF3EA3HvEL37ru dskaAmgWUf6nNHQpE7utAIicGkGId3o= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=OaPLKp4I; spf=pass (imf30.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.53 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1673702213; a=rsa-sha256; cv=none; b=sTvBWac7AqH2yUbJFlfou0UvT+m9bHH8KXv5lN31HekpuUsgymCh8kkbky8q6vQY8kgOWk WcGHRrL4RyxFOBwPYjGq65lMhtQGxCbQgHHiInxsj5YwS80hHpV54D+49tR/cLq21IVDx2 OqGZArvOgyEFvf0vEED10ukqSKEZP14= Received: by mail-wm1-f53.google.com with SMTP id h12-20020a05600c314c00b003da50afcb33so519752wmo.4 for ; Sat, 14 Jan 2023 05:16:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=xbToiHr9DoIKWP2GgDy4WohTZnzZoHKjsA3gXbib5fo=; b=OaPLKp4Ie/8AfLYBX0BtBIC9bU6e2Z2YGUE8/QNdUYrCCLooz5BnBB9SNCQBmHSpH2 XXwGWmEAgk2WcMj8OC+2dyjSJMkMmPTNEqFUhcD0qD0D+yW/JTDYv446AIx/1UxpDjQ0 ggW+LpPcVSVJbNgLMGSd+J5WTM1mFJ/PIQHVx09l24UX7Q5Xb/vDurYCqE2UuW9BBEdF /Rg5xG06BuxuSsvJj7qTSCY+1nsTTPfFsSXTpAS1Dt6upkgipZJ7B2j4oxDEmqcoYPDH kojQ7px7Ysv6twZBuVXPG6lX/RuGn/5kajPuk4fQKNL4zyaakz0/dAPsOygCqVXw1DzA lP8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xbToiHr9DoIKWP2GgDy4WohTZnzZoHKjsA3gXbib5fo=; b=0XkCuFpa6DC11gKYySTSnG6fMxnpxq5xbu7JnzKU4KFy2tQNYyEBcTCWbbCP/ch9sD mzzJu6n9bIMNqFr1SZOTIInfZwDAa/2tVLxVNv/IxE2uTPLdgchukEvdlPT95l6YuyOW tdAHu/ULm83S7hgYVSdmi/4oNLiOiaw4YW/MYZ7UlYJno478HEaY/R5cixOI6Ey/ik7l qP6eNKvV2IfN14JMpHd5uiItJH0IzGqhU26cvwcIcBYQTJdgOubCa9l/9a6k4cpHMmHn bT6T94/g8Yh1qOCWgM3AeG6cn2hniwbPiqNhossxVjd2cK96RgfZttf6kbQ8V/ycU0UO Rz8Q== X-Gm-Message-State: AFqh2kp1evqTaQefUVuQk9Orwz/wc0wgxwVvs0hK6A+wgYHFW7+TIp2r auSaKvVL6i1ATH92GwOFZpQdo3OvvuY= X-Google-Smtp-Source: AMrXdXsGWyK6Z963mFvsy7yeSVwO7/fRyW5g7cbsff5sksXWR6BIiIgk3lJ1VtDnnfMaXE6/EsHD9Q== X-Received: by 2002:a05:600c:1e1e:b0:3d2:3b4d:d619 with SMTP id ay30-20020a05600c1e1e00b003d23b4dd619mr61333449wmb.15.1673702211137; Sat, 14 Jan 2023 05:16:51 -0800 (PST) Received: from lucifer.home (host86-164-169-89.range86-164.btcentralplus.com. [86.164.169.89]) by smtp.googlemail.com with ESMTPSA id fc14-20020a05600c524e00b003a3442f1229sm37188672wmb.29.2023.01.14.05.16.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Jan 2023 05:16:50 -0800 (PST) From: Lorenzo Stoakes To: linux-mm@kvack.org, Andrew Morton , Shuah Khan , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Vlastimil Babka , Jakub Matena , Matthew Wilcox , Mel Gorman , Michal Hocko , David Hildenbrand , Lorenzo Stoakes Subject: [PATCH v5] selftest/vm: add mremap expand merge offset test Date: Sat, 14 Jan 2023 13:16:46 +0000 Message-Id: <8ff3ba3cadc0b6c1b2688ae5c851bf73aa062d57.1673701836.git.lstoakes@gmail.com> X-Mailer: git-send-email 2.39.0 MIME-Version: 1.0 X-Rspamd-Queue-Id: 2A8A880004 X-Stat-Signature: r4d9dg4ok8a7qkrek7zw315z7byopy5q X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1673702212-79748 X-HE-Meta: U2FsdGVkX1/Z83w7GzlcM8ZUx5+AiaAPZXZGTm3ITO0+YOuhLJvOZfZXOcpx8qaFhth//J4JjnElFGixSZRUbmO10Plfvk625sl5MCN8z97bRM/GmSacA2goU16+YgL5gfq13oPRu2l29AuLUJsyekdqp8jmN0uqQGJcWPm05lTaYrfoEtkwTh1v5zkviHwYRXK9jnQ0BuasSzDL1dJvOU4uLStOA0Mzqow20LFglCS8L+uy3n+HrxtIe3jPZ23fjshtdXnr27KBZb8oeuLIgxO8T6gxADKHaoBb1g2v1uD+p3n7omfnr1o5s2V3jA0j4G/cqgVNItK7Bx7Dl9g/DbWpHt1oMhaH5ValjS0uZaJ5kRap0++0xIG0pslY4ZJ/eQhHdy759ZuLyz7S4nBHYzex2HbR1my/GWEVQvpOqAJAJiff8lezWp8/e9s4xj9AEBWXURRksoTxCuUY2nEySCNJO+1kBrAe01Ffyup/AZHKHngOv+Mk1JihqJNuat8zdgbzjFWXX4WR9Ui81qZVyEHLOdj+oKI5jwtBaEkU89VfOFouZaq/Kb+75aDmXGF7FvSTCdz9QyUIcLtSj6J287lp+xrRmF5QVbhsmNNmGI8tB+PH0RoTR6oMgSTICaGJvkkQFr8fXOmrtV6fymcGT9Zh5NhhjGXWdflhJ6uqA0cE7DrxwKVpzJ7gaC0W65YY3TtWuXDCm5VWgQZ2xUorDYWRTJbn/+pksJMYRklsYs0ki/ktHV0DHlKg/UGT4/7ki4XUcht51KgzAMhV2Y0xLb8Pt+DYUj9wIGdcMhvk9XHsO+ZQdOhK0xQ2L+84RksvWIMJaeg5YKN4EJoe3G+IbRDwUgZpZ76fRVbgXjQt2C5llAFpIPEQ6j51wXsnYSu7w1b1ESy5TSFl0uH6as83gHMyMzkclN0L98V6yJdFO+j3oHnJ3U8gC9nw7MT1Ma/qaVwCDP2hpalShQtnbmP 1ag3NMYQ MHzXvSJuuQ7FVNmXeUFFlzje2D1lQLBL2VTnfvJ7QZnrm5ExeamhcJ2nsWmliQIlB/xsXJtpoSXbJn11QvCCjk6VN18ZRM2gJlbmeKDse+4IzDz/dEJbXsr8ZpbDE99Bd5E0h 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: Add a test to assert that we can mremap() and expand a mapping starting from an offset within an existing mapping. We unmap the last page in a 3 page mapping to ensure that the remap should always succeed, before remapping from the 2nd page. This is additionally a regression test for the issue solved in "mm, mremap: fix mremap() expanding vma with addr inside vma" and confirmed to fail prior to the change and pass after it. Finally, this patch updates the existing mremap expand merge test to check error conditions and reduce code duplication between the two tests. Signed-off-by: Lorenzo Stoakes Acked-by: David Hildenbrand --- v5: Increment num_expand_tests so test doesn't complain about unexpected tests being run. tools/testing/selftests/vm/mremap_test.c | 119 ++++++++++++++++++----- 1 file changed, 96 insertions(+), 23 deletions(-) diff --git a/tools/testing/selftests/vm/mremap_test.c b/tools/testing/selftests/vm/mremap_test.c index 9496346973d4..5c3773de9f0f 100644 --- a/tools/testing/selftests/vm/mremap_test.c +++ b/tools/testing/selftests/vm/mremap_test.c @@ -119,47 +119,109 @@ static unsigned long long get_mmap_min_addr(void) } /* - * This test validates that merge is called when expanding a mapping. - * Mapping containing three pages is created, middle page is unmapped - * and then the mapping containing the first page is expanded so that - * it fills the created hole. The two parts should merge creating - * single mapping with three pages. + * Using /proc/self/maps, assert that the specified address range is contained + * within a single mapping. */ -static void mremap_expand_merge(unsigned long page_size) +static bool is_range_mapped(FILE *maps_fp, void *start, void *end) { - char *test_name = "mremap expand merge"; - FILE *fp; char *line = NULL; size_t len = 0; bool success = false; - char *start = mmap(NULL, 3 * page_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - munmap(start + page_size, page_size); - mremap(start, page_size, 2 * page_size, 0); - fp = fopen("/proc/self/maps", "r"); - if (fp == NULL) { - ksft_test_result_fail("%s\n", test_name); - return; - } + rewind(maps_fp); - while (getline(&line, &len, fp) != -1) { + while (getline(&line, &len, maps_fp) != -1) { char *first = strtok(line, "- "); void *first_val = (void *)strtol(first, NULL, 16); char *second = strtok(NULL, "- "); void *second_val = (void *) strtol(second, NULL, 16); - if (first_val == start && second_val == start + 3 * page_size) { + if (first_val <= start && second_val >= end) { success = true; break; } } + + return success; +} + +/* + * This test validates that merge is called when expanding a mapping. + * Mapping containing three pages is created, middle page is unmapped + * and then the mapping containing the first page is expanded so that + * it fills the created hole. The two parts should merge creating + * single mapping with three pages. + */ +static void mremap_expand_merge(FILE *maps_fp, unsigned long page_size) +{ + char *test_name = "mremap expand merge"; + bool success = false; + char *remap, *start; + + start = mmap(NULL, 3 * page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (start == MAP_FAILED) { + ksft_print_msg("mmap failed: %s\n", strerror(errno)); + goto out; + } + + munmap(start + page_size, page_size); + remap = mremap(start, page_size, 2 * page_size, 0); + if (remap == MAP_FAILED) { + ksft_print_msg("mremap failed: %s\n", strerror(errno)); + munmap(start, page_size); + munmap(start + 2 * page_size, page_size); + goto out; + } + + success = is_range_mapped(maps_fp, start, start + 3 * page_size); + munmap(start, 3 * page_size); + +out: + if (success) + ksft_test_result_pass("%s\n", test_name); + else + ksft_test_result_fail("%s\n", test_name); +} + +/* + * Similar to mremap_expand_merge() except instead of removing the middle page, + * we remove the last then attempt to remap offset from the second page. This + * should result in the mapping being restored to its former state. + */ +static void mremap_expand_merge_offset(FILE *maps_fp, unsigned long page_size) +{ + + char *test_name = "mremap expand merge offset"; + bool success = false; + char *remap, *start; + + start = mmap(NULL, 3 * page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (start == MAP_FAILED) { + ksft_print_msg("mmap failed: %s\n", strerror(errno)); + goto out; + } + + /* Unmap final page to ensure we have space to expand. */ + munmap(start + 2 * page_size, page_size); + remap = mremap(start + page_size, page_size, 2 * page_size, 0); + if (remap == MAP_FAILED) { + ksft_print_msg("mremap failed: %s\n", strerror(errno)); + munmap(start, 2 * page_size); + goto out; + } + + success = is_range_mapped(maps_fp, start, start + 3 * page_size); + munmap(start, 3 * page_size); + +out: if (success) ksft_test_result_pass("%s\n", test_name); else ksft_test_result_fail("%s\n", test_name); - fclose(fp); } /* @@ -380,11 +442,12 @@ int main(int argc, char **argv) int i, run_perf_tests; unsigned int threshold_mb = VALIDATION_DEFAULT_THRESHOLD; unsigned int pattern_seed; - int num_expand_tests = 1; + int num_expand_tests = 2; struct test test_cases[MAX_TEST]; struct test perf_test_cases[MAX_PERF_TEST]; int page_size; time_t t; + FILE *maps_fp; pattern_seed = (unsigned int) time(&t); @@ -458,7 +521,17 @@ int main(int argc, char **argv) run_mremap_test_case(test_cases[i], &failures, threshold_mb, pattern_seed); - mremap_expand_merge(page_size); + maps_fp = fopen("/proc/self/maps", "r"); + + if (maps_fp == NULL) { + ksft_print_msg("Failed to read /proc/self/maps: %s\n", strerror(errno)); + exit(KSFT_FAIL); + } + + mremap_expand_merge(maps_fp, page_size); + mremap_expand_merge_offset(maps_fp, page_size); + + fclose(maps_fp); if (run_perf_tests) { ksft_print_msg("\n%s\n",