All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukas Doktor <ldoktor@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org,
	kvm-autotest@redhat.com, fyang@redhat.com, lmr@redhat.com,
	ldoktor@redhat.com, jzupka@redhat.com
Subject: [PATCH 3/4] cpuset test
Date: Mon, 15 Aug 2011 14:23:36 +0200	[thread overview]
Message-ID: <1313411017-2873-4-git-send-email-ldoktor@redhat.com> (raw)
In-Reply-To: <1313411017-2873-1-git-send-email-ldoktor@redhat.com>

Tests the cgroup cpuset (cpu affinity) functionality. It spawn no_cpus+1 cpu-intensive proces', limits the cpu affinity to cpu0 using cgroups and verifies. Than it do the same on all cpus except the cpu0.

Signed-off-by: Lukas Doktor <ldoktor@redhat.com>
---
 client/tests/cgroup/cgroup.py |  161 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 160 insertions(+), 1 deletions(-)

diff --git a/client/tests/cgroup/cgroup.py b/client/tests/cgroup/cgroup.py
index 45636f2..dc5a1b3 100755
--- a/client/tests/cgroup/cgroup.py
+++ b/client/tests/cgroup/cgroup.py
@@ -22,7 +22,7 @@ class cgroup(test.test):
 
         err = ""
         # Run available tests
-        for i in ['memory']:
+        for i in ['memory', 'cpuset']:
             logging.info("---< 'test_%s' START >---", i)
             try:
                 if not self.modules.get_pwd(i):
@@ -241,3 +241,162 @@ class cgroup(test.test):
 
 
 
+    def test_cpuset(self):
+        """
+        Cpuset test
+        1) Initiate CPU load on CPU0, than spread into CPU* - CPU0
+        """
+        class per_cpu_load:
+            """
+            Handles the per_cpu_load stats
+            self.values [cpus, cpu0, cpu1, ...]
+            """
+            def __init__(self):
+                """
+                Init
+                """
+                self.values = []
+                self.f = open('/proc/stat', 'r')
+                line = self.f.readline()
+                while line:
+                    if line.startswith('cpu'):
+                        self.values.append(int(line.split()[1]))
+                    else:
+                        break
+                    line = self.f.readline()
+
+            def reload(self):
+                """
+                Reload current values
+                """
+                self.values = self.get()
+
+            def get(self):
+                """
+                Get the current values
+                @return vals: array of current values [cpus, cpu0, cpu1..]
+                """
+                self.f.seek(0)
+                self.f.flush()
+                vals = []
+                for i in range(len(self.values)):
+                    vals.append(int(self.f.readline().split()[1]))
+                return vals
+
+            def tick(self):
+                """
+                Reload values and returns the load between the last tick/reload
+                @return vals: array of load between ticks/reloads
+                              values [cpus, cpu0, cpu1..]
+                """
+                vals = self.get()
+                ret = []
+                for i in range(len(self.values)):
+                    ret.append(vals[i] - self.values[i])
+                self.values = vals
+                return ret
+
+        def cleanup(supress=False):
+            # cleanup
+            logging.debug("test_cpuset: Cleanup")
+            err = ""
+            try:
+                for task in tasks:
+                    for i in range(10):
+                        task.terminate()
+                        if task.poll() != None:
+                            break
+                        time.sleep(1)
+                    if i >= 9:
+                        logging.error("test_cpuset: Subprocess didn't finish")
+            except Exception, inst:
+                err += "\nCan't terminate tasks: %s" % inst
+            if item.rm_cgroup(pwd):
+                err += "\nCan't remove cgroup direcotry"
+            if err:
+                if supress:
+                    logging.warn("Some parts of cleanup failed%s" % err)
+                else:
+                    raise error.TestFail("Some parts of cleanup failed%s" % err)
+
+        # Preparation
+        item = CG('cpuset', self._client)
+        if item.initialize(self.modules):
+            raise error.TestFail("cgroup init failed")
+
+        # FIXME: new cpuset cgroup doesn't have any mems and cpus assigned
+        # thus smoke_test won't work
+        #if item.smoke_test():
+        #    raise error.TestFail("smoke_test failed")
+
+        try:
+            # Available cpus: cpuset.cpus = "0-$CPUS\n"
+            no_cpus = int(item.get_prop("cpuset.cpus").split('-')[1]) + 1
+        except:
+            raise error.TestFail("Failed to get no_cpus or no_cpus = 1")
+
+        pwd = item.mk_cgroup()
+        if pwd == None:
+            raise error.TestFail("Can't create cgroup")
+        # FIXME: new cpuset cgroup doesn't have any mems and cpus assigned
+        try:
+            tmp = item.get_prop("cpuset.cpus")
+            item.set_property("cpuset.cpus", tmp, pwd)
+            tmp = item.get_prop("cpuset.mems")
+            item.set_property("cpuset.mems", tmp, pwd)
+        except:
+            cleanup(True)
+            raise error.TestFail("Failed to set cpus and mems of"
+                                 "a new cgroup")
+
+        ################################################
+        # Cpu allocation test
+        # Use cpu0 and verify, than all cpu* - cpu0 and verify
+        ################################################
+        logging.debug("test_cpuset: Cpu allocation test")
+
+        tasks = []
+        # Run no_cpus + 1 jobs
+        for i in range(no_cpus + 1):
+            tasks.append(item.test("cpu"))
+            if item.set_cgroup(tasks[i].pid, pwd):
+                cleanup(True)
+                raise error.TestFail("Failed to set cgroup")
+            tasks[i].stdin.write('\n')
+        stats = per_cpu_load()
+        # Use only the first CPU
+        item.set_property("cpuset.cpus", 0, pwd)
+        stats.reload()
+        time.sleep(10)
+        # [0] = all cpus
+        s1 = stats.tick()[1:]
+        s2 = s1[1:]
+        s1 = s1[0]
+        for _s in s2:
+            if s1 < _s:
+                cleanup(True)
+                raise error.TestFail("Unused processor had higher utilization\n"
+                                     "used cpu: %s, remaining cpus: %s"
+                                     % (s1, s2))
+
+        if no_cpus == 2:
+            item.set_property("cpuset.cpus", "1", pwd)
+        else:
+            item.set_property("cpuset.cpus", "1-%d"%(no_cpus-1), pwd)
+        stats.reload()
+        time.sleep(10)
+        s1 = stats.tick()[1:]
+        s2 = s1[0]
+        s1 = s1[1:]
+        for _s in s1:
+            if s2 > _s:
+                cleanup(True)
+                raise error.TestFail("Unused processor had higher utilization\n"
+                                     "used cpus: %s, remaining cpu: %s"
+                                     % (s1, s2))
+        logging.debug("test_cpuset: Cpu allocation test passed")
+
+        ################################################
+        # CLEANUP
+        ################################################
+        cleanup()
-- 
1.7.6

  parent reply	other threads:[~2011-08-15 12:23 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-15 12:23 [autotest][PATCH] cgroup test + modifications Lukas Doktor
2011-08-15 12:23 ` [PATCH 1/4] [NEW] cgroup test * general smoke_test + module dependend subtests (memory test included) * library for future use in other tests (kvm) Lukas Doktor
2011-08-18 11:33   ` Jiri Zupka
2011-08-21  9:15     ` Lukáš Doktor
2011-08-15 12:23 ` [PATCH 2/4] bugfixies Lukas Doktor
2011-08-15 12:23 ` Lukas Doktor [this message]
2011-08-15 12:23 ` [PATCH 4/4] [FIX] Use file instead of PIPE in memfill test (problem with sync) Lukas Doktor
2011-09-01  8:03 ` [autotest][PATCH] cgroup test + modifications Jan Stancek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1313411017-2873-4-git-send-email-ldoktor@redhat.com \
    --to=ldoktor@redhat.com \
    --cc=autotest@test.kernel.org \
    --cc=fyang@redhat.com \
    --cc=jzupka@redhat.com \
    --cc=kvm-autotest@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=lmr@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.