Skip to content

Commit d576fe3

Browse files
committed
Make it more compact
1 parent d80e4ce commit d576fe3

File tree

1 file changed

+48
-78
lines changed

1 file changed

+48
-78
lines changed

openhcl/openhcl_boot/src/host_params/dma_hint.rs

+48-78
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,21 @@
66
use igvm_defs::{MemoryMapEntryType, PAGE_SIZE_4K};
77
use super::PartitionInfo;
88

9-
struct DmaLookupStruct {
10-
/// Logical processors for VM.
11-
vp_count: u32,
12-
/// Vtl2AddressRangeSize - Vtl2MmioAddressRangeSize.
13-
vtl2_memory_mb: u32,
14-
/// DMA hint in MiB.
15-
dma_hint_mb: u32,
16-
}
17-
189
/// Lookup table for DMA hint calculation.
19-
const LOOKUP_TABLE: &'static [DmaLookupStruct] = &[
20-
DmaLookupStruct {
21-
vp_count: 2,
22-
vtl2_memory_mb: 98,
23-
dma_hint_mb: 4,
24-
},
25-
DmaLookupStruct {
26-
vp_count: 4,
27-
vtl2_memory_mb: 110,
28-
dma_hint_mb: 6,
29-
},
30-
DmaLookupStruct {
31-
vp_count: 8,
32-
vtl2_memory_mb: 148,
33-
dma_hint_mb: 10,
34-
},
35-
DmaLookupStruct {
36-
vp_count: 16,
37-
vtl2_memory_mb: 256,
38-
dma_hint_mb: 18,
39-
},
40-
DmaLookupStruct {
41-
vp_count: 32,
42-
vtl2_memory_mb: 516,
43-
dma_hint_mb: 36,
44-
},
45-
DmaLookupStruct {
46-
vp_count: 48,
47-
vtl2_memory_mb: 718,
48-
dma_hint_mb: 52,
49-
},
50-
DmaLookupStruct {
51-
vp_count: 64,
52-
vtl2_memory_mb: 924,
53-
dma_hint_mb: 68,
54-
},
55-
DmaLookupStruct {
56-
vp_count: 96,
57-
vtl2_memory_mb: 1340,
58-
dma_hint_mb: 102,
59-
},
10+
/// Using tuples instead of structs to keep it readable.
11+
/// Let's keep the table sorted by VP count, then by assigned memory.
12+
/// Using u16 to keep the memory req short.
13+
/// Max VTL2 memory known today is 24838 MiB.
14+
/// (vp_count, vtl2_memory_mb, dma_hint_mb)
15+
const LOOKUP_TABLE: &[(u16, u16, u16)] = &[
16+
(2, 98, 4),
17+
(4, 110, 6),
18+
(8, 148, 10),
19+
(16, 256, 18),
20+
(32, 516, 36),
21+
(48, 718, 52),
22+
(64, 924, 68),
23+
(96, 1340, 102),
6024
];
6125

6226
/// Round up to next 2MiB.
@@ -77,34 +41,40 @@ pub fn vtl2_calculate_dma_hint(vp_count: usize, storage: &PartitionInfo) -> u64
7741
if mem_size > 0 && mem_size < 0xFFFFFFFF00000 {
7842
let mem_size_mb = (mem_size / 1048576) as u32;
7943

80-
let mut min_vtl2_memory_mb = 1000000;
44+
let mut min_vtl2_memory_mb = 65535;
8145
let mut max_vtl2_memory_mb = 0;
8246

8347
// To avoid using floats, scale ratios to 1:1000.
8448
let mut min_ratio_1000th = 100000;
8549
let mut max_ratio_1000th = 1000;
8650

87-
let mut min_vp_count = 1;
88-
let mut max_vp_count = vp_count as u32;
89-
90-
for f in LOOKUP_TABLE {
91-
if f.vp_count == vp_count as u32 {
92-
if f.vtl2_memory_mb == mem_size_mb {
93-
// Found exact match.
94-
dma_hint_4k = f.dma_hint_mb as u64 * 1048576 / PAGE_SIZE_4K;
95-
break;
96-
} else {
97-
// Prepare for possible extrapolation.
98-
min_vtl2_memory_mb = min_vtl2_memory_mb.min(f.vtl2_memory_mb);
99-
max_vtl2_memory_mb = max_vtl2_memory_mb.max(f.vtl2_memory_mb);
100-
min_ratio_1000th = min_ratio_1000th.min(f.vtl2_memory_mb as u32 * 1000 / f.dma_hint_mb as u32);
101-
max_ratio_1000th = max_ratio_1000th.max(f.vtl2_memory_mb as u32 * 1000 / f.dma_hint_mb as u32);
51+
let mut min_vp_count: u16 = 1;
52+
let mut max_vp_count = vp_count as u16;
53+
54+
for (vp_lookup, vtl2_memory_mb, dma_hint_mb) in LOOKUP_TABLE {
55+
match (*vp_lookup).cmp(&(vp_count as u16)) {
56+
core::cmp::Ordering::Less => {
57+
// Find nearest.
58+
min_vp_count = min_vp_count.max(*vp_lookup);
59+
}
60+
core::cmp::Ordering::Equal => {
61+
if *vtl2_memory_mb == mem_size_mb as u16 {
62+
// Found exact match.
63+
dma_hint_4k = *dma_hint_mb as u64 * 1048576 / PAGE_SIZE_4K;
64+
max_vtl2_memory_mb = *vtl2_memory_mb;
65+
break;
66+
} else {
67+
// Prepare for possible extrapolation.
68+
min_vtl2_memory_mb = min_vtl2_memory_mb.min(*vtl2_memory_mb);
69+
max_vtl2_memory_mb = max_vtl2_memory_mb.max(*vtl2_memory_mb);
70+
min_ratio_1000th = min_ratio_1000th.min(*vtl2_memory_mb as u32 * 1000 / *dma_hint_mb as u32);
71+
max_ratio_1000th = max_ratio_1000th.max(*vtl2_memory_mb as u32 * 1000 / *dma_hint_mb as u32);
72+
}
73+
}
74+
core::cmp::Ordering::Greater => {
75+
// Find nearest.
76+
max_vp_count = max_vp_count.min(*vp_lookup);
10277
}
103-
} else if f.vp_count < vp_count as u32 {
104-
// Find the nearest VP counts if exact match is not in the table.
105-
min_vp_count = min_vp_count.max(f.vp_count);
106-
} else if f.vp_count > vp_count as u32 {
107-
max_vp_count = max_vp_count.min(f.vp_count);
10878
}
10979
}
11080

@@ -113,17 +83,17 @@ pub fn vtl2_calculate_dma_hint(vp_count: usize, storage: &PartitionInfo) -> u64
11383
if max_vtl2_memory_mb == 0 {
11484
LOOKUP_TABLE
11585
.iter()
116-
.filter(|e| e.vp_count == min_vp_count || e.vp_count == max_vp_count)
117-
.for_each(|f| {
118-
min_vtl2_memory_mb = min_vtl2_memory_mb.min(f.vtl2_memory_mb);
119-
max_vtl2_memory_mb = max_vtl2_memory_mb.max(f.vtl2_memory_mb);
120-
min_ratio_1000th = min_ratio_1000th.min(f.vtl2_memory_mb as u32 * 1000 / f.dma_hint_mb as u32);
121-
max_ratio_1000th = max_ratio_1000th.max(f.vtl2_memory_mb as u32 * 1000 / f.dma_hint_mb as u32);
86+
.filter(|(vp_lookup, _, _)| *vp_lookup == min_vp_count || *vp_lookup == max_vp_count)
87+
.for_each(|(_, vtl2_memory_mb, dma_hint_mb)| {
88+
min_vtl2_memory_mb = min_vtl2_memory_mb.min(*vtl2_memory_mb);
89+
max_vtl2_memory_mb = max_vtl2_memory_mb.max(*vtl2_memory_mb);
90+
min_ratio_1000th = min_ratio_1000th.min(*vtl2_memory_mb as u32 * 1000 / *dma_hint_mb as u32);
91+
max_ratio_1000th = max_ratio_1000th.max(*vtl2_memory_mb as u32 * 1000 / *dma_hint_mb as u32);
12292
});
12393
}
12494

12595
if dma_hint_4k == 0 {
126-
// If we didn't find an exact match for our vp_count, try to extrapolate.
96+
// Didn't find an exact match for vp_count, try to extrapolate.
12797
dma_hint_4k = (mem_size_mb as u64 * 1000u64 * (1048576u64 / PAGE_SIZE_4K)) /
12898
((min_ratio_1000th + max_ratio_1000th) as u64 / 2u64);
12999

0 commit comments

Comments
 (0)