From nobody Sun Feb 8 17:22:00 2026 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (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 2616A219FC for ; Sat, 10 Jan 2026 17:38:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768066715; cv=none; b=i7fhs9DS59mpgW2pZzz4Wo+qWINRt+k947GGwitS/0jWAl+j1PWYt+N6MQNeOgFe7vd0WHlQfpg7pc9inzJZe9gud/duZUBjgiAlWL1gXt6D5gghg8pSTOW2fgvuul03Nd1Dm2ThGk6h5Lo7U8njGJNIHecHHhR4usMa0KRzfMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768066715; c=relaxed/simple; bh=fMaHw+qXTofFkAAvd4EcsS88G28su8UGmSgZDRfJOMs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=mkkXcmggksyD66eHh25dBaMZrIoDuK26z/WEfvYy3Uh4hoKY7J1wybqQHE0OKFM58Fz3V6kF6oFjK45tYQmp4D5H9JV5rwbqiLmRYFMqtQfGykpEVxJr5CMpccQMJwLj3hDyOHkWzezV08u8jJ7VLeAfqIHOrXYBYpC/BMqsZXs= 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=B3wywmHs; arc=none smtp.client-ip=209.85.210.182 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="B3wywmHs" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-81e98a1f55eso726205b3a.3 for ; Sat, 10 Jan 2026 09:38:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768066713; x=1768671513; 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=x0K6gwYFxZgs3ytnTDhfXvEpyJ0xEw9I1JFGMs+xJYQ=; b=B3wywmHsgtXiw9CplLwLPjMUV6uG0zxl8pPxMP8f4TFq6D/Do+tmk9qGMKxM/PLNiX HlhkiEwtNjv1SeU93Iji82Q8j99jpRflE8uEy26AjiNOc7o8JMj4Ui74NKELSVVPlLY0 Ky2unlq7cvlh+8DmbfBzUuqrLMbpeGcdiO4xj8URpeOTGzJy5ZGSvHL6U0giGgyai3MZ MsVivjB9W6B/X79uhwLU2je/qbZ/RBUiQhC5SSyHspPlHuPlZ2Hdxn7zJxMjn8lNX4Fj ZGEVjlVWtB0LRXXqrN1qv/AjqI48ewOmRyzOn4Ozm8KEra1KOzuSkDwuZnMbGaQTYZc4 CM5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768066713; x=1768671513; 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=x0K6gwYFxZgs3ytnTDhfXvEpyJ0xEw9I1JFGMs+xJYQ=; b=oOJL1igYEz9bQ0jOzb/2tfNM8JXQtWCNcVgrGT/ESvFL9NJbYcxz7mi0wzbcIzMbI4 YSytQNV2ytEh6Sfze9cYD2Qgu9kwpV091PxTfhmS339PZ1Z6wL9Qf4z375CMZeeuMyLy 45NZa/LkdNyfiLz2ynNOxcJZwUmx/SunYaT49DaLT16kt7h0yDSiHahUkU2wK9ieOuuq QA2RLhbm4C7nuuyYeubLv1LurXbZ3Z1Z814xqZUoWDQyCF+XxnAMJnLF+VBBx2xNgMUa MmiiWQEooFf1PfWxYKjFhXQtFS16SdPiRWbzf45/AGuAscf4zhH1Cs+K/lLm+inuEZHo fLjg== X-Forwarded-Encrypted: i=1; AJvYcCVqjBlZ7UyBtZbd2GXYbR+uLfrRdqtx3ts7qvIn+Tga1T+qDD7C+Ocn7RvFCsQxW91DDQHfcgtkJBhPWz4=@vger.kernel.org X-Gm-Message-State: AOJu0YzRoYjRJ2hXN9BOhg0FzFMuu+Yv+EUbH3m4aeLHG8svYftyunPd pWoFK2Yec+YL2eluDuL6G1yXcA3aVNYXzO6I+dv/A5jFmmKjnKPH5l7A X-Gm-Gg: AY/fxX6np89SLqAXDo/elsT7bvsLn/cWzU+U/eIZKnxM2qknE73Q4abWRw9UYq1gKn4 BLKV7oHmRTPIB56d5tZkNSA8uTA1n/k0RZaIxz1uPeXyefCjAUwgaNruZmGtqb2C2BqWfNWP6/2 iHrMCF9nuvLGGUB4khw8R2IQVsmKTHvUENfi8Tc3CHqkl+BpB30K7HrQSlfPOgJiX0D+L6yMAtJ pHsNhzp6T6JTRYxAHml6babITqXsNTOWICrX2kPkYsdks1/b1ftLmMFFSD9cK8kAEcKlkkNZGDP z9LuqWSKFawKRkCRqkEQQ0x5ck1p6HfRKbiBwAyCmFmNAksnEZJ/TO2JmzYdJC3R9AsT4ewFaCA nWbOQixuVQEcYP8chB+8bcpzBDUKlFRbkV2vf1RL7ZLsNw1kBpqDXeQ5CC8CNo6CscAh0la/TXK h+kfCCcoJDAfaBZzdmb6byfM5yYayTwA== X-Google-Smtp-Source: AGHT+IGJD3eU1BgTKRBh4+cXEP2gEXJtglZQjPtg9sQpGeTHpklIem4kel+pKalBs5xiwDIwJ75crg== X-Received: by 2002:a05:6a21:339b:b0:33f:4e3d:aff0 with SMTP id adf61e73a8af0-3898f8cbb87mr14257123637.21.1768066713280; Sat, 10 Jan 2026 09:38:33 -0800 (PST) Received: from [172.16.80.107] ([210.228.119.9]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2a3e3c48e8esm18030505ad.37.2026.01.10.09.38.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 10 Jan 2026 09:38:32 -0800 (PST) From: Ryota Sakamoto Date: Sun, 11 Jan 2026 02:38:07 +0900 Subject: [PATCH v2] 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: <20260111-kunit-bitops-v2-1-8c5b15341060@gmail.com> X-B4-Tracking: v=1; b=H4sIAAAAAAAC/1XMQQ7CIBCF4as0sxbDYDTiyns0XQwI7UQLDWCja Xp3sXHj8n/J+xbILrHLcGkWSG7mzDHUULsG7EChd4JvtUFJdZIotbg/AxdhuMQpC03GHC3ZszU E9TIl5/m1cW1Xe+BcYnpv+ozf9Qeh/IdmFCi8O2hC75GkuvYj8WNv4wjduq4fQa9Eh6gAAAA= X-Change-ID: 20260109-kunit-bitops-9abb5cac8cba To: Andrew Morton , Yury Norov , Rasmus Villemoes Cc: Yury Norov , Jesse Brandeburg , Wei Yang , 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. The following test logic has been ported from test_bitops_startup() in lib/test_bitops.c: - set_bit() / clear_bit() / find_first_bit() validation -> test_set_bit_clear_bit() - get_count_order() validation -> test_get_count_order() - get_count_order_long() validation -> test_get_count_order_long() 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. Sample KUnit output: KTAP version 1 # Subtest: bitops # module: bitops_kunit 1..3 KTAP version 1 # Subtest: test_set_bit_clear_bit ok 1 BITOPS_4 ok 2 BITOPS_7 ok 3 BITOPS_11 ok 4 BITOPS_31 ok 5 BITOPS_88 # test_set_bit_clear_bit: pass:5 fail:0 skip:0 total:5 ok 1 test_set_bit_clear_bit KTAP version 1 # Subtest: test_get_count_order ok 1 0x00000003 ok 2 0x00000004 ok 3 0x00001fff ok 4 0x00002000 ok 5 0x50000000 ok 6 0x80000000 ok 7 0x80003000 # test_get_count_order: pass:7 fail:0 skip:0 total:7 ok 2 test_get_count_order KTAP version 1 # Subtest: test_get_count_order_long ok 1 0x0000000300000000 ok 2 0x0000000400000000 ok 3 0x00001fff00000000 ok 4 0x0000200000000000 ok 5 0x5000000000000000 ok 6 0x8000000000000000 ok 7 0x8000300000000000 # test_get_count_order_long: pass:7 fail:0 skip:0 total:7 ok 3 test_get_count_order_long Signed-off-by: Ryota Sakamoto --- Changes in v2: - List extracted test logic in the commit message - Include KTAP execution output - Clarify in Kconfig help text that this is a partial copy - Add original authors to CC - Link to v1: https://lore.kernel.org/r/20260110-kunit-bitops-v1-1-fe39a1ff= 1a02@gmail.com --- MAINTAINERS | 1 + lib/Kconfig.debug | 14 +++++ lib/tests/Makefile | 1 + lib/tests/bitops_kunit.c | 142 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 158 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..a3642ab0363d0fa17eb8a395655= cdc4b56f031d8 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2652,6 +2652,20 @@ config TEST_SYSCTL =20 If unsure, say N. =20 +config BITOPS_KUNIT + tristate "KUnit test for bitops" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + This option enables the KUnit test suite for the bitops library + which provides functions for bit operations. + The test suite checks the functionality of the bitops library. + + Note that this is a partial copy of the original test_bitops module. + For the full coverage, enable TEST_BITOPS. + + 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