13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 33842bf24SAlan Carew */ 43842bf24SAlan Carew 53842bf24SAlan Carew #include <stdlib.h> 63842bf24SAlan Carew #include <stdint.h> 73842bf24SAlan Carew #include <inttypes.h> 83842bf24SAlan Carew #include <stdio.h> 93842bf24SAlan Carew #include <string.h> 103842bf24SAlan Carew #include <termios.h> 113842bf24SAlan Carew #include <errno.h> 123842bf24SAlan Carew 133842bf24SAlan Carew #include <cmdline_rdline.h> 143842bf24SAlan Carew #include <cmdline_parse.h> 153842bf24SAlan Carew #include <cmdline_parse_string.h> 163842bf24SAlan Carew #include <cmdline_parse_num.h> 173842bf24SAlan Carew #include <cmdline_socket.h> 183842bf24SAlan Carew #include <cmdline.h> 193842bf24SAlan Carew 203842bf24SAlan Carew #include "vm_power_cli.h" 213842bf24SAlan Carew #include "channel_manager.h" 223842bf24SAlan Carew #include "channel_monitor.h" 233842bf24SAlan Carew #include "power_manager.h" 243842bf24SAlan Carew #include "channel_commands.h" 253842bf24SAlan Carew 263842bf24SAlan Carew struct cmd_quit_result { 273842bf24SAlan Carew cmdline_fixed_string_t quit; 283842bf24SAlan Carew }; 293842bf24SAlan Carew 30f2fc83b4SThomas Monjalon static void cmd_quit_parsed(__rte_unused void *parsed_result, 313842bf24SAlan Carew struct cmdline *cl, 32f2fc83b4SThomas Monjalon __rte_unused void *data) 333842bf24SAlan Carew { 343842bf24SAlan Carew channel_monitor_exit(); 353842bf24SAlan Carew channel_manager_exit(); 363842bf24SAlan Carew power_manager_exit(); 373842bf24SAlan Carew cmdline_quit(cl); 383842bf24SAlan Carew } 393842bf24SAlan Carew 403842bf24SAlan Carew cmdline_parse_token_string_t cmd_quit_quit = 413842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit"); 423842bf24SAlan Carew 433842bf24SAlan Carew cmdline_parse_inst_t cmd_quit = { 443842bf24SAlan Carew .f = cmd_quit_parsed, /* function to call */ 453842bf24SAlan Carew .data = NULL, /* 2nd arg of func */ 463842bf24SAlan Carew .help_str = "close the application", 473842bf24SAlan Carew .tokens = { /* token list, NULL terminated */ 483842bf24SAlan Carew (void *)&cmd_quit_quit, 493842bf24SAlan Carew NULL, 503842bf24SAlan Carew }, 513842bf24SAlan Carew }; 523842bf24SAlan Carew 533842bf24SAlan Carew /* *** VM operations *** */ 543842bf24SAlan Carew struct cmd_show_vm_result { 553842bf24SAlan Carew cmdline_fixed_string_t show_vm; 563842bf24SAlan Carew cmdline_fixed_string_t vm_name; 573842bf24SAlan Carew }; 583842bf24SAlan Carew 593842bf24SAlan Carew static void 603842bf24SAlan Carew cmd_show_vm_parsed(void *parsed_result, struct cmdline *cl, 61f2fc83b4SThomas Monjalon __rte_unused void *data) 623842bf24SAlan Carew { 633842bf24SAlan Carew struct cmd_show_vm_result *res = parsed_result; 643842bf24SAlan Carew struct vm_info info; 653842bf24SAlan Carew unsigned i; 663842bf24SAlan Carew 673842bf24SAlan Carew if (get_info_vm(res->vm_name, &info) != 0) 683842bf24SAlan Carew return; 693842bf24SAlan Carew cmdline_printf(cl, "VM: '%s', status = ", info.name); 703842bf24SAlan Carew if (info.status == CHANNEL_MGR_VM_ACTIVE) 713842bf24SAlan Carew cmdline_printf(cl, "ACTIVE\n"); 723842bf24SAlan Carew else 733842bf24SAlan Carew cmdline_printf(cl, "INACTIVE\n"); 743842bf24SAlan Carew cmdline_printf(cl, "Channels %u\n", info.num_channels); 753842bf24SAlan Carew for (i = 0; i < info.num_channels; i++) { 763842bf24SAlan Carew cmdline_printf(cl, " [%u]: %s, status = ", i, 773842bf24SAlan Carew info.channels[i].channel_path); 783842bf24SAlan Carew switch (info.channels[i].status) { 793842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_CONNECTED: 803842bf24SAlan Carew cmdline_printf(cl, "CONNECTED\n"); 813842bf24SAlan Carew break; 823842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_DISCONNECTED: 833842bf24SAlan Carew cmdline_printf(cl, "DISCONNECTED\n"); 843842bf24SAlan Carew break; 853842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_DISABLED: 863842bf24SAlan Carew cmdline_printf(cl, "DISABLED\n"); 873842bf24SAlan Carew break; 883842bf24SAlan Carew case CHANNEL_MGR_CHANNEL_PROCESSING: 893842bf24SAlan Carew cmdline_printf(cl, "PROCESSING\n"); 903842bf24SAlan Carew break; 913842bf24SAlan Carew default: 923842bf24SAlan Carew cmdline_printf(cl, "UNKNOWN\n"); 933842bf24SAlan Carew break; 943842bf24SAlan Carew } 953842bf24SAlan Carew } 963842bf24SAlan Carew cmdline_printf(cl, "Virtual CPU(s): %u\n", info.num_vcpus); 973842bf24SAlan Carew for (i = 0; i < info.num_vcpus; i++) { 985776b7a3SDavid Hunt cmdline_printf(cl, " [%u]: Physical CPU %d\n", i, 995776b7a3SDavid Hunt info.pcpu_map[i]); 1003842bf24SAlan Carew } 1013842bf24SAlan Carew } 1023842bf24SAlan Carew 1033842bf24SAlan Carew 1043842bf24SAlan Carew 1053842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_show = 1063842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result, 1073842bf24SAlan Carew show_vm, "show_vm"); 1083842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_vm_name = 1093842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_vm_result, 1103842bf24SAlan Carew vm_name, NULL); 1113842bf24SAlan Carew 1123842bf24SAlan Carew cmdline_parse_inst_t cmd_show_vm_set = { 1133842bf24SAlan Carew .f = cmd_show_vm_parsed, 1143842bf24SAlan Carew .data = NULL, 1153842bf24SAlan Carew .help_str = "show_vm <vm_name>, prints the information on the " 1163842bf24SAlan Carew "specified VM(s), the information lists the number of vCPUS, the " 1173842bf24SAlan Carew "pinning to pCPU(s) as a bit mask, along with any communication " 1183842bf24SAlan Carew "channels associated with each VM", 1193842bf24SAlan Carew .tokens = { 1203842bf24SAlan Carew (void *)&cmd_vm_show, 1213842bf24SAlan Carew (void *)&cmd_show_vm_name, 1223842bf24SAlan Carew NULL, 1233842bf24SAlan Carew }, 1243842bf24SAlan Carew }; 1253842bf24SAlan Carew 1263842bf24SAlan Carew /* *** vCPU to pCPU mapping operations *** */ 1273842bf24SAlan Carew 1283842bf24SAlan Carew 1293842bf24SAlan Carew struct cmd_set_pcpu_result { 1303842bf24SAlan Carew cmdline_fixed_string_t set_pcpu; 1313842bf24SAlan Carew cmdline_fixed_string_t vm_name; 1323842bf24SAlan Carew uint8_t vcpu; 1333842bf24SAlan Carew uint8_t core; 1343842bf24SAlan Carew }; 1353842bf24SAlan Carew 1363842bf24SAlan Carew static void 1373842bf24SAlan Carew cmd_set_pcpu_parsed(void *parsed_result, struct cmdline *cl, 138f2fc83b4SThomas Monjalon __rte_unused void *data) 1393842bf24SAlan Carew { 1403842bf24SAlan Carew struct cmd_set_pcpu_result *res = parsed_result; 1413842bf24SAlan Carew 1423842bf24SAlan Carew if (set_pcpu(res->vm_name, res->vcpu, res->core) == 0) 1433842bf24SAlan Carew cmdline_printf(cl, "Pinned vCPU(%"PRId8") to pCPU core " 1443842bf24SAlan Carew "%"PRId8")\n", res->vcpu, res->core); 1453842bf24SAlan Carew else 1463842bf24SAlan Carew cmdline_printf(cl, "Unable to pin vCPU(%"PRId8") to pCPU core " 1473842bf24SAlan Carew "%"PRId8")\n", res->vcpu, res->core); 1483842bf24SAlan Carew } 1493842bf24SAlan Carew 1503842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu = 1513842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result, 1523842bf24SAlan Carew set_pcpu, "set_pcpu"); 1533842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_pcpu_vm_name = 1543842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_pcpu_result, 1553842bf24SAlan Carew vm_name, NULL); 1563842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_vcpu = 1573842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result, 158*c2341bb6SDmitry Kozlyuk vcpu, RTE_UINT8); 1593842bf24SAlan Carew cmdline_parse_token_num_t set_pcpu_core = 1603842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_pcpu_result, 161*c2341bb6SDmitry Kozlyuk core, RTE_UINT64); 1623842bf24SAlan Carew 1633842bf24SAlan Carew 1643842bf24SAlan Carew cmdline_parse_inst_t cmd_set_pcpu_set = { 1653842bf24SAlan Carew .f = cmd_set_pcpu_parsed, 1663842bf24SAlan Carew .data = NULL, 1673842bf24SAlan Carew .help_str = "set_pcpu <vm_name> <vcpu> <pcpu>, Set the binding " 1683842bf24SAlan Carew "of Virtual CPU on VM to the Physical CPU.", 1693842bf24SAlan Carew .tokens = { 1703842bf24SAlan Carew (void *)&cmd_set_pcpu, 1713842bf24SAlan Carew (void *)&cmd_set_pcpu_vm_name, 1723842bf24SAlan Carew (void *)&set_pcpu_vcpu, 1733842bf24SAlan Carew (void *)&set_pcpu_core, 1743842bf24SAlan Carew NULL, 1753842bf24SAlan Carew }, 1763842bf24SAlan Carew }; 1773842bf24SAlan Carew 1783842bf24SAlan Carew struct cmd_vm_op_result { 1793842bf24SAlan Carew cmdline_fixed_string_t op_vm; 1803842bf24SAlan Carew cmdline_fixed_string_t vm_name; 1813842bf24SAlan Carew }; 1823842bf24SAlan Carew 1833842bf24SAlan Carew static void 1843842bf24SAlan Carew cmd_vm_op_parsed(void *parsed_result, struct cmdline *cl, 185f2fc83b4SThomas Monjalon __rte_unused void *data) 1863842bf24SAlan Carew { 1873842bf24SAlan Carew struct cmd_vm_op_result *res = parsed_result; 1883842bf24SAlan Carew 1893842bf24SAlan Carew if (!strcmp(res->op_vm, "add_vm")) { 1903842bf24SAlan Carew if (add_vm(res->vm_name) < 0) 1913842bf24SAlan Carew cmdline_printf(cl, "Unable to add VM '%s'\n", res->vm_name); 1923842bf24SAlan Carew } else if (remove_vm(res->vm_name) < 0) 1933842bf24SAlan Carew cmdline_printf(cl, "Unable to remove VM '%s'\n", res->vm_name); 1943842bf24SAlan Carew } 1953842bf24SAlan Carew 1963842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_op = 1973842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result, 1983842bf24SAlan Carew op_vm, "add_vm#rm_vm"); 1993842bf24SAlan Carew cmdline_parse_token_string_t cmd_vm_name = 2003842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_vm_op_result, 2013842bf24SAlan Carew vm_name, NULL); 2023842bf24SAlan Carew 2033842bf24SAlan Carew cmdline_parse_inst_t cmd_vm_op_set = { 2043842bf24SAlan Carew .f = cmd_vm_op_parsed, 2053842bf24SAlan Carew .data = NULL, 2063842bf24SAlan Carew .help_str = "add_vm|rm_vm <name>, add a VM for " 2073842bf24SAlan Carew "subsequent operations with the CLI or remove a previously added " 2083842bf24SAlan Carew "VM from the VM Power Manager", 2093842bf24SAlan Carew .tokens = { 2103842bf24SAlan Carew (void *)&cmd_vm_op, 2113842bf24SAlan Carew (void *)&cmd_vm_name, 2123842bf24SAlan Carew NULL, 2133842bf24SAlan Carew }, 2143842bf24SAlan Carew }; 2153842bf24SAlan Carew 2163842bf24SAlan Carew /* *** VM channel operations *** */ 2173842bf24SAlan Carew struct cmd_channels_op_result { 2183842bf24SAlan Carew cmdline_fixed_string_t op; 2193842bf24SAlan Carew cmdline_fixed_string_t vm_name; 2203842bf24SAlan Carew cmdline_fixed_string_t channel_list; 2213842bf24SAlan Carew }; 2223842bf24SAlan Carew static void 2233842bf24SAlan Carew cmd_channels_op_parsed(void *parsed_result, struct cmdline *cl, 224f2fc83b4SThomas Monjalon __rte_unused void *data) 2253842bf24SAlan Carew { 2263842bf24SAlan Carew unsigned num_channels = 0, channel_num, i; 2273842bf24SAlan Carew int channels_added; 228751227a0SDavid Hunt unsigned int channel_list[RTE_MAX_LCORE]; 2293842bf24SAlan Carew char *token, *remaining, *tail_ptr; 2303842bf24SAlan Carew struct cmd_channels_op_result *res = parsed_result; 2313842bf24SAlan Carew 2323842bf24SAlan Carew if (!strcmp(res->channel_list, "all")) { 2333842bf24SAlan Carew channels_added = add_all_channels(res->vm_name); 2343842bf24SAlan Carew cmdline_printf(cl, "Added %d channels for VM '%s'\n", 2353842bf24SAlan Carew channels_added, res->vm_name); 2363842bf24SAlan Carew return; 2373842bf24SAlan Carew } 2383842bf24SAlan Carew 2393842bf24SAlan Carew remaining = res->channel_list; 2403842bf24SAlan Carew while (1) { 2413842bf24SAlan Carew if (remaining == NULL || remaining[0] == '\0') 2423842bf24SAlan Carew break; 2433842bf24SAlan Carew 2443842bf24SAlan Carew token = strsep(&remaining, ","); 2453842bf24SAlan Carew if (token == NULL) 2463842bf24SAlan Carew break; 2473842bf24SAlan Carew errno = 0; 2483842bf24SAlan Carew channel_num = (unsigned)strtol(token, &tail_ptr, 10); 2495b628fe1SBruce Richardson if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0')) 2503842bf24SAlan Carew break; 2513842bf24SAlan Carew 252751227a0SDavid Hunt if (channel_num == RTE_MAX_LCORE) { 2533842bf24SAlan Carew cmdline_printf(cl, "Channel number '%u' exceeds the maximum number " 2543842bf24SAlan Carew "of allowable channels(%u) for VM '%s'\n", channel_num, 255751227a0SDavid Hunt RTE_MAX_LCORE, res->vm_name); 2563842bf24SAlan Carew return; 2573842bf24SAlan Carew } 2583842bf24SAlan Carew channel_list[num_channels++] = channel_num; 2593842bf24SAlan Carew } 2603842bf24SAlan Carew for (i = 0; i < num_channels; i++) 2613842bf24SAlan Carew cmdline_printf(cl, "[%u]: Adding channel %u\n", i, channel_list[i]); 2623842bf24SAlan Carew 2633842bf24SAlan Carew channels_added = add_channels(res->vm_name, channel_list, 2643842bf24SAlan Carew num_channels); 2653842bf24SAlan Carew cmdline_printf(cl, "Enabled %d channels for '%s'\n", channels_added, 2663842bf24SAlan Carew res->vm_name); 2673842bf24SAlan Carew } 2683842bf24SAlan Carew 2693842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_op = 2703842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 2713842bf24SAlan Carew op, "add_channels"); 2723842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_vm_name = 2733842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 2743842bf24SAlan Carew vm_name, NULL); 2753842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_list = 2763842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_op_result, 2773842bf24SAlan Carew channel_list, NULL); 2783842bf24SAlan Carew 2793842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_op_set = { 2803842bf24SAlan Carew .f = cmd_channels_op_parsed, 2813842bf24SAlan Carew .data = NULL, 2823842bf24SAlan Carew .help_str = "add_channels <vm_name> <list>|all, add " 2833842bf24SAlan Carew "communication channels for the specified VM, the " 2843842bf24SAlan Carew "virtio channels must be enabled in the VM " 2853842bf24SAlan Carew "configuration(qemu/libvirt) and the associated VM must be active. " 2863842bf24SAlan Carew "<list> is a comma-separated list of channel numbers to add, using " 2873842bf24SAlan Carew "the keyword 'all' will attempt to add all channels for the VM", 2883842bf24SAlan Carew .tokens = { 2893842bf24SAlan Carew (void *)&cmd_channels_op, 2903842bf24SAlan Carew (void *)&cmd_channels_vm_name, 2913842bf24SAlan Carew (void *)&cmd_channels_list, 2923842bf24SAlan Carew NULL, 2933842bf24SAlan Carew }, 2943842bf24SAlan Carew }; 2953842bf24SAlan Carew 2961deb502eSMarcin Hajkowski struct cmd_set_query_result { 2971deb502eSMarcin Hajkowski cmdline_fixed_string_t set_query; 2981deb502eSMarcin Hajkowski cmdline_fixed_string_t vm_name; 2991deb502eSMarcin Hajkowski cmdline_fixed_string_t query_status; 3001deb502eSMarcin Hajkowski }; 3011deb502eSMarcin Hajkowski 3021deb502eSMarcin Hajkowski static void 3031deb502eSMarcin Hajkowski cmd_set_query_parsed(void *parsed_result, 3041deb502eSMarcin Hajkowski __rte_unused struct cmdline *cl, 3051deb502eSMarcin Hajkowski __rte_unused void *data) 3061deb502eSMarcin Hajkowski { 3071deb502eSMarcin Hajkowski struct cmd_set_query_result *res = parsed_result; 3081deb502eSMarcin Hajkowski 3091deb502eSMarcin Hajkowski if (!strcmp(res->query_status, "enable")) { 3101deb502eSMarcin Hajkowski if (set_query_status(res->vm_name, true) < 0) 3111deb502eSMarcin Hajkowski cmdline_printf(cl, "Unable to allow query for VM '%s'\n", 3121deb502eSMarcin Hajkowski res->vm_name); 3131deb502eSMarcin Hajkowski } else if (!strcmp(res->query_status, "disable")) { 3141deb502eSMarcin Hajkowski if (set_query_status(res->vm_name, false) < 0) 3151deb502eSMarcin Hajkowski cmdline_printf(cl, "Unable to disallow query for VM '%s'\n", 3161deb502eSMarcin Hajkowski res->vm_name); 3171deb502eSMarcin Hajkowski } 3181deb502eSMarcin Hajkowski } 3191deb502eSMarcin Hajkowski 3201deb502eSMarcin Hajkowski cmdline_parse_token_string_t cmd_set_query = 3211deb502eSMarcin Hajkowski TOKEN_STRING_INITIALIZER(struct cmd_set_query_result, 3221deb502eSMarcin Hajkowski set_query, "set_query"); 3231deb502eSMarcin Hajkowski cmdline_parse_token_string_t cmd_set_query_vm_name = 3241deb502eSMarcin Hajkowski TOKEN_STRING_INITIALIZER(struct cmd_set_query_result, 3251deb502eSMarcin Hajkowski vm_name, NULL); 3261deb502eSMarcin Hajkowski cmdline_parse_token_string_t cmd_set_query_status = 3271deb502eSMarcin Hajkowski TOKEN_STRING_INITIALIZER(struct cmd_set_query_result, 3281deb502eSMarcin Hajkowski query_status, "enable#disable"); 3291deb502eSMarcin Hajkowski 3301deb502eSMarcin Hajkowski cmdline_parse_inst_t cmd_set_query_set = { 3311deb502eSMarcin Hajkowski .f = cmd_set_query_parsed, 3321deb502eSMarcin Hajkowski .data = NULL, 3331deb502eSMarcin Hajkowski .help_str = "set_query <vm_name> <enable|disable>, allow or disallow queries" 3341deb502eSMarcin Hajkowski " for the specified VM", 3351deb502eSMarcin Hajkowski .tokens = { 3361deb502eSMarcin Hajkowski (void *)&cmd_set_query, 3371deb502eSMarcin Hajkowski (void *)&cmd_set_query_vm_name, 3381deb502eSMarcin Hajkowski (void *)&cmd_set_query_status, 3391deb502eSMarcin Hajkowski NULL, 3401deb502eSMarcin Hajkowski }, 3411deb502eSMarcin Hajkowski }; 3421deb502eSMarcin Hajkowski 3433842bf24SAlan Carew struct cmd_channels_status_op_result { 3443842bf24SAlan Carew cmdline_fixed_string_t op; 3453842bf24SAlan Carew cmdline_fixed_string_t vm_name; 3463842bf24SAlan Carew cmdline_fixed_string_t channel_list; 3473842bf24SAlan Carew cmdline_fixed_string_t status; 3483842bf24SAlan Carew }; 3493842bf24SAlan Carew 3503842bf24SAlan Carew static void 3513842bf24SAlan Carew cmd_channels_status_op_parsed(void *parsed_result, struct cmdline *cl, 352f2fc83b4SThomas Monjalon __rte_unused void *data) 3533842bf24SAlan Carew { 3543842bf24SAlan Carew unsigned num_channels = 0, channel_num; 3553842bf24SAlan Carew int changed; 356751227a0SDavid Hunt unsigned int channel_list[RTE_MAX_LCORE]; 3573842bf24SAlan Carew char *token, *remaining, *tail_ptr; 3583842bf24SAlan Carew struct cmd_channels_status_op_result *res = parsed_result; 3593842bf24SAlan Carew enum channel_status status; 3603842bf24SAlan Carew 3613842bf24SAlan Carew if (!strcmp(res->status, "enabled")) 3623842bf24SAlan Carew status = CHANNEL_MGR_CHANNEL_CONNECTED; 3633842bf24SAlan Carew else 3643842bf24SAlan Carew status = CHANNEL_MGR_CHANNEL_DISABLED; 3653842bf24SAlan Carew 3663842bf24SAlan Carew if (!strcmp(res->channel_list, "all")) { 3673842bf24SAlan Carew changed = set_channel_status_all(res->vm_name, status); 3683842bf24SAlan Carew cmdline_printf(cl, "Updated status of %d channels " 3693842bf24SAlan Carew "for VM '%s'\n", changed, res->vm_name); 3703842bf24SAlan Carew return; 3713842bf24SAlan Carew } 3723842bf24SAlan Carew remaining = res->channel_list; 3733842bf24SAlan Carew while (1) { 3743842bf24SAlan Carew if (remaining == NULL || remaining[0] == '\0') 3753842bf24SAlan Carew break; 3763842bf24SAlan Carew token = strsep(&remaining, ","); 3773842bf24SAlan Carew if (token == NULL) 3783842bf24SAlan Carew break; 3793842bf24SAlan Carew errno = 0; 3803842bf24SAlan Carew channel_num = (unsigned)strtol(token, &tail_ptr, 10); 3815b628fe1SBruce Richardson if ((errno != 0) || tail_ptr == NULL || (*tail_ptr != '\0')) 3823842bf24SAlan Carew break; 3833842bf24SAlan Carew 384751227a0SDavid Hunt if (channel_num == RTE_MAX_LCORE) { 3853842bf24SAlan Carew cmdline_printf(cl, "%u exceeds the maximum number of allowable " 3863842bf24SAlan Carew "channels(%u) for VM '%s'\n", channel_num, 387751227a0SDavid Hunt RTE_MAX_LCORE, res->vm_name); 3883842bf24SAlan Carew return; 3893842bf24SAlan Carew } 3903842bf24SAlan Carew channel_list[num_channels++] = channel_num; 3913842bf24SAlan Carew } 3923842bf24SAlan Carew changed = set_channel_status(res->vm_name, channel_list, num_channels, 3933842bf24SAlan Carew status); 3943842bf24SAlan Carew cmdline_printf(cl, "Updated status of %d channels " 3953842bf24SAlan Carew "for VM '%s'\n", changed, res->vm_name); 3963842bf24SAlan Carew } 3973842bf24SAlan Carew 3983842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_op = 3993842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4003842bf24SAlan Carew op, "set_channel_status"); 4013842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_vm_name = 4023842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4033842bf24SAlan Carew vm_name, NULL); 4043842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status_list = 4053842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4063842bf24SAlan Carew channel_list, NULL); 4073842bf24SAlan Carew cmdline_parse_token_string_t cmd_channels_status = 4083842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_channels_status_op_result, 4093842bf24SAlan Carew status, "enabled#disabled"); 4103842bf24SAlan Carew 4113842bf24SAlan Carew cmdline_parse_inst_t cmd_channels_status_op_set = { 4123842bf24SAlan Carew .f = cmd_channels_status_op_parsed, 4133842bf24SAlan Carew .data = NULL, 4143842bf24SAlan Carew .help_str = "set_channel_status <vm_name> <list>|all enabled|disabled, " 4153842bf24SAlan Carew " enable or disable the communication channels in " 4163842bf24SAlan Carew "list(comma-separated) for the specified VM, alternatively " 4173842bf24SAlan Carew "list can be replaced with keyword 'all'. " 4183842bf24SAlan Carew "Disabled channels will still receive packets on the host, " 4193842bf24SAlan Carew "however the commands they specify will be ignored. " 4203842bf24SAlan Carew "Set status to 'enabled' to begin processing requests again.", 4213842bf24SAlan Carew .tokens = { 4223842bf24SAlan Carew (void *)&cmd_channels_status_op, 4233842bf24SAlan Carew (void *)&cmd_channels_status_vm_name, 4243842bf24SAlan Carew (void *)&cmd_channels_status_list, 4253842bf24SAlan Carew (void *)&cmd_channels_status, 4263842bf24SAlan Carew NULL, 4273842bf24SAlan Carew }, 4283842bf24SAlan Carew }; 4293842bf24SAlan Carew 4303842bf24SAlan Carew /* *** CPU Frequency operations *** */ 4313842bf24SAlan Carew struct cmd_show_cpu_freq_result { 4323842bf24SAlan Carew cmdline_fixed_string_t show_cpu_freq; 4333842bf24SAlan Carew uint8_t core_num; 4343842bf24SAlan Carew }; 4353842bf24SAlan Carew 4363842bf24SAlan Carew static void 4373842bf24SAlan Carew cmd_show_cpu_freq_parsed(void *parsed_result, struct cmdline *cl, 438f2fc83b4SThomas Monjalon __rte_unused void *data) 4393842bf24SAlan Carew { 4403842bf24SAlan Carew struct cmd_show_cpu_freq_result *res = parsed_result; 4413842bf24SAlan Carew uint32_t curr_freq = power_manager_get_current_frequency(res->core_num); 4423842bf24SAlan Carew 4433842bf24SAlan Carew if (curr_freq == 0) { 4443842bf24SAlan Carew cmdline_printf(cl, "Unable to get frequency for core %u\n", 4453842bf24SAlan Carew res->core_num); 4463842bf24SAlan Carew return; 4473842bf24SAlan Carew } 4483842bf24SAlan Carew cmdline_printf(cl, "Core %u frequency: %"PRId32"\n", res->core_num, 4493842bf24SAlan Carew curr_freq); 4503842bf24SAlan Carew } 4513842bf24SAlan Carew 4523842bf24SAlan Carew cmdline_parse_token_string_t cmd_show_cpu_freq = 4533842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_show_cpu_freq_result, 4543842bf24SAlan Carew show_cpu_freq, "show_cpu_freq"); 4553842bf24SAlan Carew 4563842bf24SAlan Carew cmdline_parse_token_num_t cmd_show_cpu_freq_core_num = 4573842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_show_cpu_freq_result, 458*c2341bb6SDmitry Kozlyuk core_num, RTE_UINT8); 4593842bf24SAlan Carew 4603842bf24SAlan Carew cmdline_parse_inst_t cmd_show_cpu_freq_set = { 4613842bf24SAlan Carew .f = cmd_show_cpu_freq_parsed, 4623842bf24SAlan Carew .data = NULL, 4633842bf24SAlan Carew .help_str = "Get the current frequency for the specified core", 4643842bf24SAlan Carew .tokens = { 4653842bf24SAlan Carew (void *)&cmd_show_cpu_freq, 4663842bf24SAlan Carew (void *)&cmd_show_cpu_freq_core_num, 4673842bf24SAlan Carew NULL, 4683842bf24SAlan Carew }, 4693842bf24SAlan Carew }; 4703842bf24SAlan Carew 4713842bf24SAlan Carew struct cmd_set_cpu_freq_result { 4723842bf24SAlan Carew cmdline_fixed_string_t set_cpu_freq; 4733842bf24SAlan Carew uint8_t core_num; 4743842bf24SAlan Carew cmdline_fixed_string_t cmd; 4753842bf24SAlan Carew }; 4763842bf24SAlan Carew 4773842bf24SAlan Carew static void 4783842bf24SAlan Carew cmd_set_cpu_freq_parsed(void *parsed_result, struct cmdline *cl, 479f2fc83b4SThomas Monjalon __rte_unused void *data) 4803842bf24SAlan Carew { 4813842bf24SAlan Carew int ret = -1; 4823842bf24SAlan Carew struct cmd_set_cpu_freq_result *res = parsed_result; 4833842bf24SAlan Carew 4843842bf24SAlan Carew if (!strcmp(res->cmd , "up")) 4853842bf24SAlan Carew ret = power_manager_scale_core_up(res->core_num); 4863842bf24SAlan Carew else if (!strcmp(res->cmd , "down")) 4873842bf24SAlan Carew ret = power_manager_scale_core_down(res->core_num); 4883842bf24SAlan Carew else if (!strcmp(res->cmd , "min")) 4893842bf24SAlan Carew ret = power_manager_scale_core_min(res->core_num); 4903842bf24SAlan Carew else if (!strcmp(res->cmd , "max")) 4913842bf24SAlan Carew ret = power_manager_scale_core_max(res->core_num); 492567997b9SDavid Hunt else if (!strcmp(res->cmd, "enable_turbo")) 493567997b9SDavid Hunt ret = power_manager_enable_turbo_core(res->core_num); 494567997b9SDavid Hunt else if (!strcmp(res->cmd, "disable_turbo")) 495567997b9SDavid Hunt ret = power_manager_disable_turbo_core(res->core_num); 4963842bf24SAlan Carew if (ret < 0) { 4973842bf24SAlan Carew cmdline_printf(cl, "Error scaling core(%u) '%s'\n", res->core_num, 4983842bf24SAlan Carew res->cmd); 4993842bf24SAlan Carew } 5003842bf24SAlan Carew } 5013842bf24SAlan Carew 5023842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq = 5033842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result, 5043842bf24SAlan Carew set_cpu_freq, "set_cpu_freq"); 505b68bc0b8SOlivier Matz cmdline_parse_token_num_t cmd_set_cpu_freq_core_num = 5063842bf24SAlan Carew TOKEN_NUM_INITIALIZER(struct cmd_set_cpu_freq_result, 507*c2341bb6SDmitry Kozlyuk core_num, RTE_UINT8); 5083842bf24SAlan Carew cmdline_parse_token_string_t cmd_set_cpu_freq_cmd_cmd = 5093842bf24SAlan Carew TOKEN_STRING_INITIALIZER(struct cmd_set_cpu_freq_result, 510567997b9SDavid Hunt cmd, "up#down#min#max#enable_turbo#disable_turbo"); 5113842bf24SAlan Carew 5123842bf24SAlan Carew cmdline_parse_inst_t cmd_set_cpu_freq_set = { 5133842bf24SAlan Carew .f = cmd_set_cpu_freq_parsed, 5143842bf24SAlan Carew .data = NULL, 515567997b9SDavid Hunt .help_str = "set_cpu_freq <core_num> <up|down|min|max|enable_turbo|disable_turbo>, adjust the current " 516567997b9SDavid Hunt "frequency for the specified core", 5173842bf24SAlan Carew .tokens = { 5183842bf24SAlan Carew (void *)&cmd_set_cpu_freq, 5193842bf24SAlan Carew (void *)&cmd_set_cpu_freq_core_num, 5203842bf24SAlan Carew (void *)&cmd_set_cpu_freq_cmd_cmd, 5213842bf24SAlan Carew NULL, 5223842bf24SAlan Carew }, 5233842bf24SAlan Carew }; 5243842bf24SAlan Carew 5253842bf24SAlan Carew cmdline_parse_ctx_t main_ctx[] = { 5263842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_quit, 5273842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_vm_op_set, 5283842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_channels_op_set, 5293842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_channels_status_op_set, 5303842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_show_vm_set, 5313842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_show_cpu_freq_set, 5323842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_cpu_freq_set, 5333842bf24SAlan Carew (cmdline_parse_inst_t *)&cmd_set_pcpu_set, 5341deb502eSMarcin Hajkowski (cmdline_parse_inst_t *)&cmd_set_query_set, 5353842bf24SAlan Carew NULL, 5363842bf24SAlan Carew }; 5373842bf24SAlan Carew 5383842bf24SAlan Carew void 539f2fc83b4SThomas Monjalon run_cli(__rte_unused void *arg) 5403842bf24SAlan Carew { 5413842bf24SAlan Carew struct cmdline *cl; 5423842bf24SAlan Carew 5433842bf24SAlan Carew cl = cmdline_stdin_new(main_ctx, "vmpower> "); 5443842bf24SAlan Carew if (cl == NULL) 5453842bf24SAlan Carew return; 5463842bf24SAlan Carew 5473842bf24SAlan Carew cmdline_interact(cl); 5483842bf24SAlan Carew cmdline_stdin_exit(cl); 5493842bf24SAlan Carew } 550