Compare commits

...

No commits in common. "c8" and "c9-beta" have entirely different histories.
c8 ... c9-beta

11 changed files with 680 additions and 747 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/tuned-2.22.1.tar.gz
SOURCES/tuned-2.25.1.tar.gz

View File

@ -1 +1 @@
60e206fe73ea537e64141f92b331f65879766f97 SOURCES/tuned-2.22.1.tar.gz
2041e65c2e31cd76c60c401bdf538eb4253ea7b4 SOURCES/tuned-2.25.1.tar.gz

View File

@ -1,80 +0,0 @@
diff --git a/profiles/cpu-partitioning/script.sh b/profiles/cpu-partitioning/script.sh
index ec422ca..cb378b7 100755
--- a/profiles/cpu-partitioning/script.sh
+++ b/profiles/cpu-partitioning/script.sh
@@ -2,6 +2,38 @@
. /usr/lib/tuned/functions
+no_balance_cpus_file=$STORAGE/no-balance-cpus.txt
+
+change_sd_balance_bit()
+{
+ local set_bit=$1
+ local flags_cur=
+ local file=
+ local cpu=
+
+ for cpu in $(cat $no_balance_cpus_file); do
+ for file in $(find /proc/sys/kernel/sched_domain/cpu$cpu -name flags -print); do
+ flags_cur=$(cat $file)
+ if [ $set_bit -eq 1 ]; then
+ flags_cur=$((flags_cur | 0x1))
+ else
+ flags_cur=$((flags_cur & 0xfffe))
+ fi
+ echo $flags_cur > $file
+ done
+ done
+}
+
+disable_balance_domains()
+{
+ change_sd_balance_bit 0
+}
+
+enable_balance_domains()
+{
+ change_sd_balance_bit 1
+}
+
start() {
mkdir -p "${TUNED_tmpdir}/etc/systemd"
mkdir -p "${TUNED_tmpdir}/usr/lib/dracut/hooks/pre-udev"
@@ -9,6 +41,9 @@ start() {
cp 00-tuned-pre-udev.sh "${TUNED_tmpdir}/usr/lib/dracut/hooks/pre-udev/"
setup_kvm_mod_low_latency
disable_ksm
+
+ echo "$TUNED_no_balance_cores_expanded" | sed 's/,/ /g' > $no_balance_cpus_file
+ disable_balance_domains
return "$?"
}
@@ -18,6 +53,7 @@ stop() {
teardown_kvm_mod_low_latency
enable_ksm
fi
+ enable_balance_domains
return "$?"
}
diff --git a/profiles/cpu-partitioning/tuned.conf b/profiles/cpu-partitioning/tuned.conf
index 11f03cf..a682c9c 100644
--- a/profiles/cpu-partitioning/tuned.conf
+++ b/profiles/cpu-partitioning/tuned.conf
@@ -35,8 +35,6 @@ no_balance_cores_expanded=${f:cpulist_unpack:${no_balance_cores}}
# Fail if isolated_cores contains CPUs which are not online
assert2=${f:assertion:isolated_cores contains online CPU(s):${isolated_cores_expanded}:${isolated_cores_online_expanded}}
-cmd_isolcpus=${f:regex_search_ternary:${no_balance_cores}:\s*[0-9]: isolcpus=${no_balance_cores}:}
-
[sysfs]
/sys/bus/workqueue/devices/writeback/cpumask = ${not_isolated_cpumask}
/sys/devices/virtual/workqueue/cpumask = ${not_isolated_cpumask}
@@ -62,4 +60,4 @@ priority=10
initrd_remove_dir=True
initrd_dst_img=tuned-initrd.img
initrd_add_dir=${tmpdir}
-cmdline_cpu_part=+nohz=on${cmd_isolcpus} nohz_full=${isolated_cores} rcu_nocbs=${isolated_cores} tuned.non_isolcpus=${not_isolated_cpumask} intel_pstate=disable nosoftlockup
+cmdline_cpu_part=+nohz=on nohz_full=${isolated_cores} rcu_nocbs=${isolated_cores} tuned.non_isolcpus=${not_isolated_cpumask} intel_pstate=disable nosoftlockup

View File

@ -1,118 +0,0 @@
diff --git a/tuned/consts.py b/tuned/consts.py
index 3749363..3b41ed9 100644
--- a/tuned/consts.py
+++ b/tuned/consts.py
@@ -1,4 +1,8 @@
import logging
+import string
+
+NAMES_ALLOWED_CHARS = string.ascii_letters + string.digits + " !@'+-.,/:;_$&*()%<=>?#[]{|}^~" + '"'
+NAMES_MAX_LENGTH = 4096
GLOBAL_CONFIG_FILE = "/etc/tuned/tuned-main.conf"
ACTIVE_PROFILE_FILE = "/etc/tuned/active_profile"
diff --git a/tuned/daemon/controller.py b/tuned/daemon/controller.py
index 6a59a1d..94e9022 100644
--- a/tuned/daemon/controller.py
+++ b/tuned/daemon/controller.py
@@ -182,6 +182,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
def switch_profile(self, profile_name, caller = None):
if caller == "":
return (False, "Unauthorized")
+ if not self._cmd.is_valid_name(profile_name):
+ return (False, "Invalid profile_name")
return self._switch_profile(profile_name, True)
@exports.export("", "(bs)")
@@ -255,8 +257,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
@exports.export("s", "(bsss)")
def profile_info(self, profile_name, caller = None):
- if caller == "":
- return tuple(False, "", "", "")
+ if caller == "" or not self._cmd.is_valid_name(profile_name):
+ return (False, "", "", "")
if profile_name is None or profile_name == "":
profile_name = self.active_profile()
return tuple(self._daemon.profile_loader.profile_locator.get_profile_attrs(profile_name, [consts.PROFILE_ATTR_SUMMARY, consts.PROFILE_ATTR_DESCRIPTION], [""]))
@@ -287,7 +289,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
dictionary -- {plugin_name: {parameter_name: default_value}}
"""
if caller == "":
- return False
+ return {}
plugins = {}
for plugin_class in self._daemon.get_all_plugins():
plugin_name = plugin_class.__module__.split(".")[-1].split("_", 1)[1]
@@ -300,8 +302,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
@exports.export("s","s")
def get_plugin_documentation(self, plugin_name, caller = None):
"""Return docstring of plugin's class"""
- if caller == "":
- return False
+ if caller == "" or not self._cmd.is_valid_name(plugin_name):
+ return ""
return self._daemon.get_plugin_documentation(str(plugin_name))
@exports.export("s","a{ss}")
@@ -314,8 +316,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
Return:
dictionary -- {parameter_name: hint}
"""
- if caller == "":
- return False
+ if caller == "" or not self._cmd.is_valid_name(plugin_name):
+ return {}
return self._daemon.get_plugin_hints(str(plugin_name))
@exports.export("s", "b")
@@ -328,7 +330,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
Return:
bool -- True on success
"""
- if caller == "":
+ if caller == "" or not self._cmd.is_valid_name(path):
return False
if self._daemon._application and self._daemon._application._unix_socket_exporter:
self._daemon._application._unix_socket_exporter.register_signal_path(path)
@@ -342,6 +344,10 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
def instance_acquire_devices(self, devices, instance_name, caller = None):
if caller == "":
return (False, "Unauthorized")
+ if not self._cmd.is_valid_name(devices):
+ return (False, "Invalid devices")
+ if not self._cmd.is_valid_name(instance_name):
+ return (False, "Invalid instance_name")
found = False
for instance_target in self._daemon._unit_manager.instances:
if instance_target.name == instance_name:
@@ -388,6 +394,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
"""
if caller == "":
return (False, "Unauthorized", [])
+ if not self._cmd.is_valid_name(plugin_name):
+ return (False, "Invalid plugin_name", [])
if plugin_name != "" and plugin_name not in self.get_all_plugins().keys():
rets = "Plugin '%s' does not exist" % plugin_name
log.error(rets)
@@ -411,6 +419,8 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
"""
if caller == "":
return (False, "Unauthorized", [])
+ if not self._cmd.is_valid_name(instance_name):
+ return (False, "Invalid instance_name", [])
for instance in self._daemon._unit_manager.instances:
if instance.name == instance_name:
return (True, "OK", sorted(list(instance.processed_devices)))
diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
index ce51fc0..38d95ef 100644
--- a/tuned/utils/commands.py
+++ b/tuned/utils/commands.py
@@ -544,3 +544,7 @@ class commands:
import string
trans = string.maketrans(source_chars, dest_chars)
return text.translate(trans)
+
+ # Checks if name contains only valid characters and has valid length or is empty string or None
+ def is_valid_name(self, name):
+ return not name or (all(c in consts.NAMES_ALLOWED_CHARS for c in name) and len(name) <= consts.NAMES_MAX_LENGTH)

View File

@ -1,88 +0,0 @@
diff --git a/profiles/latency-performance/tuned.conf b/profiles/latency-performance/tuned.conf
index 1dec690..e592138 100644
--- a/profiles/latency-performance/tuned.conf
+++ b/profiles/latency-performance/tuned.conf
@@ -35,3 +35,17 @@ vm.dirty_background_ratio=3
# 100 tells the kernel to aggressively swap processes out of physical memory
# and move them to swap cache
vm.swappiness=10
+
+[scheduler]
+runtime=0
+# ktune sysctl settings for rhel6 servers, maximizing i/o throughput
+#
+# Minimal preemption granularity for CPU-bound tasks:
+# (default: 1 msec# (1 + ilog(ncpus)), units: nanoseconds)
+sched_min_granularity_ns = 3000000
+sched_wakeup_granularity_ns = 4000000
+
+# The total time the scheduler will consider a migrated process
+# "cache hot" and thus less likely to be re-migrated
+# (system default is 500000, i.e. 0.5 ms)
+sched_migration_cost_ns = 5000000
diff --git a/profiles/sap-hana/tuned.conf b/profiles/sap-hana/tuned.conf
index aeecf53..1b15ea3 100644
--- a/profiles/sap-hana/tuned.conf
+++ b/profiles/sap-hana/tuned.conf
@@ -20,3 +20,8 @@ kernel.numa_balancing = 0
vm.dirty_ratio = 40
vm.dirty_background_ratio = 10
vm.swappiness = 10
+
+[scheduler]
+runtime=0
+sched_min_granularity_ns = 3000000
+sched_wakeup_granularity_ns = 4000000
diff --git a/profiles/throughput-performance/tuned.conf b/profiles/throughput-performance/tuned.conf
index e4e832f..3d9c42f 100644
--- a/profiles/throughput-performance/tuned.conf
+++ b/profiles/throughput-performance/tuned.conf
@@ -67,9 +67,33 @@ vm.swappiness=10
# on older kernels
net.core.somaxconn=>2048
+[scheduler]
+runtime=0
+# ktune sysctl settings for rhel6 servers, maximizing i/o throughput
+#
+# Minimal preemption granularity for CPU-bound tasks:
+# (default: 1 msec# (1 + ilog(ncpus)), units: nanoseconds)
+sched_min_granularity_ns = 10000000
+
+# SCHED_OTHER wake-up granularity.
+# (default: 1 msec# (1 + ilog(ncpus)), units: nanoseconds)
+#
+# This option delays the preemption effects of decoupled workloads
+# and reduces their over-scheduling. Synchronous workloads will still
+# have immediate wakeup/sleep latencies.
+sched_wakeup_granularity_ns = 15000000
+
# Marvell ThunderX
[sysctl.thunderx]
type=sysctl
uname_regex=aarch64
cpuinfo_regex=${thunderx_cpuinfo_regex}
kernel.numa_balancing=0
+
+# AMD
+[scheduler.amd]
+type=scheduler
+uname_regex=x86_64
+cpuinfo_regex=${amd_cpuinfo_regex}
+runtime=0
+sched_migration_cost_ns=5000000
diff --git a/profiles/virtual-host/tuned.conf b/profiles/virtual-host/tuned.conf
index 5301d9f..24d0fb4 100644
--- a/profiles/virtual-host/tuned.conf
+++ b/profiles/virtual-host/tuned.conf
@@ -14,3 +14,10 @@ vm.dirty_background_ratio = 5
[cpu]
# Setting C3 state sleep mode/power savings
force_latency=cstate.id_no_zero:3|70
+
+[scheduler]
+runtime=0
+# The total time the scheduler will consider a migrated process
+# "cache hot" and thus less likely to be re-migrated
+# (system default is 500000, i.e. 0.5 ms)
+sched_migration_cost_ns = 5000000

View File

@ -1,11 +0,0 @@
diff --git a/profiles/postgresql/tuned.conf b/profiles/postgresql/tuned.conf
index 88da8e4..4fd3810 100644
--- a/profiles/postgresql/tuned.conf
+++ b/profiles/postgresql/tuned.conf
@@ -55,3 +55,6 @@ sched_min_granularity_ns = 10000000
# "cache hot" and thus less likely to be re-migrated
# (system default is 500000, i.e. 0.5 ms)
sched_migration_cost_ns = 50000000
+
+[scheduler.amd]
+enabled=false

View File

@ -1,54 +0,0 @@
From 7557cf975282326cdbfe55b7b803d8075ff37cba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
Date: Tue, 12 Mar 2024 20:25:43 +0100
Subject: [PATCH] epyc-eda: added new profile for EDA compute workloads on AMD
EPYC CPUs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
---
man/tuned-profiles.7 | 4 ++++
profiles/epyc-eda/tuned.conf | 14 ++++++++++++++
2 files changed, 18 insertions(+)
create mode 100644 profiles/epyc-eda/tuned.conf
diff --git a/man/tuned-profiles.7 b/man/tuned-profiles.7
index 10cad7b..600e8bb 100644
--- a/man/tuned-profiles.7
+++ b/man/tuned-profiles.7
@@ -141,6 +141,10 @@ profiles (e.g. throughput\-performance profile), example:
Profile optimized for AWS EC2 instances. It is based on the
throughput\-performance profile.
+.TP
+.BI "epyc-eda"
+Profile optimized for EDA compute workloads on AMD EPYC CPUs.
+
.SH "FILES"
.nf
.I /etc/tuned/*
diff --git a/profiles/epyc-eda/tuned.conf b/profiles/epyc-eda/tuned.conf
new file mode 100644
index 0000000..482d404
--- /dev/null
+++ b/profiles/epyc-eda/tuned.conf
@@ -0,0 +1,14 @@
+#
+# tuned configuration
+#
+
+[main]
+summary=Optimize for EDA compute workloads on AMD EPYC CPUs
+description=Configures virtual memory, CPU governors, and network settings for EDA compute workloads.
+include=throughput-performance
+
+# AMD
+[scheduler.amd]
+type=scheduler
+#Allow processes to rapidly move between cores to avoid idle time and maximize CPU usage
+sched_migration_cost_ns=10000
--
2.44.0

View File

@ -1,28 +0,0 @@
From 04ead944fdf640ed986331179e533542efc934c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
Date: Mon, 8 Apr 2024 11:03:47 +0200
Subject: [PATCH] sap-netweaver: increased vm.max_map_count
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: RHEL-31757
Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
---
profiles/sap-netweaver/tuned.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/profiles/sap-netweaver/tuned.conf b/profiles/sap-netweaver/tuned.conf
index a1cfd17..81c4d44 100644
--- a/profiles/sap-netweaver/tuned.conf
+++ b/profiles/sap-netweaver/tuned.conf
@@ -10,4 +10,4 @@ include=throughput-performance
kernel.sem = 32000 1024000000 500 32000
kernel.shmall = 18446744073692774399
kernel.shmmax = 18446744073692774399
-vm.max_map_count = 2000000
+vm.max_map_count = 2147483647
--
2.44.0

View File

@ -1,97 +0,0 @@
diff --git a/tuned/plugins/plugin_disk.py b/tuned/plugins/plugin_disk.py
index 1438e35..d6feb06 100644
--- a/tuned/plugins/plugin_disk.py
+++ b/tuned/plugins/plugin_disk.py
@@ -100,19 +100,20 @@ class DiskPlugin(hotplug.Plugin):
self._devices_supported = True
self._use_hdparm = True
self._free_devices = set()
- self._hdparm_apm_devices = set()
+ self._hdparm_apm_device_support = dict()
for device in self._hardware_inventory.get_devices("block"):
if self._device_is_supported(device):
self._free_devices.add(device.sys_name)
- if self._use_hdparm and self._is_hdparm_apm_supported(device.sys_name):
- self._hdparm_apm_devices.add(device.sys_name)
-
self._assigned_devices = set()
def _get_device_objects(self, devices):
return [self._hardware_inventory.get_device("block", x) for x in devices]
def _is_hdparm_apm_supported(self, device):
+ if not self._use_hdparm:
+ return False
+ if device in self._hdparm_apm_device_support:
+ return self._hdparm_apm_device_support[device]
(rc, out, err_msg) = self._cmd.execute(["hdparm", "-C", "/dev/%s" % device], \
no_errors = [errno.ENOENT], return_err=True)
if rc == -errno.ENOENT:
@@ -122,10 +123,13 @@ class DiskPlugin(hotplug.Plugin):
elif rc:
log.info("Device '%s' not supported by hdparm" % device)
log.debug("(rc: %s, msg: '%s')" % (rc, err_msg))
+ self._hdparm_apm_device_support[device] = False
return False
elif "unknown" in out:
log.info("Driver for device '%s' does not support apm command" % device)
+ self._hdparm_apm_device_support[device] = False
return False
+ self._hdparm_apm_device_support[device] = True
return True
@classmethod
@@ -232,7 +236,7 @@ class DiskPlugin(hotplug.Plugin):
return not "standby" in out and not "sleeping" in out
def _instance_update_dynamic(self, instance, device):
- if not device in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
return
load = instance._load_monitor.get_device_load(device)
if load is None:
@@ -315,7 +319,7 @@ class DiskPlugin(hotplug.Plugin):
# At the moment we support dynamic tuning just for devices compatible with hdparm apm commands
# If in future will be added new functionality not connected to this command,
# it is needed to change it here
- if device not in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
log.info("There is no dynamic tuning available for device '%s' at time" % device)
else:
super(DiskPlugin, self)._instance_apply_dynamic(instance, device)
@@ -350,7 +354,7 @@ class DiskPlugin(hotplug.Plugin):
@command_set("apm", per_device=True)
def _set_apm(self, value, device, sim, remove):
- if device not in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
if not sim:
log.info("apm option is not supported for device '%s'" % device)
return None
@@ -366,7 +370,7 @@ class DiskPlugin(hotplug.Plugin):
@command_get("apm")
def _get_apm(self, device, ignore_missing=False):
- if device not in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
if not ignore_missing:
log.info("apm option is not supported for device '%s'" % device)
return None
@@ -390,7 +394,7 @@ class DiskPlugin(hotplug.Plugin):
@command_set("spindown", per_device=True)
def _set_spindown(self, value, device, sim, remove):
- if device not in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
if not sim:
log.info("spindown option is not supported for device '%s'" % device)
return None
@@ -406,7 +410,7 @@ class DiskPlugin(hotplug.Plugin):
@command_get("spindown")
def _get_spindown(self, device, ignore_missing=False):
- if device not in self._hdparm_apm_devices:
+ if not self._is_hdparm_apm_supported(device):
if not ignore_missing:
log.info("spindown option is not supported for device '%s'" % device)
return None

View File

@ -0,0 +1,187 @@
diff --git a/doc/manual/modules/performance/con_inheritance-between-tuned-profiles.adoc b/doc/manual/modules/performance/con_inheritance-between-tuned-profiles.adoc
index f5ff98a..2662c29 100644
--- a/doc/manual/modules/performance/con_inheritance-between-tuned-profiles.adoc
+++ b/doc/manual/modules/performance/con_inheritance-between-tuned-profiles.adoc
@@ -15,7 +15,7 @@ include=[replaceable]_parent_
All settings from the [replaceable]_parent_ profile are loaded in this _child_ profile. In the following sections, the _child_ profile can override certain settings inherited from the [replaceable]_parent_ profile or add new settings not present in the [replaceable]_parent_ profile.
-You can create your own _child_ profile in the [filename]`/etc/tuned/profiles/` directory based on a pre-installed profile in [filename]`/usr/lib/tuned/profiles/` with only some parameters adjusted.
+You can create your own _child_ profile in the [filename]`/etc/tuned/` directory based on a pre-installed profile in [filename]`/usr/lib/tuned/` with only some parameters adjusted.
If the [replaceable]_parent_ profile is updated, such as after a *TuneD* upgrade, the changes are reflected in the _child_ profile.
diff --git a/doc/manual/modules/performance/con_the-location-of-tuned-profiles.adoc b/doc/manual/modules/performance/con_the-location-of-tuned-profiles.adoc
index 4cd35b3..678ff6a 100644
--- a/doc/manual/modules/performance/con_the-location-of-tuned-profiles.adoc
+++ b/doc/manual/modules/performance/con_the-location-of-tuned-profiles.adoc
@@ -5,17 +5,17 @@
[role="_abstract"]
*TuneD* stores profiles in the following directories:
-[filename]`/usr/lib/tuned/profiles/`::
-Distribution-specific profiles are stored in the [filename]`/usr/lib/tuned/profiles/` directory. Each profile has its own directory. The profile consists of the main configuration file called `tuned.conf`, and optionally other files, for example helper scripts.
+[filename]`/usr/lib/tuned/`::
+Distribution-specific profiles are stored in the [filename]`/usr/lib/tuned/` directory. Each profile has its own directory. The profile consists of the main configuration file called `tuned.conf`, and optionally other files, for example helper scripts.
-[filename]`/etc/tuned/profiles/`::
-If you need to customize a profile, copy the profile directory into the [filename]`/etc/tuned/profiles/` directory, which is used for custom profiles, and then adjust it. If there is a system profile and a custom profile of the same name, the custom profile located in [filename]`/etc/tuned/profiles` is used.
+[filename]`/etc/tuned/`::
+If you need to customize a profile, copy the profile directory into the [filename]`/etc/tuned/` directory, which is used for custom profiles, and then adjust it. If there is a system profile and a custom profile of the same name, the custom profile located in [filename]`/etc/tuned/` is used.
.User-defined profile directories
====
-If you want to make TuneD load profiles from a directory other than [filename]`/usr/lib/tuned/profiles/` and [filename]`/etc/tuned/profiles/`, you can list it in [filename]`/etc/tuned/tuned-main.conf` as follows:
+If you want to make TuneD load profiles from a directory other than [filename]`/usr/lib/tuned/` and [filename]`/etc/tuned/`, you can list it in [filename]`/etc/tuned/tuned-main.conf` as follows:
----
-profile_dirs=/usr/lib/tuned/profiles,/etc/tuned/profiles,/my/custom/profiles
+profile_dirs=/usr/lib/tuned,/etc/tuned,/my/custom/profiles
----
In this example, profiles are loaded also from [filename]`/my/custom/profiles/`. If two directories contain profiles with the same names, the one that is listed later takes precedence.
====
diff --git a/doc/manual/modules/performance/proc_creating-new-tuned-profiles.adoc b/doc/manual/modules/performance/proc_creating-new-tuned-profiles.adoc
index 7f7c75f..5c83a4c 100644
--- a/doc/manual/modules/performance/proc_creating-new-tuned-profiles.adoc
+++ b/doc/manual/modules/performance/proc_creating-new-tuned-profiles.adoc
@@ -17,11 +17,11 @@ endif::[]
.Procedure
-. In the [filename]`/etc/tuned/profiles/` directory, create a new directory named the same as the profile that you want to create:
+. In the [filename]`/etc/tuned/` directory, create a new directory named the same as the profile that you want to create:
+
[subs="quotes"]
----
-# mkdir /etc/tuned/profiles/[replaceable]_my-profile_
+# mkdir /etc/tuned/[replaceable]_my-profile_
----
. In the new directory, create a file named [filename]`tuned.conf`. Add a `[main]` section and plug-in definitions in it, according to your requirements.
diff --git a/doc/manual/modules/performance/proc_modifying-existing-tuned-profiles.adoc b/doc/manual/modules/performance/proc_modifying-existing-tuned-profiles.adoc
index 8134030..9ed5d0b 100644
--- a/doc/manual/modules/performance/proc_modifying-existing-tuned-profiles.adoc
+++ b/doc/manual/modules/performance/proc_modifying-existing-tuned-profiles.adoc
@@ -17,11 +17,11 @@ endif::[]
.Procedure
-. In the [filename]`/etc/tuned/profiles/` directory, create a new directory named the same as the profile that you want to create:
+. In the [filename]`/etc/tuned/` directory, create a new directory named the same as the profile that you want to create:
+
[subs="quotes"]
----
-# mkdir /etc/tuned/profiles/[replaceable]_modified-profile_
+# mkdir /etc/tuned/[replaceable]_modified-profile_
----
. In the new directory, create a file named [filename]`tuned.conf`, and set the `[main]` section as follows:
@@ -75,13 +75,13 @@ See TuneD log file ('/var/log/tuned/tuned.log') for details.
----
// .An alternative approach
-// . Alternatively, copy the directory with a system profile from /usr/lib/tuned/profiles/ to /etc/tuned/profiles/. For example:
+// . Alternatively, copy the directory with a system profile from /user/lib/tuned/ to /etc/tuned/. For example:
// +
// ----
-// # cp -r /usr/lib/tuned/profiles/throughput-performance /etc/tuned/profiles
+// # cp -r /usr/lib/tuned/throughput-performance /etc/tuned
// ----
//
-// . Then, edit the profile in /etc/tuned/profiles/ according to your needs. Note that if there are two profiles of the same name, the profile located in /etc/tuned/profiles/ is loaded. The disadvantage of this approach is that if a system profile is updated after a TuneD upgrade, the changes will not be reflected in the now-outdated modified version.
+// . Then, edit the profile in /etc/tuned according to your needs. Note that if there are two profiles of the same name, the profile located in /etc/tuned/ is loaded. The disadvantage of this approach is that if a system profile is updated after a TuneD upgrade, the changes will not be reflected in the now-outdated modified version.
[role="_additional-resources"]
.Additional resources
diff --git a/doc/manual/modules/performance/proc_setting-the-disk-scheduler-using-tuned.adoc b/doc/manual/modules/performance/proc_setting-the-disk-scheduler-using-tuned.adoc
index c4c5a3c..d66f261 100644
--- a/doc/manual/modules/performance/proc_setting-the-disk-scheduler-using-tuned.adoc
+++ b/doc/manual/modules/performance/proc_setting-the-disk-scheduler-using-tuned.adoc
@@ -58,7 +58,7 @@ $ tuned-adm active
+
[subs="quotes"]
----
-# mkdir /etc/tuned/profiles/[replaceable]__my-profile__
+# mkdir /etc/tuned/[replaceable]__my-profile__
----
. Find the system unique identifier of the selected block device:
@@ -77,7 +77,7 @@ ID_SERIAL_SHORT=_20120501030900000_
The command in the this example will return all values identified as a World Wide Name (WWN) or serial number associated with the specified block device. Although it is preferred to use a WWN, the WWN is not always available for a given device and any values returned by the example command are acceptable to use as the _device system unique ID_.
====
-. Create the `/etc/tuned/profiles/[replaceable]_my-profile_/tuned.conf` configuration file. In the file, set the following options:
+. Create the `/etc/tuned/_my-profile_/tuned.conf` configuration file. In the file, set the following options:
.. Optional: Include an existing profile:
+
diff --git a/man/tuned-adm.8 b/man/tuned-adm.8
index 972f8b6..f29966d 100644
--- a/man/tuned-adm.8
+++ b/man/tuned-adm.8
@@ -31,8 +31,8 @@ This command line utility allows you to switch between user definable tuning
profiles. Several predefined profiles are already included. You can even
create your own profile, either based on one of the existing ones by copying
it or make a completely new one. The distribution provided profiles are stored
-in subdirectories below \fI/usr/lib/tuned/profiles/\fP and the user defined profiles in
-subdirectories below \fI/etc/tuned/profiles/\fP. If there are profiles with the same name
+in subdirectories below \fI/usr/lib/tuned\fP and the user defined profiles in
+subdirectories below \fI/etc/tuned\fP. If there are profiles with the same name
in both places, user defined profiles have precedence.
.SH "OPTIONS"
diff --git a/man/tuned-profiles.7 b/man/tuned-profiles.7
index 1fc8b6b..6bd98a5 100644
--- a/man/tuned-profiles.7
+++ b/man/tuned-profiles.7
@@ -30,9 +30,9 @@ performance optimizations but there are also profiles targeted to
low power consumption, low latency and others. You can mostly deduce the
purpose of the profile by its name or you can see full description below.
-The profiles are stored in subdirectories below \fI/usr/lib/tuned/profiles/\fP. If you
-need to customize the profiles, you can copy them to \fI/etc/tuned/profiles/\fP and modify
-them as you need. When loading profiles with the same name, \fI/etc/tuned/profiles/\fP takes
+The profiles are stored in subdirectories below \fI/usr/lib/tuned\fP. If you
+need to customize the profiles, you can copy them to \fI/etc/tuned\fP and modify
+them as you need. When loading profiles with the same name, the /etc/tuned takes
precedence. In such case you will not lose your customized profiles between
TuneD updates.
@@ -150,8 +150,8 @@ throughput\-performance profile.
.SH "FILES"
.nf
-.I /etc/tuned/profiles/*
-.I /usr/lib/tuned/profiles/*
+.I /etc/tuned/*
+.I /usr/lib/tuned/*
.SH "SEE ALSO"
.BR tuned (8)
diff --git a/man/tuned.conf.5 b/man/tuned.conf.5
index c319130..464b6be 100644
--- a/man/tuned.conf.5
+++ b/man/tuned.conf.5
@@ -3,8 +3,8 @@
tuned.conf - TuneD profile definition
.SH DESCRIPTION
This man page documents format of TuneD 2.0 profile definition files.
-The profile definition is stored in /etc/tuned/profiles/<profile_name>/tuned.conf or in
-/usr/lib/tuned/profiles/<profile_name>/tuned.conf file where the /etc/tuned/profiles/ directory has
+The profile definition is stored in /etc/tuned/<profile_name>/tuned.conf or in
+/usr/lib/tuned/<profile_name>/tuned.conf file where the /etc/tuned/ directory has
higher priority.
The \fBtuned.conf\fR configures the profile and it is in ini-file format.
diff --git a/tuned-adm.bash b/tuned-adm.bash
index 18c716b..a4e6075 100644
--- a/tuned-adm.bash
+++ b/tuned-adm.bash
@@ -9,7 +9,7 @@ _tuned_adm()
if [[ "$cword" -eq 1 ]]; then
COMPREPLY=( $(compgen -W "$commands" -- "$cur" ) )
elif [[ "$cword" -eq 2 && ("$prev" == "profile" || "$prev" == "profile_info") ]]; then
- COMPREPLY=( $(compgen -W "$(command find /usr/lib/tuned/profiles /etc/tuned/profiles -mindepth 1 -maxdepth 1 -type d -printf "%f\n")" -- "$cur" ) )
+ COMPREPLY=( $(compgen -W "$(command find /usr/lib/tuned /etc/tuned -mindepth 1 -maxdepth 1 -type d -printf "%f\n")" -- "$cur" ) )
else
COMPREPLY=()
fi

File diff suppressed because it is too large Load Diff