Skip to content

Commit ffe0e52

Browse files
mickflemmpalmer-dabbelt
authored andcommitted
RISC-V: Improve init_resources()
The kernel region is always present and we know where it is, no need to look for it inside the loop, just ignore it like the rest of the reserved regions within system's memory. Additionally, we don't need to call memblock_free inside the loop, as if called it'll split the region of pre-allocated resources in two parts, messing things up, just re-use the previous pre-allocated resource and free any unused resources after both loops finish. Signed-off-by: Nick Kossifidis <[email protected]> [Palmer: commit text] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent fba8a86 commit ffe0e52

File tree

1 file changed

+46
-44
lines changed

1 file changed

+46
-44
lines changed

arch/riscv/kernel/setup.c

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
6060
* also add "System RAM" regions for compatibility with other
6161
* archs, and the rest of the known regions for completeness.
6262
*/
63+
static struct resource kimage_res = { .name = "Kernel image", };
6364
static struct resource code_res = { .name = "Kernel code", };
6465
static struct resource data_res = { .name = "Kernel data", };
6566
static struct resource rodata_res = { .name = "Kernel rodata", };
@@ -80,45 +81,54 @@ static int __init add_resource(struct resource *parent,
8081
return 1;
8182
}
8283

83-
static int __init add_kernel_resources(struct resource *res)
84+
static int __init add_kernel_resources(void)
8485
{
8586
int ret = 0;
8687

8788
/*
8889
* The memory region of the kernel image is continuous and
89-
* was reserved on setup_bootmem, find it here and register
90-
* it as a resource, then register the various segments of
91-
* the image as child nodes
90+
* was reserved on setup_bootmem, register it here as a
91+
* resource, with the various segments of the image as
92+
* child nodes.
9293
*/
93-
if (!(res->start <= code_res.start && res->end >= data_res.end))
94-
return 0;
9594

96-
res->name = "Kernel image";
97-
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
95+
code_res.start = __pa_symbol(_text);
96+
code_res.end = __pa_symbol(_etext) - 1;
97+
code_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
9898

99-
/*
100-
* We removed a part of this region on setup_bootmem so
101-
* we need to expand the resource for the bss to fit in.
102-
*/
103-
res->end = bss_res.end;
99+
rodata_res.start = __pa_symbol(__start_rodata);
100+
rodata_res.end = __pa_symbol(__end_rodata) - 1;
101+
rodata_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
104102

105-
ret = add_resource(&iomem_resource, res);
103+
data_res.start = __pa_symbol(_data);
104+
data_res.end = __pa_symbol(_edata) - 1;
105+
data_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
106+
107+
bss_res.start = __pa_symbol(__bss_start);
108+
bss_res.end = __pa_symbol(__bss_stop) - 1;
109+
bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
110+
111+
kimage_res.start = code_res.start;
112+
kimage_res.end = bss_res.end;
113+
kimage_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
114+
115+
ret = add_resource(&iomem_resource, &kimage_res);
106116
if (ret < 0)
107117
return ret;
108118

109-
ret = add_resource(res, &code_res);
119+
ret = add_resource(&kimage_res, &code_res);
110120
if (ret < 0)
111121
return ret;
112122

113-
ret = add_resource(res, &rodata_res);
123+
ret = add_resource(&kimage_res, &rodata_res);
114124
if (ret < 0)
115125
return ret;
116126

117-
ret = add_resource(res, &data_res);
127+
ret = add_resource(&kimage_res, &data_res);
118128
if (ret < 0)
119129
return ret;
120130

121-
ret = add_resource(res, &bss_res);
131+
ret = add_resource(&kimage_res, &bss_res);
122132

123133
return ret;
124134
}
@@ -129,53 +139,42 @@ static void __init init_resources(void)
129139
struct resource *res = NULL;
130140
struct resource *mem_res = NULL;
131141
size_t mem_res_sz = 0;
132-
int ret = 0, i = 0;
133-
134-
code_res.start = __pa_symbol(_text);
135-
code_res.end = __pa_symbol(_etext) - 1;
136-
code_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
137-
138-
rodata_res.start = __pa_symbol(__start_rodata);
139-
rodata_res.end = __pa_symbol(__end_rodata) - 1;
140-
rodata_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
141-
142-
data_res.start = __pa_symbol(_data);
143-
data_res.end = __pa_symbol(_edata) - 1;
144-
data_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
142+
int num_resources = 0, res_idx = 0;
143+
int ret = 0;
145144

146-
bss_res.start = __pa_symbol(__bss_start);
147-
bss_res.end = __pa_symbol(__bss_stop) - 1;
148-
bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
145+
/* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
146+
num_resources = memblock.memory.cnt + memblock.reserved.cnt + 1;
147+
res_idx = num_resources - 1;
149148

150-
mem_res_sz = (memblock.memory.cnt + memblock.reserved.cnt) * sizeof(*mem_res);
149+
mem_res_sz = num_resources * sizeof(*mem_res);
151150
mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES);
152151
if (!mem_res)
153152
panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz);
153+
154154
/*
155155
* Start by adding the reserved regions, if they overlap
156156
* with /memory regions, insert_resource later on will take
157157
* care of it.
158158
*/
159+
ret = add_kernel_resources();
160+
if (ret < 0)
161+
goto error;
162+
159163
for_each_reserved_mem_region(region) {
160-
res = &mem_res[i++];
164+
res = &mem_res[res_idx--];
161165

162166
res->name = "Reserved";
163167
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
164168
res->start = __pfn_to_phys(memblock_region_reserved_base_pfn(region));
165169
res->end = __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1;
166170

167-
ret = add_kernel_resources(res);
168-
if (ret < 0)
169-
goto error;
170-
else if (ret)
171-
continue;
172-
173171
/*
174172
* Ignore any other reserved regions within
175173
* system memory.
176174
*/
177175
if (memblock_is_memory(res->start)) {
178-
memblock_free((phys_addr_t) res, sizeof(struct resource));
176+
/* Re-use this pre-allocated resource */
177+
res_idx++;
179178
continue;
180179
}
181180

@@ -186,7 +185,7 @@ static void __init init_resources(void)
186185

187186
/* Add /memory regions to the resource tree */
188187
for_each_mem_region(region) {
189-
res = &mem_res[i++];
188+
res = &mem_res[res_idx--];
190189

191190
if (unlikely(memblock_is_nomap(region))) {
192191
res->name = "Reserved";
@@ -204,6 +203,9 @@ static void __init init_resources(void)
204203
goto error;
205204
}
206205

206+
/* Clean-up any unused pre-allocated resources */
207+
mem_res_sz = (num_resources - res_idx + 1) * sizeof(*mem_res);
208+
memblock_free((phys_addr_t) mem_res, mem_res_sz);
207209
return;
208210

209211
error:

0 commit comments

Comments
 (0)