Blame SOURCES/kvm-tools-kvm_stat-add-interactive-command-r.patch

4a2fec
From 243d90a041dca861bb85bc71df863578a8f839bd Mon Sep 17 00:00:00 2001
4a2fec
From: David Hildenbrand <david@redhat.com>
4a2fec
Date: Tue, 17 Oct 2017 19:15:42 +0200
4a2fec
Subject: [PATCH 37/69] tools/kvm_stat: add interactive command 'r'
4a2fec
MIME-Version: 1.0
4a2fec
Content-Type: text/plain; charset=UTF-8
4a2fec
Content-Transfer-Encoding: 8bit
4a2fec
4a2fec
RH-Author: David Hildenbrand <david@redhat.com>
4a2fec
Message-id: <20171017191605.2378-17-david@redhat.com>
4a2fec
Patchwork-id: 77326
4a2fec
O-Subject: [RHEL-7.5 qemu-kvm-rhev PATCH 16/39] tools/kvm_stat: add interactive command 'r'
4a2fec
Bugzilla: 1497137
4a2fec
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
4a2fec
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
4a2fec
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
4a2fec
RH-Acked-by: Thomas Huth <thuth@redhat.com>
4a2fec
4a2fec
Upstream-status: linux.git 9f114a03c6854f49065dd036c17e1b4bb947f842
4a2fec
4a2fec
Convertion of documentation (for man page generation) to texi.
4a2fec
4a2fec
commit 9f114a03c6854f49065dd036c17e1b4bb947f842
4a2fec
Author: Stefan Raspl <raspl@linux.vnet.ibm.com>
4a2fec
Date:   Fri Mar 10 13:40:15 2017 +0100
4a2fec
4a2fec
    tools/kvm_stat: add interactive command 'r'
4a2fec
4a2fec
    Provide an interactive command to reset the tracepoint statistics.
4a2fec
    Requires some extra work for debugfs, as the counters cannot be reset.
4a2fec
4a2fec
    On the up side, this offers us the opportunity to have debugfs values
4a2fec
    reset on startup and whenever a filter is modified, becoming consistent
4a2fec
    with the tracepoint provider. As a bonus, 'kvmstat -dt' will now provide
4a2fec
    useful output, instead of mixing values in totally different orders of
4a2fec
    magnitude.
4a2fec
    Furthermore, we avoid unnecessary resets when any of the filters is
4a2fec
    "changed" interactively to the previous value.
4a2fec
4a2fec
    Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
4a2fec
    Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
4a2fec
    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
4a2fec
4a2fec
Signed-off-by: David Hildenbrand <david@redhat.com>
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
---
4a2fec
 scripts/kvm/kvm_stat      | 65 +++++++++++++++++++++++++++++++++++++----------
4a2fec
 scripts/kvm/kvm_stat.texi |  3 +++
4a2fec
 2 files changed, 54 insertions(+), 14 deletions(-)
4a2fec
4a2fec
diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
4a2fec
index 676a92a..f8c48f8 100755
4a2fec
--- a/scripts/kvm/kvm_stat
4a2fec
+++ b/scripts/kvm/kvm_stat
4a2fec
@@ -716,15 +716,23 @@ class TracepointProvider(object):
4a2fec
                     ret[name] += val
4a2fec
         return ret
4a2fec
 
4a2fec
+    def reset(self):
4a2fec
+        """Reset all field counters"""
4a2fec
+        for group in self.group_leaders:
4a2fec
+            for event in group.events:
4a2fec
+                event.reset()
4a2fec
+
4a2fec
 
4a2fec
 class DebugfsProvider(object):
4a2fec
     """Provides data from the files that KVM creates in the kvm debugfs
4a2fec
     folder."""
4a2fec
     def __init__(self):
4a2fec
         self._fields = self.get_available_fields()
4a2fec
+        self._baseline = {}
4a2fec
         self._pid = 0
4a2fec
         self.do_read = True
4a2fec
         self.paths = []
4a2fec
+        self.reset()
4a2fec
 
4a2fec
     def get_available_fields(self):
4a2fec
         """"Returns a list of available fields.
4a2fec
@@ -741,6 +749,7 @@ class DebugfsProvider(object):
4a2fec
     @fields.setter
4a2fec
     def fields(self, fields):
4a2fec
         self._fields = fields
4a2fec
+        self.reset()
4a2fec
 
4a2fec
     @property
4a2fec
     def pid(self):
4a2fec
@@ -758,10 +767,11 @@ class DebugfsProvider(object):
4a2fec
             self.paths = filter(lambda x: "{}-".format(pid) in x, vms)
4a2fec
 
4a2fec
         else:
4a2fec
-            self.paths = ['']
4a2fec
+            self.paths = []
4a2fec
             self.do_read = True
4a2fec
+        self.reset()
4a2fec
 
4a2fec
-    def read(self):
4a2fec
+    def read(self, reset=0):
4a2fec
         """Returns a dict with format:'file name / field -> current value'."""
4a2fec
         results = {}
4a2fec
 
4a2fec
@@ -769,10 +779,22 @@ class DebugfsProvider(object):
4a2fec
         if not self.do_read:
4a2fec
             return results
4a2fec
 
4a2fec
-        for path in self.paths:
4a2fec
+        paths = self.paths
4a2fec
+        if self._pid == 0:
4a2fec
+            paths = []
4a2fec
+            for entry in os.walk(PATH_DEBUGFS_KVM):
4a2fec
+                for dir in entry[1]:
4a2fec
+                    paths.append(dir)
4a2fec
+        for path in paths:
4a2fec
             for field in self._fields:
4a2fec
-                results[field] = results.get(field, 0) \
4a2fec
-                                 + self.read_field(field, path)
4a2fec
+                value = self.read_field(field, path)
4a2fec
+                key = path + field
4a2fec
+                if reset:
4a2fec
+                    self._baseline[key] = value
4a2fec
+                if self._baseline.get(key, -1) == -1:
4a2fec
+                    self._baseline[key] = value
4a2fec
+                results[field] = (results.get(field, 0) + value -
4a2fec
+                                  self._baseline.get(key, 0))
4a2fec
 
4a2fec
         return results
4a2fec
 
4a2fec
@@ -786,6 +808,11 @@ class DebugfsProvider(object):
4a2fec
         except IOError:
4a2fec
             return 0
4a2fec
 
4a2fec
+    def reset(self):
4a2fec
+        """Reset field counters"""
4a2fec
+        self._baseline = {}
4a2fec
+        self.read(1)
4a2fec
+
4a2fec
 
4a2fec
 class Stats(object):
4a2fec
     """Manages the data providers and the data they provide.
4a2fec
@@ -822,14 +849,20 @@ class Stats(object):
4a2fec
         for provider in self.providers:
4a2fec
             provider.pid = self._pid_filter
4a2fec
 
4a2fec
+    def reset(self):
4a2fec
+        self.values = {}
4a2fec
+        for provider in self.providers:
4a2fec
+            provider.reset()
4a2fec
+
4a2fec
     @property
4a2fec
     def fields_filter(self):
4a2fec
         return self._fields_filter
4a2fec
 
4a2fec
     @fields_filter.setter
4a2fec
     def fields_filter(self, fields_filter):
4a2fec
-        self._fields_filter = fields_filter
4a2fec
-        self.update_provider_filters()
4a2fec
+        if fields_filter != self._fields_filter:
4a2fec
+            self._fields_filter = fields_filter
4a2fec
+            self.update_provider_filters()
4a2fec
 
4a2fec
     @property
4a2fec
     def pid_filter(self):
4a2fec
@@ -837,9 +870,10 @@ class Stats(object):
4a2fec
 
4a2fec
     @pid_filter.setter
4a2fec
     def pid_filter(self, pid):
4a2fec
-        self._pid_filter = pid
4a2fec
-        self.values = {}
4a2fec
-        self.update_provider_pid()
4a2fec
+        if pid != self._pid_filter:
4a2fec
+            self._pid_filter = pid
4a2fec
+            self.values = {}
4a2fec
+            self.update_provider_pid()
4a2fec
 
4a2fec
     def get(self):
4a2fec
         """Returns a dict with field -> (value, delta to last value) of all
4a2fec
@@ -847,11 +881,9 @@ class Stats(object):
4a2fec
         for provider in self.providers:
4a2fec
             new = provider.read()
4a2fec
             for key in provider.fields:
4a2fec
-                oldval = self.values.get(key, (0, 0))
4a2fec
+                oldval = self.values.get(key, (0, 0))[0]
4a2fec
                 newval = new.get(key, 0)
4a2fec
-                newdelta = None
4a2fec
-                if oldval is not None:
4a2fec
-                    newdelta = newval - oldval[0]
4a2fec
+                newdelta = newval - oldval
4a2fec
                 self.values[key] = (newval, newdelta)
4a2fec
         return self.values
4a2fec
 
4a2fec
@@ -1117,6 +1149,10 @@ class Tui(object):
4a2fec
                 if char == 'p':
4a2fec
                     self.show_vm_selection_by_pid()
4a2fec
                     sleeptime = DELAY_INITIAL
4a2fec
+                if char == 'r':
4a2fec
+                    self.refresh_header()
4a2fec
+                    self.stats.reset()
4a2fec
+                    sleeptime = DELAY_INITIAL
4a2fec
             except KeyboardInterrupt:
4a2fec
                 break
4a2fec
             except curses.error:
4a2fec
@@ -1190,6 +1226,7 @@ Interactive Commands:
4a2fec
    p     filter by PID
4a2fec
    q     quit
4a2fec
    x     toggle reporting of stats for individual child trace events
4a2fec
+   r     reset stats
4a2fec
 Press any other key to refresh statistics immediately.
4a2fec
 """
4a2fec
 
4a2fec
diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
4a2fec
index 203d61d..c0cb7bc 100644
4a2fec
--- a/scripts/kvm/kvm_stat.texi
4a2fec
+++ b/scripts/kvm/kvm_stat.texi
4a2fec
@@ -39,6 +39,9 @@ filter by PID
4a2fec
 @item q
4a2fec
 @kindex q
4a2fec
 quit
4a2fec
+@item r
4a2fec
+@kindex r
4a2fec
+reset stats
4a2fec
 @item x
4a2fec
 @kindex x
4a2fec
 toggle reporting of stats for child trace events
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec