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

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