MCPcopy Index your code
hub / github.com/cloud-hypervisor/cloud-hypervisor / create_memory_node

Function create_memory_node

arch/src/aarch64/fdt.rs:510–638  ·  view source on GitHub ↗
(
    fdt: &mut FdtWriter,
    guest_mem: &GuestMemoryMmap,
    numa_nodes: &NumaNodes,
)

Source from the content-addressed store, hash-verified

508}
509
510fn create_memory_node(
511 fdt: &mut FdtWriter,
512 guest_mem: &GuestMemoryMmap,
513 numa_nodes: &NumaNodes,
514) -> FdtWriterResult<()> {
515 // See https://github.com/torvalds/linux/blob/58ae0b51506802713aa0e9956d1853ba4c722c98/Documentation/devicetree/bindings/numa.txt
516 // for NUMA setting in memory node.
517 let has_generic_initiator = numa_nodes.values().any(|node| node.device_id.is_some());
518 if has_generic_initiator {
519 info!("Skipping NUMA memory node encoding in FDT with Generic Initiator devices");
520 }
521 // Skipping NUMA encoding in FDT when Generic Initiator devices
522 // are present allowed guest kernels to boot and
523 // rely solely on ACPI tables to setup NUMA
524 if numa_nodes.len() > 1 && !has_generic_initiator {
525 for numa_node_idx in 0..numa_nodes.len() {
526 let numa_node = numa_nodes.get(&(numa_node_idx as u32));
527 let mut mem_reg_prop: Vec<u64> = Vec::new();
528 let mut node_memory_addr: u64 = 0;
529 // Each memory zone of numa will have its own memory node, but
530 // different numa nodes should not share same memory zones.
531 for memory_region in numa_node.unwrap().memory_regions.iter() {
532 let memory_region_start_addr: u64 = memory_region.start_addr().raw_value();
533 let memory_region_size: u64 = memory_region.size() as u64;
534 mem_reg_prop.push(memory_region_start_addr);
535 mem_reg_prop.push(memory_region_size);
536 // Set the node address the first non-zero region address
537 if node_memory_addr == 0 {
538 node_memory_addr = memory_region_start_addr;
539 }
540 }
541 // Only create a memory node if this NUMA node has memory regions
542 if !mem_reg_prop.is_empty() {
543 let memory_node_name = format!("memory@{node_memory_addr:x}");
544 let memory_node = fdt.begin_node(&memory_node_name)?;
545 fdt.property_string("device_type", "memory")?;
546 fdt.property_array_u64("reg", &mem_reg_prop)?;
547 fdt.property_u32("numa-node-id", numa_node_idx as u32)?;
548 fdt.end_node(memory_node)?;
549 }
550 }
551 } else {
552 // Note: memory regions from "GuestMemory" are sorted and non-zero sized.
553 let ram_regions = {
554 let mut ram_regions = Vec::new();
555 let mut current_start = guest_mem
556 .iter()
557 .next()
558 .map(GuestMemoryRegion::start_addr)
559 .expect("GuestMemory must have one memory region at least")
560 .raw_value();
561 let mut current_end = current_start;
562
563 for (start, size) in guest_mem
564 .iter()
565 .map(|m| (m.start_addr().raw_value(), m.len()))
566 {
567 if current_end == start {

Callers 1

create_fdtFunction · 0.70

Calls 10

newFunction · 0.85
iterMethod · 0.80
start_addrMethod · 0.80
lenMethod · 0.45
getMethod · 0.45
sizeMethod · 0.45
pushMethod · 0.45
is_emptyMethod · 0.45
mapMethod · 0.45
nextMethod · 0.45

Tested by

no test coverage detected