Skip to content

Commit

Permalink
scheduler: Postpone cgroup blacklist check and double-check after fail
Browse files Browse the repository at this point in the history
It may happen that a process gets moved into a blacklisted cgroup
when TuneD is already applying a profile. Postpone the filtering of
processes according to the blacklist to the last possible moment to
minimize the race window.

When setting process affinity fails, re-check whether the process
belongs to a blacklisted cgroup once again and do not report an
error if that's the case.

Resolves: RHEL-72981
  • Loading branch information
zacikpa committed Jan 16, 2025
1 parent 55e272e commit 7113c91
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions tuned/plugins/plugin_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,15 +644,24 @@ def _set_rt(self, pid, sched, prio):
def _is_kthread(self, process):
return process["stat"]["flags"] & procfs.pidstat.PF_KTHREAD != 0

def _process_in_blacklisted_cgroup(self, process):
if self._cgroup_ps_blacklist_re == "":
return False
return re.search(self._cgroup_ps_blacklist_re, self._get_stat_cgroup(process)) is not None

# Returns True if we can ignore a failed affinity change of
# a process with the given PID and therefore not report it as an error.
def _ignore_set_affinity_error(self, pid):
def _ignore_set_affinity_error(self, process):
pid = process.pid
try:
process = procfs.process(pid)
if process["stat"]["state"] == "Z":
log.debug("Affinity of zombie task with PID %d could not be changed."
% pid)
return True
if self._process_in_blacklisted_cgroup(process):
log.debug("Affinity of task with PID %d could not be changed, the task was moved into a blacklisted cgroup."
% pid)
return True
if process["stat"].is_bound_to_cpu():
if self._is_kthread(process):
log.debug("Affinity of kernel thread with PID %d cannot be changed, the task's affinity mask is fixed."
Expand Down Expand Up @@ -1168,13 +1177,17 @@ def _get_affinity(self, pid):
return res

def _set_affinity(self, pid, affinity):
process = procfs.process(pid)
if self._process_in_blacklisted_cgroup(process):
log.debug("Not setting CPU affinity of PID %d, the task belongs to a blacklisted cgroup." % pid)
return
log.debug("Setting CPU affinity of PID %d to '%s'." % (pid, affinity))
try:
self._scheduler_utils.set_affinity(pid, affinity)
# Workaround for old python-schedutils (pre-0.4) which
# incorrectly raised SystemError instead of OSError
except (SystemError, OSError) as e:
if not self._ignore_set_affinity_error(pid):
if not self._ignore_set_affinity_error(process):
log.error("Failed to set affinity of PID %d to '%s': %s"
% (pid, affinity, e))

Expand All @@ -1191,9 +1204,6 @@ def _set_all_obj_affinity(self, objs, affinity, threads = False):
if self._ps_blacklist != "":
psl = [v for v in psl if re.search(self._ps_blacklist,
self._get_stat_comm(v)) is None]
if self._cgroup_ps_blacklist_re != "":
psl = [v for v in psl if re.search(self._cgroup_ps_blacklist_re,
self._get_stat_cgroup(v)) is None]
psd = dict([(v.pid, v) for v in psl])
for pid in psd:
try:
Expand Down

0 comments on commit 7113c91

Please sign in to comment.