From: Phil Auld <pauld@redhat.com>
To: Thijs Raymakers <thijs@raymakers.nl>
Cc: kzak@redhat.com, util-linux@vger.kernel.org
Subject: Re: [PATCH v2 0/1] coresched: Manage core scheduling cookies for tasks
Date: Wed, 27 Mar 2024 10:18:45 -0400 [thread overview]
Message-ID: <20240327141845.GE361020@lorien.usersys.redhat.com> (raw)
In-Reply-To: <20240327132137.GA361020@lorien.usersys.redhat.com>
On Wed, Mar 27, 2024 at 09:21:46AM -0400 Phil Auld wrote:
>
> Hi Thijs,
>
> On Wed, Mar 27, 2024 at 01:43:20PM +0100 Thijs Raymakers wrote:
> > Hi Phil,
> >
> > >> In general, `prctl` does indeed return EINVAL if the operation is not
> > >> recognized, or not supported on the system. The `PR_SCHED_CORE`
> > >> operation itself only returns EINVAL if it is called with
> > >> - an invalid operation
> > >> - an invalid type
> > >> - a negative PID
> > >> - an invalid cookie store address (for PR_SCHED_CORE_GET)
> > >> Assuming that all these cases are prevented by the util, we could
> > >> interpret a EINVAL as a sign that PR_SCHED_CORE is not supported on
> > >> the system.
> > > Fair enough. Could say something like "got EINVAL. Does your kernel
> > > support CONFIG_SCHED_CORE?".
> >
> > I've added this as a warning in case a prctl call returns EINVAL. I
> > haven't tested it on a kernel with CONFIG_SCHED_CORE=n yet but I will do
> > that later.
>
> Thanks. I'll refresh and try it again. My build machine does not have
> CONFIG_CORE_SCHED so that's easy for me to test :)
>
After fixing the missing #defines I tested this. I think this looks
good but I'd do the error line first then the CONFIG_SCHED_CORE message.
i.e:
$ ./coresched -n ls
coresched: Does your kernel support CONFIG_SCHED_CORE?
coresched: Failed to create cookie for PID 3747542: Invalid argument
should be
$ ./coresched -n ls
coresched: Failed to create cookie for PID 3747542: Invalid argument
coresched: Does your kernel support CONFIG_SCHED_CORE?
It's a little harder to clear the cookie with coresched that coreset
but otherwise I think this version is really good. It's covering all
my use cases and seems to fit my expectations pretty well.
Thanks for listening to my suggestions.
Cheers,
Phil
> >
> > > There is also
> > > err_exclusive_options(c, longopts, excl, excl_st);
> > >
> > > in the optuils.h code which can handle the tests for mutually exclusive
> > > arguments.
> > >
> > > Thomas pointed me to that. It works nicely and can remove some of the extra
> > > checks (once you get it setup). And the error then looks the same as other
> > > util-linux progs.
> >
> > Good suggestion, I replaced some of the earlier mutually exclusive
> > checks with a call to err_exclusive_options.
> >
> > > You might consider "errtryhelp(EXIT_FAILURE);" in usage failures. A lot of
> > > the progs (incl taskset which is my model for this) do that. Then you only
> > > do the full usage when given -h/--help.
> >
> > This does indeed feel a slightly nicer to use. I've added this in case a
> > of a usage failure. In case no options are given, it defaults to
> > printing the --help page. This matches the behavior of some other utils like
> > uclampset, and saves some time.
> >
> >
> > Op 26-03-2024 om 21:16 schreef Phil Auld:
> > > So "-n/--new" creates a new cookie and so does "". Just one on an existing task
> > > and one on the exec'd task. Seems inconsistent, no?
> >
> > Hmmm, I didn't intially see this as inconsistent behavior but I get why
> > you say this. I've modified this now to have -n/--new deal both with
> > assigning cookies to existing processes and to spawn new processes.
> >
> >
> > Op 26-03-2024 om 21:17 schreef Phil Auld:
> > > Btw, did you try coreset to see if it does what you need?
> >
> > I did take a look at it. Thanks for adding the functionality of copying
> > a cookie from/to an existing PID. The commands take a bit of getting
> > used to for me, so I guess it is just a matter of preference of what feels
> > natural to use.
>
> Yeah, fair enough. I wrote it so it makes sense to me ;)
>
> > Some things that weren't directly clear to me:
> > - Both `coreset ls` and `coreset -n ls` spawn a new program. If I
> > understood it correctly, the former spawns the program without
> > a cookie, and the latter spawns it with a cookie. I'm not entirely
> > sure what the point of the former would be, as the cookie would either
> > be 0 or equal to the cookie of the `coreset` process itself since the
> > cookie in inherited across execs. It is not necessary to run the
> > provided program in that case.
>
> It's more informational. Since "get" is essentially the default, coreset ls
> would run ls and report its cookie. Not totally useful but more for
> consistency and it tells you that your shell does or does not have a
> cookie set.
>
> > - Not entirely sure what the difference between --dest and --to is.
> > The names of these options are similar in meaning and do almost the
> > same thing.
>
> That's the one I added to cover your use case. Dest is specifically only
> used with --copy. It makes copy into a pull_then_push rather than a
> pull_then_exec.
>
> --to is just a push. It will push the current task's cookie to
> <pid>. This is also useful to clear a tasks cookie if your current shell does
> not have a cookie set.
>
> With your coresched tool I think you have to pick a random pid that you
> know does not have a cookie and use that to clear a different pid's cookie.
>
> > - It is not clear in what cases --scope is ignored and in which
> > cases it is necessary.
>
> Fair enough. Also I have not yet cribbed your string version of scope.
>
> > - What does `coreset -c -s 0 -d 2 -p 1 ls` do? Does it first copy the
> > cookie from PID 1 to PID 2, and then run `ls` with the same or
> > different cookie? Or the other way around?
> >
>
> It should copy pid 1's cookie to pid 2 and report that it's ignoring the
> extra input. It would not run ls in this case.
>
> -d is the destination pid in the case of copy. So --pid is copy from (in
> both exec and --dest cases).
>
> -s 0 is redundant since that's the default in coreset.
>
> > Now I do see what you meant earlier with imitating the behavior of the
> > `taskset` command. I don't think this is strictly necessary since it is
> > a different utility program, but I can understand that it can be useful
> > for people if the command behaves similar to a program that they already
> > know and have certain expectations of.
> >
> > I've modified the options of coresched to be more in line with these
> > expectations, while also addressing the things I mentioned above.
> >
> > Usage:
> > coresched [-p PID]
> > coresched --new [-t <TYPE>] -p <PID>
> > coresched --new [-t <TYPE>] -- PROGRAM [ARGS...]
> > coresched --copy -p <PID> [-t <TYPE>] -d <PID>
> > coresched --copy -p <PID> [-t <TYPE>] -- PROGRAM [ARGS...]
> >
> > This follows the taskset's behavior (i.e. perform the same operation
> > on either an existing PID or on a new program) and taskset's arguments
> > (-p for PID instead of the -s I had earlier) more closely than before.
> >
>
> I think I like the above, nice.
>
> > I've attached an interdiff of the util compared to the previous version
> > that I sent yesterday. I think that this version encompases both our use
> > cases quite nicely.
>
> Let me give it a try. I may or may not have time to get to it today.
> Other priorities arise. We'll see.
>
> I do still prefer coreset as a name but I won't die on that hill :)
>
>
> Cheers,
> Phil
>
> >
> > Thijs
> >
> > Thijs Raymakers (1):
> > coresched: Manage core scheduling cookies for tasks
> >
> > .gitignore | 1 +
> > bash-completion/coresched | 0
> > configure.ac | 12 +-
> > meson.build | 16 +-
> > meson_options.txt | 2 +-
> > schedutils/Makemodule.am | 8 +
> > schedutils/coresched.1.adoc | 16 ++
> > schedutils/coresched.c | 363 ++++++++++++++++++++++++++++++++++++
> > 8 files changed, 412 insertions(+), 6 deletions(-)
> > create mode 100644 bash-completion/coresched
> > create mode 100644 schedutils/coresched.1.adoc
> > create mode 100644 schedutils/coresched.c
> >
> > Interdiff against v1:
> > diff --git a/schedutils/coresched.c b/schedutils/coresched.c
> > index 17d775f2d..537281fdb 100644
> > --- a/schedutils/coresched.c
> > +++ b/schedutils/coresched.c
> > @@ -12,10 +12,12 @@
> > #include <stdio.h>
> > #include <sys/prctl.h>
> > #include <sys/wait.h>
> > +#include <unistd.h>
> >
> > #include "c.h"
> > #include "closestream.h"
> > #include "nls.h"
> > +#include "optutils.h"
> > #include "strutils.h"
> >
> > // These definitions might not be defined, even if the
> > @@ -26,32 +28,34 @@
> > #ifndef PR_SCHED_CORE_SCOPE_THREAD_GROUP
> > #define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
> > #endif
> > +
> > #ifndef PR_SCHED_CORE_SCOPE_PROCESS_GROUP
> > #define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
> > #endif
> >
> > typedef int core_sched_type_t;
> > +typedef unsigned long cookie_t;
> > typedef enum {
> > - SCHED_CORE_CMD_EXEC = 0,
> > - SCHED_CORE_CMD_GET = 1,
> > - SCHED_CORE_CMD_CREATE = 2,
> > - SCHED_CORE_CMD_COPY = 4,
> > + SCHED_CORE_CMD_GET,
> > + SCHED_CORE_CMD_NEW,
> > + SCHED_CORE_CMD_COPY,
> > } core_sched_cmd_t;
> >
> > struct args {
> > - pid_t from_pid;
> > - pid_t to_pid;
> > + pid_t pid;
> > + pid_t dest;
> > core_sched_type_t type;
> > core_sched_cmd_t cmd;
> > int exec_argv_offset;
> > };
> >
> > -unsigned long core_sched_get_cookie(struct args *args);
> > -void core_sched_create_cookie(struct args *args);
> > +cookie_t core_sched_get_cookie(pid_t pid);
> > +void core_sched_create_cookie(pid_t pid, core_sched_type_t type);
> > void core_sched_pull_cookie(pid_t from);
> > void core_sched_push_cookie(pid_t to, core_sched_type_t type);
> > -void core_sched_copy_cookie(struct args *args);
> > +void core_sched_copy_cookie(pid_t from, pid_t to, core_sched_type_t to_type);
> > void core_sched_exec_with_cookie(struct args *args, char **argv);
> > +void core_sched_get_and_print_cookie(pid_t pid);
> >
> > core_sched_type_t parse_core_sched_type(char *str);
> > bool verify_arguments(struct args *args);
> > @@ -59,22 +63,31 @@ void parse_arguments(int argc, char **argv, struct args *args);
> > void set_pid_or_err(pid_t *dest, pid_t src, const char *err_msg);
> > static void __attribute__((__noreturn__)) usage(void);
> >
> > -unsigned long core_sched_get_cookie(struct args *args)
> > +#define bad_usage(FMT...) \
> > + warnx(FMT); \
> > + errtryhelp(EINVAL);
> > +
> > +#define check_coresched_in_kernel(errno) \
> > + if (errno == EINVAL) { \
> > + warnx("Does your kernel support CONFIG_SCHED_CORE?"); \
> > + }
> > +
> > +cookie_t core_sched_get_cookie(pid_t pid)
> > {
> > - unsigned long cookie = 0;
> > - if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_GET, args->from_pid,
> > + cookie_t cookie = 0;
> > + if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_GET, pid,
> > PR_SCHED_CORE_SCOPE_THREAD, &cookie)) {
> > - err(errno, "Failed to get cookie from PID %d", args->from_pid);
> > + check_coresched_in_kernel(errno);
> > + err(errno, "Failed to get cookie from PID %d", pid);
> > }
> > return cookie;
> > }
> >
> > -void core_sched_create_cookie(struct args *args)
> > +void core_sched_create_cookie(pid_t pid, core_sched_type_t type)
> > {
> > - if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, args->to_pid, args->type,
> > - 0)) {
> > - err(errno, "Failed to create cookie for PID %d",
> > - args->from_pid);
> > + if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, pid, type, 0)) {
> > + check_coresched_in_kernel(errno);
> > + err(errno, "Failed to create cookie for PID %d", pid);
> > }
> > }
> >
> > @@ -82,6 +95,7 @@ void core_sched_pull_cookie(pid_t from)
> > {
> > if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_FROM, from,
> > PR_SCHED_CORE_SCOPE_THREAD, 0)) {
> > + check_coresched_in_kernel(errno);
> > err(errno, "Failed to pull cookie from PID %d", from);
> > }
> > }
> > @@ -89,14 +103,18 @@ void core_sched_pull_cookie(pid_t from)
> > void core_sched_push_cookie(pid_t to, core_sched_type_t type)
> > {
> > if (prctl(PR_SCHED_CORE, PR_SCHED_CORE_SHARE_TO, to, type, 0)) {
> > + check_coresched_in_kernel(errno);
> > err(errno, "Failed to push cookie to PID %d", to);
> > }
> > }
> >
> > -void core_sched_copy_cookie(struct args *args)
> > +void core_sched_copy_cookie(pid_t from, pid_t to, core_sched_type_t to_type)
> > {
> > - core_sched_pull_cookie(args->from_pid);
> > - core_sched_push_cookie(args->to_pid, args->type);
> > + core_sched_pull_cookie(from);
> > + cookie_t before = core_sched_get_cookie(from);
> > + core_sched_push_cookie(to, to_type);
> > + printf("%s: copied cookie 0x%lx from PID %d to PID %d\n",
> > + program_invocation_short_name, before, from, to);
> > }
> >
> > void core_sched_exec_with_cookie(struct args *args, char **argv)
> > @@ -111,11 +129,15 @@ void core_sched_exec_with_cookie(struct args *args, char **argv)
> > // If a source PID is provided, try to copy the cookie from
> > // that PID. Otherwise, create a brand new cookie with the
> > // provided type.
> > - if (args->from_pid) {
> > - core_sched_pull_cookie(args->from_pid);
> > + if (args->pid) {
> > + core_sched_pull_cookie(args->pid);
> > + core_sched_get_and_print_cookie(args->pid);
> > } else {
> > - args->to_pid = getpid();
> > - core_sched_create_cookie(args);
> > + pid_t pid = getpid();
> > + core_sched_create_cookie(pid, args->type);
> > + cookie_t after = core_sched_get_cookie(pid);
> > + printf("%s: set cookie of PID %d to 0x%lx\n",
> > + program_invocation_short_name, pid, after);
> > }
> >
> > if (execvp(argv[0], argv)) {
> > @@ -123,6 +145,13 @@ void core_sched_exec_with_cookie(struct args *args, char **argv)
> > }
> > }
> >
> > +void core_sched_get_and_print_cookie(pid_t pid)
> > +{
> > + cookie_t after = core_sched_get_cookie(pid);
> > + printf("%s: set cookie of PID %d to 0x%lx\n",
> > + program_invocation_short_name, pid, after);
> > +}
> > +
> > core_sched_type_t parse_core_sched_type(char *str)
> > {
> > if (!strncmp(str, "pid\0", 4)) {
> > @@ -133,156 +162,96 @@ core_sched_type_t parse_core_sched_type(char *str)
> > return PR_SCHED_CORE_SCOPE_PROCESS_GROUP;
> > }
> >
> > - errx(EINVAL, "'%s' is an invalid option. Must be one of pid/tgid/pgid",
> > - str);
> > + bad_usage("'%s' is an invalid option. Must be one of pid/tgid/pgid",
> > + str);
> > __builtin_unreachable();
> > }
> >
> > static void __attribute__((__noreturn__)) usage(void)
> > {
> > fputs(USAGE_HEADER, stdout);
> > - fprintf(stdout, _(" %s --get <PID>\n"), program_invocation_short_name);
> > - fprintf(stdout, _(" %s --new <PID> [-t <TYPE>]\n"),
> > + fprintf(stdout, _(" %s [-p PID]\n"), program_invocation_short_name);
> > + fprintf(stdout, _(" %s --new [-t <TYPE>] -p <PID>\n"),
> > program_invocation_short_name);
> > - fprintf(stdout, _(" %s --copy -s <PID> -d <PID> [-t <TYPE>]\n"),
> > + fprintf(stdout, _(" %s --new [-t <TYPE>] -- PROGRAM [ARGS...]\n"),
> > program_invocation_short_name);
> > - fprintf(stdout, _(" %s [-s <PID>] -- PROGRAM ARGS... \n"),
> > + fprintf(stdout, _(" %s --copy -p <PID> [-t <TYPE>] -d <PID>\n"),
> > + program_invocation_short_name);
> > + fprintf(stdout,
> > + _(" %s --copy -p <PID> [-t <TYPE>] -- PROGRAM [ARGS...]\n"),
> > program_invocation_short_name);
> >
> > fputs(USAGE_SEPARATOR, stdout);
> > fputsln(_("Manage core scheduling cookies for tasks."), stdout);
> >
> > fputs(USAGE_FUNCTIONS, stdout);
> > - fputsln(_(" -g, --get <PID> get the core scheduling cookie of a PID"),
> > + fputsln(_(" -n, --new assign a new core scheduling cookie to an existing PID or\n"
> > + " execute a program with a new cookie."),
> > stdout);
> > - fputsln(_(" -n, --new <PID> assign a new core scheduling cookie to PID"),
> > + fputsln(_(" -c, --copy copy the core scheduling cookie from an existing PID to\n"
> > + " either another PID, or copy it to a new program"),
> > stdout);
> > - fputsln(_(" -c, --copy copy the core scheduling cookie from PID to\n"
> > - " another PID, requires the --source and --dest option"),
> > + fputsln(_("\n If no function is provided, it will retrieve and print the cookie from\n"
> > + " the PID provided via --pid.\n"),
> > stdout);
> >
> > fputs(USAGE_OPTIONS, stdout);
> > - fputsln(_(" -s, --source <PID> where to copy the core scheduling cookie from."),
> > - stdout);
> > - fputsln(_(" -d, --dest <PID> where to copy the core scheduling cookie to."),
> > + fputsln(_(" -p, --pid <PID> operate on an existing PID"), stdout);
> > + fputsln(_(" -d, --dest <PID> when copying a cookie from an existing PID, --dest is\n"
> > + " the destination PID where to copy the cookie to."),
> > stdout);
> > - fputsln(_(" -t, --type type of the destination PID, or the type of\n"
> > - " the PID when a new core scheduling cookie\n"
> > - " is created. Can be one of the following:\n"
> > - " pid, tgid or pgid. Defaults to tgid."),
> > + fputsln(_(" -t, --type <TYPE> type of the destination PID, or the type of the PID\n"
> > + " when a new core scheduling cookie is created.\n"
> > + " Can be one of the following: pid, tgid or pgid.\n"
> > + " The default is tgid."),
> > stdout);
> > fputs(USAGE_SEPARATOR, stdout);
> > fprintf(stdout,
> > USAGE_HELP_OPTIONS(
> > - 25)); /* char offset to align option descriptions */
> > + 20)); /* char offset to align option descriptions */
> > fprintf(stdout, USAGE_MAN_TAIL("coresched(1)"));
> > exit(EXIT_SUCCESS);
> > }
> >
> > -bool verify_arguments(struct args *args)
> > -{
> > - // Check if the value of args->cmd is a power of 2
> > - // In that case, only a single function option was set.
> > - if (args->cmd & (args->cmd - 1)) {
> > - errx(EINVAL,
> > - "Cannot do more than one function at a time. See %s --help",
> > - program_invocation_short_name);
> > - }
> > -
> > - switch (args->cmd) {
> > - case SCHED_CORE_CMD_GET:
> > - if (args->to_pid) {
> > - errx(EINVAL,
> > - "Cannot use -d/--dest with this -g/--get. See %s --help",
> > - program_invocation_short_name);
> > - }
> > - break;
> > - case SCHED_CORE_CMD_CREATE:
> > - if (args->from_pid) {
> > - errx(EINVAL,
> > - "Cannot use -s/--source with this -n/--new. See %s --help",
> > - program_invocation_short_name);
> > - }
> > - break;
> > - case SCHED_CORE_CMD_COPY:
> > - if (!args->from_pid) {
> > - errx(EINVAL,
> > - "-s/--source PID is required when copying");
> > - }
> > - if (!args->to_pid) {
> > - errx(EINVAL, "-d/--dest PID is required when copying");
> > - }
> > - break;
> > - case SCHED_CORE_CMD_EXEC:
> > - if (args->to_pid) {
> > - errx(EINVAL,
> > - "Cannot use -d/--dest when spawning a program. See %s --help",
> > - program_invocation_short_name);
> > - }
> > - break;
> > - }
> > - return true;
> > -}
> > -
> > -void set_pid_or_err(pid_t *dest, pid_t src, const char *err_msg)
> > -{
> > - if (*dest) {
> > - errx(EINVAL, "Ambigious usage: %s", err_msg);
> > - } else {
> > - *dest = src;
> > - }
> > -}
> > -
> > -static const char *ERR_MSG_MULTIPLE_SOURCE_PIDS =
> > - "Multiple source PIDs defined";
> > void parse_arguments(int argc, char **argv, struct args *args)
> > {
> > int c;
> > - pid_t tmp;
> >
> > static const struct option longopts[] = {
> > - { "get", required_argument, NULL, 'g' },
> > - { "new", required_argument, NULL, 'n' },
> > + { "new", no_argument, NULL, 'n' },
> > { "copy", no_argument, NULL, 'c' },
> > - { "source", required_argument, NULL, 's' },
> > - { "destination", required_argument, NULL, 'd' },
> > + { "pid", required_argument, NULL, 'p' },
> > + { "dest", required_argument, NULL, 'd' },
> > { "type", required_argument, NULL, 't' },
> > { "version", no_argument, NULL, 'V' },
> > { "help", no_argument, NULL, 'h' },
> > { NULL, 0, NULL, 0 }
> > };
> > + static const ul_excl_t excl[] = {
> > + { 'c', 'n' }, // Cannot do both --new and --copy
> > + { 'd', 'n' }, // Cannot have both --new and --dest
> > + { 0 }
> > + };
> >
> > - while ((c = getopt_long(argc, argv, "g:n:cs:d:t:Vh", longopts, NULL)) !=
> > - -1)
> > + int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
> > +
> > + while ((c = getopt_long(argc, argv, "ncp:d:t:Vh", longopts, NULL)) !=
> > + -1) {
> > + err_exclusive_options(c, longopts, excl, excl_st);
> > switch (c) {
> > - case 'g':
> > - args->cmd |= SCHED_CORE_CMD_GET;
> > - tmp = strtopid_or_err(
> > - optarg, "Failed to parse PID for -g/--get");
> > - set_pid_or_err(&args->from_pid, tmp,
> > - ERR_MSG_MULTIPLE_SOURCE_PIDS);
> > - break;
> > case 'n':
> > - args->cmd |= SCHED_CORE_CMD_CREATE;
> > - tmp = strtopid_or_err(
> > - optarg, "Failed to parse PID for -n/--new");
> > - set_pid_or_err(&args->to_pid, tmp,
> > - ERR_MSG_MULTIPLE_SOURCE_PIDS);
> > + args->cmd = SCHED_CORE_CMD_NEW;
> > break;
> > case 'c':
> > - args->cmd |= SCHED_CORE_CMD_COPY;
> > + args->cmd = SCHED_CORE_CMD_COPY;
> > break;
> > - case 's':
> > - tmp = strtopid_or_err(
> > - optarg, "Failed to parse PID for -s/--source");
> > - set_pid_or_err(&args->from_pid, tmp,
> > - ERR_MSG_MULTIPLE_SOURCE_PIDS);
> > + case 'p':
> > + args->pid = strtopid_or_err(
> > + optarg, "Failed to parse PID for -p/--pid");
> > break;
> > case 'd':
> > - tmp = strtopid_or_err(
> > + args->dest = strtopid_or_err(
> > optarg, "Failed to parse PID for -d/--dest");
> > - set_pid_or_err(&args->to_pid, tmp,
> > - "Multiple destination PIDs defined");
> > break;
> > case 't':
> > args->type = parse_core_sched_type(optarg);
> > @@ -294,57 +263,98 @@ void parse_arguments(int argc, char **argv, struct args *args)
> > default:
> > errtryhelp(EXIT_FAILURE);
> > }
> > + }
> >
> > + if (args->cmd == SCHED_CORE_CMD_COPY && !args->pid) {
> > + bad_usage("--copy: requires a -p/--pid");
> > + }
> > +
> > + // More arguments have been passed, which means that the user wants to run
> > + // another program with a core scheduling cookie.
> > if (argc > optind) {
> > - if (args->cmd == SCHED_CORE_CMD_EXEC) {
> > - args->exec_argv_offset = optind;
> > - } else {
> > - // -g, -n or -c AND a program to run is provided
> > - errx(EINVAL, "bad usage, see %s --help",
> > - program_invocation_short_name);
> > + switch (args->cmd) {
> > + case SCHED_CORE_CMD_GET:
> > + bad_usage("Unknown command");
> > + break;
> > + case SCHED_CORE_CMD_NEW:
> > + if (args->pid) {
> > + bad_usage(
> > + "--new: cannot accept both a -p/--pid and a command");
> > + } else {
> > + args->exec_argv_offset = optind;
> > + }
> > + break;
> > + case SCHED_CORE_CMD_COPY:
> > + if (args->dest) {
> > + bad_usage(
> > + "--copy: cannot accept both a destination PID "
> > + "-d/--dest and a command")
> > + } else {
> > + args->exec_argv_offset = optind;
> > + }
> > + break;
> > }
> > - } else if (argc == optind && args->from_pid) {
> > - // Neither a function (-g, -n, or -c), nor a program to
> > - // run is given
> > - args->cmd = SCHED_CORE_CMD_GET;
> > }
> >
> > - verify_arguments(args);
> > + if (argc <= optind) {
> > + if (args->cmd == SCHED_CORE_CMD_NEW && !args->pid) {
> > + bad_usage(
> > + "--new: requires either a -p/--pid or a command");
> > + }
> > + if (args->cmd == SCHED_CORE_CMD_COPY && !args->dest) {
> > + bad_usage(
> > + "--copy: requires either a -d/--dest or a command");
> > + }
> > + }
> > }
> >
> > int main(int argc, char **argv)
> > {
> > - struct args arguments = { 0 };
> > - arguments.type = PR_SCHED_CORE_SCOPE_THREAD_GROUP;
> > + struct args args = { 0 };
> > + args.cmd = SCHED_CORE_CMD_GET;
> > + args.type = PR_SCHED_CORE_SCOPE_THREAD_GROUP;
> >
> > setlocale(LC_ALL, "");
> > bindtextdomain(PACKAGE, LOCALEDIR);
> > textdomain(PACKAGE);
> > close_stdout_atexit();
> >
> > - parse_arguments(argc, argv, &arguments);
> > + parse_arguments(argc, argv, &args);
> > +
> > + cookie_t cookie = 0;
> >
> > - unsigned long cookie = 0;
> > - switch (arguments.cmd) {
> > + switch (args.cmd) {
> > case SCHED_CORE_CMD_GET:
> > - cookie = core_sched_get_cookie(&arguments);
> > - if (cookie) {
> > - printf("core scheduling cookie of pid %d is 0x%lx\n",
> > - arguments.from_pid, cookie);
> > + if (args.pid) {
> > + cookie = core_sched_get_cookie(args.pid);
> > + if (cookie) {
> > + printf("%s: cookie of pid %d is 0x%lx\n",
> > + program_invocation_short_name, args.pid,
> > + cookie);
> > + } else {
> > + errx(ENODATA,
> > + "pid %d doesn't have a core scheduling cookie",
> > + args.pid);
> > + }
> > } else {
> > - printf("pid %d doesn't have a core scheduling cookie\n",
> > - arguments.from_pid);
> > - exit(1);
> > + usage();
> > + exit(0);
> > }
> > break;
> > - case SCHED_CORE_CMD_CREATE:
> > - core_sched_create_cookie(&arguments);
> > + case SCHED_CORE_CMD_NEW:
> > + if (args.pid) {
> > + core_sched_create_cookie(args.pid, args.type);
> > + core_sched_get_and_print_cookie(args.pid);
> > + } else {
> > + core_sched_exec_with_cookie(&args, argv);
> > + }
> > break;
> > case SCHED_CORE_CMD_COPY:
> > - core_sched_copy_cookie(&arguments);
> > - break;
> > - case SCHED_CORE_CMD_EXEC:
> > - core_sched_exec_with_cookie(&arguments, argv);
> > + if (args.dest) {
> > + core_sched_copy_cookie(args.pid, args.dest, args.type);
> > + } else {
> > + core_sched_exec_with_cookie(&args, argv);
> > + }
> > break;
> > default:
> > usage();
> > --
> > 2.44.0
> >
>
> --
--
next prev parent reply other threads:[~2024-03-27 14:18 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-16 17:10 [PATCH RFC] coresched: Manage core scheduling cookies for tasks Thijs Raymakers
2024-03-24 20:07 ` Karel Zak
2024-03-26 14:41 ` Phil Auld
2024-03-26 14:45 ` Phil Auld
2024-03-26 17:49 ` [PATCH 0/1] " Thijs Raymakers
2024-03-26 18:13 ` Phil Auld
[not found] ` <20240326201722.gf315070@lorien.usersys.redhat.com>
2024-03-27 12:43 ` [PATCH v2 " Thijs Raymakers
2024-03-27 13:21 ` Phil Auld
2024-03-27 14:18 ` Phil Auld [this message]
2024-03-27 15:30 ` [PATCH v3] " Thijs Raymakers
2024-04-01 17:18 ` Thomas Weißschuh
2024-04-04 22:03 ` [PATCH v4] " Thijs Raymakers
2024-04-05 6:26 ` Thomas Weißschuh
2024-04-05 14:14 ` Phil Auld
2024-04-08 21:16 ` [PATCH v5] " Thijs Raymakers
2024-04-09 6:12 ` Thomas Weißschuh
2024-04-09 11:55 ` [PATCH v6] " Thijs Raymakers
2024-04-09 13:44 ` Karel Zak
2024-04-09 14:12 ` Phil Auld
2024-04-10 21:11 ` [PATCH v7] " Thijs Raymakers
2024-04-10 22:15 ` Phil Auld
2024-04-11 11:02 ` [PATCH v8] " Thijs Raymakers
2024-04-11 13:46 ` Phil Auld
2024-04-17 10:31 ` Karel Zak
2024-04-17 11:39 ` [PATCH v9] " Thijs Raymakers
2024-04-23 9:27 ` Karel Zak
2024-04-23 10:19 ` Thomas Weißschuh
2024-04-23 11:12 ` [PATCH v10] " Thijs Raymakers
2024-04-25 15:36 ` [PATCH v11] " Thijs Raymakers
2024-04-25 15:51 ` Thomas Weißschuh
2024-04-25 16:22 ` [PATCH v12] " Thijs Raymakers
2024-04-26 7:59 ` Karel Zak
2024-04-26 18:03 ` Thomas Weißschuh
2024-04-29 8:28 ` Karel Zak
2024-04-17 12:27 ` [PATCH v8] " Phil Auld
2024-03-27 12:43 ` [PATCH v2 1/1] " Thijs Raymakers
2024-03-27 14:09 ` Phil Auld
2024-03-26 19:09 ` [PATCH 0/1] " Phil Auld
2024-03-26 19:26 ` Thijs Raymakers
2024-03-26 20:16 ` Phil Auld
2024-03-26 20:17 ` Phil Auld
2024-03-26 17:49 ` [PATCH 1/1] " Thijs Raymakers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240327141845.GE361020@lorien.usersys.redhat.com \
--to=pauld@redhat.com \
--cc=kzak@redhat.com \
--cc=thijs@raymakers.nl \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox