Skip to content

Commit 02011e8

Browse files
committed
Fix memory update overlay to emit delta instead of full remove+add
Signed-off-by: Cong Wang <cwang@multikernel.io>
1 parent e0b0e1d commit 02011e8

File tree

2 files changed

+73
-27
lines changed

2 files changed

+73
-27
lines changed

src/kerf/dtc/overlay.py

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,29 +119,53 @@ def generate_update_overlay(self, instance_name: str, old_instance, new_instance
119119
fdt_sw.begin_node("fragment@0")
120120
fdt_sw.begin_node("__overlay__")
121121

122-
# 1. memory-remove (if memory changed)
122+
# 1. memory-remove (if memory shrunk or base changed)
123123
if memory_changed:
124-
fdt_sw.begin_node("memory-remove")
125-
fdt_sw.property_string("mk,instance", instance_name)
126-
127-
fdt_sw.begin_node("region@0")
128-
reg_data = struct.pack(">QQ", old_mem_base, old_mem_size)
129-
fdt_sw.property("reg", reg_data)
130-
fdt_sw.end_node()
131-
132-
fdt_sw.end_node()
124+
if old_mem_base == new_mem_base:
125+
# Same base: only remove the excess if shrinking
126+
if old_mem_size > new_mem_size:
127+
remove_base = old_mem_base + new_mem_size
128+
remove_size = old_mem_size - new_mem_size
129+
fdt_sw.begin_node("memory-remove")
130+
fdt_sw.property_string("mk,instance", instance_name)
131+
fdt_sw.begin_node("region@0")
132+
reg_data = struct.pack(">QQ", remove_base, remove_size)
133+
fdt_sw.property("reg", reg_data)
134+
fdt_sw.end_node()
135+
fdt_sw.end_node()
136+
else:
137+
# Different base: remove entire old region
138+
fdt_sw.begin_node("memory-remove")
139+
fdt_sw.property_string("mk,instance", instance_name)
140+
fdt_sw.begin_node("region@0")
141+
reg_data = struct.pack(">QQ", old_mem_base, old_mem_size)
142+
fdt_sw.property("reg", reg_data)
143+
fdt_sw.end_node()
144+
fdt_sw.end_node()
133145

134-
# 2. memory-add (if memory changed)
146+
# 2. memory-add (if memory grew or base changed)
135147
if memory_changed:
136-
fdt_sw.begin_node("memory-add")
137-
fdt_sw.property_string("mk,instance", instance_name)
138-
139-
fdt_sw.begin_node("region@0")
140-
reg_data = struct.pack(">QQ", new_mem_base, new_mem_size)
141-
fdt_sw.property("reg", reg_data)
142-
fdt_sw.end_node()
143-
144-
fdt_sw.end_node()
148+
if old_mem_base == new_mem_base:
149+
# Same base: only add the extension if growing
150+
if new_mem_size > old_mem_size:
151+
add_base = old_mem_base + old_mem_size
152+
add_size = new_mem_size - old_mem_size
153+
fdt_sw.begin_node("memory-add")
154+
fdt_sw.property_string("mk,instance", instance_name)
155+
fdt_sw.begin_node("region@0")
156+
reg_data = struct.pack(">QQ", add_base, add_size)
157+
fdt_sw.property("reg", reg_data)
158+
fdt_sw.end_node()
159+
fdt_sw.end_node()
160+
else:
161+
# Different base: add entire new region
162+
fdt_sw.begin_node("memory-add")
163+
fdt_sw.property_string("mk,instance", instance_name)
164+
fdt_sw.begin_node("region@0")
165+
reg_data = struct.pack(">QQ", new_mem_base, new_mem_size)
166+
fdt_sw.property("reg", reg_data)
167+
fdt_sw.end_node()
168+
fdt_sw.end_node()
145169

146170
# 3. cpu-remove (if CPUs removed)
147171
if cpus_to_remove:

src/kerf/update/main.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,35 @@ def update_instance_operation(current):
280280

281281
if memory_bytes is not None:
282282
if memory_base_addr is None:
283-
found_base = find_available_memory_base(modified, memory_bytes)
284-
if found_base is None:
285-
raise ResourceError(
286-
f"No available memory region found for {memory_bytes} bytes. "
287-
"Try specifying --memory-base or reduce memory size."
288-
)
289-
memory_base_addr = found_base
283+
# Keep the same base address and extend/shrink in place
284+
old_base = existing_instance.resources.memory_base
285+
old_size = existing_instance.resources.memory_bytes
286+
287+
if memory_bytes > old_size:
288+
# Growing: validate the extension region doesn't overlap
289+
extension_base = old_base + old_size
290+
extension_size = memory_bytes - old_size
291+
try:
292+
validate_memory_allocation(
293+
modified, extension_base, extension_size,
294+
exclude_instance=instance_node_name
295+
)
296+
memory_base_addr = old_base
297+
except (ResourceError,):
298+
# Extension conflicts, find a completely new region
299+
found_base = find_available_memory_base(modified, memory_bytes)
300+
if found_base is None:
301+
raise ResourceError(
302+
f"No available memory region found for {memory_bytes} bytes. "
303+
"Try specifying --memory-base or reduce memory size."
304+
)
305+
memory_base_addr = found_base
306+
elif memory_bytes < old_size:
307+
# Shrinking: always keep the same base
308+
memory_base_addr = old_base
309+
else:
310+
# Same size, no change
311+
memory_base_addr = old_base
290312
else:
291313
validate_memory_allocation(
292314
modified, memory_base_addr, memory_bytes, exclude_instance=instance_node_name

0 commit comments

Comments
 (0)