* [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
@ 2025-04-28 17:03 Donet Tom
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
` (4 more replies)
0 siblings, 5 replies; 15+ messages in thread
From: Donet Tom @ 2025-04-28 17:03 UTC (permalink / raw)
To: Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel, Donet Tom
During node device initialization, `memory blocks` are registered under
each NUMA node. The `memory blocks` to be registered are identified using
the node’s start and end PFNs, which are obtained from the node's pg_data
However, not all PFNs within this range necessarily belong to the same
node—some may belong to other nodes. Additionally, due to the
discontiguous nature of physical memory, certain sections within a
`memory block` may be absent.
As a result, `memory blocks` that fall between a node’s start and end
PFNs may span across multiple nodes, and some sections within those blocks
may be missing. `Memory blocks` have a fixed size, which is architecture
dependent.
Due to these considerations, the memory block registration is currently
performed as follows:
for_each_online_node(nid):
start_pfn = pgdat->node_start_pfn;
end_pfn = pgdat->node_start_pfn + node_spanned_pages;
for_each_memory_block_between(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn))
mem_blk = memory_block_id(pfn_to_section_nr(pfn));
pfn_mb_start=section_nr_to_pfn(mem_blk->start_section_nr)
pfn_mb_end = pfn_start + memory_block_pfns - 1
for (pfn = pfn_mb_start; pfn < pfn_mb_end; pfn++):
if (get_nid_for_pfn(pfn) != nid):
continue;
else
do_register_memory_block_under_node(nid, mem_blk,
MEMINIT_EARLY);
Here, we derive the start and end PFNs from the node's pg_data, then
determine the memory blocks that may belong to the node. For each
`memory block` in this range, we inspect all PFNs it contains and check
their associated NUMA node ID. If a PFN within the block matches the
current node, the memory block is registered under that node.
If CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, get_nid_for_pfn() performs
a binary search in the `memblock regions` to determine the NUMA node ID
for a given PFN. If it is not enabled, the node ID is retrieved directly
from the struct page.
On large systems, this process can become time-consuming, especially since
we iterate over each `memory block` and all PFNs within it until a match is
found. When CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, the additional
overhead of the binary search increases the execution time significantly,
potentially leading to soft lockups during boot.
In this patch, we iterate over `memblock region` to identify the
`memory blocks` that belong to the current NUMA node. `memblock regions`
are contiguous memory ranges, each associated with a single NUMA node, and
they do not span across multiple nodes.
for_each_online_node(nid):
for_each_memory_region(r): // r => region
if (r->nid != nid):
continue;
else
for_each_memory_block_between(r->base, r->base + r->size - 1):
do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
We iterate over all `memblock regions` and identify those that belong to
the current NUMA node. For each `memblock region` associated with the
current node, we calculate the start and end `memory blocks` based on the
region's start and end PFNs. We then register all `memory blocks` within
that range under the current node.
Test Results on My system with 32TB RAM
=======================================
1. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled.
Without this patch
------------------
Startup finished in 1min 16.528s (kernel)
With this patch
---------------
Startup finished in 17.236s (kernel) - 78% Improvement
2. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT disabled.
Without this patch
------------------
Startup finished in 28.320s (kernel)
With this patch
---------------
Startup finished in 15.621s (kernel) - 46% Improvement
Signed-off-by: Donet Tom <donettom@linux.ibm.com>
---
v1->v2
Reworked the implementation according to suggestions from
Mike Rapoport[1]
[1] - https://lore.kernel.org/all/Z_j2Gv9n4DOj6LSs@kernel.org/
v1 - https://lore.kernel.org/all/50142a29010463f436dc5c4feb540e5de3bb09df.1744175097.git.donettom@linux.ibm.com/
---
drivers/base/memory.c | 4 ++--
drivers/base/node.c | 39 +++++++++++++++++++++++++++++++++++++++
include/linux/memory.h | 2 ++
include/linux/node.h | 11 +++++------
4 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 19469e7f88c2..7f1d266ae593 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -60,7 +60,7 @@ static inline unsigned long pfn_to_block_id(unsigned long pfn)
return memory_block_id(pfn_to_section_nr(pfn));
}
-static inline unsigned long phys_to_block_id(unsigned long phys)
+unsigned long phys_to_block_id(unsigned long phys)
{
return pfn_to_block_id(PFN_DOWN(phys));
}
@@ -632,7 +632,7 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
*
* Called under device_hotplug_lock.
*/
-static struct memory_block *find_memory_block_by_id(unsigned long block_id)
+struct memory_block *find_memory_block_by_id(unsigned long block_id)
{
struct memory_block *mem;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index cd13ef287011..4869333d366d 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -20,6 +20,7 @@
#include <linux/pm_runtime.h>
#include <linux/swap.h>
#include <linux/slab.h>
+#include <linux/memblock.h>
static const struct bus_type node_subsys = {
.name = "node",
@@ -850,6 +851,44 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
}
+/*
+ * register_memory_blocks_under_node_early : Register the memory
+ * blocks under the current node.
+ * @nid : Current node under registration
+ *
+ * This function iterates over all memblock regions and identifies the regions
+ * that belong to the current node. For each region which belongs to current
+ * node, it calculates the start and end memory blocks based on the region's
+ * start and end PFNs. It then registers all memory blocks within that range
+ * under the current node.
+ *
+ */
+void register_memory_blocks_under_node_early(int nid)
+{
+ struct memblock_region *r;
+ unsigned long start_block_id;
+ unsigned long end_block_id;
+ struct memory_block *mem;
+ unsigned long block_id;
+
+ for_each_mem_region(r) {
+ if (r->nid == nid) {
+ start_block_id = phys_to_block_id(r->base);
+ end_block_id = phys_to_block_id(r->base + r->size - 1);
+
+ for (block_id = start_block_id; block_id <= end_block_id; block_id++) {
+ mem = find_memory_block_by_id(block_id);
+ if (!mem)
+ continue;
+
+ do_register_memory_block_under_node(nid, mem, MEMINIT_EARLY);
+ put_device(&mem->dev);
+ }
+
+ }
+ }
+}
+
void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
unsigned long end_pfn,
enum meminit_context context)
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 12daa6ec7d09..cb8579226536 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -171,6 +171,8 @@ struct memory_group *memory_group_find_by_id(int mgid);
typedef int (*walk_memory_groups_func_t)(struct memory_group *, void *);
int walk_dynamic_memory_groups(int nid, walk_memory_groups_func_t func,
struct memory_group *excluded, void *arg);
+unsigned long phys_to_block_id(unsigned long phys);
+struct memory_block *find_memory_block_by_id(unsigned long block_id);
#define hotplug_memory_notifier(fn, pri) ({ \
static __meminitdata struct notifier_block fn##_mem_nb =\
{ .notifier_call = fn, .priority = pri };\
diff --git a/include/linux/node.h b/include/linux/node.h
index 2b7517892230..c5a8a7f0aac7 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -114,12 +114,16 @@ extern struct node *node_devices[];
void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
unsigned long end_pfn,
enum meminit_context context);
+void register_memory_blocks_under_node_early(int nid);
#else
static inline void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
unsigned long end_pfn,
enum meminit_context context)
{
}
+void register_memory_blocks_under_node_early(int nid)
+{
+}
#endif
extern void unregister_node(struct node *node);
@@ -134,15 +138,10 @@ static inline int register_one_node(int nid)
int error = 0;
if (node_online(nid)) {
- struct pglist_data *pgdat = NODE_DATA(nid);
- unsigned long start_pfn = pgdat->node_start_pfn;
- unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages;
-
error = __register_one_node(nid);
if (error)
return error;
- register_memory_blocks_under_node(nid, start_pfn, end_pfn,
- MEMINIT_EARLY);
+ register_memory_blocks_under_node_early(nid);
}
return error;
--
2.48.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
@ 2025-04-28 17:03 ` Donet Tom
2025-04-28 21:21 ` David Hildenbrand
` (2 more replies)
2025-04-28 21:19 ` [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time David Hildenbrand
` (3 subsequent siblings)
4 siblings, 3 replies; 15+ messages in thread
From: Donet Tom @ 2025-04-28 17:03 UTC (permalink / raw)
To: Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel, Donet Tom
The functions register_mem_block_under_node_early and get_nid_for_pfn
are not used, as register_memory_blocks_under_node_early is now used
to register memory blocks during early boot. Therefore, these unused
functions have been removed.
Signed-off-by: Donet Tom <donettom@linux.ibm.com>
---
drivers/base/node.c | 54 +--------------------------------------------
1 file changed, 1 insertion(+), 53 deletions(-)
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 4869333d366d..59ec507fc97d 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -748,15 +748,6 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
}
#ifdef CONFIG_MEMORY_HOTPLUG
-static int __ref get_nid_for_pfn(unsigned long pfn)
-{
-#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
- if (system_state < SYSTEM_RUNNING)
- return early_pfn_to_nid(pfn);
-#endif
- return pfn_to_nid(pfn);
-}
-
static void do_register_memory_block_under_node(int nid,
struct memory_block *mem_blk,
enum meminit_context context)
@@ -783,46 +774,6 @@ static void do_register_memory_block_under_node(int nid,
ret);
}
-/* register memory section under specified node if it spans that node */
-static int register_mem_block_under_node_early(struct memory_block *mem_blk,
- void *arg)
-{
- unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
- unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
- unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
- int nid = *(int *)arg;
- unsigned long pfn;
-
- for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
- int page_nid;
-
- /*
- * memory block could have several absent sections from start.
- * skip pfn range from absent section
- */
- if (!pfn_in_present_section(pfn)) {
- pfn = round_down(pfn + PAGES_PER_SECTION,
- PAGES_PER_SECTION) - 1;
- continue;
- }
-
- /*
- * We need to check if page belongs to nid only at the boot
- * case because node's ranges can be interleaved.
- */
- page_nid = get_nid_for_pfn(pfn);
- if (page_nid < 0)
- continue;
- if (page_nid != nid)
- continue;
-
- do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
- return 0;
- }
- /* mem section does not span the specified node */
- return 0;
-}
-
/*
* During hotplug we know that all pages in the memory block belong to the same
* node.
@@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
{
walk_memory_blocks_func_t func;
- if (context == MEMINIT_HOTPLUG)
- func = register_mem_block_under_node_hotplug;
- else
- func = register_mem_block_under_node_early;
+ func = register_mem_block_under_node_hotplug;
walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
(void *)&nid, func);
--
2.48.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
@ 2025-04-28 21:19 ` David Hildenbrand
2025-04-29 14:08 ` Donet Tom
2025-04-29 16:37 ` kernel test robot
` (2 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: David Hildenbrand @ 2025-04-28 21:19 UTC (permalink / raw)
To: Donet Tom, Mike Rapoport, Oscar Salvador, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 28.04.25 19:03, Donet Tom wrote:
> During node device initialization, `memory blocks` are registered under
> each NUMA node. The `memory blocks` to be registered are identified using
> the node’s start and end PFNs, which are obtained from the node's pg_data
>
> However, not all PFNs within this range necessarily belong to the same
> node—some may belong to other nodes. Additionally, due to the
> discontiguous nature of physical memory, certain sections within a
> `memory block` may be absent.>
> As a result, `memory blocks` that fall between a node’s start and end
> PFNs may span across multiple nodes, and some sections within those blocks
> may be missing. `Memory blocks` have a fixed size, which is architecture
> dependent.
>
> Due to these considerations, the memory block registration is currently
> performed as follows:
>
> for_each_online_node(nid):
> start_pfn = pgdat->node_start_pfn;
> end_pfn = pgdat->node_start_pfn + node_spanned_pages;
> for_each_memory_block_between(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn))
> mem_blk = memory_block_id(pfn_to_section_nr(pfn));
> pfn_mb_start=section_nr_to_pfn(mem_blk->start_section_nr)
> pfn_mb_end = pfn_start + memory_block_pfns - 1
> for (pfn = pfn_mb_start; pfn < pfn_mb_end; pfn++):
> if (get_nid_for_pfn(pfn) != nid):
> continue;
> else
> do_register_memory_block_under_node(nid, mem_blk,
> MEMINIT_EARLY);
>
> Here, we derive the start and end PFNs from the node's pg_data, then
> determine the memory blocks that may belong to the node. For each
> `memory block` in this range, we inspect all PFNs it contains and check
> their associated NUMA node ID. If a PFN within the block matches the
> current node, the memory block is registered under that node.
>
> If CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, get_nid_for_pfn() performs
> a binary search in the `memblock regions` to determine the NUMA node ID
> for a given PFN. If it is not enabled, the node ID is retrieved directly
> from the struct page.
>
> On large systems, this process can become time-consuming, especially since
> we iterate over each `memory block` and all PFNs within it until a match is
> found. When CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, the additional
> overhead of the binary search increases the execution time significantly,
> potentially leading to soft lockups during boot.
>
> In this patch, we iterate over `memblock region` to identify the
> `memory blocks` that belong to the current NUMA node. `memblock regions`
> are contiguous memory ranges, each associated with a single NUMA node, and
> they do not span across multiple nodes.
>
> for_each_online_node(nid):
> for_each_memory_region(r): // r => region
> if (r->nid != nid):
> continue;
> else
> for_each_memory_block_between(r->base, r->base + r->size - 1):
> do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
>
> We iterate over all `memblock regions` and identify those that belong to
> the current NUMA node. For each `memblock region` associated with the
> current node, we calculate the start and end `memory blocks` based on the
> region's start and end PFNs. We then register all `memory blocks` within
> that range under the current node.
Yes, makes sense.
>
> Test Results on My system with 32TB RAM
> =======================================
> 1. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled.
>
> Without this patch
> ------------------
> Startup finished in 1min 16.528s (kernel)
>
> With this patch
> ---------------
> Startup finished in 17.236s (kernel) - 78% Improvement
Wow!
>
> 2. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT disabled.
>
> Without this patch
> ------------------
> Startup finished in 28.320s (kernel)
>
> With this patch
> ---------------
> Startup finished in 15.621s (kernel) - 46% Improvement
>
Also very nice!
> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
> ---
>
> v1->v2
>
> Reworked the implementation according to suggestions from
> Mike Rapoport[1]
>
> [1] - https://lore.kernel.org/all/Z_j2Gv9n4DOj6LSs@kernel.org/
>
> v1 - https://lore.kernel.org/all/50142a29010463f436dc5c4feb540e5de3bb09df.1744175097.git.donettom@linux.ibm.com/
> ---
> drivers/base/memory.c | 4 ++--
> drivers/base/node.c | 39 +++++++++++++++++++++++++++++++++++++++
> include/linux/memory.h | 2 ++
> include/linux/node.h | 11 +++++------
> 4 files changed, 48 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
> index 19469e7f88c2..7f1d266ae593 100644
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -60,7 +60,7 @@ static inline unsigned long pfn_to_block_id(unsigned long pfn)
> return memory_block_id(pfn_to_section_nr(pfn));
> }
>
> -static inline unsigned long phys_to_block_id(unsigned long phys)
> +unsigned long phys_to_block_id(unsigned long phys)
> {
> return pfn_to_block_id(PFN_DOWN(phys));
> }
> @@ -632,7 +632,7 @@ int __weak arch_get_memory_phys_device(unsigned long start_pfn)
> *
> * Called under device_hotplug_lock.
> */
> -static struct memory_block *find_memory_block_by_id(unsigned long block_id)
> +struct memory_block *find_memory_block_by_id(unsigned long block_id)
> {
> struct memory_block *mem;
>
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index cd13ef287011..4869333d366d 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -20,6 +20,7 @@
> #include <linux/pm_runtime.h>
> #include <linux/swap.h>
> #include <linux/slab.h>
> +#include <linux/memblock.h>
>
> static const struct bus_type node_subsys = {
> .name = "node",
> @@ -850,6 +851,44 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
> kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
> }
>
> +/*
> + * register_memory_blocks_under_node_early : Register the memory
> + * blocks under the current node.
> + * @nid : Current node under registration
> + *
> + * This function iterates over all memblock regions and identifies the regions
> + * that belong to the current node. For each region which belongs to current
> + * node, it calculates the start and end memory blocks based on the region's
> + * start and end PFNs. It then registers all memory blocks within that range
> + * under the current node.
> + *
> + */
> +void register_memory_blocks_under_node_early(int nid)
> +{
> + struct memblock_region *r;
You almost achieved a reverse x-mas tree :)
> + unsigned long start_block_id;
> + unsigned long end_block_id;
> + struct memory_block *mem;
> + unsigned long block_id;
> +
> + for_each_mem_region(r) {
> + if (r->nid == nid) {
To reduce indentation
if (r->nid != nid)
continue;
> + start_block_id = phys_to_block_id(r->base);
> + end_block_id = phys_to_block_id(r->base + r->size - 1);
Probably you could make them const in the for loop
const unsigned long start_block_id = phys_to_block_id(r->base);
const unsigned long end_block_id = phys_to_block_id(r->base + r->size - 1);
Okay, so end is inclusive as well.
> +
> + for (block_id = start_block_id; block_id <= end_block_id; block_id++) {
> + mem = find_memory_block_by_id(block_id);
> + if (!mem)
> + continue;
> +
> + do_register_memory_block_under_node(nid, mem, MEMINIT_EARLY);
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
@ 2025-04-28 21:21 ` David Hildenbrand
2025-04-29 14:07 ` Donet Tom
2025-04-30 7:48 ` Oscar Salvador
2025-05-01 15:08 ` Zi Yan
2 siblings, 1 reply; 15+ messages in thread
From: David Hildenbrand @ 2025-04-28 21:21 UTC (permalink / raw)
To: Donet Tom, Mike Rapoport, Oscar Salvador, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 28.04.25 19:03, Donet Tom wrote:
Nit: I'd call this patch
"driver/base: remove register_mem_block_under_node_early()"
And then just naturally remove get_nid_for_pfn() with it, as it is the
last user and it resides in the same file.
> The functions register_mem_block_under_node_early and get_nid_for_pfn
> are not used, as register_memory_blocks_under_node_early is now used
> to register memory blocks during early boot. Therefore, these unused
> functions have been removed.
>
> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
> ---
> drivers/base/node.c | 54 +--------------------------------------------
> 1 file changed, 1 insertion(+), 53 deletions(-)
>
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 4869333d366d..59ec507fc97d 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -748,15 +748,6 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG
> -static int __ref get_nid_for_pfn(unsigned long pfn)
> -{
> -#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
> - if (system_state < SYSTEM_RUNNING)
> - return early_pfn_to_nid(pfn);
> -#endif
> - return pfn_to_nid(pfn);
> -}
> -
> static void do_register_memory_block_under_node(int nid,
> struct memory_block *mem_blk,
> enum meminit_context context)
> @@ -783,46 +774,6 @@ static void do_register_memory_block_under_node(int nid,
> ret);
> }
>
> -/* register memory section under specified node if it spans that node */
> -static int register_mem_block_under_node_early(struct memory_block *mem_blk,
> - void *arg)
> -{
> - unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
> - unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
> - unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
> - int nid = *(int *)arg;
> - unsigned long pfn;
> -
> - for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
> - int page_nid;
> -
> - /*
> - * memory block could have several absent sections from start.
> - * skip pfn range from absent section
> - */
> - if (!pfn_in_present_section(pfn)) {
> - pfn = round_down(pfn + PAGES_PER_SECTION,
> - PAGES_PER_SECTION) - 1;
> - continue;
> - }
> -
> - /*
> - * We need to check if page belongs to nid only at the boot
> - * case because node's ranges can be interleaved.
> - */
> - page_nid = get_nid_for_pfn(pfn);
> - if (page_nid < 0)
> - continue;
> - if (page_nid != nid)
> - continue;
> -
> - do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
> - return 0;
> - }
> - /* mem section does not span the specified node */
> - return 0;
> -}
> -
> /*
> * During hotplug we know that all pages in the memory block belong to the same
> * node.
> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
> {
> walk_memory_blocks_func_t func;
>
> - if (context == MEMINIT_HOTPLUG)
> - func = register_mem_block_under_node_hotplug;
> - else
> - func = register_mem_block_under_node_early;
> + func = register_mem_block_under_node_hotplug;
>
> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
> (void *)&nid, func);
You can pass func directly here and avoid the temporary variable.
Very nice!
Acked-by: David Hildenbrand <david@redhat.com>
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-28 21:21 ` David Hildenbrand
@ 2025-04-29 14:07 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-04-29 14:07 UTC (permalink / raw)
To: David Hildenbrand, Mike Rapoport, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 4/29/25 2:51 AM, David Hildenbrand wrote:
> On 28.04.25 19:03, Donet Tom wrote:
>
> Nit: I'd call this patch
>
> "driver/base: remove register_mem_block_under_node_early()"
>
> And then just naturally remove get_nid_for_pfn() with it, as it is the
> last user and it resides in the same file.
Sure, I will change it.
>
>> The functions register_mem_block_under_node_early and get_nid_for_pfn
>> are not used, as register_memory_blocks_under_node_early is now used
>> to register memory blocks during early boot. Therefore, these unused
>> functions have been removed.
>>
>> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
>> ---
>> drivers/base/node.c | 54 +--------------------------------------------
>> 1 file changed, 1 insertion(+), 53 deletions(-)
>>
>> diff --git a/drivers/base/node.c b/drivers/base/node.c
>> index 4869333d366d..59ec507fc97d 100644
>> --- a/drivers/base/node.c
>> +++ b/drivers/base/node.c
>> @@ -748,15 +748,6 @@ int unregister_cpu_under_node(unsigned int cpu,
>> unsigned int nid)
>> }
>> #ifdef CONFIG_MEMORY_HOTPLUG
>> -static int __ref get_nid_for_pfn(unsigned long pfn)
>> -{
>> -#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
>> - if (system_state < SYSTEM_RUNNING)
>> - return early_pfn_to_nid(pfn);
>> -#endif
>> - return pfn_to_nid(pfn);
>> -}
>> -
>> static void do_register_memory_block_under_node(int nid,
>> struct memory_block *mem_blk,
>> enum meminit_context context)
>> @@ -783,46 +774,6 @@ static void
>> do_register_memory_block_under_node(int nid,
>> ret);
>> }
>> -/* register memory section under specified node if it spans that
>> node */
>> -static int register_mem_block_under_node_early(struct memory_block
>> *mem_blk,
>> - void *arg)
>> -{
>> - unsigned long memory_block_pfns = memory_block_size_bytes() /
>> PAGE_SIZE;
>> - unsigned long start_pfn =
>> section_nr_to_pfn(mem_blk->start_section_nr);
>> - unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
>> - int nid = *(int *)arg;
>> - unsigned long pfn;
>> -
>> - for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
>> - int page_nid;
>> -
>> - /*
>> - * memory block could have several absent sections from start.
>> - * skip pfn range from absent section
>> - */
>> - if (!pfn_in_present_section(pfn)) {
>> - pfn = round_down(pfn + PAGES_PER_SECTION,
>> - PAGES_PER_SECTION) - 1;
>> - continue;
>> - }
>> -
>> - /*
>> - * We need to check if page belongs to nid only at the boot
>> - * case because node's ranges can be interleaved.
>> - */
>> - page_nid = get_nid_for_pfn(pfn);
>> - if (page_nid < 0)
>> - continue;
>> - if (page_nid != nid)
>> - continue;
>> -
>> - do_register_memory_block_under_node(nid, mem_blk,
>> MEMINIT_EARLY);
>> - return 0;
>> - }
>> - /* mem section does not span the specified node */
>> - return 0;
>> -}
>> -
>> /*
>> * During hotplug we know that all pages in the memory block belong
>> to the same
>> * node.
>> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid,
>> unsigned long start_pfn,
>> {
>> walk_memory_blocks_func_t func;
>> - if (context == MEMINIT_HOTPLUG)
>> - func = register_mem_block_under_node_hotplug;
>> - else
>> - func = register_mem_block_under_node_early;
>> + func = register_mem_block_under_node_hotplug;
>> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn -
>> start_pfn),
>> (void *)&nid, func);
>
> You can pass func directly here and avoid the temporary variable.
ok. I will change it.
>
> Very nice!
>
> Acked-by: David Hildenbrand <david@redhat.com>
Thanks David
I will address the review comments and submit the next version.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-28 21:19 ` [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time David Hildenbrand
@ 2025-04-29 14:08 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-04-29 14:08 UTC (permalink / raw)
To: David Hildenbrand, Mike Rapoport, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 4/29/25 2:49 AM, David Hildenbrand wrote:
> On 28.04.25 19:03, Donet Tom wrote:
>> During node device initialization, `memory blocks` are registered under
>> each NUMA node. The `memory blocks` to be registered are identified
>> using
>> the node’s start and end PFNs, which are obtained from the node's
>> pg_data
>>
>> However, not all PFNs within this range necessarily belong to the same
>> node—some may belong to other nodes. Additionally, due to the
>> discontiguous nature of physical memory, certain sections within a
>> `memory block` may be absent.> As a result, `memory blocks` that fall
>> between a node’s start and end
>> PFNs may span across multiple nodes, and some sections within those
>> blocks
>> may be missing. `Memory blocks` have a fixed size, which is architecture
>> dependent.
>>
>> Due to these considerations, the memory block registration is currently
>> performed as follows:
>>
>> for_each_online_node(nid):
>> start_pfn = pgdat->node_start_pfn;
>> end_pfn = pgdat->node_start_pfn + node_spanned_pages;
>> for_each_memory_block_between(PFN_PHYS(start_pfn),
>> PFN_PHYS(end_pfn))
>> mem_blk = memory_block_id(pfn_to_section_nr(pfn));
>> pfn_mb_start=section_nr_to_pfn(mem_blk->start_section_nr)
>> pfn_mb_end = pfn_start + memory_block_pfns - 1
>> for (pfn = pfn_mb_start; pfn < pfn_mb_end; pfn++):
>> if (get_nid_for_pfn(pfn) != nid):
>> continue;
>> else
>> do_register_memory_block_under_node(nid, mem_blk,
>> MEMINIT_EARLY);
>>
>> Here, we derive the start and end PFNs from the node's pg_data, then
>> determine the memory blocks that may belong to the node. For each
>> `memory block` in this range, we inspect all PFNs it contains and check
>> their associated NUMA node ID. If a PFN within the block matches the
>> current node, the memory block is registered under that node.
>>
>> If CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, get_nid_for_pfn()
>> performs
>> a binary search in the `memblock regions` to determine the NUMA node ID
>> for a given PFN. If it is not enabled, the node ID is retrieved directly
>> from the struct page.
>>
>> On large systems, this process can become time-consuming, especially
>> since
>> we iterate over each `memory block` and all PFNs within it until a
>> match is
>> found. When CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, the additional
>> overhead of the binary search increases the execution time
>> significantly,
>> potentially leading to soft lockups during boot.
>>
>> In this patch, we iterate over `memblock region` to identify the
>> `memory blocks` that belong to the current NUMA node. `memblock regions`
>> are contiguous memory ranges, each associated with a single NUMA
>> node, and
>> they do not span across multiple nodes.
>>
>> for_each_online_node(nid):
>> for_each_memory_region(r): // r => region
>> if (r->nid != nid):
>> continue;
>> else
>> for_each_memory_block_between(r->base, r->base + r->size - 1):
>> do_register_memory_block_under_node(nid, mem_blk,
>> MEMINIT_EARLY);
>>
>> We iterate over all `memblock regions` and identify those that belong to
>> the current NUMA node. For each `memblock region` associated with the
>> current node, we calculate the start and end `memory blocks` based on
>> the
>> region's start and end PFNs. We then register all `memory blocks` within
>> that range under the current node.
>
> Yes, makes sense.
>
>>
>> Test Results on My system with 32TB RAM
>> =======================================
>> 1. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled.
>>
>> Without this patch
>> ------------------
>> Startup finished in 1min 16.528s (kernel)
>>
>> With this patch
>> ---------------
>> Startup finished in 17.236s (kernel) - 78% Improvement
>
> Wow!
>
>>
>> 2. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT disabled.
>>
>> Without this patch
>> ------------------
>> Startup finished in 28.320s (kernel)
>>
>> With this patch
>> ---------------
>> Startup finished in 15.621s (kernel) - 46% Improvement
>>
>
> Also very nice!
>
>> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
>> ---
>>
>> v1->v2
>>
>> Reworked the implementation according to suggestions from
>> Mike Rapoport[1]
>>
>> [1] - https://lore.kernel.org/all/Z_j2Gv9n4DOj6LSs@kernel.org/
>>
>> v1 -
>> https://lore.kernel.org/all/50142a29010463f436dc5c4feb540e5de3bb09df.1744175097.git.donettom@linux.ibm.com/
>> ---
>> drivers/base/memory.c | 4 ++--
>> drivers/base/node.c | 39 +++++++++++++++++++++++++++++++++++++++
>> include/linux/memory.h | 2 ++
>> include/linux/node.h | 11 +++++------
>> 4 files changed, 48 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/base/memory.c b/drivers/base/memory.c
>> index 19469e7f88c2..7f1d266ae593 100644
>> --- a/drivers/base/memory.c
>> +++ b/drivers/base/memory.c
>> @@ -60,7 +60,7 @@ static inline unsigned long
>> pfn_to_block_id(unsigned long pfn)
>> return memory_block_id(pfn_to_section_nr(pfn));
>> }
>> -static inline unsigned long phys_to_block_id(unsigned long phys)
>> +unsigned long phys_to_block_id(unsigned long phys)
>> {
>> return pfn_to_block_id(PFN_DOWN(phys));
>> }
>> @@ -632,7 +632,7 @@ int __weak arch_get_memory_phys_device(unsigned
>> long start_pfn)
>> *
>> * Called under device_hotplug_lock.
>> */
>> -static struct memory_block *find_memory_block_by_id(unsigned long
>> block_id)
>> +struct memory_block *find_memory_block_by_id(unsigned long block_id)
>> {
>> struct memory_block *mem;
>> diff --git a/drivers/base/node.c b/drivers/base/node.c
>> index cd13ef287011..4869333d366d 100644
>> --- a/drivers/base/node.c
>> +++ b/drivers/base/node.c
>> @@ -20,6 +20,7 @@
>> #include <linux/pm_runtime.h>
>> #include <linux/swap.h>
>> #include <linux/slab.h>
>> +#include <linux/memblock.h>
>> static const struct bus_type node_subsys = {
>> .name = "node",
>> @@ -850,6 +851,44 @@ void unregister_memory_block_under_nodes(struct
>> memory_block *mem_blk)
>> kobject_name(&node_devices[mem_blk->nid]->dev.kobj));
>> }
>> +/*
>> + * register_memory_blocks_under_node_early : Register the memory
>> + * blocks under the current node.
>> + * @nid : Current node under registration
>> + *
>> + * This function iterates over all memblock regions and identifies
>> the regions
>> + * that belong to the current node. For each region which belongs to
>> current
>> + * node, it calculates the start and end memory blocks based on the
>> region's
>> + * start and end PFNs. It then registers all memory blocks within
>> that range
>> + * under the current node.
>> + *
>> + */
>> +void register_memory_blocks_under_node_early(int nid)
>> +{
>> + struct memblock_region *r;
>
> You almost achieved a reverse x-mas tree :)
>
>> + unsigned long start_block_id;
>> + unsigned long end_block_id;
>> + struct memory_block *mem;
>> + unsigned long block_id;
>> +
>> + for_each_mem_region(r) {
>> + if (r->nid == nid) {
>
> To reduce indentation
>
> if (r->nid != nid)
> continue;
ok.
>
>> + start_block_id = phys_to_block_id(r->base);
>> + end_block_id = phys_to_block_id(r->base + r->size - 1);
>
> Probably you could make them const in the for loop
>
> const unsigned long start_block_id = phys_to_block_id(r->base);
> const unsigned long end_block_id = phys_to_block_id(r->base +
> r->size - 1);
ok. I will add this change.
>
> Okay, so end is inclusive as well.
yes
>
>> +
>> + for (block_id = start_block_id; block_id <=
>> end_block_id; block_id++) {
>> + mem = find_memory_block_by_id(block_id);
>> + if (!mem)
>> + continue;
>> +
>> + do_register_memory_block_under_node(nid, mem,
>> MEMINIT_EARLY);
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
2025-04-28 21:19 ` [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time David Hildenbrand
@ 2025-04-29 16:37 ` kernel test robot
2025-04-29 17:01 ` kernel test robot
2025-04-30 7:38 ` Oscar Salvador
4 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2025-04-29 16:37 UTC (permalink / raw)
To: Donet Tom, Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: llvm, oe-kbuild-all, Linux Memory Management List, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-kernel, Donet Tom
Hi Donet,
kernel test robot noticed the following build errors:
[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.15-rc4 next-20250429]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Donet-Tom/driver-base-Remove-unused-functions/20250429-010442
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/fbe1e0c7d91bf3fa9a64ff5d84b53ded1d0d5ac7.1745852397.git.donettom%40linux.ibm.com
patch subject: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
config: s390-randconfig-001-20250429 (https://download.01.org/0day-ci/archive/20250430/202504300020.lYdm2Yud-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project f819f46284f2a79790038e1f6649172789734ae8)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300020.lYdm2Yud-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300020.lYdm2Yud-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from fs/attr.c:18:
In file included from include/linux/security.h:35:
In file included from include/linux/bpf.h:30:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
1 warning generated.
--
In file included from mm/slub.c:14:
In file included from include/linux/swap.h:11:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
mm/slub.c:414:6: warning: unused function 'stat_add' [-Wunused-function]
414 | void stat_add(const struct kmem_cache *s, enum stat_item si, int v)
| ^~~~~~~~
mm/slub.c:527:21: warning: unused function 'get_freepointer_safe' [-Wunused-function]
527 | static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
| ^~~~~~~~~~~~~~~~~~~~
mm/slub.c:627:1: warning: unused function 'slub_set_cpu_partial' [-Wunused-function]
627 | slub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects)
| ^~~~~~~~~~~~~~~~~~~~
mm/slub.c:691:20: warning: unused function '__slab_update_freelist' [-Wunused-function]
691 | static inline bool __slab_update_freelist(struct kmem_cache *s, struct slab *slab,
| ^~~~~~~~~~~~~~~~~~~~~~
mm/slub.c:1889:20: warning: unused function 'set_track' [-Wunused-function]
1889 | static inline void set_track(struct kmem_cache *s, void *object,
| ^~~~~~~~~
mm/slub.c:3429:19: warning: unused function 'node_match' [-Wunused-function]
3429 | static inline int node_match(struct slab *slab, int node)
| ^~~~~~~~~~
7 warnings generated.
--
In file included from mm/mremap.c:12:
In file included from include/linux/mm_inline.h:8:
In file included from include/linux/swap.h:11:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
mm/mremap.c:288:20: warning: unused function 'arch_supports_page_table_move' [-Wunused-function]
288 | static inline bool arch_supports_page_table_move(void)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/mremap.c:287:39: note: expanded from macro 'arch_supports_page_table_move'
287 | #define arch_supports_page_table_move arch_supports_page_table_move
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
--
In file included from kernel/jump_label.c:9:
In file included from include/linux/memory.h:19:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/jump_label.c:415:20: warning: unused function 'static_key_type' [-Wunused-function]
415 | static inline bool static_key_type(struct static_key *key)
| ^~~~~~~~~~~~~~~
kernel/jump_label.c:420:20: warning: unused function 'static_key_linked' [-Wunused-function]
420 | static inline bool static_key_linked(struct static_key *key)
| ^~~~~~~~~~~~~~~~~
kernel/jump_label.c:425:20: warning: unused function 'static_key_clear_linked' [-Wunused-function]
425 | static inline void static_key_clear_linked(struct static_key *key)
| ^~~~~~~~~~~~~~~~~~~~~~~
kernel/jump_label.c:430:20: warning: unused function 'static_key_set_linked' [-Wunused-function]
430 | static inline void static_key_set_linked(struct static_key *key)
| ^~~~~~~~~~~~~~~~~~~~~
5 warnings generated.
--
In file included from io_uring/uring_cmd.c:7:
In file included from include/linux/security.h:35:
In file included from include/linux/bpf.h:30:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
io_uring/uring_cmd.c:306:19: warning: unused function 'io_uring_cmd_getsockopt' [-Wunused-function]
306 | static inline int io_uring_cmd_getsockopt(struct socket *sock,
| ^~~~~~~~~~~~~~~~~~~~~~~
io_uring/uring_cmd.c:333:19: warning: unused function 'io_uring_cmd_setsockopt' [-Wunused-function]
333 | static inline int io_uring_cmd_setsockopt(struct socket *sock,
| ^~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
--
In file included from kernel/trace/ftrace.c:17:
In file included from include/linux/stop_machine.h:5:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/trace/ftrace.c:4354:19: warning: unused function 'test_for_valid_rec' [-Wunused-function]
4354 | static inline int test_for_valid_rec(struct dyn_ftrace *rec)
| ^~~~~~~~~~~~~~~~~~
2 warnings generated.
--
In file included from kernel/sched/fair.c:57:
In file included from kernel/sched/sched.h:31:
In file included from include/linux/cpufreq.h:12:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/sched/fair.c:484:20: warning: unused function 'list_del_leaf_cfs_rq' [-Wunused-function]
484 | static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
| ^~~~~~~~~~~~~~~~~~~~
kernel/sched/fair.c:505:19: warning: unused function 'tg_is_idle' [-Wunused-function]
505 | static inline int tg_is_idle(struct task_group *tg)
| ^~~~~~~~~~
kernel/sched/fair.c:6747:20: warning: unused function 'sync_throttle' [-Wunused-function]
6747 | static inline void sync_throttle(struct task_group *tg, int cpu) {}
| ^~~~~~~~~~~~~
kernel/sched/fair.c:6771:37: warning: unused function 'tg_cfs_bandwidth' [-Wunused-function]
6771 | static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
| ^~~~~~~~~~~~~~~~
kernel/sched/fair.c:6775:20: warning: unused function 'destroy_cfs_bandwidth' [-Wunused-function]
6775 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {}
| ^~~~~~~~~~~~~~~~~~~~~
6 warnings generated.
--
In file included from kernel/sched/core.c:14:
In file included from include/linux/syscalls_api.h:1:
In file included from include/linux/syscalls.h:94:
In file included from include/trace/syscall.h:5:
In file included from include/linux/tracepoint.h:22:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/sched/core.c:6444:1: warning: unused function 'class_core_lock_lock_ptr' [-Wunused-function]
6444 | DEFINE_LOCK_GUARD_1(core_lock, int,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6445 | sched_core_lock(*_T->lock, &_T->flags),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6446 | sched_core_unlock(*_T->lock, &_T->flags),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6447 | unsigned long flags)
| ~~~~~~~~~~~~~~~~~~~~
include/linux/cleanup.h:408:49: note: expanded from macro 'DEFINE_LOCK_GUARD_1'
408 | __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \
| ^
409 | __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/cleanup.h:387:10: note: expanded from macro '\
__DEFINE_UNLOCK_GUARD'
387 | \
| ^
388 | __DEFINE_GUARD_LOCK_PTR(_name, &_T->lock)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/cleanup.h:295:23: note: expanded from macro '\
__DEFINE_GUARD_LOCK_PTR'
295 | static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \
| ^~~~~~~~~~~~~~~~~~~~~~~~
<scratch space>:36:1: note: expanded from here
36 | class_core_lock_lock_ptr
| ^~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
--
In file included from kernel/trace/rv/monitors/snep/snep.c:3:
In file included from include/linux/tracepoint.h:22:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/trace/rv/monitors/snep/snep.c:21:1: warning: unused function 'da_handle_start_run_event_snep' [-Wunused-function]
21 | DECLARE_DA_MON_PER_CPU(snep, unsigned char);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:536:48: note: expanded from macro 'DECLARE_DA_MON_PER_CPU'
536 | DECLARE_DA_MON_INIT_PER_CPU(name, type) \
| ^
537 | DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:438:20: note: expanded from macro '\
DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT'
438 | static inline bool da_handle_start_run_event_##name(enum events_##name event) \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<scratch space>:2:1: note: expanded from here
2 | da_handle_start_run_event_snep
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
--
In file included from kernel/trace/rv/monitors/scpd/scpd.c:3:
In file included from include/linux/tracepoint.h:22:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/trace/rv/monitors/scpd/scpd.c:21:1: warning: unused function 'da_handle_start_run_event_scpd' [-Wunused-function]
21 | DECLARE_DA_MON_PER_CPU(scpd, unsigned char);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:536:48: note: expanded from macro 'DECLARE_DA_MON_PER_CPU'
536 | DECLARE_DA_MON_INIT_PER_CPU(name, type) \
| ^
537 | DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:438:20: note: expanded from macro '\
DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT'
438 | static inline bool da_handle_start_run_event_##name(enum events_##name event) \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<scratch space>:2:1: note: expanded from here
2 | da_handle_start_run_event_scpd
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
--
In file included from kernel/trace/rv/monitors/wip/wip.c:3:
In file included from include/linux/tracepoint.h:22:
In file included from include/linux/static_call.h:135:
In file included from include/linux/cpu.h:17:
>> include/linux/node.h:124:6: warning: no previous prototype for function 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^
include/linux/node.h:124:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
124 | void register_memory_blocks_under_node_early(int nid)
| ^
| static
kernel/trace/rv/monitors/wip/wip.c:20:1: warning: unused function 'da_handle_start_run_event_wip' [-Wunused-function]
20 | DECLARE_DA_MON_PER_CPU(wip, unsigned char);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:536:48: note: expanded from macro 'DECLARE_DA_MON_PER_CPU'
536 | DECLARE_DA_MON_INIT_PER_CPU(name, type) \
| ^
537 | DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/rv/da_monitor.h:438:20: note: expanded from macro '\
DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT'
438 | static inline bool da_handle_start_run_event_##name(enum events_##name event) \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<scratch space>:172:1: note: expanded from here
172 | da_handle_start_run_event_wip
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
..
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
` (2 preceding siblings ...)
2025-04-29 16:37 ` kernel test robot
@ 2025-04-29 17:01 ` kernel test robot
2025-05-01 14:10 ` Donet Tom
2025-04-30 7:38 ` Oscar Salvador
4 siblings, 1 reply; 15+ messages in thread
From: kernel test robot @ 2025-04-29 17:01 UTC (permalink / raw)
To: Donet Tom, Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich
Cc: oe-kbuild-all, Linux Memory Management List, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-kernel, Donet Tom
Hi Donet,
kernel test robot noticed the following build errors:
[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.15-rc4 next-20250429]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Donet-Tom/driver-base-Remove-unused-functions/20250429-010442
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/fbe1e0c7d91bf3fa9a64ff5d84b53ded1d0d5ac7.1745852397.git.donettom%40linux.ibm.com
patch subject: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
config: x86_64-buildonly-randconfig-004-20250429 (https://download.01.org/0day-ci/archive/20250430/202504300024.YxAyenLy-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300024.YxAyenLy-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504300024.YxAyenLy-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
In file included from include/linux/swap.h:11,
from include/linux/suspend.h:5,
from arch/x86/kernel/asm-offsets.c:14:
>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
ld: security/keys/encrypted-keys/masterkey_trusted.o: in function `register_memory_blocks_under_node_early':
>> security/keys/encrypted-keys/masterkey_trusted.c:125: multiple definition of `register_memory_blocks_under_node_early'; security/keys/encrypted-keys/encrypted.o:include/linux/node.h:125: first defined here
--
In file included from include/linux/cpu.h:17,
from include/linux/static_call.h:135,
from include/linux/tracepoint.h:22,
from include/trace/events/tlb.h:9,
from arch/x86/include/asm/mmu_context.h:9,
from include/linux/mmu_context.h:5,
from include/linux/cpuset.h:18,
from include/linux/sched/isolation.h:5,
from kernel/sched/build_policy.c:19:
>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from kernel/sched/build_policy.c:52:
kernel/sched/rt.c:9:18: warning: 'max_rt_runtime' defined but not used [-Wunused-const-variable=]
9 | static const u64 max_rt_runtime = MAX_BW;
| ^~~~~~~~~~~~~~
--
ld: drivers/usb/host/xhci-mem.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
ld: drivers/usb/host/xhci-ring.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
ld: drivers/usb/host/xhci-hub.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
ld: drivers/usb/host/xhci-trace.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
ld: drivers/usb/host/xhci-dbgcap.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
--
In file included from include/linux/acpi.h:18,
from include/linux/i2c.h:13,
from drivers/power/supply/sbs-battery.c:13:
>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/power/supply/sbs-battery.c: In function 'sbs_get_property':
drivers/power/supply/sbs-battery.c:834:30: warning: '%04x' directive writing between 4 and 8 bytes into a region of size 5 [-Wformat-overflow=]
834 | sprintf(sbs_serial, "%04x", ret);
| ^~~~
In function 'sbs_get_battery_serial_number',
inlined from 'sbs_get_property' at drivers/power/supply/sbs-battery.c:965:9:
drivers/power/supply/sbs-battery.c:834:29: note: directive argument in the range [0, 2147483647]
834 | sprintf(sbs_serial, "%04x", ret);
| ^~~~~~
drivers/power/supply/sbs-battery.c:834:9: note: 'sprintf' output between 5 and 9 bytes into a destination of size 5
834 | sprintf(sbs_serial, "%04x", ret);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
In file included from include/linux/swap.h:11,
from include/linux/suspend.h:5,
from include/linux/regulator/consumer.h:35,
from include/linux/phy/phy.h:17,
from include/linux/usb/otg.h:13,
from include/linux/usb/of.h:11,
from drivers/usb/core/usb.c:41:
>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/usb/core/usb.c: In function 'usb_alloc_dev':
drivers/usb/core/usb.c:706:37: warning: '%d' directive output may be truncated writing between 1 and 11 bytes into a region of size between 0 and 15 [-Wformat-truncation=]
706 | "%s.%d", parent->devpath, port1);
| ^~
drivers/usb/core/usb.c:706:33: note: using the range [-2147483648, 2147483647] for directive argument
706 | "%s.%d", parent->devpath, port1);
| ^~~~~~~
drivers/usb/core/usb.c:705:25: note: 'snprintf' output between 3 and 28 bytes into a destination of size 16
705 | snprintf(dev->devpath, sizeof dev->devpath,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
706 | "%s.%d", parent->devpath, port1);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
ld: drivers/i3c/master.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/device.o:include/linux/node.h:125: first defined here
--
ld: drivers/i3c/master/mipi-i3c-hci/ext_caps.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/pio.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/dma.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/cmd_v1.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/cmd_v2.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/dat_v1.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/dct_v1.o: in function `register_memory_blocks_under_node_early':
drivers/i3c/master/mipi-i3c-hci/dct_v1.c:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
ld: drivers/i3c/master/mipi-i3c-hci/hci_quirks.o: in function `register_memory_blocks_under_node_early':
drivers/i3c/master/mipi-i3c-hci/hci_quirks.c:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
--
In file included from include/linux/acpi.h:18,
from include/linux/i2c.h:13,
from drivers/hwmon/pmbus/ibm-cffps.c:11:
>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
124 | void register_memory_blocks_under_node_early(int nid)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/hwmon/pmbus/ibm-cffps.c: In function 'ibm_cffps_debugfs_read':
drivers/hwmon/pmbus/ibm-cffps.c:169:60: warning: '%02X' directive output may be truncated writing between 2 and 8 bytes into a region of size 3 [-Wformat-truncation=]
169 | snprintf(&data[i * 2], 3, "%02X", rc);
| ^~~~
drivers/hwmon/pmbus/ibm-cffps.c:169:59: note: directive argument in the range [0, 2147483647]
169 | snprintf(&data[i * 2], 3, "%02X", rc);
| ^~~~~~
drivers/hwmon/pmbus/ibm-cffps.c:169:33: note: 'snprintf' output between 3 and 9 bytes into a destination of size 3
169 | snprintf(&data[i * 2], 3, "%02X", rc);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/hwmon/pmbus/ibm-cffps.c:180:60: warning: '%04X' directive output may be truncated writing between 4 and 8 bytes into a region of size 5 [-Wformat-truncation=]
180 | snprintf(&data[i * 4], 5, "%04X", rc);
| ^~~~
drivers/hwmon/pmbus/ibm-cffps.c:180:59: note: directive argument in the range [0, 2147483647]
180 | snprintf(&data[i * 4], 5, "%04X", rc);
| ^~~~~~
drivers/hwmon/pmbus/ibm-cffps.c:180:33: note: 'snprintf' output between 5 and 9 bytes into a destination of size 5
180 | snprintf(&data[i * 4], 5, "%04X", rc);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
ld: drivers/usb/typec/tipd/trace.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/typec/tipd/core.o:include/linux/node.h:125: first defined here
--
ld: drivers/usb/cdns3/drd.o: in function `register_memory_blocks_under_node_early':
>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/cdns3/core.o:include/linux/node.h:125: first defined here
..
vim +125 security/keys/encrypted-keys/masterkey_trusted.c
b886d83c5b621a Thomas Gleixner 2019-06-01 1 // SPDX-License-Identifier: GPL-2.0-only
982e617a313b57 Mimi Zohar 2011-08-27 2 /*
982e617a313b57 Mimi Zohar 2011-08-27 3 * Copyright (C) 2010 IBM Corporation
982e617a313b57 Mimi Zohar 2011-08-27 4 * Copyright (C) 2010 Politecnico di Torino, Italy
c9fecf505a3421 Alexander A. Klimov 2020-07-05 5 * TORSEC group -- https://security.polito.it
982e617a313b57 Mimi Zohar 2011-08-27 6 *
982e617a313b57 Mimi Zohar 2011-08-27 7 * Authors:
982e617a313b57 Mimi Zohar 2011-08-27 8 * Mimi Zohar <zohar@us.ibm.com>
982e617a313b57 Mimi Zohar 2011-08-27 9 * Roberto Sassu <roberto.sassu@polito.it>
982e617a313b57 Mimi Zohar 2011-08-27 10 *
5395d312dff00d Kees Cook 2017-05-13 11 * See Documentation/security/keys/trusted-encrypted.rst
982e617a313b57 Mimi Zohar 2011-08-27 12 */
982e617a313b57 Mimi Zohar 2011-08-27 13
982e617a313b57 Mimi Zohar 2011-08-27 14 #include <linux/uaccess.h>
cc100551b4d92f Stephen Rothwell 2011-09-15 15 #include <linux/err.h>
982e617a313b57 Mimi Zohar 2011-08-27 16 #include <keys/trusted-type.h>
ee0b31a25a0101 Mimi Zohar 2012-01-17 17 #include <keys/encrypted-type.h>
ee0b31a25a0101 Mimi Zohar 2012-01-17 18 #include "encrypted.h"
982e617a313b57 Mimi Zohar 2011-08-27 19
982e617a313b57 Mimi Zohar 2011-08-27 20 /*
982e617a313b57 Mimi Zohar 2011-08-27 21 * request_trusted_key - request the trusted key
982e617a313b57 Mimi Zohar 2011-08-27 22 *
982e617a313b57 Mimi Zohar 2011-08-27 23 * Trusted keys are sealed to PCRs and other metadata. Although userspace
982e617a313b57 Mimi Zohar 2011-08-27 24 * manages both trusted/encrypted key-types, like the encrypted key type
982e617a313b57 Mimi Zohar 2011-08-27 25 * data, trusted key type data is not visible decrypted from userspace.
982e617a313b57 Mimi Zohar 2011-08-27 26 */
982e617a313b57 Mimi Zohar 2011-08-27 27 struct key *request_trusted_key(const char *trusted_desc,
146aa8b1453bd8 David Howells 2015-10-21 28 const u8 **master_key, size_t *master_keylen)
982e617a313b57 Mimi Zohar 2011-08-27 29 {
982e617a313b57 Mimi Zohar 2011-08-27 30 struct trusted_key_payload *tpayload;
982e617a313b57 Mimi Zohar 2011-08-27 31 struct key *tkey;
982e617a313b57 Mimi Zohar 2011-08-27 32
028db3e290f15a Linus Torvalds 2019-07-10 33 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
982e617a313b57 Mimi Zohar 2011-08-27 34 if (IS_ERR(tkey))
982e617a313b57 Mimi Zohar 2011-08-27 35 goto error;
982e617a313b57 Mimi Zohar 2011-08-27 36
982e617a313b57 Mimi Zohar 2011-08-27 37 down_read(&tkey->sem);
146aa8b1453bd8 David Howells 2015-10-21 38 tpayload = tkey->payload.data[0];
982e617a313b57 Mimi Zohar 2011-08-27 39 *master_key = tpayload->key;
982e617a313b57 Mimi Zohar 2011-08-27 40 *master_keylen = tpayload->key_len;
982e617a313b57 Mimi Zohar 2011-08-27 41 error:
982e617a313b57 Mimi Zohar 2011-08-27 42 return tkey;
982e617a313b57 Mimi Zohar 2011-08-27 43 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
` (3 preceding siblings ...)
2025-04-29 17:01 ` kernel test robot
@ 2025-04-30 7:38 ` Oscar Salvador
2025-05-01 13:55 ` Donet Tom
4 siblings, 1 reply; 15+ messages in thread
From: Oscar Salvador @ 2025-04-30 7:38 UTC (permalink / raw)
To: Donet Tom
Cc: Mike Rapoport, David Hildenbrand, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-mm, linux-kernel
On Mon, Apr 28, 2025 at 10:33:46PM +0530, Donet Tom wrote:
> During node device initialization, `memory blocks` are registered under
> each NUMA node. The `memory blocks` to be registered are identified using
> the node’s start and end PFNs, which are obtained from the node's pg_data
>
Hi Donet,
> Test Results on My system with 32TB RAM
> =======================================
> 1. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled.
>
> Without this patch
> ------------------
> Startup finished in 1min 16.528s (kernel)
>
> With this patch
> ---------------
> Startup finished in 17.236s (kernel) - 78% Improvement
That is pretty impressive.
> +void register_memory_blocks_under_node_early(int nid)
> +{
> + struct memblock_region *r;
> + unsigned long start_block_id;
> + unsigned long end_block_id;
> + struct memory_block *mem;
> + unsigned long block_id;
> +
> + for_each_mem_region(r) {
> + if (r->nid == nid) {
> + start_block_id = phys_to_block_id(r->base);
> + end_block_id = phys_to_block_id(r->base + r->size - 1);
> +
> + for (block_id = start_block_id; block_id <= end_block_id; block_id++) {
> + mem = find_memory_block_by_id(block_id);
> + if (!mem)
> + continue;
I would just mention what David already said here, reduce identation,
and maybe declare the variables where they are needed. It might be clearer.
> +
> + do_register_memory_block_under_node(nid, mem, MEMINIT_EARLY);
> + put_device(&mem->dev);
I will comment on the "context" on patch#2.
> +void register_memory_blocks_under_node_early(int nid);
static void ... ?
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
2025-04-28 21:21 ` David Hildenbrand
@ 2025-04-30 7:48 ` Oscar Salvador
2025-05-01 13:49 ` Donet Tom
2025-05-01 15:08 ` Zi Yan
2 siblings, 1 reply; 15+ messages in thread
From: Oscar Salvador @ 2025-04-30 7:48 UTC (permalink / raw)
To: Donet Tom
Cc: Mike Rapoport, David Hildenbrand, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-mm, linux-kernel
On Mon, Apr 28, 2025 at 10:33:47PM +0530, Donet Tom wrote:
> The functions register_mem_block_under_node_early and get_nid_for_pfn
> are not used, as register_memory_blocks_under_node_early is now used
> to register memory blocks during early boot. Therefore, these unused
> functions have been removed.
>
> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
> ---
> drivers/base/node.c | 54 +--------------------------------------------
> 1 file changed, 1 insertion(+), 53 deletions(-)
...
> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
> {
> walk_memory_blocks_func_t func;
>
> - if (context == MEMINIT_HOTPLUG)
> - func = register_mem_block_under_node_hotplug;
> - else
> - func = register_mem_block_under_node_early;
> + func = register_mem_block_under_node_hotplug;
>
> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
> (void *)&nid, func);
So we have now:
register_memory_blocks_under_node - wrt. hotplug
register_memory_blocks_under_node_early - wrt. boot
AFAICS, we can drop the 'context' parameter from this function because
we do not need it anymore, right? The functions that get called
eventually, register_mem_block_under_node_hotplug() and
register_mem_block_under_node_early(), already know its context and pass
it on to do_register_memory_block_under_node().
--
Oscar Salvador
SUSE Labs
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-30 7:48 ` Oscar Salvador
@ 2025-05-01 13:49 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-05-01 13:49 UTC (permalink / raw)
To: Oscar Salvador
Cc: Mike Rapoport, David Hildenbrand, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-mm, linux-kernel
On 4/30/25 1:18 PM, Oscar Salvador wrote:
> On Mon, Apr 28, 2025 at 10:33:47PM +0530, Donet Tom wrote:
>> The functions register_mem_block_under_node_early and get_nid_for_pfn
>> are not used, as register_memory_blocks_under_node_early is now used
>> to register memory blocks during early boot. Therefore, these unused
>> functions have been removed.
>>
>> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
>> ---
>> drivers/base/node.c | 54 +--------------------------------------------
>> 1 file changed, 1 insertion(+), 53 deletions(-)
> ...
>
>> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
>> {
>> walk_memory_blocks_func_t func;
>>
>> - if (context == MEMINIT_HOTPLUG)
>> - func = register_mem_block_under_node_hotplug;
>> - else
>> - func = register_mem_block_under_node_early;
>> + func = register_mem_block_under_node_hotplug;
>>
>> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
>> (void *)&nid, func);
> So we have now:
>
> register_memory_blocks_under_node - wrt. hotplug
> register_memory_blocks_under_node_early - wrt. boot
>
> AFAICS, we can drop the 'context' parameter from this function because
> we do not need it anymore, right? The functions that get called
> eventually, register_mem_block_under_node_hotplug() and
> register_mem_block_under_node_early(), already know its context and pass
> it on to do_register_memory_block_under_node().
Hi Oscar
Yes we can drop 'context' parameter. I will add this change in next version.
Thanks
Donet
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-30 7:38 ` Oscar Salvador
@ 2025-05-01 13:55 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-05-01 13:55 UTC (permalink / raw)
To: Oscar Salvador
Cc: Mike Rapoport, David Hildenbrand, Greg Kroah-Hartman,
Andrew Morton, rafael, Danilo Krummrich, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-mm, linux-kernel
On 4/30/25 1:08 PM, Oscar Salvador wrote:
> On Mon, Apr 28, 2025 at 10:33:46PM +0530, Donet Tom wrote:
>> During node device initialization, `memory blocks` are registered under
>> each NUMA node. The `memory blocks` to be registered are identified using
>> the node’s start and end PFNs, which are obtained from the node's pg_data
>>
> Hi Donet,
>
>> Test Results on My system with 32TB RAM
>> =======================================
>> 1. Boot time with CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled.
>>
>> Without this patch
>> ------------------
>> Startup finished in 1min 16.528s (kernel)
>>
>> With this patch
>> ---------------
>> Startup finished in 17.236s (kernel) - 78% Improvement
> That is pretty impressive.
>
>> +void register_memory_blocks_under_node_early(int nid)
>> +{
>> + struct memblock_region *r;
>> + unsigned long start_block_id;
>> + unsigned long end_block_id;
>> + struct memory_block *mem;
>> + unsigned long block_id;
>> +
>> + for_each_mem_region(r) {
>> + if (r->nid == nid) {
>> + start_block_id = phys_to_block_id(r->base);
>> + end_block_id = phys_to_block_id(r->base + r->size - 1);
>> +
>> + for (block_id = start_block_id; block_id <= end_block_id; block_id++) {
>> + mem = find_memory_block_by_id(block_id);
>> + if (!mem)
>> + continue;
> I would just mention what David already said here, reduce identation,
> and maybe declare the variables where they are needed. It might be clearer.
Sure, I will change it.
>> +
>> + do_register_memory_block_under_node(nid, mem, MEMINIT_EARLY);
>> + put_device(&mem->dev);
> I will comment on the "context" on patch#2.
>
>> +void register_memory_blocks_under_node_early(int nid);
> static void ... ?
Yes, We can make it as static. I will add it in next version.
Thanks
Donet
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
2025-04-29 17:01 ` kernel test robot
@ 2025-05-01 14:10 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-05-01 14:10 UTC (permalink / raw)
To: kernel test robot, Mike Rapoport, David Hildenbrand,
Oscar Salvador, Greg Kroah-Hartman, Andrew Morton, rafael,
Danilo Krummrich
Cc: oe-kbuild-all, Linux Memory Management List, Ritesh Harjani,
Jonathan Cameron, Alison Schofield, Yury Norov, Dave Jiang,
linux-kernel
On 4/29/25 10:31 PM, kernel test robot wrote:
> Hi Donet,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on akpm-mm/mm-everything]
> [also build test ERROR on linus/master v6.15-rc4 next-20250429]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Donet-Tom/driver-base-Remove-unused-functions/20250429-010442
> base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
> patch link: https://lore.kernel.org/r/fbe1e0c7d91bf3fa9a64ff5d84b53ded1d0d5ac7.1745852397.git.donettom%40linux.ibm.com
> patch subject: [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time
> config: x86_64-buildonly-randconfig-004-20250429 (https://download.01.org/0day-ci/archive/20250430/202504300024.YxAyenLy-lkp@intel.com/config)
> compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250430/202504300024.YxAyenLy-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202504300024.YxAyenLy-lkp@intel.com/
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from include/linux/swap.h:11,
> from include/linux/suspend.h:5,
> from arch/x86/kernel/asm-offsets.c:14:
>>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
> 124 | void register_memory_blocks_under_node_early(int nid)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --
> ld: security/keys/encrypted-keys/masterkey_trusted.o: in function `register_memory_blocks_under_node_early':
>>> security/keys/encrypted-keys/masterkey_trusted.c:125: multiple definition of `register_memory_blocks_under_node_early'; security/keys/encrypted-keys/encrypted.o:include/linux/node.h:125: first defined here
> --
> In file included from include/linux/cpu.h:17,
> from include/linux/static_call.h:135,
> from include/linux/tracepoint.h:22,
> from include/trace/events/tlb.h:9,
> from arch/x86/include/asm/mmu_context.h:9,
> from include/linux/mmu_context.h:5,
> from include/linux/cpuset.h:18,
> from include/linux/sched/isolation.h:5,
> from kernel/sched/build_policy.c:19:
>>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
Thanks for the report. I will fix this and send a revised version.
> 124 | void register_memory_blocks_under_node_early(int nid)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from kernel/sched/build_policy.c:52:
> kernel/sched/rt.c:9:18: warning: 'max_rt_runtime' defined but not used [-Wunused-const-variable=]
> 9 | static const u64 max_rt_runtime = MAX_BW;
> | ^~~~~~~~~~~~~~
> --
> ld: drivers/usb/host/xhci-mem.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
> ld: drivers/usb/host/xhci-ring.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
> ld: drivers/usb/host/xhci-hub.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
> ld: drivers/usb/host/xhci-trace.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
> ld: drivers/usb/host/xhci-dbgcap.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/host/xhci.o:include/linux/node.h:125: first defined here
> --
> In file included from include/linux/acpi.h:18,
> from include/linux/i2c.h:13,
> from drivers/power/supply/sbs-battery.c:13:
>>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
> 124 | void register_memory_blocks_under_node_early(int nid)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/power/supply/sbs-battery.c: In function 'sbs_get_property':
> drivers/power/supply/sbs-battery.c:834:30: warning: '%04x' directive writing between 4 and 8 bytes into a region of size 5 [-Wformat-overflow=]
> 834 | sprintf(sbs_serial, "%04x", ret);
> | ^~~~
> In function 'sbs_get_battery_serial_number',
> inlined from 'sbs_get_property' at drivers/power/supply/sbs-battery.c:965:9:
> drivers/power/supply/sbs-battery.c:834:29: note: directive argument in the range [0, 2147483647]
> 834 | sprintf(sbs_serial, "%04x", ret);
> | ^~~~~~
> drivers/power/supply/sbs-battery.c:834:9: note: 'sprintf' output between 5 and 9 bytes into a destination of size 5
> 834 | sprintf(sbs_serial, "%04x", ret);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --
> In file included from include/linux/swap.h:11,
> from include/linux/suspend.h:5,
> from include/linux/regulator/consumer.h:35,
> from include/linux/phy/phy.h:17,
> from include/linux/usb/otg.h:13,
> from include/linux/usb/of.h:11,
> from drivers/usb/core/usb.c:41:
>>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
> 124 | void register_memory_blocks_under_node_early(int nid)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/usb/core/usb.c: In function 'usb_alloc_dev':
> drivers/usb/core/usb.c:706:37: warning: '%d' directive output may be truncated writing between 1 and 11 bytes into a region of size between 0 and 15 [-Wformat-truncation=]
> 706 | "%s.%d", parent->devpath, port1);
> | ^~
> drivers/usb/core/usb.c:706:33: note: using the range [-2147483648, 2147483647] for directive argument
> 706 | "%s.%d", parent->devpath, port1);
> | ^~~~~~~
> drivers/usb/core/usb.c:705:25: note: 'snprintf' output between 3 and 28 bytes into a destination of size 16
> 705 | snprintf(dev->devpath, sizeof dev->devpath,
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 706 | "%s.%d", parent->devpath, port1);
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --
> ld: drivers/i3c/master.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/device.o:include/linux/node.h:125: first defined here
> --
> ld: drivers/i3c/master/mipi-i3c-hci/ext_caps.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/pio.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/dma.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/cmd_v1.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/cmd_v2.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/dat_v1.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/dct_v1.o: in function `register_memory_blocks_under_node_early':
> drivers/i3c/master/mipi-i3c-hci/dct_v1.c:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> ld: drivers/i3c/master/mipi-i3c-hci/hci_quirks.o: in function `register_memory_blocks_under_node_early':
> drivers/i3c/master/mipi-i3c-hci/hci_quirks.c:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/i3c/master/mipi-i3c-hci/core.o:include/linux/node.h:125: first defined here
> --
> In file included from include/linux/acpi.h:18,
> from include/linux/i2c.h:13,
> from drivers/hwmon/pmbus/ibm-cffps.c:11:
>>> include/linux/node.h:124:6: warning: no previous prototype for 'register_memory_blocks_under_node_early' [-Wmissing-prototypes]
> 124 | void register_memory_blocks_under_node_early(int nid)
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/hwmon/pmbus/ibm-cffps.c: In function 'ibm_cffps_debugfs_read':
> drivers/hwmon/pmbus/ibm-cffps.c:169:60: warning: '%02X' directive output may be truncated writing between 2 and 8 bytes into a region of size 3 [-Wformat-truncation=]
> 169 | snprintf(&data[i * 2], 3, "%02X", rc);
> | ^~~~
> drivers/hwmon/pmbus/ibm-cffps.c:169:59: note: directive argument in the range [0, 2147483647]
> 169 | snprintf(&data[i * 2], 3, "%02X", rc);
> | ^~~~~~
> drivers/hwmon/pmbus/ibm-cffps.c:169:33: note: 'snprintf' output between 3 and 9 bytes into a destination of size 3
> 169 | snprintf(&data[i * 2], 3, "%02X", rc);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/hwmon/pmbus/ibm-cffps.c:180:60: warning: '%04X' directive output may be truncated writing between 4 and 8 bytes into a region of size 5 [-Wformat-truncation=]
> 180 | snprintf(&data[i * 4], 5, "%04X", rc);
> | ^~~~
> drivers/hwmon/pmbus/ibm-cffps.c:180:59: note: directive argument in the range [0, 2147483647]
> 180 | snprintf(&data[i * 4], 5, "%04X", rc);
> | ^~~~~~
> drivers/hwmon/pmbus/ibm-cffps.c:180:33: note: 'snprintf' output between 5 and 9 bytes into a destination of size 5
> 180 | snprintf(&data[i * 4], 5, "%04X", rc);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --
> ld: drivers/usb/typec/tipd/trace.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/typec/tipd/core.o:include/linux/node.h:125: first defined here
> --
> ld: drivers/usb/cdns3/drd.o: in function `register_memory_blocks_under_node_early':
>>> include/linux/node.h:125: multiple definition of `register_memory_blocks_under_node_early'; drivers/usb/cdns3/core.o:include/linux/node.h:125: first defined here
> ..
>
>
> vim +125 security/keys/encrypted-keys/masterkey_trusted.c
>
> b886d83c5b621a Thomas Gleixner 2019-06-01 1 // SPDX-License-Identifier: GPL-2.0-only
> 982e617a313b57 Mimi Zohar 2011-08-27 2 /*
> 982e617a313b57 Mimi Zohar 2011-08-27 3 * Copyright (C) 2010 IBM Corporation
> 982e617a313b57 Mimi Zohar 2011-08-27 4 * Copyright (C) 2010 Politecnico di Torino, Italy
> c9fecf505a3421 Alexander A. Klimov 2020-07-05 5 * TORSEC group -- https://security.polito.it
> 982e617a313b57 Mimi Zohar 2011-08-27 6 *
> 982e617a313b57 Mimi Zohar 2011-08-27 7 * Authors:
> 982e617a313b57 Mimi Zohar 2011-08-27 8 * Mimi Zohar <zohar@us.ibm.com>
> 982e617a313b57 Mimi Zohar 2011-08-27 9 * Roberto Sassu <roberto.sassu@polito.it>
> 982e617a313b57 Mimi Zohar 2011-08-27 10 *
> 5395d312dff00d Kees Cook 2017-05-13 11 * See Documentation/security/keys/trusted-encrypted.rst
> 982e617a313b57 Mimi Zohar 2011-08-27 12 */
> 982e617a313b57 Mimi Zohar 2011-08-27 13
> 982e617a313b57 Mimi Zohar 2011-08-27 14 #include <linux/uaccess.h>
> cc100551b4d92f Stephen Rothwell 2011-09-15 15 #include <linux/err.h>
> 982e617a313b57 Mimi Zohar 2011-08-27 16 #include <keys/trusted-type.h>
> ee0b31a25a0101 Mimi Zohar 2012-01-17 17 #include <keys/encrypted-type.h>
> ee0b31a25a0101 Mimi Zohar 2012-01-17 18 #include "encrypted.h"
> 982e617a313b57 Mimi Zohar 2011-08-27 19
> 982e617a313b57 Mimi Zohar 2011-08-27 20 /*
> 982e617a313b57 Mimi Zohar 2011-08-27 21 * request_trusted_key - request the trusted key
> 982e617a313b57 Mimi Zohar 2011-08-27 22 *
> 982e617a313b57 Mimi Zohar 2011-08-27 23 * Trusted keys are sealed to PCRs and other metadata. Although userspace
> 982e617a313b57 Mimi Zohar 2011-08-27 24 * manages both trusted/encrypted key-types, like the encrypted key type
> 982e617a313b57 Mimi Zohar 2011-08-27 25 * data, trusted key type data is not visible decrypted from userspace.
> 982e617a313b57 Mimi Zohar 2011-08-27 26 */
> 982e617a313b57 Mimi Zohar 2011-08-27 27 struct key *request_trusted_key(const char *trusted_desc,
> 146aa8b1453bd8 David Howells 2015-10-21 28 const u8 **master_key, size_t *master_keylen)
> 982e617a313b57 Mimi Zohar 2011-08-27 29 {
> 982e617a313b57 Mimi Zohar 2011-08-27 30 struct trusted_key_payload *tpayload;
> 982e617a313b57 Mimi Zohar 2011-08-27 31 struct key *tkey;
> 982e617a313b57 Mimi Zohar 2011-08-27 32
> 028db3e290f15a Linus Torvalds 2019-07-10 33 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
> 982e617a313b57 Mimi Zohar 2011-08-27 34 if (IS_ERR(tkey))
> 982e617a313b57 Mimi Zohar 2011-08-27 35 goto error;
> 982e617a313b57 Mimi Zohar 2011-08-27 36
> 982e617a313b57 Mimi Zohar 2011-08-27 37 down_read(&tkey->sem);
> 146aa8b1453bd8 David Howells 2015-10-21 38 tpayload = tkey->payload.data[0];
> 982e617a313b57 Mimi Zohar 2011-08-27 39 *master_key = tpayload->key;
> 982e617a313b57 Mimi Zohar 2011-08-27 40 *master_keylen = tpayload->key_len;
> 982e617a313b57 Mimi Zohar 2011-08-27 41 error:
> 982e617a313b57 Mimi Zohar 2011-08-27 42 return tkey;
> 982e617a313b57 Mimi Zohar 2011-08-27 43 }
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
2025-04-28 21:21 ` David Hildenbrand
2025-04-30 7:48 ` Oscar Salvador
@ 2025-05-01 15:08 ` Zi Yan
2025-05-01 15:15 ` Donet Tom
2 siblings, 1 reply; 15+ messages in thread
From: Zi Yan @ 2025-05-01 15:08 UTC (permalink / raw)
To: Donet Tom
Cc: Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich,
Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 28 Apr 2025, at 13:03, Donet Tom wrote:
> The functions register_mem_block_under_node_early and get_nid_for_pfn
> are not used, as register_memory_blocks_under_node_early is now used
> to register memory blocks during early boot. Therefore, these unused
> functions have been removed.
>
> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
> ---
> drivers/base/node.c | 54 +--------------------------------------------
> 1 file changed, 1 insertion(+), 53 deletions(-)
>
> diff --git a/drivers/base/node.c b/drivers/base/node.c
> index 4869333d366d..59ec507fc97d 100644
> --- a/drivers/base/node.c
> +++ b/drivers/base/node.c
> @@ -748,15 +748,6 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
> }
>
> #ifdef CONFIG_MEMORY_HOTPLUG
> -static int __ref get_nid_for_pfn(unsigned long pfn)
> -{
> -#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
> - if (system_state < SYSTEM_RUNNING)
> - return early_pfn_to_nid(pfn);
> -#endif
> - return pfn_to_nid(pfn);
> -}
> -
> static void do_register_memory_block_under_node(int nid,
> struct memory_block *mem_blk,
> enum meminit_context context)
> @@ -783,46 +774,6 @@ static void do_register_memory_block_under_node(int nid,
> ret);
> }
>
> -/* register memory section under specified node if it spans that node */
> -static int register_mem_block_under_node_early(struct memory_block *mem_blk,
> - void *arg)
> -{
> - unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
> - unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
> - unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
> - int nid = *(int *)arg;
> - unsigned long pfn;
> -
> - for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
> - int page_nid;
> -
> - /*
> - * memory block could have several absent sections from start.
> - * skip pfn range from absent section
> - */
> - if (!pfn_in_present_section(pfn)) {
> - pfn = round_down(pfn + PAGES_PER_SECTION,
> - PAGES_PER_SECTION) - 1;
> - continue;
> - }
> -
> - /*
> - * We need to check if page belongs to nid only at the boot
> - * case because node's ranges can be interleaved.
> - */
> - page_nid = get_nid_for_pfn(pfn);
> - if (page_nid < 0)
> - continue;
> - if (page_nid != nid)
> - continue;
> -
> - do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
> - return 0;
> - }
> - /* mem section does not span the specified node */
> - return 0;
> -}
> -
> /*
> * During hotplug we know that all pages in the memory block belong to the same
> * node.
> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
> {
Should this function be renamed to register_memory_blocks_under_node_hotplug
to reflect its current implementation?
> walk_memory_blocks_func_t func;
>
> - if (context == MEMINIT_HOTPLUG)
> - func = register_mem_block_under_node_hotplug;
> - else
> - func = register_mem_block_under_node_early;
> + func = register_mem_block_under_node_hotplug;
>
> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
> (void *)&nid, func);
> --
> 2.48.1
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/2] driver/base: Remove unused functions
2025-05-01 15:08 ` Zi Yan
@ 2025-05-01 15:15 ` Donet Tom
0 siblings, 0 replies; 15+ messages in thread
From: Donet Tom @ 2025-05-01 15:15 UTC (permalink / raw)
To: Zi Yan
Cc: Mike Rapoport, David Hildenbrand, Oscar Salvador,
Greg Kroah-Hartman, Andrew Morton, rafael, Danilo Krummrich,
Ritesh Harjani, Jonathan Cameron, Alison Schofield, Yury Norov,
Dave Jiang, linux-mm, linux-kernel
On 5/1/25 8:38 PM, Zi Yan wrote:
> On 28 Apr 2025, at 13:03, Donet Tom wrote:
>
>> The functions register_mem_block_under_node_early and get_nid_for_pfn
>> are not used, as register_memory_blocks_under_node_early is now used
>> to register memory blocks during early boot. Therefore, these unused
>> functions have been removed.
>>
>> Signed-off-by: Donet Tom <donettom@linux.ibm.com>
>> ---
>> drivers/base/node.c | 54 +--------------------------------------------
>> 1 file changed, 1 insertion(+), 53 deletions(-)
>>
>> diff --git a/drivers/base/node.c b/drivers/base/node.c
>> index 4869333d366d..59ec507fc97d 100644
>> --- a/drivers/base/node.c
>> +++ b/drivers/base/node.c
>> @@ -748,15 +748,6 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
>> }
>>
>> #ifdef CONFIG_MEMORY_HOTPLUG
>> -static int __ref get_nid_for_pfn(unsigned long pfn)
>> -{
>> -#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
>> - if (system_state < SYSTEM_RUNNING)
>> - return early_pfn_to_nid(pfn);
>> -#endif
>> - return pfn_to_nid(pfn);
>> -}
>> -
>> static void do_register_memory_block_under_node(int nid,
>> struct memory_block *mem_blk,
>> enum meminit_context context)
>> @@ -783,46 +774,6 @@ static void do_register_memory_block_under_node(int nid,
>> ret);
>> }
>>
>> -/* register memory section under specified node if it spans that node */
>> -static int register_mem_block_under_node_early(struct memory_block *mem_blk,
>> - void *arg)
>> -{
>> - unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE;
>> - unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
>> - unsigned long end_pfn = start_pfn + memory_block_pfns - 1;
>> - int nid = *(int *)arg;
>> - unsigned long pfn;
>> -
>> - for (pfn = start_pfn; pfn <= end_pfn; pfn++) {
>> - int page_nid;
>> -
>> - /*
>> - * memory block could have several absent sections from start.
>> - * skip pfn range from absent section
>> - */
>> - if (!pfn_in_present_section(pfn)) {
>> - pfn = round_down(pfn + PAGES_PER_SECTION,
>> - PAGES_PER_SECTION) - 1;
>> - continue;
>> - }
>> -
>> - /*
>> - * We need to check if page belongs to nid only at the boot
>> - * case because node's ranges can be interleaved.
>> - */
>> - page_nid = get_nid_for_pfn(pfn);
>> - if (page_nid < 0)
>> - continue;
>> - if (page_nid != nid)
>> - continue;
>> -
>> - do_register_memory_block_under_node(nid, mem_blk, MEMINIT_EARLY);
>> - return 0;
>> - }
>> - /* mem section does not span the specified node */
>> - return 0;
>> -}
>> -
>> /*
>> * During hotplug we know that all pages in the memory block belong to the same
>> * node.
>> @@ -895,10 +846,7 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
>> {
> Should this function be renamed to register_memory_blocks_under_node_hotplug
> to reflect its current implementation?
Yes, we can rename it since it will only be called during hotplug. I will add it in next version.
Thanks
Donet
>
>> walk_memory_blocks_func_t func;
>>
>> - if (context == MEMINIT_HOTPLUG)
>> - func = register_mem_block_under_node_hotplug;
>> - else
>> - func = register_mem_block_under_node_early;
>> + func = register_mem_block_under_node_hotplug;
>>
>> walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
>> (void *)&nid, func);
>> --
>> 2.48.1
>
> --
> Best Regards,
> Yan, Zi
>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-05-01 15:15 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-28 17:03 [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time Donet Tom
2025-04-28 17:03 ` [PATCH v2 2/2] driver/base: Remove unused functions Donet Tom
2025-04-28 21:21 ` David Hildenbrand
2025-04-29 14:07 ` Donet Tom
2025-04-30 7:48 ` Oscar Salvador
2025-05-01 13:49 ` Donet Tom
2025-05-01 15:08 ` Zi Yan
2025-05-01 15:15 ` Donet Tom
2025-04-28 21:19 ` [PATCH v2 1/2] driver/base: Optimize memory block registration to reduce boot time David Hildenbrand
2025-04-29 14:08 ` Donet Tom
2025-04-29 16:37 ` kernel test robot
2025-04-29 17:01 ` kernel test robot
2025-05-01 14:10 ` Donet Tom
2025-04-30 7:38 ` Oscar Salvador
2025-05-01 13:55 ` Donet Tom
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).