Skip to content

Commit

Permalink
linux: move reset cpu affinity to scheduler
Browse files Browse the repository at this point in the history
and set it only when there is no exec cpu affinity mask specified.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Nov 25, 2024
1 parent 3760ed9 commit d63c20a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 31 deletions.
15 changes: 0 additions & 15 deletions src/libcrun/cgroup-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,20 +506,5 @@ enter_cgroup (int cgroup_mode, pid_t pid, pid_t init_pid, const char *path,
if (UNLIKELY (ret < 0))
return ret;
}
/* Reset the inherited cpu affinity. Old kernels do that automatically, but
new kernels remember the affinity that was set before the cgroup move.
This is undesirable, because it inherits the systemd affinity when the container
should really move to the container space cpus.
The sched_setaffinity call will always return an error (EINVAL or ENODEV)
when used like this. This is expected and part of the backward compatibility.
See: https://issues.redhat.com/browse/OCPBUGS-15102 */
ret = sched_setaffinity (pid, 0, NULL);
if (LIKELY (ret < 0))
{
if (UNLIKELY (! ((errno == EINVAL) || (errno == ENODEV))))
return crun_make_error (err, errno, "failed to reset affinity");
}
return 0;
}
16 changes: 0 additions & 16 deletions src/libcrun/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,22 +334,6 @@ libcrun_cgroup_enter (struct libcrun_cgroup_args *args, struct libcrun_cgroup_st
return ret;
}
}
/* Reset the inherited cpu affinity. Old kernels do that automatically, but
new kernels remember the affinity that was set before the cgroup move.
This is undesirable, because it inherits the systemd affinity when the container
should really move to the container space cpus.
The sched_setaffinity call will always return an error (EINVAL or ENODEV)
when used like this. This is expected and part of the backward compatibility.
See: https://issues.redhat.com/browse/OCPBUGS-15102 */
ret = sched_setaffinity (args->pid, 0, NULL);
if (LIKELY (ret < 0))
{
if (UNLIKELY (! ((errno == EINVAL) || (errno == ENODEV))))
return crun_make_error (err, errno, "failed to reset affinity");
}

success:
*out = status;
status = NULL;
Expand Down
4 changes: 4 additions & 0 deletions src/libcrun/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -2590,6 +2590,10 @@ libcrun_container_run_internal (libcrun_container_t *container, libcrun_context_
if (UNLIKELY (ret < 0))
goto fail;

ret = libcrun_reset_cpu_affinity_mask (pid, err);
if (UNLIKELY (ret < 0))
goto fail;

ret = libcrun_set_io_priority (pid, def->process, err);
if (UNLIKELY (ret < 0))
goto fail;
Expand Down
16 changes: 16 additions & 0 deletions src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -4738,6 +4738,15 @@ handle_pidfd_receiver (pid_t pid, libcrun_container_t *container, libcrun_error_
return send_fd_to_socket (client_fd, pidfd, err);
}

static bool
has_exec_cpu_affinity (runtime_spec_schema_config_schema_process *process)
{
if (process == NULL || process->exec_cpu_affinity == NULL)
return false;
return (! is_empty_string (process->exec_cpu_affinity->initial))
|| (! is_empty_string (process->exec_cpu_affinity->final));
}

pid_t
libcrun_run_linux_container (libcrun_container_t *container, container_entrypoint_t entrypoint, void *args,
int *sync_socket_out, struct libcrun_dirfd_s *cgroup_dirfd, libcrun_error_t *err)
Expand Down Expand Up @@ -5060,6 +5069,13 @@ join_process_parent_helper (libcrun_context_t *context,
return ret;
}

if (! has_exec_cpu_affinity (process))
{
ret = libcrun_reset_cpu_affinity_mask (pid, err);
if (UNLIKELY (ret < 0))
return ret;
}

if (need_move_to_cgroup)
{
if (sub_cgroup)
Expand Down
24 changes: 24 additions & 0 deletions src/libcrun/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@ syscall_sched_setattr (pid_t pid, struct sched_attr_s *attr, unsigned int flags)
#endif
}

int
libcrun_reset_cpu_affinity_mask (pid_t pid, libcrun_error_t *err)
{
int ret;

/* Reset the inherited cpu affinity. Old kernels do that automatically, but
new kernels remember the affinity that was set before the cgroup move.
This is undesirable, because it inherits the systemd affinity when the container
should really move to the container space cpus.
The sched_setaffinity call will always return an error (EINVAL or ENODEV)
when used like this. This is expected and part of the backward compatibility.
See: https://issues.redhat.com/browse/OCPBUGS-15102 */
ret = sched_setaffinity (pid, 0, NULL);
if (LIKELY (ret < 0))
{
if (UNLIKELY (! ((errno == EINVAL) || (errno == ENODEV))))
return crun_make_error (err, errno, "failed to reset affinity");
}

return 0;
}

int
libcrun_set_scheduler (pid_t pid, runtime_spec_schema_config_schema_process *process, libcrun_error_t *err)
{
Expand Down
2 changes: 2 additions & 0 deletions src/libcrun/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ int libcrun_set_scheduler (pid_t pid, runtime_spec_schema_config_schema_process

int libcrun_set_cpu_affinity_from_string (pid_t pid, const char *str, libcrun_error_t *err);

int libcrun_reset_cpu_affinity_mask (pid_t pid, libcrun_error_t *err);

#endif

0 comments on commit d63c20a

Please sign in to comment.