[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:37:49 UTC 2011


Default:

wbemcli -nl -arc KVM_ProcResourceAllocationSettingData ai 
'local/root/virt:KVM_Processor.CreationClassName="KVM_Processor",DeviceID="WinXP10/0",SystemCreationClassName="KVM_ComputerSystem",SystemName="WinXP10"' 

oc0840652111.ibm.com/root

/virt:KVM_ProcResourceAllocationSettingData.InstanceID="WinXP10/proc"

-Caption=
-Description=
-Generation=
-InstanceID="WinXP10/proc"
-ElementName=
-ConfigurationName=
-ChangeableType=
-ResourceType=3
-OtherResourceType=
-ResourceSubType=
-PoolID=
-ConsumerVisibility=
-HostResource=
-AllocationUnits=
-VirtualQuantity=1
-Reservation=
-Limit=0
-Weight=1024
-AutomaticAllocation=
-AutomaticDeallocation=
-Parent=
-Connection=
-Address=
-MappingBehavior=
-AddressOnParent=
-VirtualQuantityUnits="count"

Change CPU share outside of CIM:

# virsh schedinfo --set cpu_shares=512 WinXP10
Scheduler      : posix
cpu_shares     : 512

# wbemcli -nl -arc KVM_ProcResourceAllocationSettingData ai 
'local/root/virt:KVM_Processor.CreationClassName="KVM_Processor",DeviceID="WinXP10/0",SystemCreationClassName="KVM_ComputerSystem",SystemName="WinXP10"' 

oc0840652111.ibm.com/root/virt:KVM_ProcResourceAllocationSettingData.InstanceID="WinXP10/proc"
-Caption=
-Description=
-Generation=
-InstanceID="WinXP10/proc"
-ElementName=
-ConfigurationName=
-ChangeableType=
-ResourceType=3
-OtherResourceType=
-ResourceSubType=
-PoolID=
-ConsumerVisibility=
-HostResource=
-AllocationUnits=
-VirtualQuantity=1
-Reservation=
-Limit=0
-Weight=512
-AutomaticAllocation=
-AutomaticDeallocation=
-Parent=
-Connection=
-Address=
-MappingBehavior=
-AddressOnParent=
-VirtualQuantityUnits="count"

I'm getting the following error when I try to modify via CIM.

HTTP/1.1 401 Unauthorized
content-length: 0000000000
WWW-Authenticate: Basic realm="oc0840652111.ibm.com"

But I think that is a problem with my configuration, not the patch.

+1.

Thanks, Gareth.



On 10/03/2011 05:52 AM, Gareth S. Bestor wrote:
> # 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