89 lines
3.1 KiB
Diff
89 lines
3.1 KiB
Diff
|
|
From ab35334d374e588bec12d201fb8869c536f0545d Mon Sep 17 00:00:00 2001
|
||
|
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||
|
|
Date: Sat, 2 Oct 2021 12:13:16 +0800
|
||
|
|
Subject: [PATCH] Detect the kernel.task_delayacct sysctl value
|
||
|
|
|
||
|
|
If you have ever turned on the kernel.task_delayacct sysctl for the
|
||
|
|
current
|
||
|
|
Linux boot, then the heuristic that iotop uses to find out if swapin/io
|
||
|
|
are
|
||
|
|
available, gives a false negative, so the sysctl has to be checked too
|
||
|
|
now.
|
||
|
|
|
||
|
|
Fixes: https://github.com/Tomas-M/iotop/issues/21
|
||
|
|
Reported-by: @ManuLinares
|
||
|
|
Forwarded-by: Boian Bonev <bbonev@ipacct.com>
|
||
|
|
|
||
|
|
Conflict: Adapt patch context
|
||
|
|
Reference: https://repo.or.cz/iotop.git/commit/ab35334d374e588bec12d201fb8869c536f0545d
|
||
|
|
---
|
||
|
|
iotop/data.py | 8 ++++++++
|
||
|
|
iotop/ui.py | 14 +++++++++++---
|
||
|
|
2 files changed, 19 insertions(+), 3 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/iotop/data.py b/iotop/data.py
|
||
|
|
index 606376f..b784a19 100644
|
||
|
|
--- a/iotop/data.py
|
||
|
|
+++ b/iotop/data.py
|
||
|
|
@@ -459,3 +459,11 @@ class ProcessList(DumpableObject):
|
||
|
|
|
||
|
|
def clear(self):
|
||
|
|
self.processes = {}
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+def sysctl_task_delayacct():
|
||
|
|
+ try:
|
||
|
|
+ with open('/proc/sys/kernel/task_delayacct') as f:
|
||
|
|
+ return bool(int(f.read().strip()))
|
||
|
|
+ except FileNotFoundError:
|
||
|
|
+ return None
|
||
|
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||
|
|
index 5ab8fd4..4ffbeea 100644
|
||
|
|
--- a/iotop/ui.py
|
||
|
|
+++ b/iotop/ui.py
|
||
|
|
@@ -31,7 +31,7 @@ import sys
|
||
|
|
import time
|
||
|
|
from collections import OrderedDict
|
||
|
|
|
||
|
|
-from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats
|
||
|
|
+from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats, sysctl_task_delayacct
|
||
|
|
from iotop.data import ThreadInfo
|
||
|
|
from iotop.version import VERSION
|
||
|
|
from iotop import ioprio
|
||
|
|
@@ -383,7 +383,7 @@ class IOTopUI(object):
|
||
|
|
def format(p):
|
||
|
|
stats = format_stats(self.options, p, self.process_list.duration)
|
||
|
|
io_delay, swapin_delay, read_bytes, write_bytes = stats
|
||
|
|
- if Stats.has_blkio_delay_total:
|
||
|
|
+ if self.has_swapin_io:
|
||
|
|
delay_stats = '%7s %7s ' % (swapin_delay, io_delay)
|
||
|
|
else:
|
||
|
|
delay_stats = ' ?unavailable? '
|
||
|
|
@@ -435,6 +435,14 @@ class IOTopUI(object):
|
||
|
|
pid += 'TID'
|
||
|
|
titles = [pid, ' PRIO', ' USER', ' DISK READ', ' DISK WRITE',
|
||
|
|
' SWAPIN', ' IO', ' COMMAND']
|
||
|
|
+ self.has_swapin_io = Stats.has_blkio_delay_total
|
||
|
|
+ if self.has_swapin_io:
|
||
|
|
+ # Linux kernels without the sysctl return None and
|
||
|
|
+ # iotop just uses the heuristic for those versions.
|
||
|
|
+ # Linux kernels with the sysctl return True or False
|
||
|
|
+ # and iotop then uses the sysctl value instead.
|
||
|
|
+ if sysctl_task_delayacct() == False:
|
||
|
|
+ self.has_swapin_io = False
|
||
|
|
lines = self.get_data()
|
||
|
|
if self.options.time:
|
||
|
|
titles = [' TIME'] + titles
|
||
|
|
@@ -453,7 +461,7 @@ class IOTopUI(object):
|
||
|
|
else:
|
||
|
|
self.win.erase()
|
||
|
|
|
||
|
|
- if Stats.has_blkio_delay_total:
|
||
|
|
+ if self.has_swapin_io:
|
||
|
|
status_msg = None
|
||
|
|
else:
|
||
|
|
status_msg = ('CONFIG_TASK_DELAY_ACCT '
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|