From patchwork Sun Sep 3 15:13:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Fernandes X-Patchwork-Id: 13373275 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 83414C83F2D for ; Sun, 3 Sep 2023 15:13:53 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E5260280015; Sun, 3 Sep 2023 11:13:45 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DEB12280016; Sun, 3 Sep 2023 11:13:45 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BB6DE280015; Sun, 3 Sep 2023 11:13:45 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id A7BC3280012 for ; Sun, 3 Sep 2023 11:13:45 -0400 (EDT) Received: from smtpin18.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 8378BA04A2 for ; Sun, 3 Sep 2023 15:13:45 +0000 (UTC) X-FDA: 81195630810.18.329DF41 Received: from mail-io1-f50.google.com (mail-io1-f50.google.com [209.85.166.50]) by imf08.hostedemail.com (Postfix) with ESMTP id BB918160004 for ; Sun, 3 Sep 2023 15:13:43 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=joelfernandes.org header.s=google header.b=A231ZIJX; spf=pass (imf08.hostedemail.com: domain of joel@joelfernandes.org designates 209.85.166.50 as permitted sender) smtp.mailfrom=joel@joelfernandes.org; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1693754023; 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=f+nqtAseasZFOdOpIwYvU1wfrPMXCZ3Zt4BE+IzJOeI=; b=3wYasARv+QExGmxPEubc/Xf8J9N/3Fs2kts8BiQDdzdNCKI8Az131trVLm+4ulV7cMAGtA 9nplm7nd/7/hHIhPJUWyZMEB4dqTGOwKZlVY7/wchfyp5NttgJuGMnGM9FJdlSrgWEFDcA BvUvwj5MCv0dVYQomPALHEVkGGTzI1Q= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1693754023; a=rsa-sha256; cv=none; b=OckiAko53t4UhfokWEevSMYxTpz5IDCfMzUJkWMl5fgcQlX+fJvQKk0PU75m0rq3/QKEob sY+NyMJ1x5OSjJizue5nRgv420++dgiAwXRLhwOor2Wbj87Zd7Nd/dnxFhLst0WWGYJADk 0Y5WNQfUnq01jhFD9COwkh5TWuesFZE= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=joelfernandes.org header.s=google header.b=A231ZIJX; spf=pass (imf08.hostedemail.com: domain of joel@joelfernandes.org designates 209.85.166.50 as permitted sender) smtp.mailfrom=joel@joelfernandes.org; dmarc=none Received: by mail-io1-f50.google.com with SMTP id ca18e2360f4ac-7927f241772so32597739f.1 for ; Sun, 03 Sep 2023 08:13:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; t=1693754023; x=1694358823; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f+nqtAseasZFOdOpIwYvU1wfrPMXCZ3Zt4BE+IzJOeI=; b=A231ZIJXm8TsYIGGaLH7Ri9HM+010274Kdso1CqH2D/evgwYMDCso1CsZm8VSksKfl xrg+q9H1+3spVwBfMpJ1p2Yf0mEVqCchpNgLfALHmXFKFTedceyRNIfc/kMA1V1mXUhQ VBV2F7q3hB+hREJtb1og+pePxICPwVbhf2HIc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693754023; x=1694358823; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f+nqtAseasZFOdOpIwYvU1wfrPMXCZ3Zt4BE+IzJOeI=; b=MhUaHQ2t46C5Cmk1EQvZZsZWrqH9PN/RtrE4L4BomSiN++as9L8s4vArQD5TU03RRS GmR7iszBqSex7hKTKgKsDmU19EyiqeySMrRokuBIEgPXlaC6JCVARY0En/rQBjj2pwil XYOkzxPhTJ50ck4iskyNOQQ314vSiWCZ5FdG5Iglxy56l+HDOJjm1CQvAhB+szsCD3o1 Z3UoA4vynRi7nxM9bK4NALp7r5rM+dTdaOG55VnorTzq8tgbQUApStaS0mW+P+coc1v3 IPAj97/GXdxaZvyRv5O3n/CxrpzBaZoNp0llw6ptD9pGNVFP5rw3u0LzT974eZM8k+AY kdvA== X-Gm-Message-State: AOJu0Yzg5nxHAD57dwHua37Pc6CdcW3U0EDBCw0GCS69AMkr3Ga1iNeh 48q9K2IX8SIDpJ99fr2TiC4Scg== X-Google-Smtp-Source: AGHT+IG0ubtl3WQP2iLAfgo/8U3Gp+Qcadj9ljmVKqqAyOzu0TCZj645xHn8dTLLCtLKiiIphITokw== X-Received: by 2002:a6b:ec16:0:b0:792:82f8:6f90 with SMTP id c22-20020a6bec16000000b0079282f86f90mr8856879ioh.16.1693754022914; Sun, 03 Sep 2023 08:13:42 -0700 (PDT) Received: from joelboxx5.corp.google.com (156.190.123.34.bc.googleusercontent.com. [34.123.190.156]) by smtp.gmail.com with ESMTPSA id f5-20020a6b5105000000b007835a305f61sm2605897iob.36.2023.09.03.08.13.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Sep 2023 08:13:42 -0700 (PDT) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: Joel Fernandes , Lorenzo Stoakes , linux-kselftest@vger.kernel.org, linux-mm@kvack.org, Shuah Khan , Vlastimil Babka , Michal Hocko , Linus Torvalds , Kirill A Shutemov , "Liam R. Howlett" , "Paul E. McKenney" , Suren Baghdasaryan , Kalesh Singh , Lokesh Gidra Subject: [PATCH v6 7/7] selftests: mm: Add a test for moving from an offset from start of mapping Date: Sun, 3 Sep 2023 15:13:28 +0000 Message-ID: <20230903151328.2981432-8-joel@joelfernandes.org> X-Mailer: git-send-email 2.42.0.283.g2d96d420d3-goog In-Reply-To: <20230903151328.2981432-1-joel@joelfernandes.org> References: <20230903151328.2981432-1-joel@joelfernandes.org> MIME-Version: 1.0 X-Stat-Signature: yc6ozg9a5tdb9atzr6bo1auy6tzittac X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: BB918160004 X-Rspam-User: X-HE-Tag: 1693754023-618438 X-HE-Meta: U2FsdGVkX18RfecSG9iklJqk8MqvWOCWVns8o5jJryhxWg43jEsc51QxfMEJKEuFTz9k34NKWgWCrJE7KE7yEj9KRMQzvSTqglypmO6kpYlWRNX/1DnLDJDdfH9iUIYCH7UMa6ADipKVZZyTQexlAzqHku1kC+AA/2Nk4ZLvk3tnCZ/F+6Tq7JUux+ipI1KCDmeE5im2EN4x3fRnpyKdswKauuWSVL13sq9Qxinbn3Wc3ljH7FuVCCSW21lEo1gYc9LiLd4lzjCWWxygXcHiSWdEMN68/Jy3dZwtcf60MrTFrJk5y7oZi94EOAIpm1sIjFmcNFDWjwwez7zTWN0DF+oZPzl98Mx3eT+KZywMCYzTim4an9ijWqns8EKfrZOTkXQaTSGW7XpiQDEKKNkjGYVj4LejwzwjP35g1J9CCkVZqau7vR2yKXRTw2n50fAZIH2DghgFPb17WZX7RZpyT0RDzGzX/OwEeYZpjjyorXAPtw3u+y6o/57FluXLbSv/3HsCvKkLLd5qbVUycN4qWn4mfLHyLj/nFIOA6tt+P7cxw418S374fW1mQ/iFctmUbhDoxOfBrx+JQBFXftu2xLuasFKlJ8LszomHSQXaBsgjSe71qxaW2YO3GFwcHGxK9pwQ2fac/umNPF/TCq/LbnDZKDoH2DvoPSoB67mJPzeKUjoFsXlx3fmAcnAvlek88eiM4BG0ssMWxYCnFKtSjUZn6SwXIZbtm+T7SDXFe/jVQzqoSQQm54Lsa4zRS2V10bIn9n6yGIYS4wY5nWIEvSuCztLc2W1fnyh3yexqsdlAYDxRn0qFWBN3gwJwZwQEXfuieXHb2dT5qP2m+n2Nej5OLwHuG9rjYw8k1Kft2Izt624iV30aSPONtXJS9QMPPwzMaGuiZertZawWK45sSK8sMfmU+PdYuJZkjb+jQifxxdL9g2yEbU6VmkoKrWzr4oeuT5opQ3xsQ0z/v5w 5r6hICfz EOVLdWdqHgPrnnNB6yWk4+YP5C883oQcLbjA4/YqvgF6aoGUlbplkaY56T7+jep0s55aJhjHa7fKG+7SUnnv09t7/lZ3nXQU9It5JnBJlXSUf/y1wFDMhPTqDqZI2NvzLfLdeIUk+vE0T/KQ92fS3I/xa8ALJAbbQgVMBlSwgpxDIskq4NFVQ9tn5r3UD2ZE6LAAr719xktA0F15iX/ePNFHvlA3qkl6WqfzL0G+UH6uSV3n2xSeHT2ZmShwCKc0FW5aCs+m93tMoEUwiRtBDM3H7KgCN+icjFDaBiAdmYODKCIYVFVYr8H1DcL6dgJ0+7RCwKtGnXKUZIDSNLSNWID9j+ZEiClFe7EIGVbccEOrBZ/za+7GHc6W1Be33xinMEeUZQiRr0Op1oeCuT76CeIjouxobDExbGAqMFTxtz56pECF/cpqaHc+F/bgU0PV5asP+MiYsLp4U5wLbLspeDm7VPUGnv/ewWZ0KpBUFGPmcKI4j9A/ZSygmrA== 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: From: Joel Fernandes It is possible that the aligned address falls on no existing mapping, however that does not mean that we can just align it down to that. This test verifies that the "vma->vm_start != addr_to_align" check in can_align_down() prevents disastrous results if aligning down when source and dest are mutually aligned within a PMD but the source/dest addresses requested are not at the beginning of the respective mapping containing these addresses. Reviewed-by: Lorenzo Stoakes Signed-off-by: Joel Fernandes (Google) --- tools/testing/selftests/mm/mremap_test.c | 189 ++++++++++++++++------- 1 file changed, 134 insertions(+), 55 deletions(-) diff --git a/tools/testing/selftests/mm/mremap_test.c b/tools/testing/selftests/mm/mremap_test.c index 12a095457f4c..1f836e670a37 100644 --- a/tools/testing/selftests/mm/mremap_test.c +++ b/tools/testing/selftests/mm/mremap_test.c @@ -24,6 +24,7 @@ #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #define SIZE_MB(m) ((size_t)m * (1024 * 1024)) +#define SIZE_KB(k) ((size_t)k * 1024) struct config { unsigned long long src_alignment; @@ -148,6 +149,60 @@ static bool is_range_mapped(FILE *maps_fp, void *start, void *end) return success; } +/* + * Returns the start address of the mapping on success, else returns + * NULL on failure. + */ +static void *get_source_mapping(struct config c) +{ + unsigned long long addr = 0ULL; + void *src_addr = NULL; + unsigned long long mmap_min_addr; + + mmap_min_addr = get_mmap_min_addr(); + /* + * For some tests, we need to not have any mappings below the + * source mapping. Add some headroom to mmap_min_addr for this. + */ + mmap_min_addr += 10 * _4MB; + +retry: + addr += c.src_alignment; + if (addr < mmap_min_addr) + goto retry; + + src_addr = mmap((void *) addr, c.region_size, PROT_READ | PROT_WRITE, + MAP_FIXED_NOREPLACE | MAP_ANONYMOUS | MAP_SHARED, + -1, 0); + if (src_addr == MAP_FAILED) { + if (errno == EPERM || errno == EEXIST) + goto retry; + goto error; + } + /* + * Check that the address is aligned to the specified alignment. + * Addresses which have alignments that are multiples of that + * specified are not considered valid. For instance, 1GB address is + * 2MB-aligned, however it will not be considered valid for a + * requested alignment of 2MB. This is done to reduce coincidental + * alignment in the tests. + */ + if (((unsigned long long) src_addr & (c.src_alignment - 1)) || + !((unsigned long long) src_addr & c.src_alignment)) { + munmap(src_addr, c.region_size); + goto retry; + } + + if (!src_addr) + goto error; + + return src_addr; +error: + ksft_print_msg("Failed to map source region: %s\n", + strerror(errno)); + return NULL; +} + /* * This test validates that merge is called when expanding a mapping. * Mapping containing three pages is created, middle page is unmapped @@ -300,60 +355,6 @@ static void mremap_move_within_range(char pattern_seed) ksft_test_result_fail("%s\n", test_name); } -/* - * Returns the start address of the mapping on success, else returns - * NULL on failure. - */ -static void *get_source_mapping(struct config c) -{ - unsigned long long addr = 0ULL; - void *src_addr = NULL; - unsigned long long mmap_min_addr; - - mmap_min_addr = get_mmap_min_addr(); - /* - * For some tests, we need to not have any mappings below the - * source mapping. Add some headroom to mmap_min_addr for this. - */ - mmap_min_addr += 10 * _4MB; - -retry: - addr += c.src_alignment; - if (addr < mmap_min_addr) - goto retry; - - src_addr = mmap((void *) addr, c.region_size, PROT_READ | PROT_WRITE, - MAP_FIXED_NOREPLACE | MAP_ANONYMOUS | MAP_SHARED, - -1, 0); - if (src_addr == MAP_FAILED) { - if (errno == EPERM || errno == EEXIST) - goto retry; - goto error; - } - /* - * Check that the address is aligned to the specified alignment. - * Addresses which have alignments that are multiples of that - * specified are not considered valid. For instance, 1GB address is - * 2MB-aligned, however it will not be considered valid for a - * requested alignment of 2MB. This is done to reduce coincidental - * alignment in the tests. - */ - if (((unsigned long long) src_addr & (c.src_alignment - 1)) || - !((unsigned long long) src_addr & c.src_alignment)) { - munmap(src_addr, c.region_size); - goto retry; - } - - if (!src_addr) - goto error; - - return src_addr; -error: - ksft_print_msg("Failed to map source region: %s\n", - strerror(errno)); - return NULL; -} - /* Returns the time taken for the remap on success else returns -1. */ static long long remap_region(struct config c, unsigned int threshold_mb, char pattern_seed) @@ -487,6 +488,83 @@ static long long remap_region(struct config c, unsigned int threshold_mb, return ret; } +/* + * Verify that an mremap aligning down does not destroy + * the beginning of the mapping just because the aligned + * down address landed on a mapping that maybe does not exist. + */ +static void mremap_move_1mb_from_start(char pattern_seed) +{ + char *test_name = "mremap move 1mb from start at 1MB+256KB aligned src"; + void *src = NULL, *dest = NULL; + int i, success = 1; + + /* Config to reuse get_source_mapping() to do an aligned mmap. */ + struct config c = { + .src_alignment = SIZE_MB(1) + SIZE_KB(256), + .region_size = SIZE_MB(6) + }; + + src = get_source_mapping(c); + if (!src) { + success = 0; + goto out; + } + + c.src_alignment = SIZE_MB(1) + SIZE_KB(256); + dest = get_source_mapping(c); + if (!dest) { + success = 0; + goto out; + } + + /* Set byte pattern for source block. */ + srand(pattern_seed); + for (i = 0; i < SIZE_MB(2); i++) { + ((char *)src)[i] = (char) rand(); + } + + /* + * Unmap the beginning of dest so that the aligned address + * falls on no mapping. + */ + munmap(dest, SIZE_MB(1)); + + void *new_ptr = mremap(src + SIZE_MB(1), SIZE_MB(1), SIZE_MB(1), + MREMAP_MAYMOVE | MREMAP_FIXED, dest + SIZE_MB(1)); + if (new_ptr == MAP_FAILED) { + perror("mremap"); + success = 0; + goto out; + } + + /* Verify byte pattern after remapping */ + srand(pattern_seed); + for (i = 0; i < SIZE_MB(1); i++) { + char c = (char) rand(); + + if (((char *)src)[i] != c) { + ksft_print_msg("Data at src at %d got corrupted due to unrelated mremap\n", + i); + ksft_print_msg("Expected: %#x\t Got: %#x\n", c & 0xff, + ((char *) src)[i] & 0xff); + success = 0; + } + } + +out: + if (src && munmap(src, c.region_size) == -1) + perror("munmap src"); + + if (dest && munmap(dest, c.region_size) == -1) + perror("munmap dest"); + + if (success) + ksft_test_result_pass("%s\n", test_name); + else + ksft_test_result_fail("%s\n", test_name); +} + static void run_mremap_test_case(struct test test_case, int *failures, unsigned int threshold_mb, unsigned int pattern_seed) @@ -565,7 +643,7 @@ int main(int argc, char **argv) unsigned int threshold_mb = VALIDATION_DEFAULT_THRESHOLD; unsigned int pattern_seed; int num_expand_tests = 2; - int num_misc_tests = 1; + int num_misc_tests = 2; struct test test_cases[MAX_TEST] = {}; struct test perf_test_cases[MAX_PERF_TEST]; int page_size; @@ -666,6 +744,7 @@ int main(int argc, char **argv) fclose(maps_fp); mremap_move_within_range(pattern_seed); + mremap_move_1mb_from_start(pattern_seed); if (run_perf_tests) { ksft_print_msg("\n%s\n",