From patchwork Mon Feb 24 14:47:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Jackman X-Patchwork-Id: 13988326 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 B7214C021BB for ; Mon, 24 Feb 2025 14:47:33 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 4DE4B6B009F; Mon, 24 Feb 2025 09:47:33 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 48EE76B00A0; Mon, 24 Feb 2025 09:47:33 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 21F4D6B00A1; Mon, 24 Feb 2025 09:47:33 -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 030606B009F for ; Mon, 24 Feb 2025 09:47:32 -0500 (EST) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id AC715B09D0 for ; Mon, 24 Feb 2025 14:47:32 +0000 (UTC) X-FDA: 83155116744.19.F09BA29 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf16.hostedemail.com (Postfix) with ESMTP id BE70E180013 for ; Mon, 24 Feb 2025 14:47:30 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=tSSShfjW; spf=pass (imf16.hostedemail.com: domain of 3gYa8ZwgKCMQtkmuwkxlqyyqvo.mywvsx47-wwu5kmu.y1q@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3gYa8ZwgKCMQtkmuwkxlqyyqvo.mywvsx47-wwu5kmu.y1q@flex--jackmanb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740408450; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Cx79yAQvvtOreEIgXQgmWnaukRcNTY0vcbEckVNMqhA=; b=hudODtfZTx4gALNyHGIfD301d5fsj6Jox3WZUPklzTEVrpqLTNa8kiWYDKOhOL6VLnW33g Vx2mJdrUyBdchC98VkE9RQgKtDXvk7+f7B/S9wUn5NojyuGxyF7mr5UJWpUtcLZKqTnkc8 heiqQzTW4jZKhhARqxduR+/ds5/6qbs= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=tSSShfjW; spf=pass (imf16.hostedemail.com: domain of 3gYa8ZwgKCMQtkmuwkxlqyyqvo.mywvsx47-wwu5kmu.y1q@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3gYa8ZwgKCMQtkmuwkxlqyyqvo.mywvsx47-wwu5kmu.y1q@flex--jackmanb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740408450; a=rsa-sha256; cv=none; b=RkpfXrYvwfxsnAYYDq0KTrEdcxqMmSOIsqrJGUg9ez+YkaKSydu2i6s6m8t82iRWP3w64/ BLS/e1gSY5OluFB2hwwjmKC/qWFAsNmt3xMYngROtwdeiaX5JN9PxsBSMOD3cyZUdgxUTH Of2dYyNDdleHPEqwaYcluU34vZPOseY= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43aafafe6b7so2200815e9.1 for ; Mon, 24 Feb 2025 06:47:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1740408449; x=1741013249; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Cx79yAQvvtOreEIgXQgmWnaukRcNTY0vcbEckVNMqhA=; b=tSSShfjWfHYMRW1xH6XpSxf5AAfni1JdTQaTlK3qVp92xurwjwUg05P8whH8s3TQOy wx06zdJEuBdD+lq7CJ37gdmSxNChqnpXe/J2kCfFSoqOybfeTsaVbq3UMoOjqfPeduNZ QJDC2z7+6ufM5tBupwdnRHsCj5FRojR2zCVOqe+raMeCFtXY79Pq67nxkCCXK4vYt59C tleZO8LcOZ5RGgdfrbkUnfDIwnBZuHp1NGQ/2CTweVWGHnH120wRFc5pgYYy82vunqtj 9we7fp5GBklwUJFasTFa5niyECtl24OkLXzcUedZuBmJ43hfYyq44CCM86HaKbfGv7El xy+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740408449; x=1741013249; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Cx79yAQvvtOreEIgXQgmWnaukRcNTY0vcbEckVNMqhA=; b=O1mGnIHZplRRuUJ0KBFM2xG5ggu8/e5NPezMclg++BI/uDz7U+TS22uitBT5vSxoD9 I/1U4GrfMl8jYPcWDByjRDBbpJwrT74DtvdG7GCauK1kNwVrmWv9MWwq3SmkSEeScRPH VJeuupWMQ4Zyvu+StVHCyQyHanrkgU4rKp+bQU4v3HWdvSJLOrdMmxQvnDTwjVO0gzgf joaFj0GOXABt2k30rSKWXffTHdKiHjPXehSK9fqakD6+Zy7ypUUC4s6MPMrbueAhuaad KIMhmleNmd10HAyarfbW1x36AOEZC8xIfmHkUxrjrzS42MXA6AGaXIq0SzaELFhybLRq qWiw== X-Forwarded-Encrypted: i=1; AJvYcCX5QqZznggirBxJwxkpaH1KtJX60dmno06zlDrGbHNkZLE9G1wcm+v1yNuzhYbcCn24g0QPvrtTHA==@kvack.org X-Gm-Message-State: AOJu0YyO6TcRRASIwihy+EHvdKHzV2Cw629RF/rCRu79m5QO0F+ZL/he mtM0sIb1/Y44U/PzQYoFnjI7p18q268WrCLT5IBTN9Q/wpUmbamvHIEuJnmoj6H3Yafj4eU62Sq LKY/j3ilqvg== X-Google-Smtp-Source: AGHT+IFgzCZS8e4eXhzZ0Xu7b9rwIWCAcRNX6T6m7WXpW/BUkn6CvzEZFi5nDx4xFkLSY1Sid/xnIUacfnELow== X-Received: from wmqd6.prod.google.com ([2002:a05:600c:34c6:b0:439:98eb:28cd]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:b9b:b0:439:8ef6:5782 with SMTP id 5b1f17b1804b1-439ae1e8be4mr121933775e9.10.1740408449496; Mon, 24 Feb 2025 06:47:29 -0800 (PST) Date: Mon, 24 Feb 2025 14:47:11 +0000 In-Reply-To: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> Mime-Version: 1.0 References: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> X-Mailer: b4 0.15-dev Message-ID: <20250224-page-alloc-kunit-v1-1-d337bb440889@google.com> Subject: [PATCH RFC 1/4] kunit: Allocate assertion data with GFP_ATOMIC From: Brendan Jackman To: Brendan Higgins , David Gow , Rae Moar , Andrew Morton , David Hildenbrand , Oscar Salvador Cc: Lorenzo Stoakes , Vlastimil Babka , Michal Hocko , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Brendan Jackman , Yosry Ahmed X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: BE70E180013 X-Stat-Signature: uaf79wiyszfjwn5dr6jtsg35hn5i79tg X-Rspam-User: X-HE-Tag: 1740408450-34550 X-HE-Meta: U2FsdGVkX19IABe2/q88b64K8FtwyqOrnrdhzrmunmDoJjCh24NISg3Y/JEjTfXmVsTpu0cbnYcy6omTMpdkzW0/MLdB1TcEHiP7/KseDCK7S3cpnlNljA+tq4u1FxBXlC/Zs986ALE71NsXsLC2GESGv0+7V5q26Dhb03KaQrqfWrL6ZkORMW6p+5gDedCIRO47q49CPrSn0+wtB5TS2BmzNm+kY1fmK//xEPI7T6ZSx9SVOivQORcPxf9pM+mjY7/2Pq26SAuJQmellWCHGSJunQH50yOQrE7oVSTg9ib0wDdDWFogoNAy/8L2f+lSDIB0GifPzj92TOSOycuHjmszOdNio68uZwLazv6xcK4+6JUm2NsrRzGBHYj9hJCSWta8jlVDOWSqAnMD1ADnf/OEgCR3DvmxKCCrfXj5KvFLajYryKoIhPrcLfoCXsjW9XwS0V7yLtyJfdk9jwteuqolcXSZV6/WZqu+6e2SEfxKr1fQuLLi1cJp9XMXWgiBv00cxBFArNpfJ1Mt6DYdWRLkvPPhN1nnK2kTNfFxzjQUGN89u79FXkBXCfkdNWycQg4Rp+kp+wsyXEosAQS8pJlQRW6gU9V3gU8L9ZwAwveYWb5U3aGFk4QRmSLG9P+GU4BH58HSnpAL+Ms6PRB3td/ffYQbmM5+5m3II3gBF0pAaoR4j1uTjjsqKXGKN3VWXtr8KwC9IuoO9APsNYGuw6Wq5Y8Qc2CKnXDSVqNVx3wWBeXr17J5LA6e86WI7EMtOaN8SyyXQBxswEbXQCejHPzY3MkdYKTZuwIdDpbPibmwXoNUVYUt1PA4gBmNrg7jgcXJG4RootPe0hvOtisZkKAM5XwChUIlTGoi/FUy0njYujnrF6uu0tggOz8vMzM9YwtlfQmOqhDM5zyoRWUSXxT3oQ3kciH1T1EL0h7aMRR5TMBfGpjokGeOu7errIuZ8r4fDelg9lhIJecwiiz O6IEwx7l GN97dis+vYwp/My5f20UogL7LmTmIEZqMF0vjE0hxEXglYCAV2Rcljodj2xgycywtYK43d7IUTvzWXwSsdeaZTxDxP1b9emQKUepHEbBFSMnhxtL32Q4WgjP3GCDQwhhTOhrwZD8KmiPSFc0qln16yZX5VqOCavYwJUr0r3vSjlYhg0Q2P1xCIPXy2exXxqM5R5gxtGj2GgZWBt16RwYoxIIgkqIvNz4x1lH5Gz39T0HOP/OTycqFqs0tHmwA8lWlgavIcYwrRFNGB+mqwsPxDb1sLRrE23Lu6A8/G32C4z6/o0Nn1sHh6I9RfUxUTni+EiHYEAVOXSSt/yvow3Dy429l2pCgwzEZULNuD4D8hiQN5MecHIzF+GUUejPp4iEQjJrSOojiGgIqKKfmjcY6MEg0eCRKfob9gFNK2gx3OuQ0tfsocTzrPyy42dSqhgXscyDfPpdITQIAAo5U0UwpO6dd1+nXMgut/cJwlvLzRBE1WGwGPaUiCF7/TMtDAzC2XMFIMVriAM7/QKkxejM+Ztap8TkcsqlWUd6B/x6iiqNA/JOvkddn+jjGJMe/GfSiBqPh7A0IAy6RZJqNSwyDqw3bPLxzSYFDPUPVwyB1jbq0Sms= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000054, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: At present KUnit doesn't handle assertions happening in atomic contexts. A later commit will add tests that make assertions with spinlocks held. In preparation, switch to GFP_ATOMIC. "Just use GFP_ATOMIC" is not generally a solution to this kind of problem: since it uses up memory reserves, instead it should be only used when truly needed. However, for test code that should not be expected to run in production systems it seems tolerable, given that it avoids creating more complex APIs. Signed-off-by: Brendan Jackman --- lib/kunit/assert.c | 2 +- lib/kunit/resource.c | 2 +- lib/kunit/test.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c index 867aa5c4bccf764757e190948b8e3a2439116786..f08656c5fb247b510c4215445cc307ed1205a96c 100644 --- a/lib/kunit/assert.c +++ b/lib/kunit/assert.c @@ -101,7 +101,7 @@ VISIBLE_IF_KUNIT bool is_literal(const char *text, long long value) if (strlen(text) != len) return false; - buffer = kmalloc(len+1, GFP_KERNEL); + buffer = kmalloc(len+1, GFP_ATOMIC); if (!buffer) return false; diff --git a/lib/kunit/resource.c b/lib/kunit/resource.c index f0209252b179f8b48d47ecc244c468ed80e23bdc..eac511af4f8d7843d58c4e3976c77a9c4def86a7 100644 --- a/lib/kunit/resource.c +++ b/lib/kunit/resource.c @@ -98,7 +98,7 @@ int kunit_add_action(struct kunit *test, void (*action)(void *), void *ctx) KUNIT_ASSERT_NOT_NULL_MSG(test, action, "Tried to action a NULL function!"); - action_ctx = kzalloc(sizeof(*action_ctx), GFP_KERNEL); + action_ctx = kzalloc(sizeof(*action_ctx), GFP_ATOMIC); if (!action_ctx) return -ENOMEM; diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 146d1b48a0965e8aaddb6162928f408bbb542645..08d0ff51bd85845a08b40cd3933dd588bd10bddf 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -279,7 +279,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, kunit_set_failure(test); - stream = kunit_alloc_string_stream(test, GFP_KERNEL); + stream = kunit_alloc_string_stream(test, GFP_ATOMIC); if (IS_ERR(stream)) { WARN(true, "Could not allocate stream to print failed assertion in %s:%d\n", From patchwork Mon Feb 24 14:47:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Jackman X-Patchwork-Id: 13988327 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 056AAC021A4 for ; Mon, 24 Feb 2025 14:47:36 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 705196B00A1; Mon, 24 Feb 2025 09:47:35 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 68D8D6B00A3; Mon, 24 Feb 2025 09:47:35 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 52DBD6B00A2; Mon, 24 Feb 2025 09:47:35 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 2F2366B00A0 for ; Mon, 24 Feb 2025 09:47:35 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id E0F7C1612E6 for ; Mon, 24 Feb 2025 14:47:34 +0000 (UTC) X-FDA: 83155116828.13.F2666AE Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf14.hostedemail.com (Postfix) with ESMTP id A9D32100012 for ; Mon, 24 Feb 2025 14:47:32 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=nZfZc38x; spf=pass (imf14.hostedemail.com: domain of 3g4a8ZwgKCMYvmowymzns00sxq.o0yxuz69-yyw7mow.03s@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3g4a8ZwgKCMYvmowymzns00sxq.o0yxuz69-yyw7mow.03s@flex--jackmanb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740408452; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=GCHGbSH5u71x3rPQwLU8VHf0HNWJtt0XTaDImu1fyhU=; b=lcX93/P9DsJxDhNHWGeIRCFKTDvYD08o1gdnzCWTu9OKU2k+FwmC5qaEc3/XvtjhEWlmQy 1paQd0ArGLpi/pzINcWmCXxdaz8y2Axt9fhU47nqGDyLW/xfHMg8nI/Wvd0RCs+CD0/ErM WzwJcq7Sf3u5BNkCQbRXoMAY26+2EFI= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=nZfZc38x; spf=pass (imf14.hostedemail.com: domain of 3g4a8ZwgKCMYvmowymzns00sxq.o0yxuz69-yyw7mow.03s@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3g4a8ZwgKCMYvmowymzns00sxq.o0yxuz69-yyw7mow.03s@flex--jackmanb.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740408452; a=rsa-sha256; cv=none; b=2Y6yOV3kakW+zVKkDDnfRRkE/RUysQrJCXBh084SAaNTjnJ95pvGa0DttAuLXf6EqCR51q E7YThGWXBFB2kNUdr5wEuCoktnJFs8wVc0MMOJH9dHRECzuGJuLofO48174h6Xsmr63AF+ ONyzF1L2MJfHfUE8wY17/8lkR1trtW0= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43943bd1409so31780265e9.3 for ; Mon, 24 Feb 2025 06:47:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1740408451; x=1741013251; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=GCHGbSH5u71x3rPQwLU8VHf0HNWJtt0XTaDImu1fyhU=; b=nZfZc38xzhuKn8r3Av95h757GURuPj7tIYAaCJ8n9T4EQWcA3GlPSUTernW1FX+DQH rJmuBQJEOViYIuvCl3G6eROsp/XZg3lvkAwwB7PzdeWNIpNYYZJE0fq2a+eMan4dFESJ rRVccpeEzeStqcIpdMKpDxja7UZyuIhEKm9/kCGJg98qKe7M4xh8eF2aJaLyxHQLyIim hYn5mkvIyKlF5uKINzDekewzK/xWvLm3lMXXyRRqHTD8Lv9nKTaVgqbGDuRmWanSIoV3 bQgB1xoNf3BGO8PYcjz+2pX7PGOpuAXGln1oqwG/dALdWxjb9BedFsZHWE62rESY0lzF a8fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740408451; x=1741013251; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GCHGbSH5u71x3rPQwLU8VHf0HNWJtt0XTaDImu1fyhU=; b=IzOnAC8NNsDXkGX/IkBH2HUGf9Mgh2REzzRMkNZdur7zTfwJvmWv2jYkEGIescJQg3 fxBO+FDUHUGeZO7reqaKa9K/hXVwt5Wf0VGTgcOQM0dxtyDoTQ2u7d7YQCztZ4idHOMK wR1T31W4Z65tR/9R+uhsdZ1XI3482G0e0UUiwu7ITijRE6z8kQuRFVSFEGL0KBdrLnhL wc/pYPsP8r9eayj9UNxMclECWCK7PM/aX+taL3l1+c25PeHQvXmsUtc6Z1pOr1TlxlpN 74kZl6xh05JICTWCVYz26J92Q6wrdvnai1AX8UkPYF/mvEIfj4W1n3jFHkfca8hQj5Zf WmOA== X-Forwarded-Encrypted: i=1; AJvYcCVC2mv0l6ynWLV2oI4IYJrcNEY6LbxKfk86n/je3vfFu3TD5bbo7lduWYfEKbwY+bO8pF8jniysOw==@kvack.org X-Gm-Message-State: AOJu0YxTwjNo90rh/9dg5nMlLLvFiXiOI1vXVUNvT54dQsL2IHgSnWXk rfr1vubiOH5IEQyE0+fDFk3MmPhvO5P6zFcahSIurF22yu6nmR2W3Ks0SZZ8sgXr7JVattNEaCd +BNFvCYWHeA== X-Google-Smtp-Source: AGHT+IFwIHbdkreZNxpIcvirfoEEWXDLZ8e9Qs1I57U8z8tdFzGqrcazUy7/EH9Qq/dKoOv0alrn0GIwiDqq/Q== X-Received: from wmrn16.prod.google.com ([2002:a05:600c:5010:b0:439:846f:f9c8]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4fd3:b0:439:9543:9488 with SMTP id 5b1f17b1804b1-439ae2196a6mr90807405e9.21.1740408451368; Mon, 24 Feb 2025 06:47:31 -0800 (PST) Date: Mon, 24 Feb 2025 14:47:12 +0000 In-Reply-To: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> Mime-Version: 1.0 References: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> X-Mailer: b4 0.15-dev Message-ID: <20250224-page-alloc-kunit-v1-2-d337bb440889@google.com> Subject: [PATCH RFC 2/4] mm/page_alloc_test: Add empty KUnit boilerplate From: Brendan Jackman To: Brendan Higgins , David Gow , Rae Moar , Andrew Morton , David Hildenbrand , Oscar Salvador Cc: Lorenzo Stoakes , Vlastimil Babka , Michal Hocko , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Brendan Jackman , Yosry Ahmed X-Rspam-User: X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: A9D32100012 X-Stat-Signature: jqeoxa8fqub86tsy4zr56joj666t8sxg X-HE-Tag: 1740408452-815493 X-HE-Meta: U2FsdGVkX18Hk5+nAR6hImNcbC/vLjiPnF4FJ6EsiAZqWhrOwciBsSDlLqT43AIFI2JWgPGqV7Upva6aHgYHnoywccrW/l79q2DFBizbOQY86HnnLO3V1Fx0OgkSv8T5TnCj8ufu9TD7tZnlW0CRQG1SCFCqg/AFu0N5qIonn6inBByN/OGo5NfBhqd3OgijtLR0xe6Dxs9N1F4QA3niyWiboC+NxksBu0j3uhrGHfDO7Bt1hn7M75fAF1PvVK1lyO2y6JdxO5J62B5Y8B9LHxgOzKOQoSsBvT2TexUiIvZiS/jqoKxLGDPDBC8CVAcrWNGS+8XGp8PTL25+WBuj1aQIK4RpYhQicLIaTYMSku+xF90dQCcYgYFaGY5CITDNT15Yus6puUiDY+d2JaSrPHCW8W3fW6X2jW1twKyY9DqwJAlT5mpgC+Tl2rjl0Hn/f4fejusfTjfXz7MrEpcY92ixRxP3kVP/PvK18BAGXsFMbseMdXOjv+vQcrvUpRZ6qCv1FDIb8fmpU4DE99gOWmAWYQfXiUARU3yjMd+M4AqHnHbs9dyMtZaXOPuWeVhUIS7pka7aSNRnr/Y1x0i+OcQd5Yv8qjMLRi3okKpNRrbDvjbrmW57OCH8wKWgH8kXwYu+jVtEQu1zxfxxVf50zfpW8H+51SOHT4HElhNfAqxHjtJAXgid+zgrNfVy6kSn2wQO4w//jKAXzo7/MWzi97s1vORyvZLOBk9d+EjIj0fTHLNo6TBsAF7VlOyIpiHqEOmOe+f9Q2bUbnLsDARWWKCZWBL03NaXJJhBpDRN3Wb2E/AvctOAa6bgOgHpNkHrT5XLQArDVESSMdGBhw0GuGHFxFdoHKDa7ZQdp79VvOP7ZDSoFGPr75f63F/zdVr8q+anNNwP4Po95Nqe9v5x0sHbS7D0XDuBRgLbV/Krt2SllmBghu69AHZ3syyxWNKBmCGu0u8AvZkhXQlwQdc MuxMhOvs bnJK5uZvY2cq8mEGOGAW1xAo3qym3hfniyZuRGfSDQ90bMb3q1da7UzXyPM+9PTqMTW/zNBeW4Fage/gBtGT+5eXAmrlbwcEtHSHUdQRZdN2jnIOEmFj4nzPjN//w0yAJppllZWgm/BM5HxHephPcNW9CJjrI0/vrP9LCojKTCVi29xJb3t83+vpJfY5RNOIYoWcaW1HbzTlteAXTk/gSVhA1y3CpYzGHAgbsHsSf8Wx0BASs5lgXJdEoiei+ON2xNttLD8caIq10XZR50e8eXUZd6VuaV7MMKCKMmltp5vO4mLWgbjolmRd+1OYRIOOep16TrcairZvJTBBwPSF+gTAUMk7RlHhHwZRn4OznHQEEHUWk6nYAG+uCGs+r0VIidIDATvAfJg1VBmvSpSVLBxxvJx451ZFtPQTYePHO5j6xxeIb8jq7lBQOJXhOUONyDhmdu9Vip0TWSSuFFhbQ7yhnNB3RBeegA7jIRR0KIvjvw8i7heJAZS2lFp7hUppWpIpDy+9TZeeA6yLvf0HJMk7M4SCYPnGbGhZVKkn49kI8GLtVFwSFLVeJ+THGSgJxr1NUbcT9eHq/oVJUEKFG1o6nPamWuWCbwHxTn+MR+C3S6v2Qadaz5YjCfX4OniUKZnIA+SU/e0J9JLc= X-Bogosity: Ham, tests=bogofilter, spamicity=0.040364, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add the Kbuild plumbing to create a new KUnit suite. Create the suite, with no tests inside it. Signed-off-by: Brendan Jackman --- mm/.kunitconfig | 2 ++ mm/Kconfig | 8 ++++++++ mm/Makefile | 2 ++ mm/page_alloc_test.c | 21 +++++++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/mm/.kunitconfig b/mm/.kunitconfig new file mode 100644 index 0000000000000000000000000000000000000000..fcc28557fa1c1412b21f9dbddbf6a63adca6f2b4 --- /dev/null +++ b/mm/.kunitconfig @@ -0,0 +1,2 @@ +CONFIG_KUNIT=y +CONFIG_PAGE_ALLOC_KUNIT_TEST=y \ No newline at end of file diff --git a/mm/Kconfig b/mm/Kconfig index 1b501db064172cf54f1b1259893dfba676473c56..1fac51c536c66243a1321195a78eb40668386158 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1358,6 +1358,14 @@ config PT_RECLAIM Note: now only empty user PTE page table pages will be reclaimed. +config PAGE_ALLOC_KUNIT_TEST + tristate "KUnit test for page allocator" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Builds unit tests for page allocator. + + If unsure, say N. source "mm/damon/Kconfig" diff --git a/mm/Makefile b/mm/Makefile index 850386a67b3e0e3b543b27691a6512c448815697..7b8018e0e6510881fac6e4295fdd1472e38d743d 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -61,6 +61,8 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ page-alloc-y := page_alloc.o page-alloc-$(CONFIG_SHUFFLE_PAGE_ALLOCATOR) += shuffle.o +obj-$(CONFIG_PAGE_ALLOC_KUNIT_TEST) += page_alloc_test.o + # Give 'memory_hotplug' its own module-parameter namespace memory-hotplug-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o diff --git a/mm/page_alloc_test.c b/mm/page_alloc_test.c new file mode 100644 index 0000000000000000000000000000000000000000..377dfdd50a3c6928e15210cc87d5399c1db80da7 --- /dev/null +++ b/mm/page_alloc_test.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct kunit_case test_cases[] = { {} }; + +static struct kunit_suite test_suite = { + .name = "page_alloc", + .test_cases = test_cases, +}; +kunit_test_suite(test_suite); + +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); From patchwork Mon Feb 24 14:47:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Jackman X-Patchwork-Id: 13988328 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 C8E7EC021A4 for ; Mon, 24 Feb 2025 14:47:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2E4306B00A2; Mon, 24 Feb 2025 09:47:37 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 293686B00A3; Mon, 24 Feb 2025 09:47:37 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0E84A6B00A4; Mon, 24 Feb 2025 09:47:36 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id D33BF6B00A2 for ; Mon, 24 Feb 2025 09:47:36 -0500 (EST) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 8962C1203ED for ; Mon, 24 Feb 2025 14:47:36 +0000 (UTC) X-FDA: 83155116912.16.5DDF434 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf02.hostedemail.com (Postfix) with ESMTP id 8505580015 for ; Mon, 24 Feb 2025 14:47:34 +0000 (UTC) Authentication-Results: imf02.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=z3zAATHt; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf02.hostedemail.com: domain of 3hYa8ZwgKCMgxoqy0o1pu22uzs.q20zw18B-00y9oqy.25u@flex--jackmanb.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3hYa8ZwgKCMgxoqy0o1pu22uzs.q20zw18B-00y9oqy.25u@flex--jackmanb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740408454; a=rsa-sha256; cv=none; b=dx51kbeFDsqyIC/6EmdIBNBOXfsyHs/WI+DyzNgRE7BDsWuXsKpW33o3Fng1nzUfSO5UPA F6x5PhApnEI9gAyCEtit72QfJcpGXcuPDxtGLAvz8NBG86MZs7yplmO6KppY/SMTmzNiUW MNvV4UL7yK7xdmP80Uant5Z+r0KC9Po= ARC-Authentication-Results: i=1; imf02.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=z3zAATHt; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf02.hostedemail.com: domain of 3hYa8ZwgKCMgxoqy0o1pu22uzs.q20zw18B-00y9oqy.25u@flex--jackmanb.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3hYa8ZwgKCMgxoqy0o1pu22uzs.q20zw18B-00y9oqy.25u@flex--jackmanb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740408454; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=6sXFXBg+7MhZsXsNbEHU7cZAUpeJWSKspLCJpInfPLA=; b=vgT6hNWloO2W1gwzIJtq40WwN8YM+iPv4009O4FdQwfRMTynxR1mynysoG/uQy0vJtdG4N pa/SyHAuM6trr4Ybwory8v5vGNPlTYY7io84OaV8dB7qN+u0Eh6dlr6ExlpgYJMfo0W2yT ZQM9eCVH+yU7wvaHi7RcwxAfMXWAj9g= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4394b2c19ccso38338785e9.1 for ; Mon, 24 Feb 2025 06:47:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1740408453; x=1741013253; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6sXFXBg+7MhZsXsNbEHU7cZAUpeJWSKspLCJpInfPLA=; b=z3zAATHtQM3Mr4ED5ujMQ7bBhLRaGg/XTARmnnM/ElfVsKi7vSfmAW2gjeceIhMuQj ILUFlHw3ZCaR6vjliB7tmD2tUmECMkS8m2FyLWalA2s3ZAguwMxy2Oo4gvW+eOs+d1IN jVipilBcbKsGdO2FnR02M075qb9MQ62PvOsHrHRizdLYUBDS0pP+0B0uxPE3l2Aaz+F1 Ig8cbikPKtFcmRlAZb7u/Reie6HyBrKMsozabUnPWKcKPBREJ3ez+lKOxmn4EfFyxDI7 TOvv5ogoDjOm6dd3Z8M/jqf0UdxgB3QRLsXTceGIrEgnu8Kio9Z2v5y8g3qE6VkjDJL3 zgow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740408453; x=1741013253; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6sXFXBg+7MhZsXsNbEHU7cZAUpeJWSKspLCJpInfPLA=; b=bW75qsw7tPHBzsyH3UGSlEiJA/c0yUEre0ebISuy+9u7xKSNOJAYIysXQLbRAx93Wc PmyMDbjEoOTgqYIK6APWGuI6NisAVuHafDN16tsgbKVNQN5U1qkbKonu/NeOY20daceo AKSFi/uzo6PuPfugfClHjfKbKchQVsybmxRhI8aaYVHY6f/UDo6Bc39p+QiwW3XDtUXX Jnh/Evh2ZQS25p+Jhcc00e4N3M70K9KcnxrihzwT7yStaNNNUnTmSuqIF2Iy0Pkeg3N/ Arcu/QG3u2MyVjyV/ctPy5k6VeGHvpjlH185DKnQG3CkpDkKZC99dSbiYUu8wTpB12pT nZig== X-Forwarded-Encrypted: i=1; AJvYcCVh9I3u/px+YLSrPNspEdx8tb0jgLquviHjjObkuf1zpaxqA89h8LUS2RhPcnNiA3zOd3dOdF9EtQ==@kvack.org X-Gm-Message-State: AOJu0Ywe6fB4KNGYUYOuW1nt6fHtRIM1e7roy6S6vALwl/k1BDOZzVoz repejv+woHX8irz1IoKuToQgkkxHXcCEhHjTdNTbz4m5ZQVc3Lt34XFokhSVxvOfnHScLooi7Av bjjjoXlGMvw== X-Google-Smtp-Source: AGHT+IHO7N6qYrH/BUokoWLhGYhgqcjpGiqKJ3qIp+kO3mhMur74Ev86E0j6gIXIm+MPWKLOpxpEcFg/elTSuA== X-Received: from wmpz20.prod.google.com ([2002:a05:600c:a14:b0:439:7ebc:1bdd]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1d21:b0:439:9b39:b31 with SMTP id 5b1f17b1804b1-439b411c2bcmr91798975e9.8.1740408453303; Mon, 24 Feb 2025 06:47:33 -0800 (PST) Date: Mon, 24 Feb 2025 14:47:13 +0000 In-Reply-To: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> Mime-Version: 1.0 References: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> X-Mailer: b4 0.15-dev Message-ID: <20250224-page-alloc-kunit-v1-3-d337bb440889@google.com> Subject: [PATCH RFC 3/4] mm/page_alloc_test: Add logic to isolate a node for testing From: Brendan Jackman To: Brendan Higgins , David Gow , Rae Moar , Andrew Morton , David Hildenbrand , Oscar Salvador Cc: Lorenzo Stoakes , Vlastimil Babka , Michal Hocko , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Brendan Jackman , Yosry Ahmed X-Rspam-User: X-Rspamd-Queue-Id: 8505580015 X-Rspamd-Server: rspam12 X-Stat-Signature: 5wdt6c9nkyfgqr6kncg797eoeyjtpxqf X-HE-Tag: 1740408454-220508 X-HE-Meta: U2FsdGVkX19FJN4P/mD0ITGCbRiq+G+4vLfJpPMWrGsneXgxycKCMaODT/3maQAA5+ZBAH9FHqAEsVmDJZRggCxnaaZaXVNaT6K1Uim6U1PD+StJ84xXfBdtpnV2+9wGEEzmqi6FWiqJ36s+2PIgXODUfQ/9rsoPMvSCk3DrVOFHnl7y38LhBgZxOZFipFyj3r935DIN6zz/xgmMiyrz6V+rtdFuYYgP5uRBvCPiD5FISqK9cFV+ncRBUIKKuHHpoKXm3r07yy6rcOP941SxjCPh7vpxZ4Cb/RnkBZ2iZBIOB2kpN6DGJer6AGcYDcwS90hv6AmaoCwwFQBUQnS5chrHBRmYoM4qEGcKO9gWjBg71ewa9xfEDHoy5aJ2y4dgtRUkRwl3Q9N101v4nFInNxAfsj+T7monRu5FqThcJ3wNteULwIh5OIbYZkjlKQdsoHSPADs5l08JujCve9jDl6wozp8hOEfa5c2yEYw83pWy9B/OjSyWxi1YEADAnK+K4+81IhMlKGSfZzKG0ot+cQsDYD6SoRcy+IX7szIdp/Y2FlEVKbk1p70iChNHbbBJnB074LkThmSIPScFRLeuiSCkUNLHQ/WPCJXsH6v5Ti7cQSy+CRx9G7ExFJl7UhJsdNihSFQQmwmYX4q/GJWa3c7F1+IZ3aNjI+Uvp8k4eHP5A2Gt+886pAWrgNc580GVvpDlA1deW/fSQQphpxNJTvpg6a1JUDGSO6KJiSKTWlieI0qGNlxcEEOQN8esvyj0o8PxtwJ3TBzbkqwXju71Tgg1K/Ktjhe6oV1qATAXVpu6tsBVMZCteqYdBu/RhWHHyy5wCuNanOO4YrCHJUoU7AXSYKi09dIJa6ev9yZIaaiRTFQqaQs3GZ2MP99FzTONEy0rDkRTt8d6Lkx9l6Rv8QFEhW+fwWrSXViSxAcuvD67LfTlcF8Yu4jf4+I90AgxoCYDWoJIAF1CkYL2Tg1 KzDAzAv5 zZexos+oEq6Xq0LOcb/e+4k/End84/C6bH3t866E36uaUWo0pK/9RO4WzL5NPqOcamyR3XDdWgAJBH6hljzc8cHhU6SwCLoXh++CgEf/KU9GFUEvSj7jbc9iTt9uWXds3GCs/uUbzYKWhFpUX2uFrbgs2w2EcxcPNtJ6yfDh21hPFT1cZe014voziJrwhEKOrWhLyteI+S0jQxRhisznRZIENqtItbCWuuDDWsUqB8atFuCb90qaS5SdMmPhUg2zwQWW/+5Sz07sJd/0lPQzYDXkJdRJhrA9/dLaQXLcXPPFOUOZVdP6WbjJ+Wbag877oH/ffUS5DkaPdNCD7GO+K7bOanPwfX3WYLOvsLstzIe8N9HM3rAUVChhMHuzNqopQs6az+H+pm2EFNhwcK+QXz0bINLUvykrEQWOV/q378bTCwwvoYMoiDyH45aRDTSsrV0OZUu+7BeBXQ2JRLcgB5rQYBJ0t+9G9i/4GFKbp4Vxxmg+rZ/LeSmNUpIRTyTsDnZNNXlemGW7ixgOGcyznDsYp1N8VWAfxWGyS4oZvU6mxTHyPi1DJ5aTpxk3S37ihdNWS96JXaPGTvDgeAYOF+mvjYzir187q0ZihdgF5zS3Bv60= 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: In order to test the page allocator, we need an "instance" of the page allocator that is not subject to unpredictable perturbation by the live system. The closest thing that we have to an "instance" of the allocator is a NUMA node. So, introduce a new concept of an "isolated" node. This is an extension of the existing concept of a "fake" node, with the addition that nothing else in the system will touch it unless instructed to by the test code. The node is created during boot but has no memory nor any CPUs attached. It is not on any other node's fallback lists. Any code that pays general attention to NODE_DATA in such a way that might cause the page allocator data structures to be modified asynchronously to the test, is enlightened to ignore it via the node_isolated() helper. Then, during initialization of the allocator test suite, hotplug out some memory and then plug it back in to the isolated node. The node can then be used for testing. Because it's easy to miss code that needs enlightenment, which can lead to confusing test behaviour, also add some defensive checks to try and interference with the isolated node before the start of the test. Signed-off-by: Brendan Jackman --- drivers/base/memory.c | 5 +- include/linux/memory.h | 4 ++ include/linux/nodemask.h | 13 +++++ kernel/kthread.c | 3 + mm/.kunitconfig | 10 +++- mm/Kconfig | 2 +- mm/internal.h | 11 ++++ mm/memory_hotplug.c | 26 ++++++--- mm/numa_memblks.c | 22 ++++++++ mm/page_alloc.c | 37 +++++++++++- mm/page_alloc_test.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 260 insertions(+), 15 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 348c5dbbfa68ad30d34b344ace1dd8deac0e1947..cdb893d7f13324862ee0943df080440d19fbd957 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -26,6 +26,8 @@ #include #include +#include + #define MEMORY_CLASS_NAME "memory" static const char *const online_type_to_str[] = { @@ -183,7 +185,7 @@ static inline unsigned long memblk_nr_poison(struct memory_block *mem) /* * Must acquire mem_hotplug_lock in write mode. */ -static int memory_block_online(struct memory_block *mem) +VISIBLE_IF_KUNIT int memory_block_online(struct memory_block *mem) { unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; @@ -250,6 +252,7 @@ static int memory_block_online(struct memory_block *mem) mem_hotplug_done(); return ret; } +EXPORT_SYMBOL_IF_KUNIT(memory_block_online); /* * Must acquire mem_hotplug_lock in write mode. diff --git a/include/linux/memory.h b/include/linux/memory.h index c0afee5d126ef65d420770e1f8669842c499c8de..99139a6e9c11a407a8d7bfb17b7bbe3d276048ff 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -177,6 +177,10 @@ int walk_dynamic_memory_groups(int nid, walk_memory_groups_func_t func, register_memory_notifier(&fn##_mem_nb); \ }) +#ifdef CONFIG_KUNIT +int memory_block_online(struct memory_block *mem); +#endif + #ifdef CONFIG_NUMA void memory_block_add_nid(struct memory_block *mem, int nid, enum meminit_context context); diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 9fd7a0ce9c1a7336df46f12622867e6786a5c0a9..6ea38963487e1fbb800eab69e5e6413aa17a8047 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -536,6 +536,19 @@ static __always_inline int node_random(const nodemask_t *maskp) #define for_each_node(node) for_each_node_state(node, N_POSSIBLE) #define for_each_online_node(node) for_each_node_state(node, N_ONLINE) + +#ifdef CONFIG_PAGE_ALLOC_KUNIT_TEST +/* + * An isolated node is a fake node for testing, that boots with no memory and no + * attached CPUs, and nothing should touch it except for test code. + */ +extern bool node_isolated(int node); +/* Only one isolated node is supported at present and it cannot be un-isolated. */ +extern void node_set_isolated(int node); +#else +static inline bool node_isolated(int node) { return false; } +#endif /* CONFIG_PAGE_ALLOC_KUNIT_TEST */ + /* * For nodemask scratch area. * NODEMASK_ALLOC(type, name) allocates an object with a specified type and diff --git a/kernel/kthread.c b/kernel/kthread.c index 5dc5b0d7238e85ad4074076e4036062c7bfcae74..93f65c5935cba8a59c7d3df2e36335130c3e1f71 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -511,6 +512,8 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), struct kthread_create_info *create = kmalloc(sizeof(*create), GFP_KERNEL); + VM_WARN_ON(node != NUMA_NO_NODE && node_isolated(node)); + if (!create) return ERR_PTR(-ENOMEM); create->threadfn = threadfn; diff --git a/mm/.kunitconfig b/mm/.kunitconfig index fcc28557fa1c1412b21f9dbddbf6a63adca6f2b4..4ff4e1654c3e9b364072d33bfffb3a2336825859 100644 --- a/mm/.kunitconfig +++ b/mm/.kunitconfig @@ -1,2 +1,10 @@ CONFIG_KUNIT=y -CONFIG_PAGE_ALLOC_KUNIT_TEST=y \ No newline at end of file +CONFIG_PAGE_ALLOC_KUNIT_TEST=y + +# Required for NUMA +CONFIG_SMP=y +# Used by tests to carve out fake node for isolating page_alloc data. +CONFIG_NUMA=y +CONFIG_NUMA_EMU=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y \ No newline at end of file diff --git a/mm/Kconfig b/mm/Kconfig index 1fac51c536c66243a1321195a78eb40668386158..64c3794120002a839f56e3feb284c6d5c2635f40 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1360,7 +1360,7 @@ config PT_RECLAIM config PAGE_ALLOC_KUNIT_TEST tristate "KUnit test for page allocator" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && NUMA && MEMORY_HOTREMOVE default KUNIT_ALL_TESTS help Builds unit tests for page allocator. diff --git a/mm/internal.h b/mm/internal.h index 109ef30fee11f8b399f6bac42eab078cd51e01a5..9dbe5853b90b53ff261ba1b2fca12eabfda1a9de 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1545,5 +1545,16 @@ static inline bool reclaim_pt_is_enabled(unsigned long start, unsigned long end, } #endif /* CONFIG_PT_RECLAIM */ +#ifdef CONFIG_PAGE_ALLOC_KUNIT_TEST +/* + * Note that node_isolated() is separate, that's a "public API". But only + * test code needs to look up which node is isolated. + */ +extern int isolated_node; +#endif + +#ifdef CONFIG_KUNIT +void drain_pages(unsigned int cpu); +#endif #endif /* __MM_INTERNAL_H */ diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index e3655f07dd6e33efb3e811cab07f240649487441..968c23b6f347cf6a0c30d00cb556166b8df9c9c3 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1198,10 +1198,12 @@ int online_pages(unsigned long pfn, unsigned long nr_pages, arg.nr_pages = nr_pages; node_states_check_changes_online(nr_pages, zone, &arg); - ret = memory_notify(MEM_GOING_ONLINE, &arg); - ret = notifier_to_errno(ret); - if (ret) - goto failed_addition; + if (!node_isolated(nid)) { + ret = memory_notify(MEM_GOING_ONLINE, &arg); + ret = notifier_to_errno(ret); + if (ret) + goto failed_addition; + } /* * Fixup the number of isolated pageblocks before marking the sections @@ -1242,19 +1244,27 @@ int online_pages(unsigned long pfn, unsigned long nr_pages, /* reinitialise watermarks and update pcp limits */ init_per_zone_wmark_min(); - kswapd_run(nid); - kcompactd_run(nid); + /* + * Don't run daemons on the special test node, if that needs to be + * tested the test should run it. + */ + if (!node_isolated(nid)) { + kswapd_run(nid); + kcompactd_run(nid); + } writeback_set_ratelimit(); - memory_notify(MEM_ONLINE, &arg); + if (!node_isolated(nid)) + memory_notify(MEM_ONLINE, &arg); return 0; failed_addition: pr_debug("online_pages [mem %#010llx-%#010llx] failed\n", (unsigned long long) pfn << PAGE_SHIFT, (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); - memory_notify(MEM_CANCEL_ONLINE, &arg); + if (!node_isolated(nid)) + memory_notify(MEM_CANCEL_ONLINE, &arg); remove_pfn_range_from_zone(zone, pfn, nr_pages); return ret; } diff --git a/mm/numa_memblks.c b/mm/numa_memblks.c index ff4054f4334dae42ee3b3668da18bba01dc3cd8b..190c879af2c779df1be448c45c43b0570bb6c308 100644 --- a/mm/numa_memblks.c +++ b/mm/numa_memblks.c @@ -7,6 +7,8 @@ #include #include +#include "internal.h" + int numa_distance_cnt; static u8 *numa_distance; @@ -371,6 +373,24 @@ static void __init numa_clear_kernel_node_hotplug(void) } } +#ifdef CONFIG_PAGE_ALLOC_KUNIT_TEST +static inline void make_isolated_node(void) +{ + int node; + + node = num_possible_nodes(); + if (!numa_valid_node(node)) { + pr_err("All node IDs used, can't fake another.\n"); + } else { + node_set(num_possible_nodes(), node_possible_map); + node_set_isolated(node); + } +} +#else +static inline void make_isolated_node(void) { } +#endif + + static int __init numa_register_meminfo(struct numa_meminfo *mi) { int i; @@ -381,6 +401,8 @@ static int __init numa_register_meminfo(struct numa_meminfo *mi) if (WARN_ON(nodes_empty(node_possible_map))) return -EINVAL; + make_isolated_node(); + for (i = 0; i < mi->nr_blks; i++) { struct numa_memblk *mb = &mi->blk[i]; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 579789600a3c7bfb7b0d847d51af702a9d4b139a..9472da738119589150db26126dfcf808e2dc9371 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -56,6 +56,7 @@ #include #include #include +#include #include "internal.h" #include "shuffle.h" #include "page_reporting.h" @@ -291,6 +292,26 @@ static bool __free_unaccepted(struct page *page); int page_group_by_mobility_disabled __read_mostly; +/* + * Test harness for KUnit - pick a node that we will never allocate from, except + * for in the page allocator tests. + */ +#ifdef CONFIG_PAGE_ALLOC_KUNIT_TEST +int isolated_node = NUMA_NO_NODE; +EXPORT_SYMBOL(isolated_node); + +void node_set_isolated(int node) +{ + WARN_ON(isolated_node != NUMA_NO_NODE); + isolated_node = node; +} + +bool node_isolated(int node) +{ + return node == isolated_node; +} +#endif /* CONFIG_POAGE_ALLOC_KUNIT_TEST */ + #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT /* * During boot we initialize deferred pages on-demand, as needed, but once @@ -2410,7 +2431,7 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) /* * Drain pcplists of all zones on the indicated processor. */ -static void drain_pages(unsigned int cpu) +VISIBLE_IF_KUNIT void drain_pages(unsigned int cpu) { struct zone *zone; @@ -2418,6 +2439,7 @@ static void drain_pages(unsigned int cpu) drain_pages_zone(cpu, zone); } } +EXPORT_SYMBOL_IF_KUNIT(drain_pages); /* * Spill all of this CPU's per-cpu pages back into the buddy allocator. @@ -5087,6 +5109,8 @@ int find_next_best_node(int node, nodemask_t *used_node_mask) } for_each_node_state(n, N_MEMORY) { + if (node_isolated(n)) + continue; /* Don't want a node to appear more than once */ if (node_isset(n, *used_node_mask)) @@ -5134,8 +5158,17 @@ static void build_zonelists_in_node_order(pg_data_t *pgdat, int *node_order, for (i = 0; i < nr_nodes; i++) { int nr_zones; + int other_nid = node_order[i]; + pg_data_t *node = NODE_DATA(other_nid); - pg_data_t *node = NODE_DATA(node_order[i]); + /* + * Never fall back to the isolated node. The isolated node has + * to be able to fall back to other nodes because that fallback + * is relied on for allocating data structures that describe the + * node. + */ + if (node_isolated(other_nid) && other_nid != pgdat->node_id) + continue; nr_zones = build_zonerefs_node(node, zonerefs); zonerefs += nr_zones; diff --git a/mm/page_alloc_test.c b/mm/page_alloc_test.c index 377dfdd50a3c6928e15210cc87d5399c1db80da7..c6bcfcaf61b57ca35ad1b5fc48fd07d0402843bc 100644 --- a/mm/page_alloc_test.c +++ b/mm/page_alloc_test.c @@ -3,19 +3,157 @@ #include #include #include +#include #include #include #include #include +#include "internal.h" + +#define EXPECT_PCPLIST_EMPTY(test, zone, cpu, pindex) ({ \ + struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); \ + struct page *page; \ + \ + lockdep_assert_held(&pcp->lock); \ + page = list_first_entry_or_null( \ + &pcp->lists[pindex], struct page, pcp_list); \ + \ + if (page) { \ + KUNIT_FAIL(test, "PCPlist %d on CPU %d wasn't empty", i, cpu); \ + dump_page(page, "unexpectedly on pcplist"); \ + } \ +}) + +static void action_drain_pages_all(void *unused) +{ + int cpu; + + for_each_online_cpu(cpu) + drain_pages(cpu); +} + +/* Runs before each test. */ +static int test_init(struct kunit *test) +{ + struct zone *zone_normal; + int cpu; + + if (isolated_node == NUMA_NO_NODE) + kunit_skip(test, "No fake NUMA node ID allocated"); + + zone_normal = &NODE_DATA(isolated_node)->node_zones[ZONE_NORMAL]; + + /* + * Nothing except these tests should be allocating from the fake node so + * the pcplists should be empty. Obviously this is racy but at least it + * can probabilistically detect issues that would otherwise make for + * really confusing test results. + */ + for_each_possible_cpu(cpu) { + struct per_cpu_pages *pcp = per_cpu_ptr(zone_normal->per_cpu_pageset, cpu); + unsigned long flags; + int i; + + spin_lock_irqsave(&pcp->lock, flags); + for (i = 0; i < ARRAY_SIZE(pcp->lists); i++) + EXPECT_PCPLIST_EMPTY(test, zone_normal, cpu, i); + spin_unlock_irqrestore(&pcp->lock, flags); + } + + /* Also ensure we don't leave a mess for the next test. */ + kunit_add_action(test, action_drain_pages_all, NULL); + + return 0; +} + +static int memory_block_online_cb(struct memory_block *mem, void *unused) +{ + return memory_block_online(mem); +} + +struct region { + int node; + unsigned long start; + unsigned long size; +}; + +/* + * Unplug some memory from a "real" node and plug it into the isolated node, for + * use during the tests. + */ +static int populate_isolated_node(struct kunit_suite *suite) +{ + struct zone *zone_movable = &NODE_DATA(0)->node_zones[ZONE_MOVABLE]; + phys_addr_t zone_start = zone_movable->zone_start_pfn << PAGE_SHIFT; + phys_addr_t zone_size = zone_movable->spanned_pages << PAGE_SHIFT; + unsigned long bs = memory_block_size_bytes(); + u64 start = round_up(zone_start, bs); + /* Plug a memory block if we can find it. */ + unsigned long size = round_down(min(zone_size, bs), bs); + int err; + + if (!size) { + pr_err("Couldn't find ZONE_MOVABLE block to offline\n"); + pr_err("Try setting/expanding movablecore=\n"); + return -1; + } + + err = offline_and_remove_memory(start, size); + if (err) { + pr_notice("Couldn't offline PFNs 0x%llx - 0x%llx\n", + start >> PAGE_SHIFT, (start + size) >> PAGE_SHIFT); + return err; + } + err = add_memory(isolated_node, start, size, MMOP_ONLINE); + if (err) { + pr_notice("Couldn't add PFNs 0x%llx - 0x%llx\n", + start >> PAGE_SHIFT, (start + size) >> PAGE_SHIFT); + goto add_and_online_memory; + } + err = walk_memory_blocks(start, size, NULL, memory_block_online_cb); + if (err) { + pr_notice("Couldn't online PFNs 0x%llx - 0x%llx\n", + start >> PAGE_SHIFT, (start + size) >> PAGE_SHIFT); + goto remove_memory; + } + + return 0; + +remove_memory: + if (WARN_ON(remove_memory(start, size))) + return err; +add_and_online_memory: + if (WARN_ON(add_memory(0, start, size, MMOP_ONLINE))) + return err; + WARN_ON(walk_memory_blocks(start, size, NULL, memory_block_online_cb)); + return err; +} + +static void depopulate_isolated_node(struct kunit_suite *suite) +{ + unsigned long start, size = memory_block_size_bytes(); + + if (suite->suite_init_err) + return; + + start = NODE_DATA(isolated_node)->node_start_pfn << PAGE_SHIFT; + + WARN_ON(remove_memory(start, size)); + WARN_ON(add_memory(0, start, size, MMOP_ONLINE)); + WARN_ON(walk_memory_blocks(start, size, NULL, memory_block_online_cb)); +} static struct kunit_case test_cases[] = { {} }; -static struct kunit_suite test_suite = { +struct kunit_suite page_alloc_test_suite = { .name = "page_alloc", .test_cases = test_cases, + .suite_init = populate_isolated_node, + .suite_exit = depopulate_isolated_node, + .init = test_init, }; -kunit_test_suite(test_suite); +kunit_test_suite(page_alloc_test_suite); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); From patchwork Mon Feb 24 14:47:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Jackman X-Patchwork-Id: 13988329 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 02BFCC021BB for ; Mon, 24 Feb 2025 14:47:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0C21C6B00A3; Mon, 24 Feb 2025 09:47:39 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 070886B00A4; Mon, 24 Feb 2025 09:47:38 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D425B6B00A5; Mon, 24 Feb 2025 09:47:38 -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 B56726B00A3 for ; Mon, 24 Feb 2025 09:47:38 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 6BDF6C16E4 for ; Mon, 24 Feb 2025 14:47:38 +0000 (UTC) X-FDA: 83155116996.13.2F689EC Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf20.hostedemail.com (Postfix) with ESMTP id 6DF111C000D for ; Mon, 24 Feb 2025 14:47:36 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=ON60Svna; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of 3h4a8ZwgKCMozqs02q3rw44w1u.s421y3AD-220Bqs0.47w@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3h4a8ZwgKCMozqs02q3rw44w1u.s421y3AD-220Bqs0.47w@flex--jackmanb.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740408456; a=rsa-sha256; cv=none; b=zImI5f3BAqLU39aUg9Dk5mxQDAjsquyPHjG2edk4LFYQlnh9p4dIWWIaOma3VOPOTtxMNG YNHRQJ4JGQ4IdKMKDeWRTDogvnn5axLdHzmJyGp2Q8j8WGgLqBdPvWnkhJ2qwqbx2kvppl EFyLoSMer6pcMdhdgcjx+byfM39vjpE= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=ON60Svna; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf20.hostedemail.com: domain of 3h4a8ZwgKCMozqs02q3rw44w1u.s421y3AD-220Bqs0.47w@flex--jackmanb.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3h4a8ZwgKCMozqs02q3rw44w1u.s421y3AD-220Bqs0.47w@flex--jackmanb.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740408456; 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: in-reply-to:in-reply-to:references:references:dkim-signature; bh=2Fz5NU1PueoQjecq9oG9iR+vgvt/Z95TUw+fwY0nW88=; b=VaRbojDsK6vOgz94FsGUhc6NrNIAldB5bfDCiHb0manU2x4NxWj5PfNhbcivLysea2mtP4 V4UzSkiXsrn0L3/CUjSa74B2/0FT2r3aJQaAeDES5w1XjWBXWZv7mwjXVq7Nr8AwtqDQgB pOJ9/1K3l7LglUzIlNk7OqTG/wdUjPQ= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-438da39bb69so34037715e9.0 for ; Mon, 24 Feb 2025 06:47:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1740408455; x=1741013255; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2Fz5NU1PueoQjecq9oG9iR+vgvt/Z95TUw+fwY0nW88=; b=ON60Svna36JSnR/f6kMrFE/IBNsGMb4VaoqjcEbSAY4YIhciEsKkUlKry0pNnbyhFU wvkGBsiFZRAvO4usVNTc95adqPBZIPuQG3XJJg1Y+z83/L1IgclSJDHGCmhO7Iq19wHz jYqDT8yzUilfsPyh1yY+Xy3RVV2k6cxuNFlgsHWA2HR5GJycxPKjIfWpflk2/NJiPNOl ZOrswqIf1xSl+ETkUFW/0t3Uj06CLIBoAQ8z18HiTmRoiE4Ip08pt/hzI0wo14jNf5B0 NkfBkc/9kLWFWEsKfW9a7dHQIKlcMjuFjAba7T69M5vgivVE+RDI83QxLBCJIOa4jk9S iBBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740408455; x=1741013255; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2Fz5NU1PueoQjecq9oG9iR+vgvt/Z95TUw+fwY0nW88=; b=WPOvwRr7lcvG1b7F+2TFyYOJ1wucZvwgnAPwSbQNBFdd63mb9NDDqIVaZT7S0jzE0H Eh0vhXLuqhcbahISjVFWAUhduU9w6SytdDs4d5naQGqvomnaWmzZYzNNKmsAj+gwfDgn 1uPgbFEZrAgXuQrSAiu8fz4/f33wprx84nDIWgP6hywc11UbkdR4U8b2IRd0Y9TB5Dli sByX5HvVf6qkJuBOXTuZ3tBLKlaIPPB4xN6+lrab2Q6FZ3hwqbV4EeBI7NZiA2B1iueb aa4pTyTSfckl0iA+58gqTHRPRtgHcLkCNtPOHb5v5+UhcFLUydOB4tkhbXzlT3WuCF6O P6IQ== X-Forwarded-Encrypted: i=1; AJvYcCVIKYtohINj+2J7O8Ck8iOd87jGqfc2S4Pa4rsqnjConGpTWDNwH2iN+KG+JOwlm7pOjcSVOTeI+g==@kvack.org X-Gm-Message-State: AOJu0Yyvvnjmv7Y41tA13zqL7FZJ5V3Ey5MQxYOmORc8UQRV59tJ4Zd8 rthYhK/lV3xS78jUM3zgMiEG9Oe5GpoOaBorG/6qGUCn7ktwVS1zrPyANGTL4eUNGILYJifmghA zT1vtnVFIlA== X-Google-Smtp-Source: AGHT+IEAGhOq6ZLG1kWNmTBHOtlzeySJw4C81f6PzEKZO3mD1LQVv/+voZGC5+kCMIWufaPww+gOqaaEPDa8Ww== X-Received: from wmqe19.prod.google.com ([2002:a05:600c:4e53:b0:439:831e:ca7c]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:468f:b0:439:5541:53cc with SMTP id 5b1f17b1804b1-439ae2206d5mr101272755e9.29.1740408455220; Mon, 24 Feb 2025 06:47:35 -0800 (PST) Date: Mon, 24 Feb 2025 14:47:14 +0000 In-Reply-To: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> Mime-Version: 1.0 References: <20250224-page-alloc-kunit-v1-0-d337bb440889@google.com> X-Mailer: b4 0.15-dev Message-ID: <20250224-page-alloc-kunit-v1-4-d337bb440889@google.com> Subject: [PATCH RFC 4/4] mm/page_alloc_test: Add smoke-test for page allocation From: Brendan Jackman To: Brendan Higgins , David Gow , Rae Moar , Andrew Morton , David Hildenbrand , Oscar Salvador Cc: Lorenzo Stoakes , Vlastimil Babka , Michal Hocko , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Brendan Jackman , Yosry Ahmed X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: 6DF111C000D X-Stat-Signature: sh7mm3tmjafyi9r5rpt6zqpsi4yx3stj X-Rspam-User: X-HE-Tag: 1740408456-423300 X-HE-Meta: U2FsdGVkX1/fNlk9HUc66rWbYQHtyF+MX21VZRFMOdAWxwJWjTZ8KCq2c0RaAiIWaps2QodglHAN+CoV0Y6nYWoepDtJi5lQtuj03KiRwoGQ0v0Ncf2A61MwTZrKNAWnDmbrMozdRA/+o0vh1RX4iH9W8FDShwEr+WTmF53OR97N10JOGs5UE6sGJvUtSZ8AkEL1TfmJQRUz114HTKCkGljU56M0Gl7ZIsWzyFaS6u3Z387Cq3se1E6DHsXwx8qSCJ7Pjyg7Ls7ZuFoZ/5VxgJvW0mrDne/0fUz9iyO8oYCmyDJLIqMr+z7uMkWeXAg3fzeGX1L0XpPRG3R5Jn7AK2FhtbffcEtS/o2uC/4Q2AOI+pF5zsey6M7wWnCSVbj0T5ipWXatX4c5KUD40xKvk5qj0OTmtSXIvuEeby92MhCXCZbjBXZx2bxhwZwtNQcyG2uctowCU4/cDICX7oHL7PsA/vYVWY06GcSeXodjNAHkbZMxJHDJ6yH7t2TwRYC163JTQzeKYcdnx396aO9wSzG5DdqNiLk+iiLiEf9VbTi/hvwbcqmg71+uSSY9zGZG6Ejk9VVbi8MuxzYC77KyiuBYwyeMx5tc/R6AWL69DeGv2N0MqriAgCuFh0URKHYACrNnXpq73heuIjLKxdIJg+ZFI/AZBwL7QvMQgUJ4sJEzFsIwVhBm8V0nHuEdSylZMjGZZpyKITKGVMsJGscSGolqURJW59TGXFQ8xAvwdwZtTMwHamZ9hAcZ+JZxSUvASeysZ2SbRxpDeCjNDOwpW8vtlv7IBpGBrO+P3IyyaBpxZqAcZNphg4IJc1xZcHPvXBY6FHmpkjyRExhzDUxsKamizC5vbRvbUYsCgHKTbaHTzKmuIG5nhvfpKpBH0i0I5+x9D5Z0KpWhbsL7ZI6xcWBOGU8dEJ+1NPqPKD5hxdhGZV7YuKsYwlHwHJ4wlDxBGZ2lhf79lFQizPXwBGv gf7n5lBM cC1PlkQiRA/deDT5XUn2opEXLgDUKB4w+p8j1Mrq0PBL5EJHtuOmsrkToWEoqM9FrjFiQJ9LFEP5e/tCt/bPo44EIjUrrCoDXkpWjxnuQ5yQL9M5d3ZkRYiFk2rmLZbEN7Un1hlTLY4ltiOVzGzukxr4fI8TlhVOGcC6FmYLoaBeF/I8lZlawKq61rQPH85wg7Aaqq0+S5c5nDe6mBeJuquxzT1HgAxKVX64cPW6fWtbUJaEKL9LPAqJYKDapYiGkjFOaDDUlcERa5p3m2MYxU3Tgz9MgF1Sren1BfH2Ex8C7Xk8J7GcAmhoSaxf6mt2FOM3sr8LwZRN2HIACdOOtmk7XuQGuWdGRNRn0Z9ZkxwWL7FcUxQgRV1trY3PheINEuavERfqLvYEDb9+0nXjXUbBznGPHqF2mOj1eIu8XG/ETTunXb/pfP51deeMFbEudEfIAqOn17TanpQOZ6e6t8ILtW7Cooc85DdSUt82MxOqrjzO4k1tA8D0dNs/knmZE51dzeNnEoBUgyig9ywzWFZw+RzcL6mUZqWrL1z9gS1r02V6sZEiDpCRjNPGz9sfRtvx5NiZyJ/sUrS4b1Fff4/AhPguJg7GQS31pZZPMoULIU04= 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: This is the bare minimum to illustrate what KUnit code would look like that covers the page allocator. Even this trivial test illustrates a couple of nice things that are possible when testing via KUnit 1. We can directly assert that the correct zone was used. (Although note due to the simplistic setup, you can have any zone you like as long as it's ZONE_NORMAL). 2. We can assert that a page got freed. It's probably pretty unlikely that we'd have a bug that actually causes a page to get leaked by the allocator, but it serves as a good example of the kind of assertions we can make by judicously peeking at allocator internals. Signed-off-by: Brendan Jackman --- mm/page_alloc_test.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/mm/page_alloc_test.c b/mm/page_alloc_test.c index c6bcfcaf61b57ca35ad1b5fc48fd07d0402843bc..0c4effb151f4cd31ec6a696615a9b6ae4964b332 100644 --- a/mm/page_alloc_test.c +++ b/mm/page_alloc_test.c @@ -26,6 +26,139 @@ } \ }) +#define EXPECT_WITHIN_ZONE(test, page, zone) ({ \ + unsigned long pfn = page_to_pfn(page); \ + unsigned long start_pfn = zone->zone_start_pfn; \ + unsigned long end_pfn = start_pfn + zone->spanned_pages; \ + \ + KUNIT_EXPECT_TRUE_MSG(test, \ + pfn >= start_pfn && pfn < end_pfn, \ + "Wanted PFN 0x%lx - 0x%lx, got 0x%lx", \ + start_pfn, end_pfn, pfn); \ + KUNIT_EXPECT_PTR_EQ_MSG(test, page_zone(page), zone, \ + "Wanted %px (%s), got %px (%s)", \ + zone, zone->name, page_zone(page), page_zone(page)->name); \ +}) + +static void action_nodemask_free(void *ctx) +{ + NODEMASK_FREE(ctx); +} + +/* + * Call __alloc_pages_noprof with a nodemask containing only the nid. + * + * Never returns NULL. + */ +static inline struct page *alloc_pages_force_nid(struct kunit *test, + gfp_t gfp, int order, int nid) +{ + NODEMASK_ALLOC(nodemask_t, nodemask, GFP_KERNEL); + struct page *page; + + KUNIT_ASSERT_NOT_NULL(test, nodemask); + kunit_add_action(test, action_nodemask_free, &nodemask); + nodes_clear(*nodemask); + node_set(nid, *nodemask); + + page = __alloc_pages_noprof(GFP_KERNEL, 0, nid, nodemask); + KUNIT_ASSERT_NOT_NULL(test, page); + return page; +} + +static inline bool page_on_buddy_list(struct page *want_page, struct list_head *head) +{ + struct page *found_page; + + list_for_each_entry(found_page, head, buddy_list) { + if (found_page == want_page) + return true; + } + + return false; +} + +/* Test case parameters that are independent of alloc order. */ +static const struct { + gfp_t gfp_flags; + enum zone_type want_zone; +} alloc_fresh_gfps[] = { + /* + * The way we currently set up the isolated node, everything ends up in + * ZONE_NORMAL. + */ + { .gfp_flags = GFP_KERNEL, .want_zone = ZONE_NORMAL }, + { .gfp_flags = GFP_ATOMIC, .want_zone = ZONE_NORMAL }, + { .gfp_flags = GFP_USER, .want_zone = ZONE_NORMAL }, + { .gfp_flags = GFP_DMA32, .want_zone = ZONE_NORMAL }, +}; + +struct alloc_fresh_test_case { + int order; + int gfp_idx; +}; + +/* Generate test cases as the cross product of orders and alloc_fresh_gfps. */ +static const void *alloc_fresh_gen_params(const void *prev, char *desc) +{ + /* Buffer to avoid allocations. */ + static struct alloc_fresh_test_case tc; + + if (!prev) { + /* First call */ + tc.order = 0; + tc.gfp_idx = 0; + return &tc; + } + + tc.gfp_idx++; + if (tc.gfp_idx >= ARRAY_SIZE(alloc_fresh_gfps)) { + tc.gfp_idx = 0; + tc.order++; + } + if (tc.order > MAX_PAGE_ORDER) + /* Finished. */ + return NULL; + + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "order %d %pGg\n", + tc.order, &alloc_fresh_gfps[tc.gfp_idx].gfp_flags); + return &tc; +} + +/* Smoke test: allocate from a node where everything is in a pristine state. */ +static void test_alloc_fresh(struct kunit *test) +{ + const struct alloc_fresh_test_case *tc = test->param_value; + gfp_t gfp_flags = alloc_fresh_gfps[tc->gfp_idx].gfp_flags; + enum zone_type want_zone_type = alloc_fresh_gfps[tc->gfp_idx].want_zone; + struct zone *want_zone = &NODE_DATA(isolated_node)->node_zones[want_zone_type]; + struct list_head *buddy_list; + struct per_cpu_pages *pcp; + struct page *page, *merged_page; + int cpu; + + page = alloc_pages_force_nid(test, gfp_flags, tc->order, isolated_node); + + EXPECT_WITHIN_ZONE(test, page, want_zone); + + cpu = get_cpu(); + __free_pages(page, 0); + pcp = per_cpu_ptr(want_zone->per_cpu_pageset, cpu); + put_cpu(); + + /* + * Should end up back in the free area when drained. Because everything + * is free, it should get buddy-merged up to the maximum order. + */ + drain_zone_pages(want_zone, pcp); + KUNIT_EXPECT_TRUE(test, PageBuddy(page)); + KUNIT_EXPECT_EQ(test, buddy_order(page), MAX_PAGE_ORDER); + KUNIT_EXPECT_TRUE(test, list_empty(&pcp->lists[MIGRATE_UNMOVABLE])); + merged_page = pfn_to_page(round_down(page_to_pfn(page), 1 << MAX_PAGE_ORDER)); + buddy_list = &want_zone->free_area[MAX_PAGE_ORDER].free_list[MIGRATE_UNMOVABLE]; + KUNIT_EXPECT_TRUE(test, page_on_buddy_list(merged_page, buddy_list)); +} + static void action_drain_pages_all(void *unused) { int cpu; @@ -144,7 +277,11 @@ static void depopulate_isolated_node(struct kunit_suite *suite) WARN_ON(add_memory(0, start, size, MMOP_ONLINE)); WARN_ON(walk_memory_blocks(start, size, NULL, memory_block_online_cb)); } -static struct kunit_case test_cases[] = { {} }; + +static struct kunit_case test_cases[] = { + KUNIT_CASE_PARAM(test_alloc_fresh, alloc_fresh_gen_params), + {} +}; struct kunit_suite page_alloc_test_suite = { .name = "page_alloc",