* [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap()
@ 2025-03-28 11:43 Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 1/2] libs: " Petr Vorel
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Petr Vorel @ 2025-03-28 11:43 UTC (permalink / raw)
To: ltp
Hi,
not a huge improvement, but because all tst_get_nodemap() are in the
setup (and only ksm06.c allows input parameter) we could have struct
tst_test member which would call safe_get_nodemap().
e.g.:
.nodemap = (const struct tst_path_val) {
.type = TST_NUMA_MEM
.required = 2,
},
safe_get_nodemap(tst_test->nodemap->type,
tst_test->nodemap->required * getpagesize() / 1024);
This would not work for non - page sized nodes, e.g.:
nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
=> extra member would need to be added:
.nodemap = (const struct tst_path_val) {
.type = TST_NUMA_MEM
.required = 2,
.size = PAGES_ALLOCATED, // default == 1
},
would call:
safe_get_nodemap(tst_test->nodemap->type,
tst_test->nodemap->required * tst_test->nodemap->size * getpagesize() / 1024,
tst_test->nodemap->required);
Petr Vorel (2):
libs: Add safe_get_nodemap()
Use safe_get_nodemap()
include/tst_numa.h | 41 ++++++++++++++++++-
libs/numa/tst_numa.c | 14 +++++++
testcases/kernel/mem/ksm/ksm06.c | 4 +-
.../syscalls/get_mempolicy/get_mempolicy01.c | 4 +-
.../syscalls/get_mempolicy/get_mempolicy02.c | 4 +-
testcases/kernel/syscalls/mbind/mbind02.c | 4 +-
testcases/kernel/syscalls/mbind/mbind03.c | 4 +-
testcases/kernel/syscalls/mbind/mbind04.c | 4 +-
.../syscalls/set_mempolicy/set_mempolicy01.c | 4 +-
.../syscalls/set_mempolicy/set_mempolicy02.c | 4 +-
.../syscalls/set_mempolicy/set_mempolicy03.c | 4 +-
.../syscalls/set_mempolicy/set_mempolicy04.c | 4 +-
12 files changed, 63 insertions(+), 32 deletions(-)
--
2.49.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* [LTP] [RFC][PATCH 1/2] libs: Add safe_get_nodemap()
2025-03-28 11:43 [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Petr Vorel
@ 2025-03-28 11:43 ` Petr Vorel
2025-03-31 16:00 ` Cyril Hrubis
2025-03-28 11:43 ` [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap() Petr Vorel
2025-03-31 15:52 ` [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Cyril Hrubis
2 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2025-03-28 11:43 UTC (permalink / raw)
To: ltp
This requires to add also tst_numa_type_name().
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
include/tst_numa.h | 41 +++++++++++++++++++++++++++++++++++++++--
libs/numa/tst_numa.c | 14 ++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/include/tst_numa.h b/include/tst_numa.h
index a1f9616300..191a57fa6b 100644
--- a/include/tst_numa.h
+++ b/include/tst_numa.h
@@ -106,8 +106,30 @@ enum tst_numa_types {
};
/**
- * tst_get_nodemap() - Allocates and returns numa node map, which is an array of numa nodes which
- * contain desired resources e.g. memory.
+ * tst_numa_type_name() - Convert enum tst_numa_types to a description of a NUMA type.
+ *
+ * @type Bitflags of enum tst_numa_types specifying desired resources.
+ *
+ * @return a string describing a NUMA type.
+ */
+static inline const char *tst_numa_type_name(int type)
+{
+ if (type & ~(TST_NUMA_MEM))
+ tst_brk(TBROK, "Invalid type %i\n", type);
+
+ switch (type) {
+ case TST_NUMA_MEM:
+ return " memory";
+ case TST_NUMA_ANY:
+ return "";
+ default:
+ return " unknown";
+ }
+}
+
+/**
+ * tst_get_nodemap() - Allocates and returns numa node map, which is an array of
+ * NUMA nodes which contain desired resources e.g. memory.
*
* @type: Bitflags of enum tst_numa_types specifying desired resources.
* @min_mem_kb: Minimal free RAM on memory nodes, if given node has less than
@@ -119,4 +141,19 @@ enum tst_numa_types {
*/
struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb);
+/**
+ * safe_get_nodemap() - Calls tst_get_nodemap() with check for minimal required
+ * NUMA nodes. Call tst_brk(TCONF) if not enough NUMA nodes.
+ *
+ * @type: Bitflags of enum tst_numa_types specifying desired resources.
+ * @min_mem_kb: Minimal free RAM on memory nodes, if given node has less than
+ * requested amount of free+buffers memory it's not included in
+ * the resulting list of nodes.
+ * @required: Minimal number of a required NUMA nodes.
+ *
+ * return: On success returns allocated and initialized struct tst_nodemap which contains
+ * array of numa node ids that contains desired resources.
+ */
+struct tst_nodemap *safe_get_nodemap(int type, size_t min_mem_kb, size_t required);
+
#endif /* TST_NUMA_H__ */
diff --git a/libs/numa/tst_numa.c b/libs/numa/tst_numa.c
index c3297013be..f004e29014 100644
--- a/libs/numa/tst_numa.c
+++ b/libs/numa/tst_numa.c
@@ -221,4 +221,18 @@ struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb)
return nodes;
}
+struct tst_nodemap *safe_get_nodemap(int type, size_t min_mem_kb, size_t required)
+{
+ struct tst_nodemap *nodes;
+
+ nodes = tst_get_nodemap(type, min_mem_kb);
+
+ if (nodes->cnt < required) {
+ tst_brk(TCONF, "Test requires at least %zi NUMA%s node%s",
+ required, tst_numa_type_name(type), required > 1 ? "s" : "");
+ }
+
+ return nodes;
+}
+
#endif
--
2.49.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap()
2025-03-28 11:43 [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 1/2] libs: " Petr Vorel
@ 2025-03-28 11:43 ` Petr Vorel
2025-03-31 16:06 ` Cyril Hrubis
2025-03-31 15:52 ` [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Cyril Hrubis
2 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2025-03-28 11:43 UTC (permalink / raw)
To: ltp
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
testcases/kernel/mem/ksm/ksm06.c | 4 +---
testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c | 4 +---
testcases/kernel/syscalls/get_mempolicy/get_mempolicy02.c | 4 +---
testcases/kernel/syscalls/mbind/mbind02.c | 4 +---
testcases/kernel/syscalls/mbind/mbind03.c | 4 +---
testcases/kernel/syscalls/mbind/mbind04.c | 4 +---
testcases/kernel/syscalls/set_mempolicy/set_mempolicy01.c | 4 +---
testcases/kernel/syscalls/set_mempolicy/set_mempolicy02.c | 4 +---
testcases/kernel/syscalls/set_mempolicy/set_mempolicy03.c | 4 +---
testcases/kernel/syscalls/set_mempolicy/set_mempolicy04.c | 4 +---
10 files changed, 10 insertions(+), 30 deletions(-)
diff --git a/testcases/kernel/mem/ksm/ksm06.c b/testcases/kernel/mem/ksm/ksm06.c
index a8e73275dd..936980dee6 100644
--- a/testcases/kernel/mem/ksm/ksm06.c
+++ b/testcases/kernel/mem/ksm/ksm06.c
@@ -124,9 +124,7 @@ static void setup(void)
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, nr_pages * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, nr_pages * page_size / 1024, 2);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
index 3c854d1096..031c35f40e 100644
--- a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
+++ b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
@@ -142,9 +142,7 @@ static void setup(void)
{
unsigned int i;
- node = tst_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024);
- if (node->cnt < 1)
- tst_brk(TCONF, "test requires at least one NUMA memory node");
+ node = safe_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024, 1);
nodemask = numa_allocate_nodemask();
empty_nodemask = numa_allocate_nodemask();
diff --git a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy02.c b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy02.c
index 79ff5d94f8..9344cdbb12 100644
--- a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy02.c
+++ b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy02.c
@@ -55,9 +55,7 @@ static struct test_case tcase[] = {
static void setup(void)
{
- node = tst_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024);
- if (node->cnt < 1)
- tst_brk(TCONF, "test requires at least one NUMA memory node");
+ node = safe_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024, 1);
nodemask = numa_allocate_nodemask();
}
diff --git a/testcases/kernel/syscalls/mbind/mbind02.c b/testcases/kernel/syscalls/mbind/mbind02.c
index cd6a032269..c690ac858e 100644
--- a/testcases/kernel/syscalls/mbind/mbind02.c
+++ b/testcases/kernel/syscalls/mbind/mbind02.c
@@ -32,9 +32,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * page_size / 1024, 2);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/mbind/mbind03.c b/testcases/kernel/syscalls/mbind/mbind03.c
index 3d477c9cbb..58967cc06a 100644
--- a/testcases/kernel/syscalls/mbind/mbind03.c
+++ b/testcases/kernel/syscalls/mbind/mbind03.c
@@ -29,9 +29,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * page_size / 1024, 2);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/mbind/mbind04.c b/testcases/kernel/syscalls/mbind/mbind04.c
index 50028835f9..795905cc14 100644
--- a/testcases/kernel/syscalls/mbind/mbind04.c
+++ b/testcases/kernel/syscalls/mbind/mbind04.c
@@ -31,9 +31,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024, 2);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy01.c b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy01.c
index 39e7156d06..92ef165d79 100644
--- a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy01.c
+++ b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy01.c
@@ -32,9 +32,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024, 2);
/*
* In most cases, set_mempolicy01 finish quickly, but when the platform
diff --git a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy02.c b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy02.c
index 3db9c20090..57fef862da 100644
--- a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy02.c
+++ b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy02.c
@@ -33,9 +33,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * ALLOC_ON_NODE * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * ALLOC_ON_NODE * page_size / 1024, 2);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy03.c b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy03.c
index 5cfcda6d8c..ac464e5bc1 100644
--- a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy03.c
+++ b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy03.c
@@ -31,9 +31,7 @@ static void setup(void)
{
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024, 2);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy04.c b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy04.c
index 2a1d2e1b9a..8e0ed2dc2a 100644
--- a/testcases/kernel/syscalls/set_mempolicy/set_mempolicy04.c
+++ b/testcases/kernel/syscalls/set_mempolicy/set_mempolicy04.c
@@ -44,9 +44,7 @@ static void setup(void)
page_size = getpagesize();
- nodes = tst_get_nodemap(TST_NUMA_MEM, node_min_pages * page_size / 1024);
- if (nodes->cnt <= 1)
- tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
+ nodes = safe_get_nodemap(TST_NUMA_MEM, node_min_pages * page_size / 1024, 2);
}
static void cleanup(void)
--
2.49.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap()
2025-03-28 11:43 [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 1/2] libs: " Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap() Petr Vorel
@ 2025-03-31 15:52 ` Cyril Hrubis
2025-03-31 17:31 ` Petr Vorel
2 siblings, 1 reply; 9+ messages in thread
From: Cyril Hrubis @ 2025-03-31 15:52 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> not a huge improvement, but because all tst_get_nodemap() are in the
> setup (and only ksm06.c allows input parameter) we could have struct
> tst_test member which would call safe_get_nodemap().
>
> e.g.:
>
> .nodemap = (const struct tst_path_val) {
> .type = TST_NUMA_MEM
> .required = 2,
> },
I do not get this, the struct tst_path_val is something completely
different.
> safe_get_nodemap(tst_test->nodemap->type,
> tst_test->nodemap->required * getpagesize() / 1024);
>
> This would not work for non - page sized nodes, e.g.:
> nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
>
> => extra member would need to be added:
>
> .nodemap = (const struct tst_path_val) {
> .type = TST_NUMA_MEM
> .required = 2,
> .size = PAGES_ALLOCATED, // default == 1
> },
I've avoided the size to be in pages and choosen kilobytes instead
because the page size can differ a lot.
> would call:
>
> safe_get_nodemap(tst_test->nodemap->type,
> tst_test->nodemap->required * tst_test->nodemap->size * getpagesize() / 1024,
^
This does not make any sense.
The memory parameter is supposed to be minimal free memory on each node,
for each node we check that it has at least min_mem_kb in the
node_has_enough_memory() function.
There is no point in multiplying that by the number of nodes we require.
And this looks like it uses kilobytes not pages.
> tst_test->nodemap->required);
I guess that what you meant is that we will add tst_numa structure such as:
struct tst_numa {
enum tst_numa_types node_type;
unsigned int min_nodes;
unsigned int min_mem_kb;
};
And then use that in tst_test structure. That would certainly make
sense, but I guess that we would have to move the numa library to the
lib/ as well. I'm not sure that we can have a function call from
tst_test.c library to something that is not compiled in by default.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 1/2] libs: Add safe_get_nodemap()
2025-03-28 11:43 ` [LTP] [RFC][PATCH 1/2] libs: " Petr Vorel
@ 2025-03-31 16:00 ` Cyril Hrubis
2025-03-31 17:55 ` Petr Vorel
0 siblings, 1 reply; 9+ messages in thread
From: Cyril Hrubis @ 2025-03-31 16:00 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
On Fri, Mar 28, 2025 at 12:43:10PM +0100, Petr Vorel wrote:
> This requires to add also tst_numa_type_name().
>
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
> include/tst_numa.h | 41 +++++++++++++++++++++++++++++++++++++++--
> libs/numa/tst_numa.c | 14 ++++++++++++++
> 2 files changed, 53 insertions(+), 2 deletions(-)
>
> diff --git a/include/tst_numa.h b/include/tst_numa.h
> index a1f9616300..191a57fa6b 100644
> --- a/include/tst_numa.h
> +++ b/include/tst_numa.h
> @@ -106,8 +106,30 @@ enum tst_numa_types {
> };
>
> /**
> - * tst_get_nodemap() - Allocates and returns numa node map, which is an array of numa nodes which
> - * contain desired resources e.g. memory.
> + * tst_numa_type_name() - Convert enum tst_numa_types to a description of a NUMA type.
> + *
> + * @type Bitflags of enum tst_numa_types specifying desired resources.
> + *
> + * @return a string describing a NUMA type.
> + */
> +static inline const char *tst_numa_type_name(int type)
> +{
> + if (type & ~(TST_NUMA_MEM))
> + tst_brk(TBROK, "Invalid type %i\n", type);
> +
> + switch (type) {
> + case TST_NUMA_MEM:
> + return " memory";
> + case TST_NUMA_ANY:
> + return "";
> + default:
> + return " unknown";
> + }
> +}
> +
> +/**
> + * tst_get_nodemap() - Allocates and returns numa node map, which is an array of
> + * NUMA nodes which contain desired resources e.g. memory.
> *
> * @type: Bitflags of enum tst_numa_types specifying desired resources.
> * @min_mem_kb: Minimal free RAM on memory nodes, if given node has less than
> @@ -119,4 +141,19 @@ enum tst_numa_types {
> */
> struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb);
>
> +/**
> + * safe_get_nodemap() - Calls tst_get_nodemap() with check for minimal required
> + * NUMA nodes. Call tst_brk(TCONF) if not enough NUMA nodes.
> + *
> + * @type: Bitflags of enum tst_numa_types specifying desired resources.
> + * @min_mem_kb: Minimal free RAM on memory nodes, if given node has less than
> + * requested amount of free+buffers memory it's not included in
> + * the resulting list of nodes.
> + * @required: Minimal number of a required NUMA nodes.
> + *
> + * return: On success returns allocated and initialized struct tst_nodemap which contains
> + * array of numa node ids that contains desired resources.
> + */
> +struct tst_nodemap *safe_get_nodemap(int type, size_t min_mem_kb, size_t required);
> +
> #endif /* TST_NUMA_H__ */
> diff --git a/libs/numa/tst_numa.c b/libs/numa/tst_numa.c
> index c3297013be..f004e29014 100644
> --- a/libs/numa/tst_numa.c
> +++ b/libs/numa/tst_numa.c
> @@ -221,4 +221,18 @@ struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb)
> return nodes;
> }
>
> +struct tst_nodemap *safe_get_nodemap(int type, size_t min_mem_kb, size_t required)
> +{
> + struct tst_nodemap *nodes;
> +
> + nodes = tst_get_nodemap(type, min_mem_kb);
> +
> + if (nodes->cnt < required) {
> + tst_brk(TCONF, "Test requires at least %zi NUMA%s node%s",
> + required, tst_numa_type_name(type), required > 1 ? "s" : "");
^
It does not make any sense to
request a NUMA with at least 1
node. Every computer has at least 1
node.
It may make sense to TBROK if the minimal number of nodes <= 1
> + }
> +
> + return nodes;
> +}
> +
> #endif
> --
> 2.49.0
>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap()
2025-03-28 11:43 ` [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap() Petr Vorel
@ 2025-03-31 16:06 ` Cyril Hrubis
0 siblings, 0 replies; 9+ messages in thread
From: Cyril Hrubis @ 2025-03-31 16:06 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> --- a/testcases/kernel/mem/ksm/ksm06.c
> +++ b/testcases/kernel/mem/ksm/ksm06.c
> @@ -124,9 +124,7 @@ static void setup(void)
>
> page_size = getpagesize();
>
> - nodes = tst_get_nodemap(TST_NUMA_MEM, nr_pages * page_size / 1024);
> - if (nodes->cnt <= 1)
> - tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
> + nodes = safe_get_nodemap(TST_NUMA_MEM, nr_pages * page_size / 1024, 2);
> }
>
> static struct tst_test test = {
> diff --git a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
> index 3c854d1096..031c35f40e 100644
> --- a/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
> +++ b/testcases/kernel/syscalls/get_mempolicy/get_mempolicy01.c
> @@ -142,9 +142,7 @@ static void setup(void)
> {
> unsigned int i;
>
> - node = tst_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024);
> - if (node->cnt < 1)
> - tst_brk(TCONF, "test requires at least one NUMA memory node");
> + node = safe_get_nodemap(TST_NUMA_MEM, PAGES_ALLOCATED * getpagesize() / 1024, 1);
Hmm, we are actually requesting at least 1 node.
The question is if we shouldn't change this. It's very unlikely that we
get wrong answer about on which node memory has been allocated if there
is only one node.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap()
2025-03-31 15:52 ` [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Cyril Hrubis
@ 2025-03-31 17:31 ` Petr Vorel
2025-04-02 10:14 ` Cyril Hrubis
0 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2025-03-31 17:31 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
> Hi!
> > not a huge improvement, but because all tst_get_nodemap() are in the
> > setup (and only ksm06.c allows input parameter) we could have struct
> > tst_test member which would call safe_get_nodemap().
> > e.g.:
> > .nodemap = (const struct tst_path_val) {
> > .type = TST_NUMA_MEM
> > .required = 2,
> > },
> I do not get this, the struct tst_path_val is something completely
> different.
I'm sorry, copy paste error. This was meant to be a new struct,
e.g. struct tst_nodemap_val. But I see you below suggested struct tst_numa.
> > safe_get_nodemap(tst_test->nodemap->type,
> > tst_test->nodemap->required * getpagesize() / 1024);
> > This would not work for non - page sized nodes, e.g.:
> > nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
> > => extra member would need to be added:
> > .nodemap = (const struct tst_path_val) {
> > .type = TST_NUMA_MEM
> > .required = 2,
> > .size = PAGES_ALLOCATED, // default == 1
> > },
> I've avoided the size to be in pages and choosen kilobytes instead
> because the page size can differ a lot.
Make sense.
> > would call:
> > safe_get_nodemap(tst_test->nodemap->type,
> > tst_test->nodemap->required * tst_test->nodemap->size * getpagesize() / 1024,
> ^
> This does not make any sense.
> The memory parameter is supposed to be minimal free memory on each node,
> for each node we check that it has at least min_mem_kb in the
> node_has_enough_memory() function.
> There is no point in multiplying that by the number of nodes we require.
> And this looks like it uses kilobytes not pages.
> > tst_test->nodemap->required);
> I guess that what you meant is that we will add tst_numa structure such as:
> struct tst_numa {
> enum tst_numa_types node_type;
> unsigned int min_nodes;
> unsigned int min_mem_kb;
> };
+1, thanks for suggesting a proper struct :).
BTW why we can use enum tst_numa_types in struct and not as function parameter?
-struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb);
+struct tst_nodemap *tst_get_nodemap(enum tst_numa_types type, size_t min_mem_kb);
Old toolchains? Maybe not needed nowadays? I guess with using enum we could get
rid of the check for enum validity:
if (type & ~(TST_NUMA_MEM))
tst_brk(TBROK, "Invalid type %i\n", type);
> And then use that in tst_test structure. That would certainly make
> sense, but I guess that we would have to move the numa library to the
> lib/ as well. I'm not sure that we can have a function call from
> tst_test.c library to something that is not compiled in by default.
Correct, file is in libs/numa/tst_numa.c. But how about use predecessor check?
if (tst_test->numa) {
#ifdef HAVE_NUMA_V2
...
#else
tst_brk(TCONF, NUMA_ERROR_MSG);
#endif
}
With help we would even get rid of else part of the compile check in the
tests:
#else
TST_TEST_TCONF(NUMA_ERROR_MSG);
But we would have modify lib/Makefile to conditionally add "-lnuma -lltpnuma".
"-lnuma" would be based on NUMA_LIBS (stored in include/mk/config.mk, detected
in m4/ltp-numa.m4), e.g. something like this could work:
ifneq ($(NUMA_LIBS),)
LDLIBS += $(NUMA_LIBS) -lltpnuma
endif
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 1/2] libs: Add safe_get_nodemap()
2025-03-31 16:00 ` Cyril Hrubis
@ 2025-03-31 17:55 ` Petr Vorel
0 siblings, 0 replies; 9+ messages in thread
From: Petr Vorel @ 2025-03-31 17:55 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
> > +struct tst_nodemap *safe_get_nodemap(int type, size_t min_mem_kb, size_t required)
> > +{
> > + struct tst_nodemap *nodes;
> > +
> > + nodes = tst_get_nodemap(type, min_mem_kb);
> > +
> > + if (nodes->cnt < required) {
> > + tst_brk(TCONF, "Test requires at least %zi NUMA%s node%s",
> > + required, tst_numa_type_name(type), required > 1 ? "s" : "");
> ^
> It does not make any sense to
> request a NUMA with at least 1
> node. Every computer has at least 1
> node.
Thanks!
> It may make sense to TBROK if the minimal number of nodes <= 1
+1.
I guess we will find use for this even in the case of more complicated version
with struct tst_numa (it'd be used in tst_lib.c and in tests which specify nodes
via the command line parameter.
Thanks for your review!
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap()
2025-03-31 17:31 ` Petr Vorel
@ 2025-04-02 10:14 ` Cyril Hrubis
0 siblings, 0 replies; 9+ messages in thread
From: Cyril Hrubis @ 2025-04-02 10:14 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hi!
> +1, thanks for suggesting a proper struct :).
>
> BTW why we can use enum tst_numa_types in struct and not as function parameter?
Lazines I suppose.
> -struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb);
> +struct tst_nodemap *tst_get_nodemap(enum tst_numa_types type, size_t min_mem_kb);
>
> Old toolchains? Maybe not needed nowadays? I guess with using enum we could get
> rid of the check for enum validity:
> if (type & ~(TST_NUMA_MEM))
> tst_brk(TBROK, "Invalid type %i\n", type);
No we couldn't because you can stil pass whatever you want even when the
type is enum.
> > And then use that in tst_test structure. That would certainly make
> > sense, but I guess that we would have to move the numa library to the
> > lib/ as well. I'm not sure that we can have a function call from
> > tst_test.c library to something that is not compiled in by default.
>
> Correct, file is in libs/numa/tst_numa.c. But how about use predecessor check?
>
> if (tst_test->numa) {
> #ifdef HAVE_NUMA_V2
> ...
> #else
> tst_brk(TCONF, NUMA_ERROR_MSG);
> #endif
> }
>
> With help we would even get rid of else part of the compile check in the
> tests:
>
> #else
> TST_TEST_TCONF(NUMA_ERROR_MSG);
>
> But we would have modify lib/Makefile to conditionally add "-lnuma -lltpnuma".
> "-lnuma" would be based on NUMA_LIBS (stored in include/mk/config.mk, detected
> in m4/ltp-numa.m4), e.g. something like this could work:
>
> ifneq ($(NUMA_LIBS),)
> LDLIBS += $(NUMA_LIBS) -lltpnuma
> endif
I do no think that this would be enough, because all tests are linking
againts -lltp and if -lltp potentionally calls into the libnuma suddenly
all tests has to be linked againts libnuma. Or libnuma must be moved
into the ltp library.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-04-02 10:14 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-28 11:43 [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 1/2] libs: " Petr Vorel
2025-03-31 16:00 ` Cyril Hrubis
2025-03-31 17:55 ` Petr Vorel
2025-03-28 11:43 ` [LTP] [RFC][PATCH 2/2] Use safe_get_nodemap() Petr Vorel
2025-03-31 16:06 ` Cyril Hrubis
2025-03-31 15:52 ` [LTP] [RFC][PATCH 0/2] Add safe_get_nodemap() Cyril Hrubis
2025-03-31 17:31 ` Petr Vorel
2025-04-02 10:14 ` Cyril Hrubis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox