When in perf mode (so not polling) previously the GUI would be refreshed at the arrival of any single perf event. This may mean that it would get refreshed all the time especially on quite loaded systems, causing very high CPU load and unuseable GUI.
The patch limits the refresh to the minimum refresh_time (already used for polling and configurable via -R command line by the user) to prevent such cases. If no events arrive, the GUI will still not be refreshed at all as before.
Signed-off-by: Federico Pellegrin fede@evolware.org --- tuna/gui/procview.py | 14 ++++++++++---- tuna/tuna_gui.py | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index fce0b52..28a73a3 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -219,6 +219,7 @@ class procview: self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile + self.evlist_added = True
self.evlist = None try: @@ -346,7 +347,7 @@ class procview: else: self.perf_counter[tid] = event.sample_period
- self.show() + self.evlist_added = True # Mark that event arrived, so next periodic show() will refresh GUI return True
def perf_init(self): @@ -425,9 +426,14 @@ class procview: # create the rows. if not self.refreshing and not force_refresh: return - row = self.tree_store.get_iter_first() - self.update_rows(self.ps, row, None) - self.treeview.show_all() + + # If using perf only refresh if we saw at least a new event since last refresh + if not self.evlist or self.evlist_added: + self.evlist_added = None + + row = self.tree_store.get_iter_first() + self.update_rows(self.ps, row, None) + self.treeview.show_all()
def update_rows(self, threads, row, parent_row): new_tids = list(threads.keys()) diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 1296beb..ac50d93 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -146,7 +146,7 @@ class main_gui: if not self.procview.evlist: # Poll, as we don't have perf self.ps.reload() self.ps.reload_threads() - self.procview.show() + self.procview.show() self.irqview.refresh() return True
Add command line option (-d, --disable_perf) to explicitly disable usage of perf facility for procview. Previously if the perf attach succeeds, it will always be used. Now if -d is passed it will be not tried.
Default behaviour is kept as before.
Rationale for adding this option: -) On very loaded systems (mostly with processes / threads varing very often) perf may end up being triggered all the time, causing a continuous widget refresh which will cause 100% CPU usage of tuna and therefore a very sluggish and hardly usable GUI. This can be in case partially alleviated by reducing the refresh time via the recently added refresh time option. -) As it is now (maybe we could change?) perf doesn't deliver the same data as polling /proc does, for example perf will not update context switch data. So having the possibility for the user to go anyway for acquiring data from /proc (as ugly as polling is) to have also that data displayed, if needed, sounds like a reasonable approach.
Signed-off-by: Federico Pellegrin fede@evolware.org --- docs/tuna.8 | 3 +++ tuna-cmd.py | 12 +++++++++--- tuna/gui/procview.py | 11 ++++++----- tuna/tuna_gui.py | 4 ++-- 4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/docs/tuna.8 b/docs/tuna.8 index dd69ec6..b6431be 100644 --- a/docs/tuna.8 +++ b/docs/tuna.8 @@ -65,6 +65,9 @@ CPU-LIST affected by commands. Requires a CPU number or a comma-separated list \fB-C\fR, \fB--affect_children\fR Operation will affect children threads. .TP +\fB-d\fR, \fB--disable_perf\fR +Explicitly disable usage of perf in GUI for process view +.TP \fB-f\fR, \fB--filter\fR Disable display of selected CPUs in \fB--gui\fR. Requires \fB-c\R. .TP diff --git a/tuna-cmd.py b/tuna-cmd.py index c27abd1..ecfa15e 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -59,6 +59,8 @@ def usage(): {"cpulist": _('CPU-LIST')})) print(fmt % ('-C, --affect_children', _('Operation will affect children threads'))) + print(fmt % ('-d, --disable_perf', + _('Explicitly disable usage of perf in GUI for process view'))) print(fmt % ('-f, --filter', _('Display filter the selected entities'))) print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % @@ -495,14 +497,14 @@ def main():
i18n_init() try: - short = "a:c:CfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" + short = "a:c:dCfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" long = ["cpus=", "affect_children", "filter", "gui", "help", "isolate", "include", "no_kthreads", "move", "nohz_full", "show_sockets", "priority=", "show_threads", "show_irqs", "irqs=", "save=", "sockets=", "threads=", "no_uthreads", "version", "what_is", "spread", "cgroup", "config_file_apply=", - "config_file_list=", "run=", "refresh="] + "config_file_list=", "run=", "refresh=", "disable_perf"] if have_inet_diag: short += "n" long.append("show_sockets") @@ -528,6 +530,7 @@ def main(): show_sockets = False p_waiting_action = False gui_refresh = 2500 + disable_perf = False
for o, a in opts: if o in ("-h", "--help"): @@ -588,6 +591,9 @@ def main(): except Exception as err: print("tuna: --refresh %s" % err) sys.exit(2) + elif o in ("-d", "--disable_perf"): + run_gui = True + disable_perf = True elif o in ("-i", "--isolate"): if not cpu_list: print("tuna: --isolate " + _("requires a cpu list!")) @@ -747,7 +753,7 @@ def main():
try: cpus_filtered = filter and cpu_list or [] - app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh) + app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh, disable_perf) app.run() except KeyboardInterrupt: pass diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 28a73a3..440a289 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -214,7 +214,7 @@ class procview: gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
def __init__(self, treeview, ps, show_kthreads, show_uthreads, - cpus_filtered, gladefile): + cpus_filtered, gladefile, disable_perf): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus @@ -222,10 +222,11 @@ class procview: self.evlist_added = True
self.evlist = None - try: - self.perf_init() - except: # No perf, poll /proc baby, poll - pass + if not disable_perf: + try: + self.perf_init() + except: # No perf, poll /proc baby, poll + pass
if "voluntary_ctxt_switches" not in ps[1]["status"]: self.nr_columns = 5 diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index ac50d93..f1f2caa 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -23,7 +23,7 @@ tuna_glade = None
class main_gui:
- def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500): + def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500, disable_perf=False): global tuna_glade
(app, localedir) = ('tuna', '/usr/share/locale') @@ -46,7 +46,7 @@ class main_gui: self.procview = procview( self.wtree.get_object("processlist"), self.ps, show_kthreads, show_uthreads, - cpus_filtered, tuna_glade) + cpus_filtered, tuna_glade, disable_perf) self.irqview = irqview( self.wtree.get_object("irqlist"), self.irqs, self.ps, cpus_filtered,
On Fri, 14 May 2021, Federico Pellegrin wrote:
Add command line option (-d, --disable_perf) to explicitly disable usage of perf facility for procview. Previously if the perf attach succeeds, it will always be used. Now if -d is passed it will be not tried.
Default behaviour is kept as before.
Rationale for adding this option: -) On very loaded systems (mostly with processes / threads varing very often) perf may end up being triggered all the time, causing a continuous widget refresh which will cause 100% CPU usage of tuna and therefore a very sluggish and hardly usable GUI. This can be in case partially alleviated by reducing the refresh time via the recently added refresh time option. -) As it is now (maybe we could change?) perf doesn't deliver the same data as polling /proc does, for example perf will not update context switch data. So having the possibility for the user to go anyway for acquiring data from /proc (as ugly as polling is) to have also that data displayed, if needed, sounds like a reasonable approach.
Signed-off-by: Federico Pellegrin fede@evolware.org
docs/tuna.8 | 3 +++ tuna-cmd.py | 12 +++++++++--- tuna/gui/procview.py | 11 ++++++----- tuna/tuna_gui.py | 4 ++-- 4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/docs/tuna.8 b/docs/tuna.8 index dd69ec6..b6431be 100644 --- a/docs/tuna.8 +++ b/docs/tuna.8 @@ -65,6 +65,9 @@ CPU-LIST affected by commands. Requires a CPU number or a comma-separated list \fB-C\fR, \fB--affect_children\fR Operation will affect children threads. .TP +\fB-d\fR, \fB--disable_perf\fR +Explicitly disable usage of perf in GUI for process view +.TP \fB-f\fR, \fB--filter\fR Disable display of selected CPUs in \fB--gui\fR. Requires \fB-c\R. .TP diff --git a/tuna-cmd.py b/tuna-cmd.py index c27abd1..ecfa15e 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -59,6 +59,8 @@ def usage(): {"cpulist": _('CPU-LIST')})) print(fmt % ('-C, --affect_children', _('Operation will affect children threads')))
- print(fmt % ('-d, --disable_perf',
print(fmt % ('-f, --filter', _('Display filter the selected entities'))) print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') %_('Explicitly disable usage of perf in GUI for process view')))
@@ -495,14 +497,14 @@ def main():
i18n_init() try:
short = "a:c:CfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx"
short = "a:c:dCfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" long = ["cpus=", "affect_children", "filter", "gui", "help", "isolate", "include", "no_kthreads", "move", "nohz_full", "show_sockets", "priority=", "show_threads", "show_irqs", "irqs=", "save=", "sockets=", "threads=", "no_uthreads", "version", "what_is", "spread", "cgroup", "config_file_apply=",
"config_file_list=", "run=", "refresh="]
"config_file_list=", "run=", "refresh=", "disable_perf"] if have_inet_diag: short += "n" long.append("show_sockets")
@@ -528,6 +530,7 @@ def main(): show_sockets = False p_waiting_action = False gui_refresh = 2500
disable_perf = False
for o, a in opts: if o in ("-h", "--help"):
@@ -588,6 +591,9 @@ def main(): except Exception as err: print("tuna: --refresh %s" % err) sys.exit(2)
elif o in ("-d", "--disable_perf"):
run_gui = True
disable_perf = True elif o in ("-i", "--isolate"): if not cpu_list: print("tuna: --isolate " + _("requires a cpu list!"))
@@ -747,7 +753,7 @@ def main():
try: cpus_filtered = filter and cpu_list or []
app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh)
app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh, disable_perf) app.run() except KeyboardInterrupt: pass
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 28a73a3..440a289 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -214,7 +214,7 @@ class procview: gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
def __init__(self, treeview, ps, show_kthreads, show_uthreads,
cpus_filtered, gladefile):
cpus_filtered, gladefile, disable_perf): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus
@@ -222,10 +222,11 @@ class procview: self.evlist_added = True
self.evlist = None
try:
self.perf_init()
except: # No perf, poll /proc baby, poll
pass
if not disable_perf:
try:
self.perf_init()
except: # No perf, poll /proc baby, poll
pass if "voluntary_ctxt_switches" not in ps[1]["status"]: self.nr_columns = 5
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index ac50d93..f1f2caa 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -23,7 +23,7 @@ tuna_glade = None
class main_gui:
- def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500):
def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500, disable_perf=False): global tuna_glade
(app, localedir) = ('tuna', '/usr/share/locale')
@@ -46,7 +46,7 @@ class main_gui: self.procview = procview( self.wtree.get_object("processlist"), self.ps, show_kthreads, show_uthreads,
cpus_filtered, tuna_glade)
cpus_filtered, tuna_glade, disable_perf) self.irqview = irqview( self.wtree.get_object("irqlist"), self.irqs, self.ps, cpus_filtered,
-- 2.31.1
Signed-off-by: John Kacur jkacur@redhat.com
Do you think this could be replaced by a feature that would automatically limit the updates if they were too frequent? I think it gets to be confusing when there are too many commandline options for a gui that a user might not understand, and would just want things to work.
Hi John, First of all thanks a lot for merging the patches!
I believe that the first patch (so 1/2) already takes care of keeping the refresh under a certain threshold as passed by -R. This should at least prevent major overloads. I'm not sure if automatically changing this further could be a possible improvement.
But still I believe the main "feature" of being able to disable perf (so this option we are discussing here in 2/2) is that perf doesn't seem to deliver certain data, like ie. context switch data. I've given a fast look at that time if I could get that additional data also via the perf hook, but was not able to figure out if it could be feasible. Maybe I can try to give a better look as soon as I have some time (or maybe some perf expert can chime in?) to see if we could get all the data we get from procfs also via perf. In that case then I'd agree that we could just stick to the automatic detection. I try to give a look ASAP and let you know!
In the meantime: do you think it would be worth doing a 0.16 release? Since 0.15 I think quite some stuff changed now and we have a good GTK3 support now. Would it make sense to do a release to make it more realistic for distros to update to this version then?
Cheers, Federico
Il giorno sab 22 mag 2021 alle ore 06:31 John Kacur jkacur@redhat.com ha scritto:
On Fri, 14 May 2021, Federico Pellegrin wrote:
Add command line option (-d, --disable_perf) to explicitly disable usage of perf facility for procview. Previously if the perf attach succeeds, it will always be used. Now if -d is passed it will be not tried.
Default behaviour is kept as before.
Rationale for adding this option: -) On very loaded systems (mostly with processes / threads varing very often) perf may end up being triggered all the time, causing a continuous widget refresh which will cause 100% CPU usage of tuna and therefore a very sluggish and hardly usable GUI. This can be in case partially alleviated by reducing the refresh time via the recently added refresh time option. -) As it is now (maybe we could change?) perf doesn't deliver the same data as polling /proc does, for example perf will not update context switch data. So having the possibility for the user to go anyway for acquiring data from /proc (as ugly as polling is) to have also that data displayed, if needed, sounds like a reasonable approach.
Signed-off-by: Federico Pellegrin fede@evolware.org
docs/tuna.8 | 3 +++ tuna-cmd.py | 12 +++++++++--- tuna/gui/procview.py | 11 ++++++----- tuna/tuna_gui.py | 4 ++-- 4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/docs/tuna.8 b/docs/tuna.8 index dd69ec6..b6431be 100644 --- a/docs/tuna.8 +++ b/docs/tuna.8 @@ -65,6 +65,9 @@ CPU-LIST affected by commands. Requires a CPU number
or a comma-separated list
\fB-C\fR, \fB--affect_children\fR Operation will affect children threads. .TP +\fB-d\fR, \fB--disable_perf\fR +Explicitly disable usage of perf in GUI for process view +.TP \fB-f\fR, \fB--filter\fR Disable display of selected CPUs in \fB--gui\fR. Requires \fB-c\R. .TP diff --git a/tuna-cmd.py b/tuna-cmd.py index c27abd1..ecfa15e 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -59,6 +59,8 @@ def usage(): {"cpulist": _('CPU-LIST')})) print(fmt % ('-C, --affect_children', _('Operation will affect children threads')))
- print(fmt % ('-d, --disable_perf',
_('Explicitly disable usage of perf in GUI for process
view')))
print(fmt % ('-f, --filter', _('Display filter the selected entities'))) print(fmt % ('-i, --isolate', _('Move all threads
away from %(cpulist)s') %
@@ -495,14 +497,14 @@ def main():
i18n_init() try:
short = "a:c:CfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx"
short = "a:c:dCfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" long = ["cpus=", "affect_children", "filter", "gui", "help", "isolate", "include", "no_kthreads", "move",
"nohz_full",
"show_sockets", "priority=", "show_threads", "show_irqs", "irqs=", "save=", "sockets=", "threads=", "no_uthreads", "version", "what_is", "spread", "cgroup",
"config_file_apply=",
"config_file_list=", "run=", "refresh="]
"config_file_list=", "run=", "refresh=", "disable_perf"] if have_inet_diag: short += "n" long.append("show_sockets")
@@ -528,6 +530,7 @@ def main(): show_sockets = False p_waiting_action = False gui_refresh = 2500
disable_perf = False
for o, a in opts: if o in ("-h", "--help"):
@@ -588,6 +591,9 @@ def main(): except Exception as err: print("tuna: --refresh %s" % err) sys.exit(2)
elif o in ("-d", "--disable_perf"):
run_gui = True
disable_perf = True elif o in ("-i", "--isolate"): if not cpu_list: print("tuna: --isolate " + _("requires a cpu list!"))
@@ -747,7 +753,7 @@ def main():
try: cpus_filtered = filter and cpu_list or []
app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered,
gui_refresh)
app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered,
gui_refresh, disable_perf)
app.run() except KeyboardInterrupt: pass
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 28a73a3..440a289 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -214,7 +214,7 @@ class procview: gui.list_store_column(_("Command Line"),
GObject.TYPE_STRING))
def __init__(self, treeview, ps, show_kthreads, show_uthreads,
cpus_filtered, gladefile):
cpus_filtered, gladefile, disable_perf): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus
@@ -222,10 +222,11 @@ class procview: self.evlist_added = True
self.evlist = None
try:
self.perf_init()
except: # No perf, poll /proc baby, poll
pass
if not disable_perf:
try:
self.perf_init()
except: # No perf, poll /proc baby, poll
pass if "voluntary_ctxt_switches" not in ps[1]["status"]: self.nr_columns = 5
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index ac50d93..f1f2caa 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -23,7 +23,7 @@ tuna_glade = None
class main_gui:
- def __init__(self, show_kthreads=True, show_uthreads=True,
cpus_filtered=[], refresh_time=2500):
- def __init__(self, show_kthreads=True, show_uthreads=True,
cpus_filtered=[], refresh_time=2500, disable_perf=False):
global tuna_glade (app, localedir) = ('tuna', '/usr/share/locale')
@@ -46,7 +46,7 @@ class main_gui: self.procview = procview( self.wtree.get_object("processlist"), self.ps, show_kthreads, show_uthreads,
cpus_filtered, tuna_glade)
cpus_filtered, tuna_glade, disable_perf) self.irqview = irqview( self.wtree.get_object("irqlist"), self.irqs, self.ps, cpus_filtered,
-- 2.31.1
Signed-off-by: John Kacur jkacur@redhat.com
Do you think this could be replaced by a feature that would automatically limit the updates if they were too frequent? I think it gets to be confusing when there are too many commandline options for a gui that a user might not understand, and would just want things to work.
On Tue, 25 May 2021, Federico Pellegrin wrote:
Hi John, First of all thanks a lot for merging the patches!
I believe that the first patch (so 1/2) already takes care of keeping the refresh under a certain threshold as passed by -R. This should at least prevent major overloads. I'm not sure if automatically changing this further could be a possible improvement.
But still I believe the main "feature" of being able to disable perf (so this option we are discussing here in 2/2) is that perf doesn't seem to deliver certain data, like ie. context switch data. I've given a fast look at that time if I could get that additional data also via the perf hook, but was not able to figure out if it could be feasible. Maybe I can try to give a better look as soon as I have some time (or maybe some perf expert can chime in?) to see if we could get all the data we get from procfs also via perf. In that case then I'd agree that we could just stick to the automatic detection. I try to give a look ASAP and let you know!
In the meantime: do you think it would be worth doing a 0.16 release? Since 0.15 I think quite some stuff changed now and we have a good GTK3 support now. Would it make sense to do a release to make it more realistic for distros to update to this version then?
Yes, in fact that was my plan, I might have some minor clean-ups first but will release a 0.16 shortly.
John
Cheers, Federico
Il giorno sab 22 mag 2021 alle ore 06:31 John Kacur jkacur@redhat.com ha scritto:
On Fri, 14 May 2021, Federico Pellegrin wrote: > Add command line option (-d, --disable_perf) to explicitly disable > usage of perf facility for procview. Previously if the perf attach > succeeds, it will always be used. Now if -d is passed it will be not > tried. > > Default behaviour is kept as before. > > Rationale for adding this option: > -) On very loaded systems (mostly with processes / threads varing very > often) perf may end up being triggered all the time, causing a > continuous widget refresh which will cause 100% CPU usage of tuna > and therefore a very sluggish and hardly usable GUI. This can be in > case partially alleviated by reducing the refresh time via the > recently added refresh time option. > -) As it is now (maybe we could change?) perf doesn't deliver the > same data as polling /proc does, for example perf will not update > context switch data. So having the possibility for the user to go > anyway for acquiring data from /proc (as ugly as polling is) to have > also that data displayed, if needed, sounds like a reasonable > approach. > > Signed-off-by: Federico Pellegrin <fede@evolware.org> > --- > docs/tuna.8 | 3 +++ > tuna-cmd.py | 12 +++++++++--- > tuna/gui/procview.py | 11 ++++++----- > tuna/tuna_gui.py | 4 ++-- > 4 files changed, 20 insertions(+), 10 deletions(-) > > diff --git a/docs/tuna.8 b/docs/tuna.8 > index dd69ec6..b6431be 100644 > --- a/docs/tuna.8 > +++ b/docs/tuna.8 > @@ -65,6 +65,9 @@ CPU\-LIST affected by commands. Requires a CPU number or a comma-separated list > \fB\-C\fR, \fB\-\-affect_children\fR > Operation will affect children threads. > .TP > +\fB\-d\fR, \fB\-\-disable_perf\fR > +Explicitly disable usage of perf in GUI for process view > +.TP > \fB\-f\fR, \fB\-\-filter\fR > Disable display of selected CPUs in \fB--gui\fR. Requires \fB-c\R. > .TP > diff --git a/tuna-cmd.py b/tuna-cmd.py > index c27abd1..ecfa15e 100755 > --- a/tuna-cmd.py > +++ b/tuna-cmd.py > @@ -59,6 +59,8 @@ def usage(): > {"cpulist": _('CPU-LIST')})) > print(fmt % ('-C, --affect_children', > _('Operation will affect children threads'))) > + print(fmt % ('-d, --disable_perf', > + _('Explicitly disable usage of perf in GUI for process view'))) > print(fmt % ('-f, --filter', > _('Display filter the selected entities'))) > print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % > @@ -495,14 +497,14 @@ def main(): > > i18n_init() > try: > - short = "a:c:CfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" > + short = "a:c:dCfgGhiIKlmNp:PQq:r:R:s:S:t:UvWx" > long = ["cpus=", "affect_children", "filter", "gui", "help", > "isolate", "include", "no_kthreads", "move", "nohz_full", > "show_sockets", "priority=", "show_threads", > "show_irqs", "irqs=", > "save=", "sockets=", "threads=", "no_uthreads", > "version", "what_is", "spread", "cgroup", "config_file_apply=", > - "config_file_list=", "run=", "refresh="] > + "config_file_list=", "run=", "refresh=", "disable_perf"] > if have_inet_diag: > short += "n" > long.append("show_sockets") > @@ -528,6 +530,7 @@ def main(): > show_sockets = False > p_waiting_action = False > gui_refresh = 2500 > + disable_perf = False > > for o, a in opts: > if o in ("-h", "--help"): > @@ -588,6 +591,9 @@ def main(): > except Exception as err: > print("tuna: --refresh %s" % err) > sys.exit(2) > + elif o in ("-d", "--disable_perf"): > + run_gui = True > + disable_perf = True > elif o in ("-i", "--isolate"): > if not cpu_list: > print("tuna: --isolate " + _("requires a cpu list!")) > @@ -747,7 +753,7 @@ def main(): > > try: > cpus_filtered = filter and cpu_list or [] > - app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh) > + app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered, gui_refresh, disable_perf) > app.run() > except KeyboardInterrupt: > pass > diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py > index 28a73a3..440a289 100755 > --- a/tuna/gui/procview.py > +++ b/tuna/gui/procview.py > @@ -214,7 +214,7 @@ class procview: > gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) > > def __init__(self, treeview, ps, show_kthreads, show_uthreads, > - cpus_filtered, gladefile): > + cpus_filtered, gladefile, disable_perf): > self.ps = ps > self.treeview = treeview > self.nr_cpus = procfs.cpuinfo().nr_cpus > @@ -222,10 +222,11 @@ class procview: > self.evlist_added = True > > self.evlist = None > - try: > - self.perf_init() > - except: # No perf, poll /proc baby, poll > - pass > + if not disable_perf: > + try: > + self.perf_init() > + except: # No perf, poll /proc baby, poll > + pass > > if "voluntary_ctxt_switches" not in ps[1]["status"]: > self.nr_columns = 5 > diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py > index ac50d93..f1f2caa 100755 > --- a/tuna/tuna_gui.py > +++ b/tuna/tuna_gui.py > @@ -23,7 +23,7 @@ tuna_glade = None > > class main_gui: > > - def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500): > + def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[], refresh_time=2500, disable_perf=False): > global tuna_glade > > (app, localedir) = ('tuna', '/usr/share/locale') > @@ -46,7 +46,7 @@ class main_gui: > self.procview = procview( > self.wtree.get_object("processlist"), > self.ps, show_kthreads, show_uthreads, > - cpus_filtered, tuna_glade) > + cpus_filtered, tuna_glade, disable_perf) > self.irqview = irqview( > self.wtree.get_object("irqlist"), > self.irqs, self.ps, cpus_filtered, > -- > 2.31.1 Signed-off-by: John Kacur <jkacur@redhat.com> Do you think this could be replaced by a feature that would automatically limit the updates if they were too frequent? I think it gets to be confusing when there are too many commandline options for a gui that a user might not understand, and would just want things to work.
On Fri, 14 May 2021, Federico Pellegrin wrote:
When in perf mode (so not polling) previously the GUI would be refreshed at the arrival of any single perf event. This may mean that it would get refreshed all the time especially on quite loaded systems, causing very high CPU load and unuseable GUI.
The patch limits the refresh to the minimum refresh_time (already used for polling and configurable via -R command line by the user) to prevent such cases. If no events arrive, the GUI will still not be refreshed at all as before.
Signed-off-by: Federico Pellegrin fede@evolware.org
tuna/gui/procview.py | 14 ++++++++++---- tuna/tuna_gui.py | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index fce0b52..28a73a3 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -219,6 +219,7 @@ class procview: self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile
self.evlist_added = True self.evlist = None try:
@@ -346,7 +347,7 @@ class procview: else: self.perf_counter[tid] = event.sample_period
self.show()
self.evlist_added = True # Mark that event arrived, so next periodic show() will refresh GUI return True
def perf_init(self):
@@ -425,9 +426,14 @@ class procview: # create the rows. if not self.refreshing and not force_refresh: return
row = self.tree_store.get_iter_first()
self.update_rows(self.ps, row, None)
self.treeview.show_all()
# If using perf only refresh if we saw at least a new event since last refresh
if not self.evlist or self.evlist_added:
self.evlist_added = None
row = self.tree_store.get_iter_first()
self.update_rows(self.ps, row, None)
self.treeview.show_all()
def update_rows(self, threads, row, parent_row): new_tids = list(threads.keys())
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 1296beb..ac50d93 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -146,7 +146,7 @@ class main_gui: if not self.procview.evlist: # Poll, as we don't have perf self.ps.reload() self.ps.reload_threads()
self.procview.show()
self.procview.show() self.irqview.refresh() return True
-- 2.31.1
Signed-off-by: John Kacur jkacur@redhat.com
On Fri, 14 May 2021, Federico Pellegrin wrote:
When in perf mode (so not polling) previously the GUI would be refreshed at the arrival of any single perf event. This may mean that it would get refreshed all the time especially on quite loaded systems, causing very high CPU load and unuseable GUI.
The patch limits the refresh to the minimum refresh_time (already used for polling and configurable via -R command line by the user) to prevent such cases. If no events arrive, the GUI will still not be refreshed at all as before.
Signed-off-by: Federico Pellegrin fede@evolware.org
tuna/gui/procview.py | 14 ++++++++++---- tuna/tuna_gui.py | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index fce0b52..28a73a3 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -219,6 +219,7 @@ class procview: self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile
self.evlist_added = True self.evlist = None try:
@@ -346,7 +347,7 @@ class procview: else: self.perf_counter[tid] = event.sample_period
self.show()
self.evlist_added = True # Mark that event arrived, so next periodic show() will refresh GUI return True
def perf_init(self):
@@ -425,9 +426,14 @@ class procview: # create the rows. if not self.refreshing and not force_refresh: return
row = self.tree_store.get_iter_first()
self.update_rows(self.ps, row, None)
self.treeview.show_all()
# If using perf only refresh if we saw at least a new event since last refresh
if not self.evlist or self.evlist_added:
self.evlist_added = None
row = self.tree_store.get_iter_first()
self.update_rows(self.ps, row, None)
self.treeview.show_all()
def update_rows(self, threads, row, parent_row): new_tids = list(threads.keys())
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 1296beb..ac50d93 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -146,7 +146,7 @@ class main_gui: if not self.procview.evlist: # Poll, as we don't have perf self.ps.reload() self.ps.reload_threads()
self.procview.show()
self.procview.show() self.irqview.refresh() return True
-- 2.31.1
Signed-off-by: John Kacur jkacur@redhat.com
tuna-devel@lists.fedorahosted.org