在 7/1/25 5:04 PM, Ming Wang 写道:You've raised a very good point. The reason for moving the parsing logic to the top, rather than just modifying the original else block, is to handle the fundamentally different behaviors required for mem=SIZE versus mem=SIZE@START. The key lies in thisexisting block of code which handles the mem=SIZE@START case:
The LoongArch mem= parameter parser was previously limited to theI don't understand. Isn't it better to modify the else{} directly here?
mem=SIZE@START format. This was inconvenient for the common use case
of simply capping the total system memory, as it forced users to
manually specify a start address. It was also inconsistent with the
behavior on other architectures.
This patch enhances the parser in early_parse_mem() to also support the
more user-friendly mem=SIZE format. The implementation now checks for
the presence of the '@' symbol to determine the user's intent:
- If mem=SIZE is provided (no '@'), the kernel now calls
memblock_enforce_memory_limit(). This trims memory from the top down
to the specified size.
- If mem=SIZE@START is used, the original behavior is retained for
backward compatibility. This allows for defining specific memory
banks.
This change introduces an important usage rule reflected in the code's
comments: the mem=SIZE format should only be specified once on the
kernel command line. It acts as a single, global cap on total memory. In
contrast, the mem=SIZE@START format can be used multiple times to
define several distinct memory regions.
Signed-off-by: Ming Wang <wangming01@xxxxxxxxxxx>
---
arch/loongarch/kernel/setup.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/ setup.c
index b99fbb388fe0..af59ba180dc2 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -191,6 +191,16 @@ static int __init early_parse_mem(char *p)
return -EINVAL;
}
+ start = 0;
+ size = memparse(p, &p);
+ if (*p == '@') /* Every mem=... should contain '@' */
+ start = memparse(p + 1, &p);
+ else { /* Only one mem=... is allowed if no '@' */
+ usermem = 1;
+ memblock_enforce_memory_limit(size);
+ return 0;
+ }
+
/*
* If a user specifies memory size, we
* blow away any automatically generated
@@ -201,14 +211,6 @@ static int __init early_parse_mem(char *p)
memblock_remove(memblock_start_of_DRAM(),
memblock_end_of_DRAM() - memblock_start_of_DRAM());
}
- start = 0;
- size = memparse(p, &p);
- if (*p == '@')
- start = memparse(p + 1, &p);
- else {
- pr_err("Invalid format!\n");
- return -EINVAL;
- }
Thanks,
Yanteng