acrn-dm: implement cpu_affinity command line argument

User has a chance to specify VCPU affinity through acrn-dm command line
argument. Examples of the command line:

3 PCPUs: 1/2/3
--cpu_affinity 1-3

5 PCPUs: 2/3/6/7/8
--cpu_affinity 2,3,6-8

8 PCPUs: 2/3/6/7/9/10/11/12
--cpu_affinity 2,3,6-7,9,10-12

The specified pCPUs must be included in the guest VM's statically
defined vm_config[].cpu_affinity_bitmap.

Tracked-On: #4616
Signed-off-by: Zide Chen <zide.chen@intel.com>
This commit is contained in:
Zide Chen 2020-01-21 14:53:21 -08:00 committed by wenlingz
parent 3691e305c0
commit 71bdc27a0f
3 changed files with 87 additions and 0 deletions

View File

@ -164,6 +164,7 @@ usage(int code)
#endif
" --vsbl: vsbl file path\n"
" --ovmf: ovmf file path\n"
" --pcpu_list: list of pCPUs assigned to this VM\n"
" --part_info: guest partition info file path\n"
" --enable_trusty: enable trusty for guest\n"
" --debugexit: enable debug exit function\n"
@ -718,6 +719,7 @@ sig_handler_term(int signo)
enum {
CMD_OPT_VSBL = 1000,
CMD_OPT_OVMF,
CMD_OPT_PCPU_LIST,
CMD_OPT_PART_INFO,
CMD_OPT_TRUSTY_ENABLE,
CMD_OPT_VIRTIO_POLL_ENABLE,
@ -757,6 +759,7 @@ static struct option long_options[] = {
#endif
{"vsbl", required_argument, 0, CMD_OPT_VSBL},
{"ovmf", required_argument, 0, CMD_OPT_OVMF},
{"pcpu_list", required_argument, 0, CMD_OPT_PCPU_LIST},
{"part_info", required_argument, 0, CMD_OPT_PART_INFO},
{"enable_trusty", no_argument, 0,
CMD_OPT_TRUSTY_ENABLE},
@ -874,6 +877,10 @@ main(int argc, char *argv[])
errx(EX_USAGE, "invalid ovmf param %s", optarg);
skip_pci_mem64bar_workaround = true;
break;
case CMD_OPT_PCPU_LIST:
if (acrn_parse_pcpu_list(optarg) != 0)
errx(EX_USAGE, "invalid pcpu param %s", optarg);
break;
case CMD_OPT_PART_INFO:
if (acrn_parse_guest_part_info(optarg) != 0) {
errx(EX_USAGE,

View File

@ -85,6 +85,82 @@ check_api(int fd)
}
static int devfd = -1;
static uint64_t cpu_affinity_bitmap = 0UL;
static void add_one_pcpu(int pcpu_id)
{
if (cpu_affinity_bitmap & (1UL << pcpu_id)) {
pr_err("%s: pcpu_id %d has been allocated to this VM.\n", __func__, pcpu_id);
return;
}
cpu_affinity_bitmap |= (1UL << pcpu_id);
}
/*
* example options:
* --pcpu_list 1,2,3
* --pcpu_list 1-3
* --pcpu_list 1,3,4-6
* --pcpu_list 1,3,4-6,9
*/
int acrn_parse_pcpu_list(char *opt)
{
char *str, *cp;
int pcpu_id;
int pcpu_start, pcpu_end;
cp = strdup(opt);
if (!cp) {
pr_err("%s: strdup returns NULL\n", __func__);
return -1;
}
while (cp) {
str = strpbrk(cp, ",-");
/* no more entries delimited by ',' or '-' */
if (!str) {
if (!dm_strtoi(cp, NULL, 10, &pcpu_id)) {
add_one_pcpu(pcpu_id);
break;
}
}
if (*str == ',') {
/* after this, 'cp' points to the character after ',' */
str = strsep(&cp, ",");
/* parse the entry before ',' */
if (dm_strtoi(str, NULL, 10, &pcpu_id)) {
return -1;
}
add_one_pcpu(pcpu_id);
}
if (*str == '-') {
str = strsep(&cp, "-");
/* parse the entry before and after '-' respectively */
if (dm_strtoi(str, NULL, 10, &pcpu_start) || dm_strtoi(cp, NULL, 10, &pcpu_end)) {
return -1;
}
if (pcpu_end <= pcpu_start) {
return -1;
}
for (; pcpu_start <= pcpu_end; pcpu_start++) {
add_one_pcpu(pcpu_start);
}
/* skip the ',' after pcpu_end */
str = strsep(&cp, ",");
}
}
return 0;
}
struct vmctx *
vm_create(const char *name, uint64_t req_buf, int *vcpu_num)
@ -150,6 +226,9 @@ vm_create(const char *name, uint64_t req_buf, int *vcpu_num)
create_vm.vm_flag &= (~GUEST_FLAG_IO_COMPLETION_POLLING);
}
/* command line arguments specified CPU affinity could overwrite HV's static configuration */
create_vm.cpu_affinity = cpu_affinity_bitmap;
if (is_rtvm) {
create_vm.vm_flag |= GUEST_FLAG_RT;
create_vm.vm_flag |= GUEST_FLAG_IO_COMPLETION_POLLING;

View File

@ -134,6 +134,7 @@ int vm_set_ptdev_intx_info(struct vmctx *ctx, uint16_t virt_bdf,
int vm_reset_ptdev_intx_info(struct vmctx *ctx, uint16_t virt_bdf,
uint16_t phys_bdf, int virt_pin, bool pic_pin);
int acrn_parse_pcpu_list(char *arg);
int vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id);
int vm_set_vcpu_regs(struct vmctx *ctx, struct acrn_set_vcpu_regs *cpu_regs);