From 1565138efe31c2db22aad6ccbca953860edbf6ec Mon Sep 17 00:00:00 2001 From: Lemmy Huang Date: Mon, 17 Feb 2025 16:34:11 +0800 Subject: [PATCH 1/2] profiles: add spark-omni Signed-off-by: Lemmy Huang --- profiles/spark-omni/tuned.conf | 17 +++++ tuned-adm.py | 13 ++++ tuned/admin/__init__.py | 1 + tuned/admin/proc.py | 113 +++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 profiles/spark-omni/tuned.conf create mode 100644 tuned/admin/proc.py diff --git a/profiles/spark-omni/tuned.conf b/profiles/spark-omni/tuned.conf new file mode 100644 index 0000000..e8afbb2 --- /dev/null +++ b/profiles/spark-omni/tuned.conf @@ -0,0 +1,17 @@ +# +# tuned configuration +# + +[main] +summary=Optimize for spark-omni +include=latency-performance + +[vm] +uname_regex=aarch64 +transparent_hugepages=never +transparent_hugepage.defrag=never + +[scheduler] +uname_regex=aarch64 +sched_features=BOUND_NUMA +proc.bound=1 diff --git a/tuned-adm.py b/tuned-adm.py index de0c39e..16cd135 100755 --- a/tuned-adm.py +++ b/tuned-adm.py @@ -74,10 +74,12 @@ if __name__ == "__main__": parser_off = subparsers.add_parser("off", help="switch off all tunings") parser_off.set_defaults(action="off") + parser_off.add_argument("--pid", action="store_const", const=0, help="pid") parser_profile = subparsers.add_parser("profile", help="switch to a given profile, or list available profiles if no profile is given") parser_profile.set_defaults(action="profile") parser_profile.add_argument("profiles", metavar="profile", type=str, nargs="*", help="profile name") + parser_profile.add_argument("--pid", metavar="pid", type=int, nargs="?", default=None, help="pid") parser_profile_info = subparsers.add_parser("profile_info", help="show information/description of given profile or current profile if no profile is specified") parser_profile_info.set_defaults(action="profile_info") @@ -128,6 +130,17 @@ if __name__ == "__main__": daemon = config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON) dbus = daemon and config.get_bool(consts.CFG_ENABLE_DBUS, consts.CFG_DEF_ENABLE_DBUS) + profile_names = options.get("profiles") + if "pid" in options: + pid = options.pop("pid") + if pid != None: + if pid < 0: + parser.print_usage(file = sys.stderr) + sys.exit(1) + proc = tuned.admin.Proc(action_name, profile_dirs, profile_names, pid, debug, log_level) + if proc.profile_pid_active(): + sys.exit(0) + try: admin = tuned.admin.Admin(profile_dirs, dbus, debug, asynco, timeout, log_level) diff --git a/tuned/admin/__init__.py b/tuned/admin/__init__.py index 3b476ce..88d1520 100644 --- a/tuned/admin/__init__.py +++ b/tuned/admin/__init__.py @@ -1,3 +1,4 @@ from .admin import * from .exceptions import * from .dbus_controller import * +from .proc import * diff --git a/tuned/admin/proc.py b/tuned/admin/proc.py new file mode 100644 index 0000000..f7534e2 --- /dev/null +++ b/tuned/admin/proc.py @@ -0,0 +1,113 @@ + +import tuned.admin +from tuned.utils.commands import commands +import os +import sys +import logging + +class Proc(object): + CONF_FILE_OFFSET = 1 + CONF_VALUE_OFFSET = 2 + + def __init__(self, action_name, profile_dirs, profile_names, pid=0, + debug = False, log_level = logging.ERROR): + self._cmd = commands(debug) + self._debug = debug + self._log_level = log_level + + self._action_name = action_name + self._profile_dirs = profile_dirs + self._profile_names = profile_names + self._pid = pid + + self._spark_omni_conf = [ + "uname_regex", "", "aarch64", + "proc.bound", "/proc/%d/bound", "0", + "sched_features", "/sys/kernel/debug/sched_features", "NO_BOUND_NUMA", + "transparent_hugepages", "/sys/kernel/mm/transparent_hugepage/enabled", "always", + "transparent_hugepage.defrag", "/sys/kernel/mm/transparent_hugepage/defrag", "madvise", + ] + self._all_proflie_conf = { + "spark-omni" : self._spark_omni_conf + } + + def _log(self, log): + if self._debug: + print("[DEBUG] " + log) + + def _profile_path(self, profile): + for dir in self._profile_dirs: + path = dir + "/%s/tuned.conf" % profile + if os.path.exists(path): + return path + return "" + + def _get_profile(self, profile): + if profile == None: + return None + path = self._profile_path(profile) + if path == "": + return None + + self._log("_get_profile: path %s" % path) + + profile_conf = self._all_proflie_conf[profile] + if self._pid <= 0: + return profile_conf + + # reset uname_regex="" + profile_conf[self.CONF_VALUE_OFFSET] = "" + + with open(path, 'r') as file: + for line in file: + line = line.strip() + if line.startswith('#') or "=" not in line: + continue + key, value = line.split('=', 1) + if key in profile_conf: + i = profile_conf.index(key) + profile_conf[i + self.CONF_VALUE_OFFSET] = value + self._log("_get_profile: %s %s" % (key, value)) + return profile_conf + + def _set_profile(self, profile_conf): + if profile_conf[self.CONF_VALUE_OFFSET] != "aarch64": + return + + for i in range(0, len(profile_conf), self.CONF_VALUE_OFFSET + 1): + f = i + self.CONF_FILE_OFFSET + v = i + self.CONF_VALUE_OFFSET + if "/proc/" in profile_conf[f]: + if self._pid <= 0: + continue + file = profile_conf[f] % self._pid + else: + file = profile_conf[f] + + self._log("_set_profile: %s %s" % (file, profile_conf[v])) + if os.path.exists(file): + self._cmd.write_to_file(file, profile_conf[v]) + return + + def _profile_pid_on(self): + if self._profile_names == None or self._pid <= 0: + return + for profile in self._profile_names: + profile_conf = self._get_profile(profile) + self._set_profile(profile_conf) + return + + def _profile_pid_off(self): + for profile in self._all_proflie_conf: + profile_conf = self._get_profile(profile) + self._set_profile(profile_conf) + return + + def profile_pid_active(self): + is_exit = False; + if self._action_name == "off": + self._profile_pid_off() + elif self._action_name == "profile": + self._profile_pid_on() + is_exit = True; + return is_exit -- 2.33.0