Commit b8ee5575 authored by SeongJae Park's avatar SeongJae Park Committed by Andrew Morton

mm/damon/sysfs-test: add a unit test for damon_sysfs_set_targets()

damon_sysfs_set_targets() had a bug that can result in unexpected memory
usage and monitoring overhead increase.  The bug has fixed by a previous
commit.  Add a unit test for avoiding a similar bug of future.

Link: https://lkml.kernel.org/r/20231022210735.46409-3-sj@kernel.orgSigned-off-by: default avatarSeongJae Park <sj@kernel.org>
Cc: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 62f76a7b
...@@ -59,6 +59,18 @@ config DAMON_SYSFS ...@@ -59,6 +59,18 @@ config DAMON_SYSFS
This builds the sysfs interface for DAMON. The user space can use This builds the sysfs interface for DAMON. The user space can use
the interface for arbitrary data access monitoring. the interface for arbitrary data access monitoring.
config DAMON_SYSFS_KUNIT_TEST
bool "Test for damon debugfs interface" if !KUNIT_ALL_TESTS
depends on DAMON_SYSFS && KUNIT=y
default KUNIT_ALL_TESTS
help
This builds the DAMON sysfs interface Kunit test suite.
For more information on KUnit and unit tests in general, please refer
to the KUnit documentation.
If unsure, say N.
config DAMON_DBGFS config DAMON_DBGFS
bool "DAMON debugfs interface (DEPRECATED!)" bool "DAMON debugfs interface (DEPRECATED!)"
depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS depends on DAMON_VADDR && DAMON_PADDR && DEBUG_FS
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Data Access Monitor Unit Tests
*
* Author: SeongJae Park <sj@kernel.org>
*/
#ifdef CONFIG_DAMON_SYSFS_KUNIT_TEST
#ifndef _DAMON_SYSFS_TEST_H
#define _DAMON_SYSFS_TEST_H
#include <kunit/test.h>
static unsigned int nr_damon_targets(struct damon_ctx *ctx)
{
struct damon_target *t;
unsigned int nr_targets = 0;
damon_for_each_target(t, ctx)
nr_targets++;
return nr_targets;
}
static int __damon_sysfs_test_get_any_pid(int min, int max)
{
struct pid *pid;
int i;
for (i = min; i <= max; i++) {
pid = find_get_pid(i);
if (pid) {
put_pid(pid);
return i;
}
}
return -1;
}
static void damon_sysfs_test_set_targets(struct kunit *test)
{
struct damon_sysfs_targets *sysfs_targets;
struct damon_sysfs_target *sysfs_target;
struct damon_ctx *ctx;
sysfs_targets = damon_sysfs_targets_alloc();
sysfs_targets->nr = 1;
sysfs_targets->targets_arr = kmalloc_array(1,
sizeof(*sysfs_targets->targets_arr), GFP_KERNEL);
sysfs_target = damon_sysfs_target_alloc();
sysfs_target->pid = __damon_sysfs_test_get_any_pid(12, 100);
sysfs_target->regions = damon_sysfs_regions_alloc();
sysfs_targets->targets_arr[0] = sysfs_target;
ctx = damon_new_ctx();
damon_sysfs_set_targets(ctx, sysfs_targets);
KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(ctx));
sysfs_target->pid = __damon_sysfs_test_get_any_pid(
sysfs_target->pid + 1, 200);
damon_sysfs_set_targets(ctx, sysfs_targets);
KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(ctx));
damon_destroy_ctx(ctx);
kfree(sysfs_targets->targets_arr);
kfree(sysfs_targets);
kfree(sysfs_target);
}
static struct kunit_case damon_sysfs_test_cases[] = {
KUNIT_CASE(damon_sysfs_test_set_targets),
{},
};
static struct kunit_suite damon_sysfs_test_suite = {
.name = "damon-sysfs",
.test_cases = damon_sysfs_test_cases,
};
kunit_test_suite(damon_sysfs_test_suite);
#endif /* _DAMON_SYSFS_TEST_H */
#endif /* CONFIG_DAMON_SYSFS_KUNIT_TEST */
...@@ -1836,3 +1836,5 @@ static int __init damon_sysfs_init(void) ...@@ -1836,3 +1836,5 @@ static int __init damon_sysfs_init(void)
return err; return err;
} }
subsys_initcall(damon_sysfs_init); subsys_initcall(damon_sysfs_init);
#include "sysfs-test.h"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment