From patchwork Fri Feb 3 19:04:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nhat Pham X-Patchwork-Id: 13128277 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 C5221C636D6 for ; Fri, 3 Feb 2023 19:04:22 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7515E6B0075; Fri, 3 Feb 2023 14:04:21 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 6D9486B0078; Fri, 3 Feb 2023 14:04:21 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 578B16B007B; Fri, 3 Feb 2023 14:04:21 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 4607A6B0075 for ; Fri, 3 Feb 2023 14:04:21 -0500 (EST) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id DFB691612CC for ; Fri, 3 Feb 2023 19:04:20 +0000 (UTC) X-FDA: 80426906280.07.1DBD036 Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) by imf30.hostedemail.com (Postfix) with ESMTP id B1D938001B for ; Fri, 3 Feb 2023 19:04:17 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=HwyZleEv; spf=pass (imf30.hostedemail.com: domain of nphamcs@gmail.com designates 209.85.216.46 as permitted sender) smtp.mailfrom=nphamcs@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1675451057; a=rsa-sha256; cv=none; b=RX/HUuPDsViUiZ3dWLbUjLb55Hry/vWxnud6f/bw0Hj9oIkuWh/xYJhu/skWsp+86b4tiO bv9eHWsQWx8+yuYzyFgEJZXkqORrX8FzhyCIoj6/hZlemtYi/jlvhc9Dt7ORs/0QI4uZGB yq4pAt9XEA7o6EocULkWja9Sh1tKEmE= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=HwyZleEv; spf=pass (imf30.hostedemail.com: domain of nphamcs@gmail.com designates 209.85.216.46 as permitted sender) smtp.mailfrom=nphamcs@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=1675451057; 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=xv2Em6KNiGaU6QjEB8S2E3cr0KOpR5Jc9laazewASFk=; b=cCZiLzsv/okFjJLZWiF65OyCvJIiXfdfOrebEj0F1yWgmbZ9rhyhn1XMk8Y9g5La/FVhra hhyyhZJDpTB6Wqw1IJuBLrP/nJARciIlq4TmM6KD4fyd2HP7A7261M0H0hdYSyaXW3P6o0 at4HHFVmYyezSeXcgRBzLCJBsnodqCc= Received: by mail-pj1-f46.google.com with SMTP id o16-20020a17090ad25000b00230759a8c06so2857242pjw.2 for ; Fri, 03 Feb 2023 11:04:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; 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=xv2Em6KNiGaU6QjEB8S2E3cr0KOpR5Jc9laazewASFk=; b=HwyZleEvFQv+a0d7MkRwkz23KIAZdIe5KUwjzU/ZcdmnU0J60Fnt+TRVyVWM5i0ARo YoI/T+fLVqBOoEWmNnIWzqmh6CF9yIsr6Qv8PSt5yRBWO4lfO/BhslI+GgSJB4qNXHKV f/TKHCxjsCnzNmSNhCQzRcr9IkcnE5oyHbmk8JEcAKRddJAkwCI7VGYZxifrW3Tr6WIm HdxF4lRROLKUMyCc4ZIVs1huLN8JdK7uz6H3g9etbfzYwBAySqhuOJM8W2Jo7jGIt/Tn e6QVuhJyazBNXcDK59gVRs6wWbPZKAY0d+kFjmNOsxB35rccz43p1jyVDRH/yElujNvR hrkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=xv2Em6KNiGaU6QjEB8S2E3cr0KOpR5Jc9laazewASFk=; b=FxkX8ltsDGtIYV1JWGKh8LP6ZeGKJNHwmaOy9tCKOx9Y0xnJK8OspjVHi85CBQGFsX 1rsekRQeFo+no4ZqAgI8Rp7IdH2FdafgG+oQ3TsNLsXcF1HEw9NQS0bvPLz1YkT/TBU/ nOBO1jVPR4fXYHmW1bhN751EE+84tpCkfSCfge9R1Pd2+k8pR+hMmY9NDs0Acm7S+zgE jYayuO3dR7AjdxKL2LGE4YD1qc+rdAvFVu1M9YWXSFhocotFDNfxihdYyzHfHqL388jz gb7AACXcUOLaX+pa9TICXXZjvo77zY2Qgl1TukCEvAdw56p6iuHCAhWfCucEkDWitCdk v7uw== X-Gm-Message-State: AO0yUKXttOb1lg4InC82+PMazoO5QsQ5zzdDwKOhwf11LP2LcLrwSSw2 +4s/AQe+aJ/RAhB5qk1fxfI= X-Google-Smtp-Source: AK7set9HotqUUCNuJMOi2vhBQ7GifcOr9y6Pa3VmeJv3LiXHw5XZAslumbxMFgWMRI3JzCCjENiJHg== X-Received: by 2002:a17:90a:e7c6:b0:22c:51b0:6b49 with SMTP id kb6-20020a17090ae7c600b0022c51b06b49mr11259985pjb.37.1675451056516; Fri, 03 Feb 2023 11:04:16 -0800 (PST) Received: from localhost (fwdproxy-prn-002.fbsv.net. [2a03:2880:ff:2::face:b00c]) by smtp.gmail.com with ESMTPSA id v12-20020a17090a0c8c00b0022be7a9e196sm5331387pja.1.2023.02.03.11.04.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Feb 2023 11:04:16 -0800 (PST) From: Nhat Pham To: akpm@linux-foundation.org Cc: hannes@cmpxchg.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, bfoster@redhat.com, willy@infradead.org, linux-api@vger.kernel.org, kernel-team@meta.com Subject: [PATCH v9 3/3] selftests: Add selftests for cachestat Date: Fri, 3 Feb 2023 11:04:13 -0800 Message-Id: <20230203190413.2559707-4-nphamcs@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230203190413.2559707-1-nphamcs@gmail.com> References: <20230203190413.2559707-1-nphamcs@gmail.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Queue-Id: B1D938001B X-Rspamd-Server: rspam01 X-Stat-Signature: 8zpxd5uqpsc3nstgqgxk6m4anm5xqwyq X-HE-Tag: 1675451057-112652 X-HE-Meta: U2FsdGVkX19GJP/Ee/dez0SmjWKLsue4/wVfIeYKdGJr7I44hzYFzJfyayT0zzPU4GuULiBprwMamhisCjOxvHIKGpEsOjdh4QDce/xWGG7tinLSpaseB25De3DzliYJkWPl0nCzFjIX1jl5wZHnN9klpYZT0FrtcU2w8UEIev3HI+PjhXlRaSzqYcg+u2HKgiIKbAiGWPHeFoWnDgwpWUJZXMQmghkdJ+SbTWX7rJWC38QDat4CdcLZ/SBTPT9N0wor7/1wdOl6tNGzia97xAp+/Ah9L1bLkM3Y7YEq9dLR4zBFOMICD/UxMDIfNTwqQHt2aFiQqO1H2AAmpqDEENHRCfp5RKfj3SOoQjQMvI/0EdxhW8OeASFPYSyDzcihh6C6kJ+w0G9zDZwL3h+5tzNTrlbnCmhwrCdh/FeVlisBZ0UilmXCcs7B9C4cNYva51fIpjhlMrL2rBj3fm0TjYzGbQQWMHHJlCvXiiMOcyNJw9taEPgiQ5Xvu7t0jwiHO9GqlJSMeEcRL5LFC2/Bqj3XBiPK5aAgU3HYnCBnRJjCFIbM+KGcEozMzbawQ5xahl4hdBuu1eLHffkReBRSxRjhBnY4qXcIAFiiVpveTqQNWmXn9UDJgG7VXtEAkbSaqPBtDXX7MnPFgH+YI5zCzKRDxkpo/VbdYxUpExQrT5umMwNRy7su6QaIBrDJRg8V7IoyO2PCnNOV94ybKgH0a1QO/JCmnTTkVnRou6bCEXehk5UPlWUHXw3DJhk8vVt2L44oub8JnKOqYNbm23O9wdPaOY779vzkXxj/fL0u1G8kN+GWE3sDH4JlPM1G9Ey1ng9Vyc5BmSbHUHCf5nlOS7zKvPBu7GPQqcxKHNBnFjI53Ao5PB03qx6RNHfPnHiEjRIeLw80JCXZvxQm/NjeLmnyzl8WWPz5IodWffqxv6Ukgnp5DBK2TCRTPgmUDT4fzQS36swVhPDpWj97/qg GkC0cIqR CtBkY6O6JKFSaA74fGKo8+w+Jl76iMfDlQe5tjE4E9rbxyAfYeKKfJ6t3M+NxpwdaH7we0v2XzD3JoN4wH/EPbaD5eNmoO0C6/ikRkCBG2rof2QB9NLqAgkbxgJ2FFZbi87VHmKLb88vZpe2oF5RZfbdEQ3n/4T+DkEqZ/arCdpdIWFnY7xma33pXc86FnyeXJPRp1LANTnbT+ONaO5Impab28+1ucQc41L5KROw5TRxHXuso97Mfqtq/x4AjihlRBf77KSG00tD9uOWS6+2/qq7ewD+JkqqPKIksvqTOU9vRT/tXmAtvX7GgBw2oCkG8GsfbaSMMaz61Zsupx8/DFR//GtK8yMezYnSGEotyGJBpO1LJdMoLuLx0zv20pzZ0zdytXNBXvgssr9mnss5GBz3B9Z4/l2ZGhax79NlE+QtzT5v9owLQu+cTHYMipnZGBR9HbovsKQ2rFGLYDXQg/iXYNot35UgsXtHumNF6SOCgC/EFtXi66/7bNiSBA4D11zy6+HQigepVe9AHrcCI8ibNtmRZqD3qRM3FRgR0hNznORKz5b6+8U3CqVrAZIeJRDgAm9mCXIxn4SnQEeMaI292R5uivCStkCE5KB6Gb34wHKWY5B4RLmlX9g== 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: Test cachestat on a newly created file, /dev/ files, and /proc/ files. Also test on a shmem file (which can also be tested with huge pages since tmpfs supports huge pages). Signed-off-by: Nhat Pham --- MAINTAINERS | 7 + tools/testing/selftests/Makefile | 1 + tools/testing/selftests/cachestat/.gitignore | 2 + tools/testing/selftests/cachestat/Makefile | 8 + .../selftests/cachestat/test_cachestat.c | 256 ++++++++++++++++++ 5 files changed, 274 insertions(+) create mode 100644 tools/testing/selftests/cachestat/.gitignore create mode 100644 tools/testing/selftests/cachestat/Makefile create mode 100644 tools/testing/selftests/cachestat/test_cachestat.c diff --git a/MAINTAINERS b/MAINTAINERS index a198da986146..792a866353ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4552,6 +4552,13 @@ S: Supported F: Documentation/filesystems/caching/cachefiles.rst F: fs/cachefiles/ +CACHESTAT: PAGE CACHE STATS FOR A FILE +M: Nhat Pham +M: Johannes Weiner +L: linux-mm@kvack.org +S: Maintained +F: tools/testing/selftests/cachestat/test_cachestat.c + CADENCE MIPI-CSI2 BRIDGES M: Maxime Ripard L: linux-media@vger.kernel.org diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 0464b2c6c1e4..3cad0b38c5c2 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -4,6 +4,7 @@ TARGETS += amd-pstate TARGETS += arm64 TARGETS += bpf TARGETS += breakpoints +TARGETS += cachestat TARGETS += capabilities TARGETS += cgroup TARGETS += clone3 diff --git a/tools/testing/selftests/cachestat/.gitignore b/tools/testing/selftests/cachestat/.gitignore new file mode 100644 index 000000000000..d6c30b43a4bb --- /dev/null +++ b/tools/testing/selftests/cachestat/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +test_cachestat diff --git a/tools/testing/selftests/cachestat/Makefile b/tools/testing/selftests/cachestat/Makefile new file mode 100644 index 000000000000..fca73aaa7d14 --- /dev/null +++ b/tools/testing/selftests/cachestat/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +TEST_GEN_PROGS := test_cachestat + +CFLAGS += $(KHDR_INCLUDES) +CFLAGS += -Wall +CFLAGS += -lrt + +include ../lib.mk diff --git a/tools/testing/selftests/cachestat/test_cachestat.c b/tools/testing/selftests/cachestat/test_cachestat.c new file mode 100644 index 000000000000..d44b6d435444 --- /dev/null +++ b/tools/testing/selftests/cachestat/test_cachestat.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../kselftest.h" + +static const char * const dev_files[] = { + "/dev/zero", "/dev/null", "/dev/urandom", + "/proc/version", "/proc" +}; +static const int cachestat_nr = 451; + +void print_cachestat(struct cachestat *cs) +{ + ksft_print_msg( + "Using cachestat: Cached: %lu, Dirty: %lu, Writeback: %lu, Evicted: %lu, Recently Evicted: %lu\n", + cs->nr_cache, cs->nr_dirty, cs->nr_writeback, + cs->nr_evicted, cs->nr_recently_evicted); +} + +bool write_exactly(int fd, size_t filesize) +{ + char data[filesize]; + bool ret = true; + int random_fd = open("/dev/urandom", O_RDONLY); + + if (random_fd < 0) { + ksft_print_msg("Unable to access urandom.\n"); + ret = false; + goto out; + } else { + int remained = filesize; + char *cursor = data; + + while (remained) { + ssize_t read_len = read(random_fd, cursor, remained); + + if (read_len <= 0) { + ksft_print_msg("Unable to read from urandom.\n"); + ret = false; + goto close_random_fd; + } + + remained -= read_len; + cursor += read_len; + } + + /* write random data to fd */ + remained = filesize; + cursor = data; + while (remained) { + ssize_t write_len = write(fd, cursor, remained); + + if (write_len <= 0) { + ksft_print_msg("Unable write random data to file.\n"); + ret = false; + goto close_random_fd; + } + + remained -= write_len; + cursor += write_len; + } + } + +close_random_fd: + close(random_fd); +out: + return ret; +} + +/* + * Open/create the file at filename, (optionally) write random data to it + * (exactly num_pages), then test the cachestat syscall on this file. + * + * If test_fsync == true, fsync the file, then check the number of dirty + * pages. + */ +bool test_cachestat(const char *filename, bool write_random, bool create, + bool test_fsync, unsigned long num_pages, int open_flags, + mode_t open_mode) +{ + size_t PS = sysconf(_SC_PAGESIZE); + int filesize = num_pages * PS; + bool ret = true; + long syscall_ret; + struct cachestat cs; + + int fd = open(filename, open_flags, open_mode); + + if (fd == -1) { + ksft_print_msg("Unable to create/open file.\n"); + goto out; + } else { + ksft_print_msg("Create/open %s\n", filename); + } + + if (write_random) { + if (!write_exactly(fd, filesize)) { + ksft_print_msg("Unable to access urandom.\n"); + ret = false; + goto out1; + } + } + + syscall_ret = syscall(cachestat_nr, fd, 0, filesize, &cs, 0); + + ksft_print_msg("Cachestat call returned %ld\n", syscall_ret); + + if (syscall_ret) { + ksft_print_msg("Cachestat returned non-zero.\n"); + ret = false; + goto out1; + + } else { + print_cachestat(&cs); + + if (write_random) { + if (cs.nr_cache + cs.nr_evicted != num_pages) { + ksft_print_msg( + "Total number of cached and evicted pages is off.\n"); + ret = false; + } + } + } + + if (test_fsync) { + if (fsync(fd)) { + ksft_print_msg("fsync fails.\n"); + ret = false; + } else { + syscall_ret = syscall(cachestat_nr, fd, 0, filesize, &cs, 0); + + ksft_print_msg("Cachestat call (after fsync) returned %ld\n", + syscall_ret); + + if (!syscall_ret) { + print_cachestat(&cs); + + if (cs.nr_dirty) { + ret = false; + ksft_print_msg( + "Number of dirty should be zero after fsync.\n"); + } + } else { + ksft_print_msg("Cachestat (after fsync) returned non-zero.\n"); + ret = false; + goto out1; + } + } + } + +out1: + close(fd); + + if (create) + remove(filename); +out: + return ret; +} + +bool test_cachestat_shmem(void) +{ + size_t PS = sysconf(_SC_PAGESIZE); + size_t filesize = PS * 512 * 2; /* 2 2MB huge pages */ + int syscall_ret; + off_t off = PS; + size_t compute_len = PS * 512; + char *filename = "tmpshmcstat"; + struct cachestat cs; + bool ret = true; + unsigned long num_pages = compute_len / PS; + int fd = shm_open(filename, O_CREAT | O_RDWR, 0600); + + if (fd < 0) { + ksft_print_msg("Unable to create shmem file.\n"); + ret = false; + goto out; + } + + if (ftruncate(fd, filesize)) { + ksft_print_msg("Unable to trucate shmem file.\n"); + ret = false; + goto close_fd; + } + + if (!write_exactly(fd, filesize)) { + ksft_print_msg("Unable to write to shmem file.\n"); + ret = false; + goto close_fd; + } + + syscall_ret = syscall(cachestat_nr, fd, off, compute_len, &cs, 0); + + if (syscall_ret) { + ksft_print_msg("Cachestat returned non-zero.\n"); + ret = false; + goto close_fd; + } else { + print_cachestat(&cs); + if (cs.nr_cache + cs.nr_evicted != num_pages) { + ksft_print_msg( + "Total number of cached and evicted pages is off.\n"); + ret = false; + } + } + +close_fd: + shm_unlink(filename); +out: + return ret; +} + +int main(void) +{ + int ret = 0; + + for (int i = 0; i < 5; i++) { + const char *dev_filename = dev_files[i]; + + if (test_cachestat(dev_filename, false, false, false, + 4, O_RDONLY, 0400)) + ksft_test_result_pass("cachestat works with %s\n", dev_filename); + else { + ksft_test_result_fail("cachestat fails with %s\n", dev_filename); + ret = 1; + } + } + + if (test_cachestat("tmpfilecachestat", true, true, + true, 4, O_CREAT | O_RDWR, 0400 | 0600)) + ksft_test_result_pass("cachestat works with a normal file\n"); + else { + ksft_test_result_fail("cachestat fails with normal file\n"); + ret = 1; + } + + if (test_cachestat_shmem()) + ksft_test_result_pass("cachestat works with a shmem file\n"); + else { + ksft_test_result_fail("cachestat fails with a shmem file\n"); + ret = 1; + } + + return ret; +}