From patchwork Mon Aug 26 12:40:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13777857 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 4F141C5321E for ; Mon, 26 Aug 2024 12:46:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BF94B6B04B5; Mon, 26 Aug 2024 08:46:18 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B86BD6B04B2; Mon, 26 Aug 2024 08:46:18 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9F96A6B04B5; Mon, 26 Aug 2024 08:46:18 -0400 (EDT) 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 7E3746B04A9 for ; Mon, 26 Aug 2024 08:46:18 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 3760A41103 for ; Mon, 26 Aug 2024 12:46:18 +0000 (UTC) X-FDA: 82494369636.24.9825765 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf03.hostedemail.com (Postfix) with ESMTP id 111C820025 for ; Mon, 26 Aug 2024 12:46:14 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=none; spf=pass (imf03.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1724676334; 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-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EC9+E4rKYBva1XZZL/Kcl5lVQf71apC+HwduGUlt5GU=; b=F14Bc4mk2gF3y8oxECoczhoJ3XPDJV3nKr++BalABiClsRme7GrYAwNNXsRN+m3Mdpbcy9 eAf1YO0D9tjakbpSp7z9QVb2X5QYot/KyzQalL5HUactGKD6Cw6rK19xHvl5exE36g27cY 8TJdzP7vx+Q9FWXM6tUPefJryicoQUI= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=none; spf=pass (imf03.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1724676334; a=rsa-sha256; cv=none; b=JZK2Cwc4O01A4gG6H/F+qqDfXKUrNf0vCkUs8VpPKDdhL4sUiGBzUXy3bmdPhf84BVHQg5 k9R9FbNU+c5v0XeNgeVMwmWfxyxGhRqU2DldhTGkpY15ZDud7wjlE0m1nOWOPRYKkvvcl9 oU+vRX5q3aa3c3cNyRs1Hkmbnq7YN5o= Received: from mail.maildlp.com (unknown [172.19.88.105]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4Wsr3J4H3vzpTgQ; Mon, 26 Aug 2024 20:44:28 +0800 (CST) Received: from dggpemf200006.china.huawei.com (unknown [7.185.36.61]) by mail.maildlp.com (Postfix) with ESMTPS id ADD1A14037E; Mon, 26 Aug 2024 20:46:07 +0800 (CST) Received: from localhost.localdomain (10.90.30.45) by dggpemf200006.china.huawei.com (7.185.36.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Mon, 26 Aug 2024 20:46:07 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Alexander Duyck , Andrew Morton , Shuah Khan , , Subject: [PATCH net-next v15 01/13] mm: page_frag: add a test module for page_frag Date: Mon, 26 Aug 2024 20:40:08 +0800 Message-ID: <20240826124021.2635705-2-linyunsheng@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20240826124021.2635705-1-linyunsheng@huawei.com> References: <20240826124021.2635705-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.90.30.45] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemf200006.china.huawei.com (7.185.36.61) X-Rspamd-Server: rspam03 X-Rspam-User: X-Rspamd-Queue-Id: 111C820025 X-Stat-Signature: 6nr58p5jc8pru83g3f8rgrnwycixygpu X-HE-Tag: 1724676374-982808 X-HE-Meta: U2FsdGVkX18ni0I2F/Tep0IISzWdRddkFlidN4ByXjgulqSDFi3EKDoaqkV849kkE1h+sEHD7nUN6vv8vH25GPhC+N7OaY+yQ6Cy+TXd4OpvVHyB8Bm62CsHUPBRe8dwde+C/PBtvrrkCV30qv0ioUUYszzghgQ0X8dzO9BLcYJjwts22/LKg4yfFMLj5G4MjlJ3kggxEOkqD65tvB3xbYke4JqLefLMvy8pLfulJs49CBUvdZhwfaMF52W+Cr9sd/Q5bLuUM0aNs/2RLJOJHuHRrzZLasNa1ElaoAb4oZgyd5veWI2QFIZ6bi73r1sqHMGa18kS4v7QBnXSt9pLy4v6se0di5PWEom/z1qrq+hKof+IWiY5UJNpz61/ilnK9xmPPFrpTTJOSRQwNjnDJvy2+I9APRn8XnecfTLznFXBTXlCqUKD6cxGZqNfv3L1yF9wscIhyG2UwriC4KrQEMUneKxBXasXTqH+r2/UfZo6wY3onhLVb5r4LfU/hjjPT/3hlimFo0jy1pO04I0QV1RKFW3+4onC0j7JDgDrhtL1CkyINOFbPObK6YEioCgwqUbAi/qaXIQDaDoBlrSUtDfvIEsHnPfwIo0dG4jLhuXq7nb+a26KW6p5KVTf5HfcSEzRqNNmH4DDzf9Kv09WBY/UmWTrJpgtEa2//LOkmQXS6UI7QKDqXe3bqE9B1mTWqbeuXa2VfbICuA5D1yNo3EZXNErnB5eBGhy2ba1nhQeicT2JHoalYFvQS7AXvrzDNDHXX6ear8G5is1VkMjqnMqz/pjQLnH5xazlu+N8JWkrPJ3wPPshdEIS9SBv7S9u8hMtujAB/FnPHqU/0MPrlpXrPs/5XMneyy7vjvKSxQm56RVFqPKgIzDWh7GgElhgLBgOz+RuS21+ZLu/JW+aD98H8ylA+fLeNGMF2JYVKlSHleeZ3ZK8h3bZTNYSo8ow9t29j/DkBL8SVqzGkm+ SuZMUpvB zvOVhxlIcxYSvGwYn1R178L7baYds+8rdfLnImc+/YFKi90zxOTGZ1BPDc1FHx7fiPrpvQyACu+kfuFqB/WM0eVaG3DxHS5oO1XhE7lxL4PnckVNI44t+4kDs8sYC2MwXGZGrA3/gHFxu/LquMGcEVO4zpKoitPzV4b6S689RUiUHNf8WMpQK7DrIpIR88JQMdgQY51Vhs032NL+jWOCLj4B1TwHFPgEKtgiIxvLEXda/Xq9rZAInqUcjE83hgg31w0c4gEQJqObQbJUZ66QxSyDIbOamGljZwxzl 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: The testing is done by ensuring that the fragment allocated from a frag_frag_cache instance is pushed into a ptr_ring instance in a kthread binded to a specified cpu, and a kthread binded to a specified cpu will pop the fragment from the ptr_ring and free the fragment. CC: Alexander Duyck Signed-off-by: Yunsheng Lin --- tools/testing/selftests/mm/Makefile | 2 + tools/testing/selftests/mm/page_frag/Makefile | 18 ++ .../selftests/mm/page_frag/page_frag_test.c | 170 ++++++++++++++++++ tools/testing/selftests/mm/run_vmtests.sh | 9 +- 4 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/mm/page_frag/Makefile create mode 100644 tools/testing/selftests/mm/page_frag/page_frag_test.c diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile index cfad627e8d94..ed196901b9ca 100644 --- a/tools/testing/selftests/mm/Makefile +++ b/tools/testing/selftests/mm/Makefile @@ -36,6 +36,8 @@ MAKEFLAGS += --no-builtin-rules CFLAGS = -Wall -I $(top_srcdir) $(EXTRA_CFLAGS) $(KHDR_INCLUDES) $(TOOLS_INCLUDES) LDLIBS = -lrt -lpthread -lm +TEST_GEN_MODS_DIR := page_frag + TEST_GEN_FILES = cow TEST_GEN_FILES += compaction_test TEST_GEN_FILES += gup_longterm diff --git a/tools/testing/selftests/mm/page_frag/Makefile b/tools/testing/selftests/mm/page_frag/Makefile new file mode 100644 index 000000000000..58dda74d50a3 --- /dev/null +++ b/tools/testing/selftests/mm/page_frag/Makefile @@ -0,0 +1,18 @@ +PAGE_FRAG_TEST_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +KDIR ?= $(abspath $(PAGE_FRAG_TEST_DIR)/../../../../..) + +ifeq ($(V),1) +Q = +else +Q = @ +endif + +MODULES = page_frag_test.ko + +obj-m += page_frag_test.o + +all: + +$(Q)make -C $(KDIR) M=$(PAGE_FRAG_TEST_DIR) modules + +clean: + +$(Q)make -C $(KDIR) M=$(PAGE_FRAG_TEST_DIR) clean diff --git a/tools/testing/selftests/mm/page_frag/page_frag_test.c b/tools/testing/selftests/mm/page_frag/page_frag_test.c new file mode 100644 index 000000000000..0e803db1ad79 --- /dev/null +++ b/tools/testing/selftests/mm/page_frag/page_frag_test.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Test module for page_frag cache + * + * Copyright: linyunsheng@huawei.com + */ + +#include +#include +#include +#include +#include +#include + +static struct ptr_ring ptr_ring; +static int nr_objs = 512; +static atomic_t nthreads; +static struct completion wait; +static struct page_frag_cache test_frag; + +static int nr_test = 5120000; +module_param(nr_test, int, 0); +MODULE_PARM_DESC(nr_test, "number of iterations to test"); + +static bool test_align; +module_param(test_align, bool, 0); +MODULE_PARM_DESC(test_align, "use align API for testing"); + +static int test_alloc_len = 2048; +module_param(test_alloc_len, int, 0); +MODULE_PARM_DESC(test_alloc_len, "alloc len for testing"); + +static int test_push_cpu; +module_param(test_push_cpu, int, 0); +MODULE_PARM_DESC(test_push_cpu, "test cpu for pushing fragment"); + +static int test_pop_cpu; +module_param(test_pop_cpu, int, 0); +MODULE_PARM_DESC(test_pop_cpu, "test cpu for popping fragment"); + +static int page_frag_pop_thread(void *arg) +{ + struct ptr_ring *ring = arg; + int nr = nr_test; + + pr_info("page_frag pop test thread begins on cpu %d\n", + smp_processor_id()); + + while (nr > 0) { + void *obj = __ptr_ring_consume(ring); + + if (obj) { + nr--; + page_frag_free(obj); + } else { + cond_resched(); + } + } + + if (atomic_dec_and_test(&nthreads)) + complete(&wait); + + pr_info("page_frag pop test thread exits on cpu %d\n", + smp_processor_id()); + + return 0; +} + +static int page_frag_push_thread(void *arg) +{ + struct ptr_ring *ring = arg; + int nr = nr_test; + + pr_info("page_frag push test thread begins on cpu %d\n", + smp_processor_id()); + + while (nr > 0) { + void *va; + int ret; + + if (test_align) { + va = page_frag_alloc_align(&test_frag, test_alloc_len, + GFP_KERNEL, SMP_CACHE_BYTES); + + WARN_ONCE((unsigned long)va & (SMP_CACHE_BYTES - 1), + "unaligned va returned\n"); + } else { + va = page_frag_alloc(&test_frag, test_alloc_len, GFP_KERNEL); + } + + if (!va) + continue; + + ret = __ptr_ring_produce(ring, va); + if (ret) { + page_frag_free(va); + cond_resched(); + } else { + nr--; + } + } + + pr_info("page_frag push test thread exits on cpu %d\n", + smp_processor_id()); + + if (atomic_dec_and_test(&nthreads)) + complete(&wait); + + return 0; +} + +static int __init page_frag_test_init(void) +{ + struct task_struct *tsk_push, *tsk_pop; + ktime_t start; + u64 duration; + int ret; + + test_frag.va = NULL; + atomic_set(&nthreads, 2); + init_completion(&wait); + + if (test_alloc_len > PAGE_SIZE || test_alloc_len <= 0 || + !cpu_active(test_push_cpu) || !cpu_active(test_pop_cpu)) + return -EINVAL; + + ret = ptr_ring_init(&ptr_ring, nr_objs, GFP_KERNEL); + if (ret) + return ret; + + tsk_push = kthread_create_on_cpu(page_frag_push_thread, &ptr_ring, + test_push_cpu, "page_frag_push"); + if (IS_ERR(tsk_push)) + return PTR_ERR(tsk_push); + + tsk_pop = kthread_create_on_cpu(page_frag_pop_thread, &ptr_ring, + test_pop_cpu, "page_frag_pop"); + if (IS_ERR(tsk_pop)) { + kthread_stop(tsk_push); + return PTR_ERR(tsk_pop); + } + + start = ktime_get(); + wake_up_process(tsk_push); + wake_up_process(tsk_pop); + + pr_info("waiting for test to complete\n"); + wait_for_completion(&wait); + + duration = (u64)ktime_us_delta(ktime_get(), start); + pr_info("%d of iterations for %s testing took: %lluus\n", nr_test, + test_align ? "aligned" : "non-aligned", duration); + + ptr_ring_cleanup(&ptr_ring, NULL); + page_frag_cache_drain(&test_frag); + + return -EAGAIN; +} + +static void __exit page_frag_test_exit(void) +{ +} + +module_init(page_frag_test_init); +module_exit(page_frag_test_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yunsheng Lin "); +MODULE_DESCRIPTION("Test module for page_frag"); diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh index 36045edb10de..9a788d5f3f28 100755 --- a/tools/testing/selftests/mm/run_vmtests.sh +++ b/tools/testing/selftests/mm/run_vmtests.sh @@ -75,6 +75,8 @@ separated by spaces: read-only VMAs - mdwe test prctl(PR_SET_MDWE, ...) +- page_frag + test handling of page fragment allocation and freeing example: ./run_vmtests.sh -t "hmm mmap ksm" EOF @@ -231,7 +233,8 @@ run_test() { ("$@" 2>&1) | tap_prefix local ret=${PIPESTATUS[0]} count_total=$(( count_total + 1 )) - if [ $ret -eq 0 ]; then + # page_frag_test.ko returns 11(EAGAIN) when insmod'ing to avoid rmmod + if [ $ret -eq 0 ] | [ $ret -eq 11 -a ${CATEGORY} == "page_frag" ]; then count_pass=$(( count_pass + 1 )) echo "[PASS]" | tap_prefix echo "ok ${count_total} ${test}" | tap_output @@ -456,6 +459,10 @@ CATEGORY="mkdirty" run_test ./mkdirty CATEGORY="mdwe" run_test ./mdwe_test +CATEGORY="page_frag" run_test insmod ./page_frag/page_frag_test.ko + +CATEGORY="page_frag" run_test insmod ./page_frag/page_frag_test.ko test_alloc_len=12 test_align=1 + echo "SUMMARY: PASS=${count_pass} SKIP=${count_skip} FAIL=${count_fail}" | tap_prefix echo "1..${count_total}" | tap_output