summaryrefslogtreecommitdiffstats
path: root/python.d
diff options
context:
space:
mode:
authorSteven Noonan <steven@uplinklabs.net>2017-09-10 14:16:26 -0700
committerSteven Noonan <steven@uplinklabs.net>2017-09-10 14:20:10 -0700
commita862c34ad543b483a4ae049fea4576b8df093b4d (patch)
tree35ad32dc9ea664d02bd6d8ccca212f1cc315439b /python.d
parent73767ab14ae545d851b16eb7b337717201389ac4 (diff)
cpuidle.chart.py: only tickle known-to-be-idle CPUs
This should prevent the netdata.plugin_pythond_cpuidle metric from spiking under load. Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Diffstat (limited to 'python.d')
-rw-r--r--python.d/cpuidle.chart.py26
1 files changed, 20 insertions, 6 deletions
diff --git a/python.d/cpuidle.chart.py b/python.d/cpuidle.chart.py
index f7199aebd9..3b404242f5 100644
--- a/python.d/cpuidle.chart.py
+++ b/python.d/cpuidle.chart.py
@@ -26,6 +26,7 @@ class Service(SimpleService):
self.definitions = {}
self._orig_name = ""
self.assignment = {}
+ self.last_schedstat = None
def __gettid(self):
# This is horrendous. We need the *thread id* (not the *process id*),
@@ -42,13 +43,13 @@ class Service(SimpleService):
tid = syscall(syscalls[platform.machine()])
return tid
- def __wake_cpus(self):
+ def __wake_cpus(self, cpus):
# Requires Python 3.3+. This will "tickle" each CPU to force it to
# update its idle counters.
if hasattr(os, 'sched_setaffinity'):
pid = self.__gettid()
save_affinity = os.sched_getaffinity(pid)
- for idx in range(0, len(self.assignment)):
+ for idx in cpus:
os.sched_setaffinity(pid, [idx])
os.sched_getaffinity(pid)
os.sched_setaffinity(pid, save_affinity)
@@ -67,14 +68,27 @@ class Service(SimpleService):
def _get_data(self):
results = {}
- # This line is critical for the stats to update. If we don't "tickle"
- # all the CPUs, then all the counters stop counting.
- self.__wake_cpus()
-
# Use the kernel scheduler stats to determine how much time was spent
# in C0 (active).
schedstat = self.__read_schedstat()
+ # Determine if any of the CPUs are idle. If they are, then we need to
+ # tickle them in order to update their C-state residency statistics.
+ if self.last_schedstat is None:
+ needs_tickle = list(self.assignment.keys())
+ else:
+ needs_tickle = []
+ for cpu, active_time in self.last_schedstat.items():
+ delta = schedstat[cpu] - active_time
+ if delta < 1:
+ needs_tickle.append(cpu)
+ self.last_schedstat = schedstat
+
+ if needs_tickle:
+ # This line is critical for the stats to update. If we don't "tickle"
+ # idle CPUs, then the counters for those CPUs stop counting.
+ self.__wake_cpus([int(cpu[3:]) for cpu in needs_tickle])
+
for cpu, metrics in self.assignment.items():
update_time = schedstat[cpu]
results[cpu + '_active_time'] = update_time