From patchwork Thu Jun 20 00:26:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song <21cnbao@gmail.com> X-Patchwork-Id: 13704758 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 CC2B8C27C53 for ; Thu, 20 Jun 2024 00:27:10 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EA4958D0093; Wed, 19 Jun 2024 20:27:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E53C58D0091; Wed, 19 Jun 2024 20:27:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CCDA48D0093; Wed, 19 Jun 2024 20:27:09 -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 AB8928D0091 for ; Wed, 19 Jun 2024 20:27:09 -0400 (EDT) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 17F83415EA for ; Thu, 20 Jun 2024 00:27:09 +0000 (UTC) X-FDA: 82249377378.27.2F68804 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) by imf09.hostedemail.com (Postfix) with ESMTP id 503DA140002 for ; Thu, 20 Jun 2024 00:27:07 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b="Vq688/Ns"; spf=pass (imf09.hostedemail.com: domain of 21cnbao@gmail.com designates 209.85.210.179 as permitted sender) smtp.mailfrom=21cnbao@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1718843222; a=rsa-sha256; cv=none; b=Xw5mjC73nJtBYrPP/D0Cka+RJjsG5k+KcBPwcHw0jXzCJ71wD4WSjlYr8ko0nLmb8h0vEn V0L0vxjgtshMpkmTKTRKesXhUtq1oNcK+O84eMwanQggZlumqFXekFNv6x3QanYaZ4zBxg COPkSEOExdzgN2eN/4eU5m5co1ZbS90= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b="Vq688/Ns"; spf=pass (imf09.hostedemail.com: domain of 21cnbao@gmail.com designates 209.85.210.179 as permitted sender) smtp.mailfrom=21cnbao@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=1718843222; 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=/phkDRQOzz1mys5+rBCaSnbv5F7N/ucY8CBHIGfrx8g=; b=0m5LTEk+UL3eKvNS0ephBlOAq/Eb33jSVyQB7WeWKjZmruPPdSwKwDXH00HuY/TjK1cww8 OhJKa18S4zb8mQ/g/z36GNpGqrpN8sIqjs0iL5zVe8Y5bA6R74pwrMJREKZmyO/Rwa7sAw O5K7hJ23KO5DZv0LWEm/iRWfmZTFvxg= Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-705bf368037so366925b3a.0 for ; Wed, 19 Jun 2024 17:27:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718843226; x=1719448026; darn=kvack.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=/phkDRQOzz1mys5+rBCaSnbv5F7N/ucY8CBHIGfrx8g=; b=Vq688/NsglgzSfpxpx6Gb3VsQLx+ShEx2tYU3QfhX7qBCy0+9SlqpbcIYPtFlCqd6w ddYMSICwe5AJa2QgXgqZlExEqV0LY6HwD1x8DlDevKcMJNKkQAQHV7M2896XcqFCPrFI kNcvVXFpamjstOPOhakzBvuq2WXsexUEjjdDoFQTSAZx9DRHRO7RUuvMJ5zLKye6KHxW FBrcxSdelfSYxZ7T0U8ynunGV9Gnc6fZk8VfwlL8IW85D6b9ymdry0EI+qBIWcdDP6HO /YwVFMKDDUknIpWNHlVu4auupDSwSgAZGfN7jbLS+apmiekdju94YufjyYyc7BeJgn47 xzrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718843226; x=1719448026; 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=/phkDRQOzz1mys5+rBCaSnbv5F7N/ucY8CBHIGfrx8g=; b=Tn5Ioh7HzSBLBodeYjngCtcIKZQutKark0valJaHH8MJTusfH0bw2s/5UkaeWPGtsA 6F07x83HgbPYpvEBbpv/c2vEso9S5guSqkN6sljizomyLXOKbec8+pvSzZgbCcBkbIkU 4wmxZCuCj6Dk5V4YDUVWy8Vdoc9xlVsmnbkB09SfYbjfFmjfKqZQ5IATFC0gYiQ9w5ig yygvPcq03TXaN7Qx8KqOmyfypxwrqR+vVliZQz4VtYgjrtmLnQ4yVACRc0iGf6CZ/bXD KdM6gCn6woySdWMbBKo+lUS9EkBAC+q7UDMgvlu7TE8KdxFj4QwSRQLB8sZOsWyCA7zh Wjhg== X-Forwarded-Encrypted: i=1; AJvYcCXR5ZqaOhbtTPPrDIxhfnRmrmXONJvL5DFTTw6VqyoAQSN4DI8Pfn+elgTfBMVjTThOEnlsoxOaW/uP4gljvc7MIac= X-Gm-Message-State: AOJu0YxIGeaUfL45UWpQ4PSPTrMNz7uqaXkh6ceQMgrXnGp46vIYfbIp Ar42RkXVA9GY02ljckbYBOcb1QKzrSu2nlzab492kFbHwC+Gg/mQ X-Google-Smtp-Source: AGHT+IEKP///BAxzukR21Dn0SGKbKyRk6+T0rDc0H3AwIZxrIsHI7d6TiHcl1VqbM0vqcWGSiAyMEA== X-Received: by 2002:a05:6a00:2f43:b0:704:1ac0:bf16 with SMTP id d2e1a72fcca58-70629c1fcbbmr3686506b3a.5.1718843225789; Wed, 19 Jun 2024 17:27:05 -0700 (PDT) Received: from localhost.localdomain ([2407:7000:8942:5500:aaa1:59ff:fe57:eb97]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-705cc967356sm11273385b3a.63.2024.06.19.17.27.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jun 2024 17:27:05 -0700 (PDT) From: Barry Song <21cnbao@gmail.com> To: akpm@linux-foundation.org, shuah@kernel.org, linux-mm@kvack.org Cc: ryan.roberts@arm.com, chrisl@kernel.org, david@redhat.com, hughd@google.com, kaleshsingh@google.com, kasong@tencent.com, linux-kernel@vger.kernel.org, ying.huang@intel.com, linux-kselftest@vger.kernel.org, Barry Song Subject: [PATCH] selftests/mm: Introduce a test program to assess swap entry allocation for thp_swapout Date: Thu, 20 Jun 2024 12:26:48 +1200 Message-Id: <20240620002648.75204-1-21cnbao@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Stat-Signature: 188f17dr7e81y4j9iimfmqt9op9tstz6 X-Rspamd-Queue-Id: 503DA140002 X-Rspam-User: X-Rspamd-Server: rspam10 X-HE-Tag: 1718843227-125798 X-HE-Meta: U2FsdGVkX1/NwUziowNOKlywsVnXSemOv2oZwmcBK/3iBVKqItqH81A2zcdgiY2NXkEm1vRtTp001aIjOe7uJKwq78ieXVVRyVQENCMcPw4LTRb0EO7MZkb9zIlfDlrgKJ2WiM00eXLj58NJVQEQ7rd4oxZYqovd0LfX49VjcS4NyUwMPnNcfQ4d0kejuYUsjK68ZkLCqlBB8VGMa59PCtSmdSaLC65sVvQID1KImtqCrXuhITqcApnkc6Xdk3YbfByNFKArg0VqHZgU8nmXUyWD++JUdl5cvhjvYTLRaRB9LKE+2cdO0zzhkvya1cH2H3B9JHXJrt0cQfWfLkHkZ/8Lg9i1CrTdzW+K8KdhzNw4FzIiCEpTpB9RWE0Zf3MLVCCXk/G4n9B5PDDvBlcvas2X5meA1fvMePx+TDHyvghfAeQu7mRqu4qLDD1AXv8ukR5/4XNFmHoNCYYrX2lD3bkqhRChm4fz04Y3Er1BRACTBuDHrVdqRJG71ydKYulAJQ33JIqcAZMY0ywOI87YwgnPvDKMYiR24OfaSwOq3PJEsjDBDw1hHyj8xaPyRR2hvcIpK/GOjasL+lB+uf0FIzgd12CcD3v6auH/xVGZ5zYeoYtRKJn3NT8QgzEjDNQGamcADGngcopog7GBnkU5uMTS8lw7EcxzZxc8ZxdYt7uic0JMVUn/A0/CM5Uz1DNarn1mxrkLcg/FCXk0GYuBOqGCE/V9qBq4agy+TibBOBgB1zOP7mgUmpZ1Ajxihtu1np0Q5O9ml71+7tSmYhdIi/Sg5VWOU/cG3g84KXuPHD5KLoqTKgB1AtSadHHtLo8wxKVOLE+L57N5KU/Mh9lYTkSr5hHEGNWq36nEbPl5cEEnrRXT7KbzDVdTAjhTJzDFNsPlQII0HTkrV+rSbmRLGJ1y6AxA8Muf0B6sPBA7ylBgDp49Y6E8mrvpsdK6aFwsz61pV+g44R97NrNJ1wg DomEfTKk CDjhQbBVWTgM58h9q2O5LC3w4C3EYs+fJB9jtKdeI8koX+oQJ6dDb90arUJ2oVtLc2ZkgTJqD+dqW0bBuwI6tvWVyXi1Ea5nCvhlLyTUVr0oY2iDLSc0+OkPgDqxRMxhvC6e0/L0RJNGOQDyPn6SvMvj/pl7VW8CRJyrRVNPNvwUE+sLQDseSeAEovKaSash/EUChZl1262+aFq//OBeeAPy6F37XMThPHOmHySTY6xXLHHh7O290YEg/fk+tmPI8e3H/Pw3Oxk5ES5fJkciNCScBO4skb6CziH4vj+L1/YEtFXS/WdgnIUZNW1K9AbeO3Ur/2iWLa8ZzCjALfoDAy2566g7NOC8qVrCeZm/Fpc+ITBAaCZr+KaSxrdZWrDkYb4drnC0OZytKqPutpMqMZiBmFAurKpTSTDRBTjxwydpYvXT06vnR3TqnFqbZPtDwl7fevaulqIwT8qkBjuU7MdHXWfK2EdcTeIOk 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: List-Subscribe: List-Unsubscribe: From: Barry Song Both Ryan and Chris have been utilizing the small test program to aid in debugging and identifying issues with swap entry allocation. While a real or intricate workload might be more suitable for assessing the correctness and effectiveness of the swap allocation policy, a small test program presents a simpler means of understanding the problem and initially verifying the improvements being made. Let's endeavor to integrate it into the self-test suite. Although it presently only accommodates 64KB and 4KB, I'm optimistic that we can expand its capabilities to support multiple sizes and simulate more complex systems in the future as required. Signed-off-by: Barry Song --- tools/testing/selftests/mm/Makefile | 1 + .../selftests/mm/thp_swap_allocator_test.c | 192 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 tools/testing/selftests/mm/thp_swap_allocator_test.c diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile index e1aa09ddaa3d..64164ad66835 100644 --- a/tools/testing/selftests/mm/Makefile +++ b/tools/testing/selftests/mm/Makefile @@ -65,6 +65,7 @@ TEST_GEN_FILES += mseal_test TEST_GEN_FILES += seal_elf TEST_GEN_FILES += on-fault-limit TEST_GEN_FILES += pagemap_ioctl +TEST_GEN_FILES += thp_swap_allocator_test TEST_GEN_FILES += thuge-gen TEST_GEN_FILES += transhuge-stress TEST_GEN_FILES += uffd-stress diff --git a/tools/testing/selftests/mm/thp_swap_allocator_test.c b/tools/testing/selftests/mm/thp_swap_allocator_test.c new file mode 100644 index 000000000000..4443a906d0f8 --- /dev/null +++ b/tools/testing/selftests/mm/thp_swap_allocator_test.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * thp_swap_allocator_test + * + * The purpose of this test program is helping check if THP swpout + * can correctly get swap slots to swap out as a whole instead of + * being split. It randomly releases swap entries through madvise + * DONTNEED and do swapout on two memory areas: a memory area for + * 64KB THP and the other area for small folios. The second memory + * can be enabled by "-s". + * Before running the program, we need to setup a zRAM or similar + * swap device by: + * echo lzo > /sys/block/zram0/comp_algorithm + * echo 64M > /sys/block/zram0/disksize + * echo never > /sys/kernel/mm/transparent_hugepage/hugepages-2048kB/enabled + * echo always > /sys/kernel/mm/transparent_hugepage/hugepages-64kB/enabled + * mkswap /dev/zram0 + * swapon /dev/zram0 + * The expected result should be 0% anon swpout fallback ratio w/ or + * w/o "-s". + * + * Author(s): Barry Song + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define MEMSIZE_MTHP (60 * 1024 * 1024) +#define MEMSIZE_SMALLFOLIO (1 * 1024 * 1024) +#define ALIGNMENT_MTHP (64 * 1024) +#define ALIGNMENT_SMALLFOLIO (4 * 1024) +#define TOTAL_DONTNEED_MTHP (16 * 1024 * 1024) +#define TOTAL_DONTNEED_SMALLFOLIO (768 * 1024) +#define MTHP_FOLIO_SIZE (64 * 1024) + +#define SWPOUT_PATH \ + "/sys/kernel/mm/transparent_hugepage/hugepages-64kB/stats/swpout" +#define SWPOUT_FALLBACK_PATH \ + "/sys/kernel/mm/transparent_hugepage/hugepages-64kB/stats/swpout_fallback" + +static void *aligned_alloc_mem(size_t size, size_t alignment) +{ + void *mem = NULL; + + if (posix_memalign(&mem, alignment, size) != 0) { + perror("posix_memalign"); + return NULL; + } + return mem; +} + +static void random_madvise_dontneed(void *mem, size_t mem_size, + size_t align_size, size_t total_dontneed_size) +{ + size_t num_pages = total_dontneed_size / align_size; + size_t i; + size_t offset; + void *addr; + + for (i = 0; i < num_pages; ++i) { + offset = (rand() % (mem_size / align_size)) * align_size; + addr = (char *)mem + offset; + if (madvise(addr, align_size, MADV_DONTNEED) != 0) + perror("madvise dontneed"); + + memset(addr, 0x11, align_size); + } +} + +static unsigned long read_stat(const char *path) +{ + FILE *file; + unsigned long value; + + file = fopen(path, "r"); + if (!file) { + perror("fopen"); + return 0; + } + + if (fscanf(file, "%lu", &value) != 1) { + perror("fscanf"); + fclose(file); + return 0; + } + + fclose(file); + return value; +} + +int main(int argc, char *argv[]) +{ + int use_small_folio = 0; + int i; + void *mem1 = aligned_alloc_mem(MEMSIZE_MTHP, ALIGNMENT_MTHP); + void *mem2 = NULL; + + if (mem1 == NULL) { + fprintf(stderr, "Failed to allocate 60MB memory\n"); + return EXIT_FAILURE; + } + + if (madvise(mem1, MEMSIZE_MTHP, MADV_HUGEPAGE) != 0) { + perror("madvise hugepage for mem1"); + free(mem1); + return EXIT_FAILURE; + } + + for (i = 1; i < argc; ++i) { + if (strcmp(argv[i], "-s") == 0) + use_small_folio = 1; + } + + if (use_small_folio) { + mem2 = aligned_alloc_mem(MEMSIZE_SMALLFOLIO, ALIGNMENT_MTHP); + if (mem2 == NULL) { + fprintf(stderr, "Failed to allocate 1MB memory\n"); + free(mem1); + return EXIT_FAILURE; + } + + if (madvise(mem2, MEMSIZE_SMALLFOLIO, MADV_NOHUGEPAGE) != 0) { + perror("madvise nohugepage for mem2"); + free(mem1); + free(mem2); + return EXIT_FAILURE; + } + } + + for (i = 0; i < 100; ++i) { + unsigned long initial_swpout; + unsigned long initial_swpout_fallback; + unsigned long final_swpout; + unsigned long final_swpout_fallback; + unsigned long swpout_inc; + unsigned long swpout_fallback_inc; + double fallback_percentage; + + initial_swpout = read_stat(SWPOUT_PATH); + initial_swpout_fallback = read_stat(SWPOUT_FALLBACK_PATH); + + random_madvise_dontneed(mem1, MEMSIZE_MTHP, ALIGNMENT_MTHP, + TOTAL_DONTNEED_MTHP); + + if (use_small_folio) { + random_madvise_dontneed(mem2, MEMSIZE_SMALLFOLIO, + ALIGNMENT_SMALLFOLIO, + TOTAL_DONTNEED_SMALLFOLIO); + } + + if (madvise(mem1, MEMSIZE_MTHP, MADV_PAGEOUT) != 0) { + perror("madvise pageout for mem1"); + free(mem1); + if (mem2 != NULL) + free(mem2); + return EXIT_FAILURE; + } + + if (use_small_folio) { + if (madvise(mem2, MEMSIZE_SMALLFOLIO, MADV_PAGEOUT) != 0) { + perror("madvise pageout for mem2"); + free(mem1); + free(mem2); + return EXIT_FAILURE; + } + } + + final_swpout = read_stat(SWPOUT_PATH); + final_swpout_fallback = read_stat(SWPOUT_FALLBACK_PATH); + + swpout_inc = final_swpout - initial_swpout; + swpout_fallback_inc = final_swpout_fallback - initial_swpout_fallback; + + fallback_percentage = (double)swpout_fallback_inc / + (swpout_fallback_inc + swpout_inc) * 100; + + printf("Iteration %d: swpout inc: %lu, swpout fallback inc: %lu, Fallback percentage: %.2f%%\n", + i + 1, swpout_inc, swpout_fallback_inc, fallback_percentage); + } + + free(mem1); + if (mem2 != NULL) + free(mem2); + + return EXIT_SUCCESS; +}