[Libvirt-cim] [PATCH] Add support for libvirt CPU cgroup for active KVM guests

Chip Vincent cvincent at linux.vnet.ibm.com
Thu Oct 13 13:39:18 UTC 2011


Thanks. Pushed.

On 10/13/2011 04:30 AM, Wayne Xia wrote:
> Tested on my laptop with libvirt 0.9.4, this version have cgroup
> feature added for inactive guest, but the libvirt-cim also acts as
> expected.
>
> Tested-by: Wayne Xia <xiawenc at linux.vnet.ibm.com>
>
>
> 于 2011-10-3 17:52, Gareth S. Bestor 写道:
>> # HG changeset patch
>> # User Gareth S. Bestor<bestor at us.ibm.com>
>> # Date 1317635486 25200
>> # Node ID 2c9a378e141c23eae0b96b2f021adbd14cfb8ef2
>> # Parent fb09136deb494008eb3aacee420ad74da7d7c294
>> Add support for libvirt CPU cgroup for active KVM guests
>> Add support for setting and retreiving the CPU cgroup setting for an
>> active KVM guest
>> using libivirt scheduling parameter support. Presently this patches
>> only supports earlier
>> libvirt versions' support of this feature, which only support setting
>> these scheduling
>> params for *active* guests only, and uses libivrt's earlier scheduling
>> APIs; a subsequent
>> patch will support both and the newer APIs (version dependent).
>> A guest's CPU cgroup setting it exposed via the
>> KVM_ProcResourceAllocationSettingData.Weight
>> property.
>> Minimum, maximum, Increment and Default weights are exposed
>> appropriately via
>> the respective Processor pool.
>> Weight for new guest can be passed in on DefineSystem[]
>> Weigh for existing (active) guest can be changed via
>> ModifyResourceSettings[]
>> Signed-off-by: Gareth S. Bestor<bestor at us.bm.com>
>>
>> diff -r fb09136deb49 -r 2c9a378e141c libxkutil/device_parsing.c
>> --- a/libxkutil/device_parsing.c Tue Aug 30 08:48:36 2011 -0700
>> +++ b/libxkutil/device_parsing.c Mon Oct 03 02:51:26 2011 -0700
>> @@ -1297,6 +1297,24 @@
>> {
>> int ret;
>>
>> + /* Change vcpu cgroup cpu_shares */
>> + if (dev->dev.vcpu.weight> 0) {
>> + virSchedParameter param;
>> +
>> + strncpy(param.field, "cpu_shares", VIR_DOMAIN_SCHED_FIELD_LENGTH);
>> + param.type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
>> + param.value.ul = dev->dev.vcpu.weight;
>> +
>> + if (virDomainSetSchedulerParameters(dom,&param, 1) != 0) {
>> + CU_DEBUG("Failed to set scheduler params for domain");
>> + return 0;
>> + }
>> +
>> + CU_DEBUG("Changed %s vcpu cgroup cpu_shares to %i",
>> + virDomainGetName(dom),
>> + dev->dev.vcpu.weight);
>> + }
>> +
>> if (dev->dev.vcpu.quantity<= 0) {
>> CU_DEBUG("Unable to set VCPU count to %i",
>> dev->dev.vcpu.quantity);
>> diff -r fb09136deb49 -r 2c9a378e141c src/Virt_ComputerSystem.c
>> --- a/src/Virt_ComputerSystem.c Tue Aug 30 08:48:36 2011 -0700
>> +++ b/src/Virt_ComputerSystem.c Mon Oct 03 02:51:26 2011 -0700
>> @@ -858,6 +858,30 @@
>> return 0;
>> }
>>
>> +static int kvm_scheduler_params(struct infostore_ctx *ctx,
>> + virSchedParameter **params)
>> +{
>> + unsigned long long value;
>> +
>> + *params = calloc(1, sizeof(virSchedParameter));
>> + if (*params == NULL)
>> + return -1;
>> +
>> + value = infostore_get_u64(ctx, "weight");
>> +
>> + if (value != 0) {
>> + strncpy((*params)[0].field,
>> + "cpu_shares",
>> + VIR_DOMAIN_SCHED_FIELD_LENGTH);
>> + (*params)[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
>> + (*params)[0].value.ul = value;
>> +
>> + return 1;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static void set_scheduler_params(virDomainPtr dom)
>> {
>> struct infostore_ctx *ctx;
>> @@ -881,6 +905,8 @@
>> count = xen_scheduler_params(ctx,&params);
>> else if (STREQC(virConnectGetType(conn), "lxc"))
>> count = lxc_scheduler_params(ctx,&params);
>> + else if (STREQC(virConnectGetType(conn), "QEMU"))
>> + count = kvm_scheduler_params(ctx,&params);
>> else {
>> CU_DEBUG("Not setting sched params for type %s",
>> virConnectGetType(conn));
>> diff -r fb09136deb49 -r 2c9a378e141c src/Virt_RASD.c
>> --- a/src/Virt_RASD.c Tue Aug 30 08:48:36 2011 -0700
>> +++ b/src/Virt_RASD.c Mon Oct 03 02:51:26 2011 -0700
>> @@ -110,7 +110,7 @@
>> virConnectPtr conn = NULL;
>> virDomainPtr dom = NULL;
>> struct infostore_ctx *info = NULL;
>> - uint32_t weight;
>> + uint32_t weight = 0;
>> uint64_t limit;
>> uint64_t count;
>>
>> @@ -147,7 +147,45 @@
>> goto out;
>> }
>>
>> - weight = (uint32_t)infostore_get_u64(info, "weight");
>> + /* Currently only support CPU cgroups for running KVM guests */
>> + if (domain_online(dom)&& STREQC(virConnectGetType(conn), "QEMU")) {
>> + char *sched;
>> + int nparams;
>> + unsigned int i;
>> + virSchedParameter *params;
>> +
>> + /* First find the number of scheduler params, in order malloc space
>> for them all */
>> + sched = virDomainGetSchedulerType(dom,&nparams);
>> + if (sched == NULL) {
>> + CU_DEBUG("Failed to get scheduler type");
>> + goto out;
>> + }
>> + CU_DEBUG("domain has %d scheduler params", nparams);
>> + free(sched);
>> +
>> + /* Now retrieve all the scheduler params for this domain */
>> + params = calloc(nparams, sizeof(virSchedParameter));
>> + if (virDomainGetSchedulerParameters(dom, params,&nparams) != 0) {
>> + CU_DEBUG("Failed to get scheduler params for domain");
>> + goto out;
>> + }
>> +
>> + /* Look for the CPU cgroup scheduler parameter, called 'cpu_shares' */
>> + for (i = 0 ; i< nparams ; i++) {
>> + CU_DEBUG("scheduler param #%d name is %s (type %d)",
>> + i, params[i].field, params[i].type);
>> + if (STREQ(params[i].field, "cpu_shares")&&
>> + (params[i].type == VIR_DOMAIN_SCHED_FIELD_ULLONG)) {
>> + CU_DEBUG("scheduler param %s = %d",
>> + params[i].field, params[i].value.ul);
>> + weight = (uint32_t)params[i].value.ul;
>> + break; /* Found it! */
>> + }
>> + }
>> + free(params);
>> + }
>> + else
>> + weight = (uint32_t)infostore_get_u64(info, "weight");
>> limit = infostore_get_u64(info, "limit");
>>
>> CMSetProperty(inst, "Weight",
>> diff -r fb09136deb49 -r 2c9a378e141c
>> src/Virt_SettingsDefineCapabilities.c
>> --- a/src/Virt_SettingsDefineCapabilities.c Tue Aug 30 08:48:36 2011
>> -0700
>> +++ b/src/Virt_SettingsDefineCapabilities.c Mon Oct 03 02:51:26 2011
>> -0700
>> @@ -410,7 +410,10 @@
>> case SDC_RASD_MIN:
>> num_procs = 0;
>> limit = 1;
>> - weight = MIN_XEN_WEIGHT;
>> + if (STARTS_WITH(CLASSNAME(ref), "Xen"))
>> + weight = MIN_XEN_WEIGHT;
>> + else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
>> + weight = MIN_KVM_WEIGHT;
>> id = "Minimum";
>> break;
>> case SDC_RASD_MAX:
>> @@ -418,19 +421,28 @@
>> if (!ret)
>> goto out;
>> limit = 0;
>> - weight = MAX_XEN_WEIGHT;
>> + if (STARTS_WITH(CLASSNAME(ref), "Xen"))
>> + weight = MAX_XEN_WEIGHT;
>> + else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
>> + weight = MAX_KVM_WEIGHT;
>> id = "Maximum";
>> break;
>> case SDC_RASD_INC:
>> num_procs = 1;
>> limit = 50;
>> - weight = INC_XEN_WEIGHT;
>> + if (STARTS_WITH(CLASSNAME(ref), "Xen"))
>> + weight = INC_XEN_WEIGHT;
>> + else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
>> + weight = INC_KVM_WEIGHT;
>> id = "Increment";
>> break;
>> case SDC_RASD_DEF:
>> num_procs = 1;
>> limit = 0;
>> - weight = DEFAULT_XEN_WEIGHT;
>> + if (STARTS_WITH(CLASSNAME(ref), "Xen"))
>> + weight = DEFAULT_XEN_WEIGHT;
>> + else if (STARTS_WITH(CLASSNAME(ref), "KVM"))
>> + weight = DEFAULT_KVM_WEIGHT;
>> id = "Default";
>> break;
>> default:
>> @@ -455,6 +467,10 @@
>> CMSetProperty(inst, "Weight",
>> (CMPIValue *)&weight, CMPI_uint32);
>> }
>> + else if (STARTS_WITH(CLASSNAME(ref), "KVM")) {
>> + CMSetProperty(inst, "Weight",
>> + (CMPIValue *)&weight, CMPI_uint32);
>> + }
>>
>> inst_list_add(list, inst);
>>
>> diff -r fb09136deb49 -r 2c9a378e141c
>> src/Virt_VirtualSystemManagementService.c
>> --- a/src/Virt_VirtualSystemManagementService.c Tue Aug 30 08:48:36
>> 2011 -0700
>> +++ b/src/Virt_VirtualSystemManagementService.c Mon Oct 03 02:51:26
>> 2011 -0700
>> @@ -1012,6 +1012,8 @@
>>
>> if (STARTS_WITH(CLASSNAME(op), "Xen"))
>> def_weight = DEFAULT_XEN_WEIGHT;
>> + else if (STARTS_WITH(CLASSNAME(op), "QEMU"))
>> + def_weight = DEFAULT_KVM_WEIGHT;
>>
>> rc = cu_get_u64_prop(inst, "Limit",&dev->dev.vcpu.limit);
>> if (rc != CMPI_RC_OK)
>> diff -r fb09136deb49 -r 2c9a378e141c
>> src/Virt_VirtualSystemManagementService.h
>> --- a/src/Virt_VirtualSystemManagementService.h Tue Aug 30 08:48:36
>> 2011 -0700
>> +++ b/src/Virt_VirtualSystemManagementService.h Mon Oct 03 02:51:26
>> 2011 -0700
>> @@ -24,6 +24,11 @@
>> #define INC_XEN_WEIGHT MAX_XEN_WEIGHT / 2
>> #define DEFAULT_XEN_WEIGHT 1024
>>
>> +#define MIN_KVM_WEIGHT 2
>> +#define MAX_KVM_WEIGHT 262144
>> +#define INC_KVM_WEIGHT 1
>> +#define DEFAULT_KVM_WEIGHT 1024
>> +
>> CMPIStatus get_vsms(const CMPIObjectPath *reference,
>> CMPIInstance **_inst,
>> const CMPIBroker *broker,
>>
>> _______________________________________________
>> Libvirt-cim mailing list
>> Libvirt-cim at redhat.com
>> https://www.redhat.com/mailman/listinfo/libvirt-cim
>
>

-- 
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list