Skip to content

Commit d61116b

Browse files
committed
Make the scheduler plugin dynamic
Remove the "runtime" option from the scheduler plugin and integrate its functionality into dynamic tuning. Currently, the scheduler plugin is the only dynamic plugin with its own implementation of dynamic tuning (not initiated periodically by the main daemon thread). Adjust default global configuration so that dynamic tuning is enabled by default, but only for the scheduler plugin.
1 parent 570e3ee commit d61116b

File tree

4 files changed

+47
-42
lines changed

4 files changed

+47
-42
lines changed

profiles/openshift/tuned.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ vm.max_map_count=262144
3333
# see rhbz#1979352; exclude containers from aligning to house keeping CPUs
3434
cgroup_ps_blacklist=/kubepods\.slice/
3535
# workaround for rhbz#1921738
36-
runtime=0
36+
dynamic=0

tests/beakerlib/Traceback-caused-by-scheduler-plugin-with/runtest.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ rlJournalStart
4343
rlRun "pushd $PROFILE_DIR/test-profile"
4444
cat << EOF > tuned.conf
4545
[scheduler]
46-
runtime=0
46+
dynamic=0
4747
EOF
4848
rlRun "popd"
4949

tuned-main.conf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
daemon = 1
88

99
# Dynamically tune devices, if disabled only static tuning will be used.
10-
dynamic_tuning = 0
10+
dynamic_tuning = 1
11+
12+
# A list of plugins to allow dynamic tuning for. The "dynamic_tuning"
13+
# option must be enabled for this to have any effect. If not set, all
14+
# plugins are allowed to perform dynamic tuning.
15+
dynamic_plugins = scheduler
1116

1217
# How long to sleep before checking for events (in seconds)
1318
# higher number means lower overhead but longer response time.

tuned/plugins/plugin_scheduler.py

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class SchedulerPlugin(base.Plugin):
273273
processes are not processed by the scheduler plug-in.
274274
+
275275
The CPU overhead of the scheduler plugin can be mitigated by using
276-
the scheduler [option]`runtime` option and setting it to `0`. This
276+
the scheduler [option]`dynamic` option and setting it to `0`. This
277277
will completely disable the dynamic scheduler functionality and the
278278
perf events will not be monitored and acted upon. The disadvantage
279279
ot this approach is the procees/thread tuning will be done only at
@@ -283,7 +283,7 @@ class SchedulerPlugin(base.Plugin):
283283
====
284284
----
285285
[scheduler]
286-
runtime=0
286+
dynamic=0
287287
isolated_cores=1,3
288288
----
289289
====
@@ -465,6 +465,10 @@ def supports_static_tuning(cls):
465465

466466
@classmethod
467467
def supports_dynamic_tuning(cls):
468+
return True
469+
470+
@classmethod
471+
def uses_periodic_tuning(cls):
468472
return False
469473

470474
def _calc_mmap_pages(self, mmap_pages):
@@ -482,10 +486,6 @@ def _calc_mmap_pages(self, mmap_pages):
482486
def _instance_init(self, instance):
483487
super(SchedulerPlugin, self)._instance_init(instance)
484488
instance._evlist = None
485-
# this is hack, runtime_tuning should be covered by dynamic_tuning configuration
486-
# TODO: add per plugin dynamic tuning configuration and use dynamic_tuning configuration
487-
# instead of runtime_tuning
488-
instance._runtime_tuning = True
489489

490490
# FIXME: do we want to do this here?
491491
# recover original values in case of crash
@@ -510,42 +510,44 @@ def _instance_init(self, instance):
510510
instance._scheduler = instance.options
511511

512512
perf_mmap_pages_raw = self._variables.expand(instance.options["perf_mmap_pages"])
513-
perf_mmap_pages = self._calc_mmap_pages(perf_mmap_pages_raw)
514-
if perf_mmap_pages == 0:
513+
instance._perf_mmap_pages = self._calc_mmap_pages(perf_mmap_pages_raw)
514+
if instance._perf_mmap_pages == 0:
515515
log.error("Invalid 'perf_mmap_pages' value specified: '%s', using default kernel value" % perf_mmap_pages_raw)
516-
perf_mmap_pages = None
517-
if perf_mmap_pages is not None and str(perf_mmap_pages) != perf_mmap_pages_raw:
516+
instance._perf_mmap_pages = None
517+
if instance._perf_mmap_pages is not None and str(instance._perf_mmap_pages) != perf_mmap_pages_raw:
518518
log.info("'perf_mmap_pages' value has to be power of two, specified: '%s', using: '%d'" %
519-
(perf_mmap_pages_raw, perf_mmap_pages))
519+
(perf_mmap_pages_raw, instance._perf_mmap_pages))
520520
for k in instance._scheduler:
521521
instance._scheduler[k] = self._variables.expand(instance._scheduler[k])
522-
if self._cmd.get_bool(instance._scheduler.get("runtime", 1)) == "0":
523-
instance._runtime_tuning = False
524-
instance._terminate = threading.Event()
525-
if self._daemon and instance._runtime_tuning:
526-
try:
527-
instance._threads = perf.thread_map()
528-
evsel = perf.evsel(type = perf.TYPE_SOFTWARE,
529-
config = perf.COUNT_SW_DUMMY,
530-
task = 1, comm = 1, mmap = 0, freq = 0,
531-
wakeup_events = 1, watermark = 1,
532-
sample_type = perf.SAMPLE_TID | perf.SAMPLE_CPU)
533-
evsel.open(cpus = self._cpus, threads = instance._threads)
534-
instance._evlist = perf.evlist(self._cpus, instance._threads)
535-
instance._evlist.add(evsel)
536-
if perf_mmap_pages is None:
537-
instance._evlist.mmap()
538-
else:
539-
instance._evlist.mmap(pages = perf_mmap_pages)
540-
# no perf
541-
except:
542-
instance._runtime_tuning = False
543522

544523
def _instance_cleanup(self, instance):
545524
if instance._evlist:
546525
for fd in instance._evlist.get_pollfd():
547526
os.close(fd.name)
548527

528+
def _instance_init_dynamic(self, instance):
529+
super(SchedulerPlugin, self)._instance_init_dynamic(instance)
530+
instance._terminate = threading.Event()
531+
try:
532+
instance._threads = perf.thread_map()
533+
evsel = perf.evsel(type = perf.TYPE_SOFTWARE,
534+
config = perf.COUNT_SW_DUMMY,
535+
task = 1, comm = 1, mmap = 0, freq = 0,
536+
wakeup_events = 1, watermark = 1,
537+
sample_type = perf.SAMPLE_TID | perf.SAMPLE_CPU)
538+
evsel.open(cpus = self._cpus, threads = instance._threads)
539+
instance._evlist = perf.evlist(self._cpus, instance._threads)
540+
instance._evlist.add(evsel)
541+
if instance._perf_mmap_pages is None:
542+
instance._evlist.mmap()
543+
else:
544+
instance._evlist.mmap(pages = instance._perf_mmap_pages)
545+
instance._thread = threading.Thread(target = self._thread_code, args = [instance])
546+
instance._thread.start()
547+
# no perf
548+
except Exception:
549+
instance._dynamic_tuning_enabled = False
550+
549551
@classmethod
550552
def _get_config_options(cls):
551553
return {
@@ -949,7 +951,7 @@ def _instance_apply_static(self, instance):
949951
and len(vals) == 5]
950952
sched_cfg = sorted(buf, key=lambda option_vals: option_vals[1][0])
951953
sched_all = dict()
952-
# for runtime tuning
954+
# for dynamic tuning
953955
instance._sched_lookup = {}
954956
for option, (rule_prio, scheduler, priority, affinity, regex) \
955957
in sched_cfg:
@@ -973,9 +975,6 @@ def _instance_apply_static(self, instance):
973975
priority, affinity)
974976
self._storage.set(self._scheduler_storage_key,
975977
self._scheduler_original)
976-
if self._daemon and instance._runtime_tuning:
977-
instance._thread = threading.Thread(target = self._thread_code, args = [instance])
978-
instance._thread.start()
979978

980979
def _restore_ps_affinity(self):
981980
try:
@@ -1020,9 +1019,6 @@ def _cgroup_cleanup_tasks(self):
10201019

10211020
def _instance_unapply_static(self, instance, rollback = consts.ROLLBACK_SOFT):
10221021
super(SchedulerPlugin, self)._instance_unapply_static(instance, rollback)
1023-
if self._daemon and instance._runtime_tuning:
1024-
instance._terminate.set()
1025-
instance._thread.join()
10261022
self._restore_ps_affinity()
10271023
self._cgroup_restore_affinity()
10281024
self._cgroup_cleanup_tasks()
@@ -1031,6 +1027,10 @@ def _instance_unapply_static(self, instance, rollback = consts.ROLLBACK_SOFT):
10311027
if self._cgroup_mount_point_init:
10321028
self._cgroup_finalize()
10331029

1030+
def _instance_deinit_dynamic(self, instance):
1031+
instance._terminate.set()
1032+
instance._thread.join()
1033+
10341034
def _cgroup_verify_affinity_one(self, cgroup, affinity):
10351035
log.debug("Verifying cgroup '%s' affinity" % cgroup)
10361036
path = "%s/%s/%s" % (self._cgroup_mount_point, cgroup, "cpuset.cpus")

0 commit comments

Comments
 (0)