qemu_command_builder/smp.rs
1use bon::Builder;
2
3use crate::to_command::ToCommand;
4
5/// Simulate a SMP system with ``n`` CPUs initially present on
6/// the machine type board. On boards supporting CPU hotplug, the optional
7/// ``maxcpus`` parameter can be set to enable further CPUs to be
8/// added at runtime. When both parameters are omitted, the maximum number
9/// of CPUs will be calculated from the provided topology members and the
10/// initial CPU count will match the maximum number. When only one of them
11/// is given then the omitted one will be set to its counterpart's value.
12/// Both parameters may be specified, but the maximum number of CPUs must
13/// be equal to or greater than the initial CPU count. Product of the
14/// CPU topology hierarchy must be equal to the maximum number of CPUs.
15/// Both parameters are subject to an upper limit that is determined by
16/// the specific machine type chosen.
17///
18/// To control reporting of CPU topology information, values of the topology
19/// parameters can be specified. Machines may only support a subset of the
20/// parameters and different machines may have different subsets supported
21/// which vary depending on capacity of the corresponding CPU targets. So
22/// for a particular machine type board, an expected topology hierarchy can
23/// be defined through the supported sub-option. Unsupported parameters can
24/// also be provided in addition to the sub-option, but their values must be
25/// set as 1 in the purpose of correct parsing.
26///
27/// Either the initial CPU count, or at least one of the topology parameters
28/// must be specified. The specified parameters must be greater than zero,
29/// explicit configuration like "cpus=0" is not allowed. Values for any
30/// omitted parameters will be computed from those which are given.
31///
32/// For example, the following sub-option defines a CPU topology hierarchy
33/// (2 sockets totally on the machine, 2 cores per socket, 2 threads per
34/// core) for a machine that only supports sockets/cores/threads.
35/// Some members of the option can be omitted but their values will be
36/// automatically computed:
37#[derive(Builder)]
38pub struct SMP {
39 /// set the number of initial CPUs to 'n' [default=1]
40 cpus: usize,
41 /// maximum number of total CPUs, including offline CPUs for hotplug, etc
42 maxcpus: Option<usize>,
43 /// number of drawers on the machine board
44 drawers: Option<usize>,
45 /// number of books in one drawer
46 books: Option<usize>,
47 /// number of sockets in one book
48 sockets: Option<usize>,
49 /// number of dies in one socket
50 dies: Option<usize>,
51 /// number of clusters in one die
52 clusters: Option<usize>,
53 /// number of modules in one cluster
54 modules: Option<usize>,
55 /// number of cores in one module
56 cores: Option<usize>,
57 /// number of threads in one core
58 threads: Option<usize>,
59}
60
61impl Default for SMP {
62 fn default() -> Self {
63 SMP::new(1)
64 }
65}
66
67impl SMP {
68 pub fn new(cpus: usize) -> Self {
69 Self {
70 cpus,
71 maxcpus: None,
72 drawers: None,
73 books: None,
74 sockets: None,
75 dies: None,
76 clusters: None,
77 modules: None,
78 cores: None,
79 threads: None,
80 }
81 }
82}
83
84impl ToCommand for SMP {
85 fn to_command(&self) -> Vec<String> {
86 let mut cmd = vec![];
87
88 cmd.push("-smp".to_string());
89
90 let mut arg = vec![self.cpus.to_string()];
91 if let Some(maxcpus) = self.maxcpus {
92 arg.push(format!("maxcpus={}", maxcpus));
93 }
94 if let Some(drawers) = self.drawers {
95 arg.push(format!("drawers={}", drawers));
96 }
97 if let Some(books) = self.books {
98 arg.push(format!("books={}", books));
99 }
100 if let Some(sockets) = self.sockets {
101 arg.push(format!("sockets={}", sockets));
102 }
103 if let Some(dies) = self.dies {
104 arg.push(format!("dies={}", dies));
105 }
106 if let Some(clusters) = self.clusters {
107 arg.push(format!("clusters={}", clusters));
108 }
109 if let Some(modules) = self.modules {
110 arg.push(format!("modules={}", modules));
111 }
112 if let Some(cores) = self.cores {
113 arg.push(format!("cores={}", cores));
114 }
115 if let Some(threads) = self.threads {
116 arg.push(format!("threads={}", threads));
117 }
118
119 cmd.push(arg.join(","));
120
121 cmd
122 }
123}