1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
13 #include <cmdline_rdline.h>
14 #include <cmdline_parse.h>
15 #include <cmdline_parse_string.h>
16 #include <cmdline_parse_num.h>
17 #include <cmdline_socket.h>
20 #include "vm_power_cli.h"
21 #include "channel_manager.h"
22 #include "channel_monitor.h"
23 #include "power_manager.h"
24 #include "channel_commands.h"
26 struct cmd_quit_result
{
27 cmdline_fixed_string_t quit
;
30 static void cmd_quit_parsed(__attribute__((unused
)) void *parsed_result
,
32 __attribute__((unused
)) void *data
)
34 channel_monitor_exit();
35 channel_manager_exit();
40 cmdline_parse_token_string_t cmd_quit_quit
=
41 TOKEN_STRING_INITIALIZER(struct cmd_quit_result
, quit
, "quit");
43 cmdline_parse_inst_t cmd_quit
= {
44 .f
= cmd_quit_parsed
, /* function to call */
45 .data
= NULL
, /* 2nd arg of func */
46 .help_str
= "close the application",
47 .tokens
= { /* token list, NULL terminated */
48 (void *)&cmd_quit_quit
,
53 /* *** VM operations *** */
54 struct cmd_show_vm_result
{
55 cmdline_fixed_string_t show_vm
;
56 cmdline_fixed_string_t vm_name
;
60 cmd_show_vm_parsed(void *parsed_result
, struct cmdline
*cl
,
61 __attribute__((unused
)) void *data
)
63 struct cmd_show_vm_result
*res
= parsed_result
;
67 if (get_info_vm(res
->vm_name
, &info
) != 0)
69 cmdline_printf(cl
, "VM: '%s', status = ", info
.name
);
70 if (info
.status
== CHANNEL_MGR_VM_ACTIVE
)
71 cmdline_printf(cl
, "ACTIVE\n");
73 cmdline_printf(cl
, "INACTIVE\n");
74 cmdline_printf(cl
, "Channels %u\n", info
.num_channels
);
75 for (i
= 0; i
< info
.num_channels
; i
++) {
76 cmdline_printf(cl
, " [%u]: %s, status = ", i
,
77 info
.channels
[i
].channel_path
);
78 switch (info
.channels
[i
].status
) {
79 case CHANNEL_MGR_CHANNEL_CONNECTED
:
80 cmdline_printf(cl
, "CONNECTED\n");
82 case CHANNEL_MGR_CHANNEL_DISCONNECTED
:
83 cmdline_printf(cl
, "DISCONNECTED\n");
85 case CHANNEL_MGR_CHANNEL_DISABLED
:
86 cmdline_printf(cl
, "DISABLED\n");
88 case CHANNEL_MGR_CHANNEL_PROCESSING
:
89 cmdline_printf(cl
, "PROCESSING\n");
92 cmdline_printf(cl
, "UNKNOWN\n");
96 cmdline_printf(cl
, "Virtual CPU(s): %u\n", info
.num_vcpus
);
97 for (i
= 0; i
< info
.num_vcpus
; i
++) {
98 cmdline_printf(cl
, " [%u]: Physical CPU %d\n", i
,
105 cmdline_parse_token_string_t cmd_vm_show
=
106 TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result
,
108 cmdline_parse_token_string_t cmd_show_vm_name
=
109 TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result
,
112 cmdline_parse_inst_t cmd_show_vm_set
= {
113 .f
= cmd_show_vm_parsed
,
115 .help_str
= "show_vm <vm_name>, prints the information on the "
116 "specified VM(s), the information lists the number of vCPUS, the "
117 "pinning to pCPU(s) as a bit mask, along with any communication "
118 "channels associated with each VM",
120 (void *)&cmd_vm_show
,
121 (void *)&cmd_show_vm_name
,
126 /* *** vCPU to pCPU mapping operations *** */
129 struct cmd_set_pcpu_result
{
130 cmdline_fixed_string_t set_pcpu
;
131 cmdline_fixed_string_t vm_name
;
137 cmd_set_pcpu_parsed(void *parsed_result
, struct cmdline
*cl
,
138 __attribute__((unused
)) void *data
)
140 struct cmd_set_pcpu_result
*res
= parsed_result
;
142 if (set_pcpu(res
->vm_name
, res
->vcpu
, res
->core
) == 0)
143 cmdline_printf(cl
, "Pinned vCPU(%"PRId8
") to pCPU core "
144 "%"PRId8
")\n", res
->vcpu
, res
->core
);
146 cmdline_printf(cl
, "Unable to pin vCPU(%"PRId8
") to pCPU core "
147 "%"PRId8
")\n", res
->vcpu
, res
->core
);
150 cmdline_parse_token_string_t cmd_set_pcpu
=
151 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result
,
152 set_pcpu
, "set_pcpu");
153 cmdline_parse_token_string_t cmd_set_pcpu_vm_name
=
154 TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result
,
156 cmdline_parse_token_num_t set_pcpu_vcpu
=
157 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result
,
159 cmdline_parse_token_num_t set_pcpu_core
=
160 TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result
,
164 cmdline_parse_inst_t cmd_set_pcpu_set
= {
165 .f
= cmd_set_pcpu_parsed
,
167 .help_str
= "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding "
168 "of Virtual CPU on VM to the Physical CPU.",
170 (void *)&cmd_set_pcpu
,
171 (void *)&cmd_set_pcpu_vm_name
,
172 (void *)&set_pcpu_vcpu
,
173 (void *)&set_pcpu_core
,
178 struct cmd_vm_op_result
{
179 cmdline_fixed_string_t op_vm
;
180 cmdline_fixed_string_t vm_name
;
184 cmd_vm_op_parsed(void *parsed_result
, struct cmdline
*cl
,
185 __attribute__((unused
)) void *data
)
187 struct cmd_vm_op_result
*res
= parsed_result
;
189 if (!strcmp(res
->op_vm
, "add_vm")) {
190 if (add_vm(res
->vm_name
) < 0)
191 cmdline_printf(cl
, "Unable to add VM '%s'\n", res
->vm_name
);
192 } else if (remove_vm(res
->vm_name
) < 0)
193 cmdline_printf(cl
, "Unable to remove VM '%s'\n", res
->vm_name
);
196 cmdline_parse_token_string_t cmd_vm_op
=
197 TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result
,
198 op_vm
, "add_vm#rm_vm");
199 cmdline_parse_token_string_t cmd_vm_name
=
200 TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result
,
203 cmdline_parse_inst_t cmd_vm_op_set
= {
204 .f
= cmd_vm_op_parsed
,
206 .help_str
= "add_vm|rm_vm <name>, add a VM for "
207 "subsequent operations with the CLI or remove a previously added "
208 "VM from the VM Power Manager",
211 (void *)&cmd_vm_name
,
216 /* *** VM channel operations *** */
217 struct cmd_channels_op_result
{
218 cmdline_fixed_string_t op
;
219 cmdline_fixed_string_t vm_name
;
220 cmdline_fixed_string_t channel_list
;
223 cmd_channels_op_parsed(void *parsed_result
, struct cmdline
*cl
,
224 __attribute__((unused
)) void *data
)
226 unsigned num_channels
= 0, channel_num
, i
;
228 unsigned int channel_list
[RTE_MAX_LCORE
];
229 char *token
, *remaining
, *tail_ptr
;
230 struct cmd_channels_op_result
*res
= parsed_result
;
232 if (!strcmp(res
->channel_list
, "all")) {
233 channels_added
= add_all_channels(res
->vm_name
);
234 cmdline_printf(cl
, "Added %d channels for VM '%s'\n",
235 channels_added
, res
->vm_name
);
239 remaining
= res
->channel_list
;
241 if (remaining
== NULL
|| remaining
[0] == '\0')
244 token
= strsep(&remaining
, ",");
248 channel_num
= (unsigned)strtol(token
, &tail_ptr
, 10);
249 if ((errno
!= 0) || tail_ptr
== NULL
|| (*tail_ptr
!= '\0'))
252 if (channel_num
== RTE_MAX_LCORE
) {
253 cmdline_printf(cl
, "Channel number '%u' exceeds the maximum number "
254 "of allowable channels(%u) for VM '%s'\n", channel_num
,
255 RTE_MAX_LCORE
, res
->vm_name
);
258 channel_list
[num_channels
++] = channel_num
;
260 for (i
= 0; i
< num_channels
; i
++)
261 cmdline_printf(cl
, "[%u]: Adding channel %u\n", i
, channel_list
[i
]);
263 channels_added
= add_channels(res
->vm_name
, channel_list
,
265 cmdline_printf(cl
, "Enabled %d channels for '%s'\n", channels_added
,
269 cmdline_parse_token_string_t cmd_channels_op
=
270 TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result
,
272 cmdline_parse_token_string_t cmd_channels_vm_name
=
273 TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result
,
275 cmdline_parse_token_string_t cmd_channels_list
=
276 TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result
,
279 cmdline_parse_inst_t cmd_channels_op_set
= {
280 .f
= cmd_channels_op_parsed
,
282 .help_str
= "add_channels <vm_name> <list>|all, add "
283 "communication channels for the specified VM, the "
284 "virtio channels must be enabled in the VM "
285 "configuration(qemu/libvirt) and the associated VM must be active. "
286 "<list> is a comma-separated list of channel numbers to add, using "
287 "the keyword 'all' will attempt to add all channels for the VM",
289 (void *)&cmd_channels_op
,
290 (void *)&cmd_channels_vm_name
,
291 (void *)&cmd_channels_list
,
296 struct cmd_channels_status_op_result
{
297 cmdline_fixed_string_t op
;
298 cmdline_fixed_string_t vm_name
;
299 cmdline_fixed_string_t channel_list
;
300 cmdline_fixed_string_t status
;
304 cmd_channels_status_op_parsed(void *parsed_result
, struct cmdline
*cl
,
305 __attribute__((unused
)) void *data
)
307 unsigned num_channels
= 0, channel_num
;
309 unsigned int channel_list
[RTE_MAX_LCORE
];
310 char *token
, *remaining
, *tail_ptr
;
311 struct cmd_channels_status_op_result
*res
= parsed_result
;
312 enum channel_status status
;
314 if (!strcmp(res
->status
, "enabled"))
315 status
= CHANNEL_MGR_CHANNEL_CONNECTED
;
317 status
= CHANNEL_MGR_CHANNEL_DISABLED
;
319 if (!strcmp(res
->channel_list
, "all")) {
320 changed
= set_channel_status_all(res
->vm_name
, status
);
321 cmdline_printf(cl
, "Updated status of %d channels "
322 "for VM '%s'\n", changed
, res
->vm_name
);
325 remaining
= res
->channel_list
;
327 if (remaining
== NULL
|| remaining
[0] == '\0')
329 token
= strsep(&remaining
, ",");
333 channel_num
= (unsigned)strtol(token
, &tail_ptr
, 10);
334 if ((errno
!= 0) || tail_ptr
== NULL
|| (*tail_ptr
!= '\0'))
337 if (channel_num
== RTE_MAX_LCORE
) {
338 cmdline_printf(cl
, "%u exceeds the maximum number of allowable "
339 "channels(%u) for VM '%s'\n", channel_num
,
340 RTE_MAX_LCORE
, res
->vm_name
);
343 channel_list
[num_channels
++] = channel_num
;
345 changed
= set_channel_status(res
->vm_name
, channel_list
, num_channels
,
347 cmdline_printf(cl
, "Updated status of %d channels "
348 "for VM '%s'\n", changed
, res
->vm_name
);
351 cmdline_parse_token_string_t cmd_channels_status_op
=
352 TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result
,
353 op
, "set_channel_status");
354 cmdline_parse_token_string_t cmd_channels_status_vm_name
=
355 TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result
,
357 cmdline_parse_token_string_t cmd_channels_status_list
=
358 TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result
,
360 cmdline_parse_token_string_t cmd_channels_status
=
361 TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result
,
362 status
, "enabled#disabled");
364 cmdline_parse_inst_t cmd_channels_status_op_set
= {
365 .f
= cmd_channels_status_op_parsed
,
367 .help_str
= "set_channel_status <vm_name> <list>|all enabled|disabled, "
368 " enable or disable the communication channels in "
369 "list(comma-separated) for the specified VM, alternatively "
370 "list can be replaced with keyword 'all'. "
371 "Disabled channels will still receive packets on the host, "
372 "however the commands they specify will be ignored. "
373 "Set status to 'enabled' to begin processing requests again.",
375 (void *)&cmd_channels_status_op
,
376 (void *)&cmd_channels_status_vm_name
,
377 (void *)&cmd_channels_status_list
,
378 (void *)&cmd_channels_status
,
383 /* *** CPU Frequency operations *** */
384 struct cmd_show_cpu_freq_result
{
385 cmdline_fixed_string_t show_cpu_freq
;
390 cmd_show_cpu_freq_parsed(void *parsed_result
, struct cmdline
*cl
,
391 __attribute__((unused
)) void *data
)
393 struct cmd_show_cpu_freq_result
*res
= parsed_result
;
394 uint32_t curr_freq
= power_manager_get_current_frequency(res
->core_num
);
396 if (curr_freq
== 0) {
397 cmdline_printf(cl
, "Unable to get frequency for core %u\n",
401 cmdline_printf(cl
, "Core %u frequency: %"PRId32
"\n", res
->core_num
,
405 cmdline_parse_token_string_t cmd_show_cpu_freq
=
406 TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result
,
407 show_cpu_freq
, "show_cpu_freq");
409 cmdline_parse_token_num_t cmd_show_cpu_freq_core_num
=
410 TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result
,
413 cmdline_parse_inst_t cmd_show_cpu_freq_set
= {
414 .f
= cmd_show_cpu_freq_parsed
,
416 .help_str
= "Get the current frequency for the specified core",
418 (void *)&cmd_show_cpu_freq
,
419 (void *)&cmd_show_cpu_freq_core_num
,
424 struct cmd_set_cpu_freq_result
{
425 cmdline_fixed_string_t set_cpu_freq
;
427 cmdline_fixed_string_t cmd
;
431 cmd_set_cpu_freq_parsed(void *parsed_result
, struct cmdline
*cl
,
432 __attribute__((unused
)) void *data
)
435 struct cmd_set_cpu_freq_result
*res
= parsed_result
;
437 if (!strcmp(res
->cmd
, "up"))
438 ret
= power_manager_scale_core_up(res
->core_num
);
439 else if (!strcmp(res
->cmd
, "down"))
440 ret
= power_manager_scale_core_down(res
->core_num
);
441 else if (!strcmp(res
->cmd
, "min"))
442 ret
= power_manager_scale_core_min(res
->core_num
);
443 else if (!strcmp(res
->cmd
, "max"))
444 ret
= power_manager_scale_core_max(res
->core_num
);
445 else if (!strcmp(res
->cmd
, "enable_turbo"))
446 ret
= power_manager_enable_turbo_core(res
->core_num
);
447 else if (!strcmp(res
->cmd
, "disable_turbo"))
448 ret
= power_manager_disable_turbo_core(res
->core_num
);
450 cmdline_printf(cl
, "Error scaling core(%u) '%s'\n", res
->core_num
,
455 cmdline_parse_token_string_t cmd_set_cpu_freq
=
456 TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result
,
457 set_cpu_freq
, "set_cpu_freq");
458 cmdline_parse_token_num_t cmd_set_cpu_freq_core_num
=
459 TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result
,
461 cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd
=
462 TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result
,
463 cmd
, "up#down#min#max#enable_turbo#disable_turbo");
465 cmdline_parse_inst_t cmd_set_cpu_freq_set
= {
466 .f
= cmd_set_cpu_freq_parsed
,
468 .help_str
= "set_cpu_freq <core_num> <up|down|min|max|enable_turbo|disable_turbo>, adjust the current "
469 "frequency for the specified core",
471 (void *)&cmd_set_cpu_freq
,
472 (void *)&cmd_set_cpu_freq_core_num
,
473 (void *)&cmd_set_cpu_freq_cmd_cmd
,
478 cmdline_parse_ctx_t main_ctx
[] = {
479 (cmdline_parse_inst_t
*)&cmd_quit
,
480 (cmdline_parse_inst_t
*)&cmd_vm_op_set
,
481 (cmdline_parse_inst_t
*)&cmd_channels_op_set
,
482 (cmdline_parse_inst_t
*)&cmd_channels_status_op_set
,
483 (cmdline_parse_inst_t
*)&cmd_show_vm_set
,
484 (cmdline_parse_inst_t
*)&cmd_show_cpu_freq_set
,
485 (cmdline_parse_inst_t
*)&cmd_set_cpu_freq_set
,
486 (cmdline_parse_inst_t
*)&cmd_set_pcpu_set
,
491 run_cli(__attribute__((unused
)) void *arg
)
495 cl
= cmdline_stdin_new(main_ctx
, "vmpower> ");
499 cmdline_interact(cl
);
500 cmdline_stdin_exit(cl
);