All of lore.kernel.org
 help / color / mirror / Atom feed
* + lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons.patch added to mm-unstable branch
@ 2026-03-16 15:59 Andrew Morton
  0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2026-03-16 15:59 UTC (permalink / raw)
  To: mm-commits, yuzhao, willy, viro, vbabka, tj, sweettea-kernel,
	surenb, sj, shakeel.butt, rppt, rostedt, roman.gushchin, rientjes,
	richard.weiyang, paulmck, objecting, mjguzik, mhocko, mhiramat,
	mathieu.desnoyers, lorenzo.stoakes, liumartin, linmiaohe,
	liam.howlett, hannes, dennis, david, cl, brauner, baolin.wang,
	aboorvad, devnexen, akpm


The patch titled
     Subject: lib: add kunit boundary tests for percpu_counter_tree comparisons
has been added to the -mm mm-unstable branch.  Its filename is
     lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via various
branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there most days

------------------------------------------------------
From: David Carlier <devnexen@gmail.com>
Subject: lib: add kunit boundary tests for percpu_counter_tree comparisons
Date: Mon, 16 Mar 2026 14:38:05 +0000

Add boundary tests for all four comparison APIs to validate that
the accuracy parameters are correctly applied:

- percpu_counter_tree_approximate_compare_value()
- percpu_counter_tree_precise_compare_value()
- percpu_counter_tree_approximate_compare()
- percpu_counter_tree_precise_compare()

The single-value tests probe the accuracy range boundaries (at,
beyond, and in the asymmetric gap between under and over) to catch
swapped accuracy parameters. The two-counter tests verify the
symmetric combined accuracy boundary for counter-to-counter
comparisons.

Link: https://lkml.kernel.org/r/20260316143805.36805-2-devnexen@gmail.com
Signed-off-by: David Carlier <devnexen@gmail.com>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Josh Law <objecting@objecting.org>
Cc: Aboorva Devarajan <aboorvad@linux.ibm.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Liam R . Howlett" <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Martin Liu <liumartin@google.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: SeongJae Park <sj@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Cc: Tejun Heo <tj@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 lib/tests/percpu_counter_tree_kunit.c |  190 ++++++++++++++++++++++++
 1 file changed, 190 insertions(+)

--- a/lib/tests/percpu_counter_tree_kunit.c~lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons
+++ a/lib/tests/percpu_counter_tree_kunit.c
@@ -86,6 +86,194 @@ static void check_counters(struct kunit
 	KUNIT_EXPECT_EQ(test, 0, percpu_counter_tree_approximate_compare(&counter[0], &counter[1]));
 }
 
+static void hpcc_test_compare_value_boundaries(struct kunit *test)
+{
+	struct percpu_counter_tree pct;
+	struct percpu_counter_tree_level_item *counter_items;
+	unsigned long under = 0, over = 0;
+	int ret;
+
+	counter_items = kzalloc(percpu_counter_tree_items_size(), GFP_KERNEL);
+	KUNIT_ASSERT_PTR_NE(test, counter_items, NULL);
+	ret = percpu_counter_tree_init(&pct, counter_items, 32, GFP_KERNEL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	percpu_counter_tree_set(&pct, 0);
+	percpu_counter_tree_approximate_accuracy_range(&pct, &under, &over);
+
+	/*
+	 * With approx_sum = precise_sum = 0, from the accuracy invariant:
+	 *   approx_sum - over <= precise_sum <= approx_sum + under
+	 * Positive deltas use 'under' as tolerance, negative use 'over'.
+	 */
+
+	/* --- percpu_counter_tree_approximate_compare_value --- */
+
+	/* At boundary: indeterminate */
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_approximate_compare_value(&pct,
+			(long)under));
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_approximate_compare_value(&pct,
+			-(long)over));
+
+	/* Beyond boundary: definitive */
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_approximate_compare_value(&pct,
+			(long)(under + 1)));
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_approximate_compare_value(&pct,
+			-(long)(over + 1)));
+
+	/* Asymmetric gap: catches swapped accuracy parameters */
+	if (under != over) {
+		if (under > over) {
+			KUNIT_EXPECT_EQ(test, 0,
+				percpu_counter_tree_approximate_compare_value(
+					&pct, (long)(over + 1)));
+			KUNIT_EXPECT_EQ(test, -1,
+				percpu_counter_tree_approximate_compare_value(
+					&pct, -(long)(over + 1)));
+		} else {
+			KUNIT_EXPECT_EQ(test, 1,
+				percpu_counter_tree_approximate_compare_value(
+					&pct, (long)(under + 1)));
+			KUNIT_EXPECT_EQ(test, 0,
+				percpu_counter_tree_approximate_compare_value(
+					&pct, -(long)(under + 1)));
+		}
+	}
+
+	/* --- percpu_counter_tree_precise_compare_value --- */
+
+	/*
+	 * With approx_sum = precise_sum = 0, the precise comparison
+	 * must return the exact result. At boundary values the
+	 * approximate fast-path returns indeterminate, exercising
+	 * the precise sum fallback.
+	 */
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_precise_compare_value(&pct, 0));
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_precise_compare_value(&pct,
+			(long)under));
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_precise_compare_value(&pct,
+			-(long)over));
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_precise_compare_value(&pct,
+			(long)(under + 1)));
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_precise_compare_value(&pct,
+			-(long)(over + 1)));
+
+	if (under != over) {
+		if (under > over) {
+			KUNIT_EXPECT_EQ(test, 1,
+				percpu_counter_tree_precise_compare_value(
+					&pct, (long)(over + 1)));
+			KUNIT_EXPECT_EQ(test, -1,
+				percpu_counter_tree_precise_compare_value(
+					&pct, -(long)(over + 1)));
+		} else {
+			KUNIT_EXPECT_EQ(test, 1,
+				percpu_counter_tree_precise_compare_value(
+					&pct, (long)(under + 1)));
+			KUNIT_EXPECT_EQ(test, -1,
+				percpu_counter_tree_precise_compare_value(
+					&pct, -(long)(under + 1)));
+		}
+	}
+
+	percpu_counter_tree_destroy(&pct);
+	kfree(counter_items);
+}
+
+static void hpcc_test_compare_counter_boundaries(struct kunit *test)
+{
+	struct percpu_counter_tree pct[2];
+	struct percpu_counter_tree_level_item *counter_items;
+	unsigned long under = 0, over = 0;
+	unsigned long combined;
+	int ret;
+
+	counter_items = kzalloc(percpu_counter_tree_items_size() * 2,
+				GFP_KERNEL);
+	KUNIT_ASSERT_PTR_NE(test, counter_items, NULL);
+	ret = percpu_counter_tree_init_many(pct, counter_items, 2, 32,
+					    GFP_KERNEL);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	percpu_counter_tree_approximate_accuracy_range(&pct[0],
+						       &under, &over);
+
+	/*
+	 * Both counters have the same configuration. The combined
+	 * accuracy for two-counter comparison is symmetric:
+	 *   accuracy_pos = over + under = under + over = accuracy_neg
+	 */
+	combined = under + over;
+
+	/* --- percpu_counter_tree_approximate_compare --- */
+
+	/* At boundary: indeterminate */
+	percpu_counter_tree_set(&pct[0], (long)combined);
+	percpu_counter_tree_set(&pct[1], 0);
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_approximate_compare(&pct[0], &pct[1]));
+
+	percpu_counter_tree_set(&pct[0], 0);
+	percpu_counter_tree_set(&pct[1], (long)combined);
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_approximate_compare(&pct[0], &pct[1]));
+
+	/* Beyond boundary: definitive */
+	percpu_counter_tree_set(&pct[0], (long)(combined + 1));
+	percpu_counter_tree_set(&pct[1], 0);
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_approximate_compare(&pct[0], &pct[1]));
+
+	percpu_counter_tree_set(&pct[0], 0);
+	percpu_counter_tree_set(&pct[1], (long)(combined + 1));
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_approximate_compare(&pct[0], &pct[1]));
+
+	/* --- percpu_counter_tree_precise_compare --- */
+
+	/* At boundary: precise gives exact result */
+	percpu_counter_tree_set(&pct[0], (long)combined);
+	percpu_counter_tree_set(&pct[1], 0);
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_precise_compare(&pct[0], &pct[1]));
+
+	percpu_counter_tree_set(&pct[0], 0);
+	percpu_counter_tree_set(&pct[1], (long)combined);
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_precise_compare(&pct[0], &pct[1]));
+
+	/* Beyond boundary: definitive */
+	percpu_counter_tree_set(&pct[0], (long)(combined + 1));
+	percpu_counter_tree_set(&pct[1], 0);
+	KUNIT_EXPECT_EQ(test, 1,
+		percpu_counter_tree_precise_compare(&pct[0], &pct[1]));
+
+	percpu_counter_tree_set(&pct[0], 0);
+	percpu_counter_tree_set(&pct[1], (long)(combined + 1));
+	KUNIT_EXPECT_EQ(test, -1,
+		percpu_counter_tree_precise_compare(&pct[0], &pct[1]));
+
+	/* Equal counters */
+	percpu_counter_tree_set(&pct[0], 42);
+	percpu_counter_tree_set(&pct[1], 42);
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_approximate_compare(&pct[0], &pct[1]));
+	KUNIT_EXPECT_EQ(test, 0,
+		percpu_counter_tree_precise_compare(&pct[0], &pct[1]));
+
+	percpu_counter_tree_destroy_many(pct, 2);
+	kfree(counter_items);
+}
+
 static int multi_thread_worker_fn(void *data)
 {
 	struct multi_thread_test_data *td = data;
@@ -383,6 +571,8 @@ static struct kunit_case hpcc_test_cases
 	KUNIT_CASE(hpcc_test_single_thread_random),
 	KUNIT_CASE(hpcc_test_multi_thread_batch_increment),
 	KUNIT_CASE(hpcc_test_multi_thread_random_walk),
+	KUNIT_CASE(hpcc_test_compare_value_boundaries),
+	KUNIT_CASE(hpcc_test_compare_counter_boundaries),
 	KUNIT_CASE(hpcc_test_init_one),
 	KUNIT_CASE(hpcc_test_set),
 	{}
_

Patches currently in -mm which might be from devnexen@gmail.com are

lib-introduce-hierarchical-per-cpu-counters-fix.patch
lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons.patch


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-03-16 15:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16 15:59 + lib-add-kunit-boundary-tests-for-percpu_counter_tree-comparisons.patch added to mm-unstable branch Andrew Morton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.