From f3a04dde1d95657f1f4c89c49586b93014b66f46 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 26 Apr 2012 09:50:20 +0200 Subject: [PATCH] Introduced dynamic_tuning and static_tunning parts of plugin and stopped useless dynamic_tuning for static-only plugins --- tuned/daemon.py | 2 ++ tuned/plugins/base.py | 24 +++++++++++++++++++----- tuned/plugins/plugin_audio.py | 11 ++++------- tuned/plugins/plugin_cpu.py | 16 +++++++--------- tuned/plugins/plugin_disk.py | 26 +++++++++++--------------- tuned/plugins/plugin_eeepc_she.py | 9 ++++++--- tuned/plugins/plugin_net.py | 16 ++++++++++------ tuned/plugins/plugin_script.py | 18 ++++++++++-------- tuned/plugins/plugin_sysctl.py | 30 +++++++++++++++++++----------- tuned/plugins/plugin_video.py | 11 ++++------- tuned/plugins/plugin_wireless.py | 13 ++++--------- tuned/plugins/repository.py | 11 +++++++++++ 12 files changed, 107 insertions(+), 80 deletions(-) diff --git a/tuned/daemon.py b/tuned/daemon.py index 1cf55d0..0ebf436 100644 --- a/tuned/daemon.py +++ b/tuned/daemon.py @@ -53,6 +53,8 @@ class Daemon(object): self.save_active_profile() + plugins_repo.do_static_tuning() + while not self._terminate.wait(10): log.debug("updating monitors") monitors_repo.update() diff --git a/tuned/plugins/base.py b/tuned/plugins/base.py index fe7abbb..8cdfae9 100644 --- a/tuned/plugins/base.py +++ b/tuned/plugins/base.py @@ -25,14 +25,28 @@ class Plugin(object): # instance methods - def __init__(self, devices = None, options = None): + def __init__(self, devices = [], options = None): self._devices = devices + if not self._devices: + self._devices = [] self._commands = {} self._options = self._get_default_options() self._options["_load_path"] = "" + if not self._options.has_key("dynamic_tuning"): + self._options["dynamic_tuning"] = "1" + if not self._options.has_key("static_tuning"): + self._options["static_tuning"] = "1" if options is not None: self._merge_options(options) + @property + def dynamic_tuning(self): + return self._options["dynamic_tuning"] in ["1", "true"] + + @property + def static_tuning(self): + return self._options["static_tuning"] in ["1", "true"] + #def __del__(self): #try: #self.cleanup() @@ -42,18 +56,18 @@ class Plugin(object): def register_command(self, option, set_fnc, revert_fnc = None, is_per_dev = False): self._commands[option] = (is_per_dev, set_fnc, revert_fnc) - def execute_commands(self, devices = []): + def execute_commands(self): for option, (is_per_dev, set_fnc, revert_fnc) in self._commands.iteritems(): if not self._options.has_key(option): continue if is_per_dev: - for dev in devices: + for dev in self._devices: set_fnc(dev, self._options[option]) else: set_fnc(self._options[option]) - def cleanup_commands(self, devices = []): + def cleanup_commands(self): for option, (is_per_dev, set_fnc, revert_fnc) in self._commands.iteritems(): if not self._options.has_key(option): continue @@ -62,7 +76,7 @@ class Plugin(object): set_fnc = revert_fnc if is_per_dev: - for dev in devices: + for dev in self._devices: set_fnc(dev, None) else: set_fnc(None) diff --git a/tuned/plugins/plugin_audio.py b/tuned/plugins/plugin_audio.py index de40416..24bca7c 100644 --- a/tuned/plugins/plugin_audio.py +++ b/tuned/plugins/plugin_audio.py @@ -17,9 +17,7 @@ class VideoPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) - - self._commands_run = False + super(self.__class__, self).__init__(devices, options) if not tuned.utils.storage.Storage.get_instance().data.has_key(STORAGE_CATEGORY): tuned.utils.storage.Storage.get_instance().data[STORAGE_CATEGORY] = {} @@ -36,15 +34,14 @@ class VideoPlugin(tuned.plugins.Plugin): return { "enable_ac97_powersave" : "", "hda_intel_powersave" : "", + "dynamic_tuning" : "0", } def cleanup(self): - self.cleanup_commands() + pass def update_tuning(self): - if not self._commands_run: - self.execute_commands() - self._commands_run = True + pass @command(STORAGE_CATEGORY, "enable_ac97_powersave") def _set_enable_ac97_powersave(self, value): diff --git a/tuned/plugins/plugin_cpu.py b/tuned/plugins/plugin_cpu.py index 4e844e4..e16314e 100644 --- a/tuned/plugins/plugin_cpu.py +++ b/tuned/plugins/plugin_cpu.py @@ -15,12 +15,14 @@ class CPULatencyPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) + super(self.__class__, self).__init__(devices, options) self._latency = None self._cpu_latency_fd = os.open("/dev/cpu_dma_latency", os.O_WRONLY) - self._load_monitor = tuned.monitors.get_repository().create("load", devices) - self._commands_run = False + + self.dynamic_tuning = None + if self.dynamic_tuning: + self._load_monitor = tuned.monitors.get_repository().create("load", devices) if not tuned.utils.storage.Storage.get_instance().data.has_key("cpu"): tuned.utils.storage.Storage.get_instance().data["cpu"] = {} @@ -47,16 +49,12 @@ class CPULatencyPlugin(tuned.plugins.Plugin): } def cleanup(self): - self.cleanup_commands() - tuned.monitors.get_repository().delete(self._load_monitor) + if self._load_monitor: + tuned.monitors.get_repository().delete(self._load_monitor) os.close(self._cpu_latency_fd) def update_tuning(self): - if not self._commands_run: - self.execute_commands() - self._commands_run = True - load = self._load_monitor.get_load()["system"] if load < self._options["load_threshold"]: self._set_latency(self._options["latency_high"]) diff --git a/tuned/plugins/plugin_disk.py b/tuned/plugins/plugin_disk.py index ea57c62..6e27439 100644 --- a/tuned/plugins/plugin_disk.py +++ b/tuned/plugins/plugin_disk.py @@ -15,17 +15,18 @@ class DiskPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) + super(self.__class__, self).__init__(devices, options) + self.devidle = {} self.stats = {} self.power = ["255", "225", "195", "165", "145", "125", "105", "85", "70", "55", "30", "20"] self.spindown = ["0", "250", "230", "210", "190", "170", "150", "130", "110", "90", "70", "60"] self.levels = len(self.power) - self._elevator_set = False - self._old_elevator = "" - self._load_monitor = tuned.monitors.get_repository().create("disk", devices) + self._load_monitor = None + if self.dynamic_tuning: + self._load_monitor = tuned.monitors.get_repository().create("disk", devices) if not tuned.utils.storage.Storage.get_instance().data.has_key("disk"): tuned.utils.storage.Storage.get_instance().data["disk"] = {} @@ -57,7 +58,7 @@ class DiskPlugin(tuned.plugins.Plugin): def tunable_devices(cls): block_devices = os.listdir("/sys/block") available = set(filter(cls._is_device_supported, block_devices)) - cls._available_devices = available + return available @classmethod def _is_device_supported(cls, device): @@ -120,13 +121,12 @@ class DiskPlugin(tuned.plugins.Plugin): def cleanup(self): log.debug("Cleanup") - tuned.monitors.get_repository().delete(self._load_monitor) + if self._load_monitor: + tuned.monitors.get_repository().delete(self._load_monitor) - for dev in self.devidle.keys(): - if self.devidle[dev]["LEVEL"] > 0: - os.system("hdparm -S0 -B255 /dev/"+dev+" > /dev/null 2>&1") - - self.cleanup_commands(self.devidle.keys()) + for dev in self.devidle.keys(): + if self.devidle[dev]["LEVEL"] > 0: + os.system("hdparm -S0 -B255 /dev/"+dev+" > /dev/null 2>&1") def update_tuning(self): load = self._load_monitor.get_load() @@ -156,10 +156,6 @@ class DiskPlugin(tuned.plugins.Plugin): log.debug("%s load: read %f, write %f" % (dev, self.stats[dev]["read"], self.stats[dev]["write"])) log.debug("%s idle: read %d, write %d, level %d" % (dev, self.devidle[dev]["read"], self.devidle[dev]["write"], self.devidle[dev]["LEVEL"])) - if not self._elevator_set: - self.execute_commands(load.keys()) - self._elevator_set = True - @command("disk", "elevator") def _set_elevator(self, dev, value): sys_file = os.path.join("/sys/block/", dev, "queue/scheduler") diff --git a/tuned/plugins/plugin_eeepc_she.py b/tuned/plugins/plugin_eeepc_she.py index f7b13ef..812dffa 100644 --- a/tuned/plugins/plugin_eeepc_she.py +++ b/tuned/plugins/plugin_eeepc_she.py @@ -13,10 +13,12 @@ class EeePCSHEPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) + super(self.__class__, self).__init__(devices, options) self._she_mode = None - self._load_monitor = tuned.monitors.get_repository().create("load", devices) + self._load_monitor = None + if self.dynamic_tuning: + self._load_monitor = tuned.monitors.get_repository().create("load", devices) @classmethod def is_supported(cls): @@ -36,7 +38,8 @@ class EeePCSHEPlugin(tuned.plugins.Plugin): } def cleanup(self): - tuned.monitors.get_repository().delete(self._load_monitor) + if self._load_monitor: + tuned.monitors.get_repository().delete(self._load_monitor) def update_tuning(self): load = self._load_monitor.get_load()["system"] diff --git a/tuned/plugins/plugin_net.py b/tuned/plugins/plugin_net.py index 7c805aa..5c7beac 100644 --- a/tuned/plugins/plugin_net.py +++ b/tuned/plugins/plugin_net.py @@ -12,12 +12,15 @@ class NetTuningPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) + super(self.__class__, self).__init__(devices, options) self.devidle = {} self.stats = {} log.info("Devices: %s" % str(devices)); - self._load_monitor = tuned.monitors.get_repository().create("net", devices) + + self._load_monitor = None + if self.dynamic_tuning: + self._load_monitor = tuned.monitors.get_repository().create("net", devices) @classmethod def tunable_devices(cls): @@ -76,11 +79,12 @@ class NetTuningPlugin(tuned.plugins.Plugin): def cleanup(self): log.info("Cleanup") - tuned.monitors.get_repository().delete(self._load_monitor) + if self._load_monitor: + tuned.monitors.get_repository().delete(self._load_monitor) - for dev in self.devidle.keys(): - if self.devidle[dev]["LEVEL"] > 0: - ethcard(dev).set_max_speed() + for dev in self.devidle.keys(): + if self.devidle[dev]["LEVEL"] > 0: + ethcard(dev).set_max_speed() def update_tuning(self): load = self._load_monitor.get_load() diff --git a/tuned/plugins/plugin_script.py b/tuned/plugins/plugin_script.py index 28c361a..ec55b9a 100644 --- a/tuned/plugins/plugin_script.py +++ b/tuned/plugins/plugin_script.py @@ -15,8 +15,7 @@ class ScriptPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) - self._updated = False + super(self.__class__, self).__init__(devices, options) self._scripts = [] self._load_ktuned() if self._options["script"].startswith("/"): @@ -28,6 +27,7 @@ class ScriptPlugin(tuned.plugins.Plugin): def _get_default_options(cls): return { "script" : "", + "dynamic_tuning" : "0", } def _load_ktuned(self): @@ -51,12 +51,14 @@ class ScriptPlugin(tuned.plugins.Plugin): log.error("Script %s error: %s" % (script, e)) return True - def cleanup(self): + def execute_commands(self): + self._call_scripts() + + def cleanup_commands(self): self._call_scripts("stop") - def update_tuning(self): - if self._updated: - return + def cleanup(self): + pass - self._updated = True - self._call_scripts() + def update_tuning(self): + pass diff --git a/tuned/plugins/plugin_sysctl.py b/tuned/plugins/plugin_sysctl.py index 6eace81..83fad5d 100644 --- a/tuned/plugins/plugin_sysctl.py +++ b/tuned/plugins/plugin_sysctl.py @@ -16,10 +16,10 @@ class SysctlPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) - self._options = options - self._updated = False + super(self.__class__, self).__init__(devices, options) self._sysctl_original = {} + self._sysctl = options + del self._sysctl["_load_path"] # Set default sysctl from the previously running tuned2 data = tuned.utils.storage.Storage.get_instance().data @@ -30,6 +30,12 @@ class SysctlPlugin(tuned.plugins.Plugin): self._load_ktuned() + @classmethod + def _get_default_options(cls): + return { + "dynamic_tuning" : "0", + } + def _load_ktuned(self): for cfg in glob.glob("/etc/ktune.d/*.conf"): f = open(os.path.join("/etc/ktune.d/", cfg)) @@ -37,7 +43,7 @@ class SysctlPlugin(tuned.plugins.Plugin): if not line.strip().startswith("#") and line.find("=") != -1: k = line.split('=')[0].strip() v = line.split('=')[1].strip() - self._options[k] = v + self._sysctl[k] = v f.close() return True @@ -54,7 +60,7 @@ class SysctlPlugin(tuned.plugins.Plugin): return (proc.returncode, out, err) def _apply_sysctl(self): - for key, value in self._options.iteritems(): + for key, value in self._sysctl.iteritems(): returncode, out, err = self._exec_sysctl(key) if not returncode and len(out.split('=')) == 2: k = out.split('=')[0].strip() @@ -73,12 +79,14 @@ class SysctlPlugin(tuned.plugins.Plugin): for key, value in self._sysctl_original.iteritems(): self._exec_sysctl(key + "=" + value, True) - def cleanup(self): + def cleanup_commands(self): self._revert_sysctl() - def update_tuning(self): - if self._updated: - return - - self._updated = True + def execute_commands(self): self._apply_sysctl() + + def cleanup(self): + pass + + def update_tuning(self): + pass diff --git a/tuned/plugins/plugin_video.py b/tuned/plugins/plugin_video.py index fb8971f..6d8aa15 100644 --- a/tuned/plugins/plugin_video.py +++ b/tuned/plugins/plugin_video.py @@ -17,9 +17,7 @@ class VideoPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) - - self._commands_run = False + super(self.__class__, self).__init__(devices, options) if not tuned.utils.storage.Storage.get_instance().data.has_key(STORAGE_CATEGORY): tuned.utils.storage.Storage.get_instance().data[STORAGE_CATEGORY] = {} @@ -31,16 +29,15 @@ class VideoPlugin(tuned.plugins.Plugin): @classmethod def _get_default_options(cls): return { + "dynamic_tuning" : "0", "radeon_powersave" : "", } def cleanup(self): - self.cleanup_commands() + pass def update_tuning(self): - if not self._commands_run: - self.execute_commands() - self._commands_run = True + pass @command(STORAGE_CATEGORY, "radeon_powersave") def _set_radeon_powersave(self, value): diff --git a/tuned/plugins/plugin_wireless.py b/tuned/plugins/plugin_wireless.py index 1c147ae..15715e8 100644 --- a/tuned/plugins/plugin_wireless.py +++ b/tuned/plugins/plugin_wireless.py @@ -15,9 +15,7 @@ class WirelessPlugin(tuned.plugins.Plugin): def __init__(self, devices, options): """ """ - super(self.__class__, self).__init__(None, options) - - self._commands_run = False + super(self.__class__, self).__init__(devices, options) if not tuned.utils.storage.Storage.get_instance().data.has_key("wireless"): tuned.utils.storage.Storage.get_instance().data["wireless"] = {} @@ -28,19 +26,16 @@ class WirelessPlugin(tuned.plugins.Plugin): @classmethod def _get_default_options(cls): return { + "dynamic_tuning" : "0", "wifi_power_level" : "", "enable_bluetooth" : "", } def cleanup(self): - self.cleanup_commands() + pass def update_tuning(self): - if not self._commands_run: - self.execute_commands() - self._commands_run = True - -# COMMANDS: + pass @command("wireless", "wifi_power_level") def _set_wifi_power_level(self, power_level): diff --git a/tuned/plugins/repository.py b/tuned/plugins/repository.py index 5396b51..fb20da9 100644 --- a/tuned/plugins/repository.py +++ b/tuned/plugins/repository.py @@ -39,13 +39,24 @@ class PluginRepository(tuned.patterns.Singleton): plugin_exception = tuned.plugins.exception.LoadPluginException(plugin_name, exception) raise plugin_exception + def do_static_tuning(self): + for plugin in self._plugins: + if not plugin.static_tuning: + continue + + log.debug("running static tuning for plugin %s" % plugin) + plugin.execute_commands() + def delete(self, plugin): assert isinstance(plugin, self._loader.interface) log.debug("removing plugin %s" % plugin) + plugin.cleanup_commands() plugin.cleanup() self._plugins.remove(plugin) def update(self): for plugin in self._plugins: + if not plugin.dynamic_tuning: + continue log.debug("updating %s" % plugin) plugin.update_tuning()