From nobody Sun Feb 8 11:25:55 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D53922253A1 for ; Fri, 9 Jan 2026 18:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767984151; cv=none; b=hbqX0ALMMMJZBLejVRSAoWLLL1QSJy6z7sdPuJefuJNdJf1QmaZtcMuF/9K0SfmE5oRwpN0me493uApc4RBjfuL8Q8+Dws33FTev9gsYjE7IgezLsGjopOrSUcGb22XobTONqJbsJ4F0h85PhcVrVNy7ntDoqAhUhgmYsp14LAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767984151; c=relaxed/simple; bh=hvmS1HKfNOu2K0Rn3vZFjhgGqb4NBPVDymGQ3DABHtg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=TiZnWjvs5ZAiD63eTiSVOobHmqn71MCALDjvMVWjLJcn+k0rfcHdCqd3AnVfu7REN9gtjQdXlATPV7ItE+YFReSw/24aSBtDzUmW1ikjXp4/ypkdOVtf9/p2P+BjoTNiEzYxh4cDKVvRNv+iUYH/IlchxRccloqegFoec4ejyvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FdGCEyQd; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FdGCEyQd" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-bbf2c3eccc9so1398121a12.0 for ; Fri, 09 Jan 2026 10:42:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767984148; x=1768588948; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=ZCtbQuo4kTOb7zKdgs/6lZBJEc9tu1NPPz4+bijPKvk=; b=FdGCEyQdx/w+92OrRh8ivDTm6qSKVvs9NKcsR12Wla5S5zFjiE9N8GpzcfUOp+u1uo Wrcciql8aZNGLV6Q+GGWIR9j2PJKNjZhu7/MYcOg68CGIvrGwzyx/o/PkXyoWSVtWuI6 XGp40/fYB/pFd1GKSTbziS/7z/BPVrR2qM/wjQMMiB3U2e0VthdGvPUVIqOkcTlQAdHq tI4c47S70hJz4Giz6aqsKc0t0hwa3NM/cpRZbgLF/6GJkpW15Q6JJQaPNctiRiUSsBKT JJOzdmkJFuxlACSkxBY5OF/1JwaPQSf361K1XCjucWjjMVOWmFoE2tW8GRRy7g2tPOIe icTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767984148; x=1768588948; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ZCtbQuo4kTOb7zKdgs/6lZBJEc9tu1NPPz4+bijPKvk=; b=HEwjjIdtVHWhl4xVqOeBJ7XI9t7SHMOzplr4OmXBrCDLs8AlTo1mI5rkBEykkXx3fn uVkP6UfF85QwYwOrW4Je8umzWX0dPO9ZWrDfVrH0DDOIOSZGP9imxEXjUJJ77XnvD9jS YR4yDnj66R1MhlYnudmNJtADJLdWOEkt8uDOwFVkJq6oG55WYdHCz5yMXW5dD+XHKx6l ITMt/T9+5TFKAzeYCqr2jnL6MYpK/FtFino+mMcG2+zZaTQHFxPBwUOQM6zYt/SxIazM FKvNtbdps/KbLMBGnbBYx6ZWBBhxhmExFfJmEQNT0eQ7YWmViB6X5Zr5dguf8V1MAPbO 1hcA== X-Gm-Message-State: AOJu0YxqyhXKcNve/RwTXvRoiu2dAk+GKdvfpKNk64MMj9D4wcclLJYV frksJk+Ry7uphCgO3/RVvbbAlpiWJsoCixPQQ1GpZsE1ZC1EHhfKxDpb7tcuYZoMCcM= X-Gm-Gg: AY/fxX5SSkiVCnhZ48/YcRlcVTUBlg99MsrmLdWD+dxb2gV1B2Vr1EO3hEBrZKqMXeT U0l9dzYHhaw/4rVb9xLVzJXDfPi4bKBw+dwmltwAfJd5dZ8F4LcdC++9uX764bY/6MPbE5deWcz XK7sGmCnn9q3bYwTSeDtqtn/Y3LOq+r44SKsQCzrzKIRBQvChe45rWypaS8AQjEATrLf6eIicMc VCM/96mo8CKwPLmJ/YEA0CTVZjfWg/qgbNNNk4vkEqhEIzQqNiQDd9rDtOFnYj4HnNnIth97ADx x3wo9sDweG4dRG19SivTEYSUXKSUnpvbZgXeBAV6Ik60oqRG73ERHNqdE1iSH0WcBRgi/ORai/Z HaqOzLy3rVYLCiiWuBDAxT/XS1YlvvmUNix8rVqfTM6OdppElkmOOZZcRXcSizPFn4wnYDaYfNZ Ib1jn6DC5Frs1WBZQv3VfOkbyk00z0vw== X-Google-Smtp-Source: AGHT+IFG3RAMcFOz38qH38h34TBVDvL0+MULcZTF6pPY4kzCJaBTpQlJZ+4XfHbvQ9Ijay/jsVL5zw== X-Received: by 2002:a17:902:d50e:b0:295:99f0:6c65 with SMTP id d9443c01a7336-2a3e39ff6fdmr154618265ad.30.1767984148221; Fri, 09 Jan 2026 10:42:28 -0800 (PST) Received: from [172.16.80.107] ([210.228.119.9]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2a3e3c48dc1sm109775715ad.40.2026.01.09.10.42.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Jan 2026 10:42:27 -0800 (PST) From: Ryota Sakamoto Date: Sat, 10 Jan 2026 03:42:21 +0900 Subject: [PATCH] lib/tests: add KUnit test for bitops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260110-kunit-bitops-v1-1-fe39a1ff1a02@gmail.com> X-B4-Tracking: v=1; b=H4sIAAAAAAAC/6tWKk4tykwtVrJSqFYqSi3LLM7MzwNyDHUUlJIzE vPSU3UzU4B8JSMDIzMDQwNL3ezSvMwS3aTMkvyCYl3LxKQk0+TEZIvkpEQloJaCotS0zAqwcdG xtbUARG48TV4AAAA= X-Change-ID: 20260109-kunit-bitops-9abb5cac8cba To: Andrew Morton , Yury Norov , Rasmus Villemoes Cc: linux-kernel@vger.kernel.org, Ryota Sakamoto X-Mailer: b4 0.14.2 Add a KUnit test suite for the bitops API. The existing 'lib/test_bitops.c' is preserved as-is because it contains ad-hoc micro-benchmarks 'test_fns' and is intended to ensure no compiler warnings from C=3D1 sparse checker or -Wextra compilations. Introduce 'lib/tests/bitops_kunit.c' for functional regression testing. It ports the test logic and data patterns from 'lib/test_bitops.c' to KUnit, verifying correct behavior across various input patterns and architecture-specific edge cases using isolated stack-allocated bitmaps. Also improve the find_first_bit() test to check the full bitmap length (BITOPS_LENGTH) instead of omitting the last bit, ensuring the bitmap is completely empty after cleanup. Verified on x86_64, i386, and arm64 architectures. Signed-off-by: Ryota Sakamoto --- MAINTAINERS | 1 + lib/Kconfig.debug | 17 ++++++ lib/tests/Makefile | 1 + lib/tests/bitops_kunit.c | 142 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 161 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a0dd762f5648b7e4e6fc62560662e43720422e01..ad978698deedca3e6acdf62145a= 48d45b579cec2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4468,6 +4468,7 @@ F: include/asm-generic/bitops.h F: include/linux/bitops.h F: lib/hweight.c F: lib/test_bitops.c +F: lib/tests/bitops_kunit.c F: tools/*/bitops* =20 BITOPS API BINDINGS [RUST] diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ba36939fda79bf890834b586c366a28acd434ef9..3d7fdea11354a421ac5b7283a14= f0752261d4a63 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2652,6 +2652,23 @@ config TEST_SYSCTL =20 If unsure, say N. =20 +config BITOPS_KUNIT + tristate "KUnit test bitops functions at runtime" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Enable this option to test the bitops functions at boot. + + KUnit tests run during boot and output the results to the debug log + in TAP format (http://testanything.org/). Only useful for kernel devs + running the KUnit test harness, and not intended for inclusion into a + production build. + + For more information on KUnit and unit tests in general please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config BITFIELD_KUNIT tristate "KUnit test bitfield functions at runtime" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 601dba4b7d966d568d0bb6671dffaf4d68489549..0f24048f36845b13daebcb504e1= 82f738e0a807f 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -5,6 +5,7 @@ # KUnit tests CFLAGS_bitfield_kunit.o :=3D $(DISABLE_STRUCTLEAK_PLUGIN) obj-$(CONFIG_BASE64_KUNIT) +=3D base64_kunit.o +obj-$(CONFIG_BITOPS_KUNIT) +=3D bitops_kunit.o obj-$(CONFIG_BITFIELD_KUNIT) +=3D bitfield_kunit.o obj-$(CONFIG_BITS_TEST) +=3D test_bits.o obj-$(CONFIG_BLACKHOLE_DEV_KUNIT_TEST) +=3D blackhole_dev_kunit.o diff --git a/lib/tests/bitops_kunit.c b/lib/tests/bitops_kunit.c new file mode 100644 index 0000000000000000000000000000000000000000..5c47a12760611a0445feb37c252= d00f3bf73f6a1 --- /dev/null +++ b/lib/tests/bitops_kunit.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2026 Ryota Sakamoto + */ + +#include +#include +#include + +/* use an enum because that's the most common BITMAP usage */ +enum bitops_fun { + BITOPS_4 =3D 4, + BITOPS_7 =3D 7, + BITOPS_11 =3D 11, + BITOPS_31 =3D 31, + BITOPS_88 =3D 88, + BITOPS_LENGTH =3D 256 +}; + +struct bitops_test_case { + const char *str; + const long nr; +}; + +static struct bitops_test_case bitops_cases[] =3D { + { + .str =3D "BITOPS_4", + .nr =3D BITOPS_4, + }, + { + .str =3D "BITOPS_7", + .nr =3D BITOPS_7, + }, + { + .str =3D "BITOPS_11", + .nr =3D BITOPS_11, + }, + { + .str =3D "BITOPS_31", + .nr =3D BITOPS_31, + }, + { + .str =3D "BITOPS_88", + .nr =3D BITOPS_88, + }, +}; + +KUNIT_ARRAY_PARAM_DESC(bitops, bitops_cases, str); + +static void test_set_bit_clear_bit(struct kunit *test) +{ + const struct bitops_test_case *params =3D test->param_value; + DECLARE_BITMAP(bitmap, BITOPS_LENGTH); + int bit_set; + + bitmap_zero(bitmap, BITOPS_LENGTH); + + set_bit(params->nr, bitmap); + KUNIT_EXPECT_TRUE(test, test_bit(params->nr, bitmap)); + + clear_bit(params->nr, bitmap); + KUNIT_EXPECT_FALSE(test, test_bit(params->nr, bitmap)); + + bit_set =3D find_first_bit(bitmap, BITOPS_LENGTH); + KUNIT_EXPECT_EQ(test, bit_set, BITOPS_LENGTH); +} + +struct order_test_case { + const char *str; + const unsigned int count; + const int expected; +}; + +static struct order_test_case order_test_cases[] =3D { + {"0x00000003", 0x00000003, 2}, + {"0x00000004", 0x00000004, 2}, + {"0x00001fff", 0x00001fff, 13}, + {"0x00002000", 0x00002000, 13}, + {"0x50000000", 0x50000000, 31}, + {"0x80000000", 0x80000000, 31}, + {"0x80003000", 0x80003000, 32}, +}; + +KUNIT_ARRAY_PARAM_DESC(order, order_test_cases, str); + +static void test_get_count_order(struct kunit *test) +{ + const struct order_test_case *params =3D test->param_value; + + KUNIT_EXPECT_EQ(test, get_count_order(params->count), params->expected); + KUNIT_EXPECT_EQ(test, get_count_order_long(params->count), params->expect= ed); +} + +#ifdef CONFIG_64BIT +struct order_long_test_case { + const char *str; + const unsigned long count; + const int expected; +}; + +static struct order_long_test_case order_long_test_cases[] =3D { + {"0x0000000300000000", 0x0000000300000000, 34}, + {"0x0000000400000000", 0x0000000400000000, 34}, + {"0x00001fff00000000", 0x00001fff00000000, 45}, + {"0x0000200000000000", 0x0000200000000000, 45}, + {"0x5000000000000000", 0x5000000000000000, 63}, + {"0x8000000000000000", 0x8000000000000000, 63}, + {"0x8000300000000000", 0x8000300000000000, 64}, +}; + +KUNIT_ARRAY_PARAM_DESC(order_long, order_long_test_cases, str); + +static void test_get_count_order_long(struct kunit *test) +{ + const struct order_long_test_case *params =3D test->param_value; + + KUNIT_EXPECT_EQ(test, get_count_order_long(params->count), params->expect= ed); +} +#endif + +static struct kunit_case bitops_test_cases[] =3D { + KUNIT_CASE_PARAM(test_set_bit_clear_bit, bitops_gen_params), + KUNIT_CASE_PARAM(test_get_count_order, order_gen_params), +#ifdef CONFIG_64BIT + KUNIT_CASE_PARAM(test_get_count_order_long, order_long_gen_params), +#endif + {}, +}; + +static struct kunit_suite bitops_test_suite =3D { + .name =3D "bitops", + .test_cases =3D bitops_test_cases, +}; + +kunit_test_suite(bitops_test_suite); + +MODULE_AUTHOR("Jesse Brandeburg "); +MODULE_AUTHOR("Wei Yang "); +MODULE_AUTHOR("Ryota Sakamoto "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Bit testing module"); --- base-commit: 79b95d74470dd97d7d0908d5a3c0734a23e51aa4 change-id: 20260109-kunit-bitops-9abb5cac8cba Best regards, --=20 Ryota Sakamoto