Kobi Ianko has uploaded a new change for review.

Change subject: Adding utility methods and conf for CPU limit MOM integration
......................................................................

Adding utility methods and conf for CPU limit MOM integration

Adding a MOM policy to monitor CPU tuning parameter.
Adding utility methods to vm.py to integrate with MOM's collectors and 
controllers

Change-Id: Ic502d9a4a976cd76bb6042bbb51f6cd281199631
Signed-off-by: Kobi Ianko <kia...@redhat.com>
---
M vdsm/mom.conf.in
M vdsm/mom.d/00-defines.policy
A vdsm/mom.d/04-cputune.policy
M vdsm/virt/vm.py
4 files changed, 139 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/58/27258/1

diff --git a/vdsm/mom.conf.in b/vdsm/mom.conf.in
index ba11038..fd5f997 100644
--- a/vdsm/mom.conf.in
+++ b/vdsm/mom.conf.in
@@ -67,8 +67,8 @@
 
 [host]
 # A comma-separated list of Collector plugins to use for Host data collection.
-collectors: HostMemory, HostKSM
+collectors: HostMemory, HostKSM, HostCpu
 
 [guest]
 # A comma-separated list of Collector plugins to use for Guest data collection.
-collectors: GuestQemuProc, GuestMemory, GuestBalloon
+collectors: GuestQemuProc, GuestMemory, GuestBalloon, GuestCpuTune
diff --git a/vdsm/mom.d/00-defines.policy b/vdsm/mom.d/00-defines.policy
index 93b70ee..2def4c9 100644
--- a/vdsm/mom.d/00-defines.policy
+++ b/vdsm/mom.d/00-defines.policy
@@ -6,4 +6,7 @@
 # Define variables for configurable options here
 (defvar ksmEnabled 1)
 (defvar balloonEnabled 0)
+(defvar cpuTuneEnabled 0)
+(defvar vcpuQuota -1)
+(defvar vcpuPeriod 1000)
 
diff --git a/vdsm/mom.d/04-cputune.policy b/vdsm/mom.d/04-cputune.policy
new file mode 100644
index 0000000..3e53cd5
--- /dev/null
+++ b/vdsm/mom.d/04-cputune.policy
@@ -0,0 +1,48 @@
+### Auto-CpuTune 
###############################################################
+
+(defvar anchor 100000)
+(defvar defaultQuota -1)
+(defvar defaultPeriod 1000)
+
+(defvar calcPeriod  (/ anchor Host.cpu_count))
+
+### Helper functions
+(def check_and_set_quota (guest)
+{
+
+    (defvar calcQuota (/ (* anchor (/ guest.user_vcpu_limit 100))) 
guest.vcpu_count)
+
+    (if (!= guest.vcpu_quota calcQuota)
+        (guest.Control "vcpu_quota" calcQuota) 0)
+})
+
+(def check_and_set_period (guest)
+{
+    (if (!= guest.vcpu_period calcPeriod)
+        (guest.Control "vcpu_period" calcPeriod) 0)
+})
+
+(def reset_quota_and_period (guest)
+{
+    (guest.Control "vcpu_quota" defaultQuota)
+    (guest.Control "vcpu_period" defaultPeriod)
+})
+
+
+### Main script
+# Methodology: The goal is to set the quota and period of the vcpuTune
+# to the values the user selected, the user setting will update once
+# a policy sync is made.
+
+# If the CpuTune is disabled, reset setting
+# else set the quota and period
+
+
+
+(if (== True cpuTuneEnabled) {
+    (with Guests guest (check_and_set_quota guest))
+    (with Guests guest (check_and_set_period guest))
+} {
+    (with Guests guest (reset_quota_and_period guest))
+})
+
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 6711bc6..41cea1e 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -2500,6 +2500,9 @@
                         int(self.conf['memSize']) * 100)
         stats['memUsage'] = utils.convertToStr(int(memUsage))
         stats['balloonInfo'] = self._getBalloonInfo()
+        stats['userCpuTuneInfo'] = self._getUserCpuTuneInfo()
+        stats['cpuTuneInfo'] = self._getCpuTuneInfo()
+        stats['cpu_count'] = self._getCpuCount()
         if self.isMigrating():
             stats['migrationProgress'] = self.migrateStatus()['progress']
         return stats
@@ -4327,6 +4330,40 @@
                         'balloon_target': str(target_mem)}
         return {}
 
+    def _getUserCpuTuneInfo(self):
+        ret = {}
+        domain = self._connection.lookupByUUIDString(self.id)
+
+        metadataCpuLimit = 
domain.getMetadata(2,'http://ovirt.org/param/vcpu_limit',0)
+
+        if metadataCpuLimit:
+            ret['user_vcpu_limit'] = metadataCpuLimit
+        else: 
+            ret['user_vcpu_quota'] = 100
+
+        return ret
+
+    def _getCpuTuneInfo(self):
+        domain = self._connection.lookupByUUIDString(self.id)
+
+        ret = domain.getSchedulerParameters({ 'vcpu_quota', 'vcpu_period'})
+
+        if ret['vcpu_quota'] == None:
+            ret['vcpu_quota'] = -1
+
+        if ret['vcpu_period'] == None:
+            ret['vcpu_period'] = 1000
+
+        return ret
+
+    def _getCpuCount(self):
+
+        domain = self._connection.lookupByUUIDString(self.id)
+        if domain.getMaxVcpus() != -1 :
+            return domain.getMaxVcpus()
+        else: 
+            return 0
+
     def setBalloonTarget(self, target):
 
         def reportError(key='balloonErr', msg=None):
@@ -4358,6 +4395,55 @@
             self.saveState()
             return {'status': doneCode}
 
+
+    def setCpuTuneQuota(self, quota):
+
+        def reportError(key='cpuTuneErr', msg=None):
+            self.log.error("Set new vcpu quota failed", exc_info=True)
+            if msg is None:
+                error = errCode[key]
+            else:
+                error = {'status': {'code': errCode[key]
+                         ['status']['code'], 'message': msg}}
+            return error
+
+        if self._dom is None:
+            return reportError()
+        try:
+            quota = int(quota)
+            self._dom.setSchedulerParameters({ 'vcpu_quota': quota})           
 
+            return {'status': doneCode}
+        except ValueError:
+            return reportError(msg='an integer is required for quota')
+        except libvirt.libvirtError as e:
+            if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+                return reportError(key='noVM')
+            return reportError(msg=e.message)
+
+    def setCpuTunePeriod(self, period):
+
+        def reportError(key='cpuTuneErr', msg=None):
+            self.log.error("Set new vcpu period failed", exc_info=True)
+            if msg is None:
+                error = errCode[key]
+            else:
+                error = {'status': {'code': errCode[key]
+                         ['status']['code'], 'message': msg}}
+            return error
+
+        if self._dom is None:
+            return reportError()
+        try:
+            period = int(period)
+            self._dom.setSchedulerParameters({ 'vcpu_period': period})         
   
+            return {'status': doneCode}
+        except ValueError:
+            return reportError(msg='an integer is required for period')
+        except libvirt.libvirtError as e:
+            if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+                return reportError(key='noVM')
+            return reportError(msg=e.message)
+
     def _getUnderlyingDeviceAddress(self, devXml):
         """
         Obtain device's address from libvirt


-- 
To view, visit http://gerrit.ovirt.org/27258
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic502d9a4a976cd76bb6042bbb51f6cd281199631
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Kobi Ianko <k...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to