Hi. Interesting catch, I think I should definitely use %lu here, but I'd rather wonder why my GCC v7.2.0 didn't notice this while clang just did… Will post v3 shortly. Thanks. On Mon, Oct 23, 2017 at 9:55 PM, Dave Anderson <anderson@xxxxxxxxxx> wrote: > Hi Oleksandr, > > Can you take a look at this warning? > > $ make warn > ... [ cut ] ... > cc -c -g -DX86_64 -DLZO -DSNAPPY -DGDB_7_6 task.c -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector -Wformat-security > task.c: In function ‘sched_policy_bit_from_str’: > task.c:7473:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 4 has type ‘ulong’ [-Wformat=] > snprintf(digit, sizeof digit, "%u", info->value); > ^ > task.c:7473:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 4 has type ‘ulong’ [-Wformat=] > ... > > Thanks, > Dave > > > ----- Original Message ----- >> This patch introduces -y option for ps builtin to filter >> tasks by scheduling policy. Applicable to both standalone >> ps invocation as well as via foreach. >> >> Signed-off-by: Oleksandr Natalenko <oleksandr@xxxxxxxxxx> >> --- >> defs.h | 15 +++++++- >> help.c | 7 +++- >> task.c | 135 >> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- >> tools.c | 5 ++- >> 4 files changed, 152 insertions(+), 10 deletions(-) >> >> diff --git a/defs.h b/defs.h >> index a694a66..e0e2c2b 100644 >> --- a/defs.h >> +++ b/defs.h >> @@ -1139,6 +1139,7 @@ extern struct machdep_table *machdep; >> #define FOREACH_a_FLAG (0x4000000) >> #define FOREACH_G_FLAG (0x8000000) >> #define FOREACH_F_FLAG2 (0x10000000) >> +#define FOREACH_y_FLAG (0x20000000) >> >> #define FOREACH_PS_EXCLUSIVE \ >> (FOREACH_g_FLAG|FOREACH_a_FLAG|FOREACH_t_FLAG|FOREACH_c_FLAG|FOREACH_p_FLAG|FOREACH_l_FLAG|FOREACH_r_FLAG|FOREACH_m_FLAG) >> @@ -1162,6 +1163,7 @@ struct foreach_data { >> int comms; >> int args; >> int regexs; >> + int policy; >> }; >> >> struct reference { >> @@ -1201,6 +1203,7 @@ struct offset_table { /* stash of >> commonly-used offsets */ >> long task_struct_pidhash_next; >> long task_struct_next_run; >> long task_struct_flags; >> + long task_struct_policy; >> long task_struct_sig; >> long task_struct_signal; >> long task_struct_blocked; >> @@ -2134,6 +2137,7 @@ struct size_table { /* stash of commonly-used >> sizes */ >> long tnt; >> long trace_print_flags; >> long task_struct_flags; >> + long task_struct_policy; >> long timer_base; >> long taint_flag; >> long nlmsghdr; >> @@ -4573,6 +4577,13 @@ enum type_code { >> */ >> #define PF_EXITING 0x00000004 /* getting shut down */ >> #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ >> +#define SCHED_NORMAL 0 >> +#define SCHED_FIFO 1 >> +#define SCHED_RR 2 >> +#define SCHED_BATCH 3 >> +#define SCHED_ISO 4 >> +#define SCHED_IDLE 5 >> +#define SCHED_DEADLINE 6 >> >> extern long _ZOMBIE_; >> #define IS_ZOMBIE(task) (task_state(task) & _ZOMBIE_) >> @@ -4600,6 +4611,7 @@ extern long _ZOMBIE_; >> #define PS_NO_HEADER (0x10000) >> #define PS_MSECS (0x20000) >> #define PS_SUMMARY (0x40000) >> +#define PS_POLICY (0x80000) >> >> #define PS_EXCLUSIVE >> (PS_TGID_LIST|PS_ARGV_ENVP|PS_TIMES|PS_CHILD_LIST|PS_PPID_LIST|PS_LAST_RUN|PS_RLIMIT|PS_MSECS|PS_SUMMARY) >> >> @@ -4617,6 +4629,7 @@ struct psinfo { >> } regex_data[MAX_PS_ARGS]; >> int regexs; >> ulong *cpus; >> + int policy; >> }; >> >> #define IS_A_NUMBER(X) (decimal(X, 0) || hexadecimal(X, 0)) >> @@ -4820,7 +4833,7 @@ char *strip_ending_char(char *, char); >> char *strip_beginning_char(char *, char); >> char *strip_comma(char *); >> char *strip_hex(char *); >> -char *upper_case(char *, char *); >> +char *upper_case(const char *, char *); >> char *first_nonspace(char *); >> char *first_space(char *); >> char *replace_string(char *, char *, char); >> diff --git a/help.c b/help.c >> index f9c5792..d37adb7 100644 >> --- a/help.c >> +++ b/help.c >> @@ -844,7 +844,7 @@ char *help_foreach[] = { >> " net run the \"net\" command (optional flags: -s -S -R -d >> -x)", >> " set run the \"set\" command", >> " ps run the \"ps\" command (optional flags: -G -s -p -c -t >> -l -a", >> -" -g -r)", >> +" -g -r -y)", >> " sig run the \"sig\" command (optional flag: -g)", >> " vtop run the \"vtop\" command (optional flags: -c -u -k)\n", >> " flag Pass this optional flag to the command selected.", >> @@ -1250,7 +1250,7 @@ NULL >> char *help_ps[] = { >> "ps", >> "display process status information", >> -"[-k|-u|-G] [-s] [-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S]\n [pid | task | >> command] ...", >> +"[-k|-u|-G] [-s] [-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S|-y policy]\n [pid >> | task | command] ...", >> " This command displays process status for selected, or all, processes" , >> " in the system. If no arguments are entered, the process data is", >> " is displayed for all processes. Specific processes may be selected", >> @@ -1318,6 +1318,9 @@ char *help_ps[] = { >> " -g display tasks by thread group, of selected, or all, tasks.", >> " -r display resource limits (rlimits) of selected, or all, tasks.", >> " -S display a summary consisting of the number of tasks in a task >> state.", >> +"-y policy filter tasks by comma-separated list of scheduling policies.", >> +" Acceptable values: NORMAL, FIFO, RR, BATCH, ISO, IDLE, >> DEADLINE", >> +" (case-insensitive) or integer equivalents, from 0 to 6." >> "\nEXAMPLES", >> " Show the process status of all current tasks:\n", >> " %s> ps", >> diff --git a/task.c b/task.c >> index 362822c..09d9c37 100644 >> --- a/task.c >> +++ b/task.c >> @@ -109,6 +109,24 @@ static void show_ps_summary(ulong); >> static void irqstacks_init(void); >> static void parse_task_thread(int argcnt, char *arglist[], struct >> task_context *); >> static void stack_overflow_check_init(void); >> +static int has_sched_policy(ulong, ulong); >> +static ulong task_policy(ulong); >> +static ulong sched_policy_bit_from_str(const char *); >> +static ulong make_sched_policy(const char *); >> + >> +static struct sched_policy_info { >> + ulong value; >> + char *name; >> +} sched_policy_info[] = { >> + { SCHED_NORMAL, "NORMAL" }, >> + { SCHED_FIFO, "FIFO" }, >> + { SCHED_RR, "RR" }, >> + { SCHED_BATCH, "BATCH" }, >> + { SCHED_ISO, "ISO" }, >> + { SCHED_IDLE, "IDLE" }, >> + { SCHED_DEADLINE, "DEADLINE" }, >> + { ULONG_MAX, NULL } >> +}; >> >> /* >> * Figure out how much space will be required to hold the task context >> @@ -273,6 +291,8 @@ task_init(void) >> MEMBER_OFFSET_INIT(task_struct_next_run, "task_struct", "next_run"); >> MEMBER_OFFSET_INIT(task_struct_flags, "task_struct", "flags"); >> MEMBER_SIZE_INIT(task_struct_flags, "task_struct", "flags"); >> + MEMBER_OFFSET_INIT(task_struct_policy, "task_struct", "policy"); >> + MEMBER_SIZE_INIT(task_struct_policy, "task_struct", "policy"); >> MEMBER_OFFSET_INIT(task_struct_pidhash_next, >> "task_struct", "pidhash_next"); >> MEMBER_OFFSET_INIT(task_struct_pgrp, "task_struct", "pgrp"); >> @@ -2974,7 +2994,7 @@ cmd_ps(void) >> cpuspec = NULL; >> flag = 0; >> >> - while ((c = getopt(argcnt, args, "SgstcpkuGlmarC:")) != EOF) { >> + while ((c = getopt(argcnt, args, "SgstcpkuGlmarC:y:")) != EOF) { >> switch(c) >> { >> case 'k': >> @@ -3075,6 +3095,11 @@ cmd_ps(void) >> make_cpumask(cpuspec, psinfo.cpus, FAULT_ON_ERROR, NULL); >> break; >> >> + case 'y': >> + flag |= PS_POLICY; >> + psinfo.policy = make_sched_policy(optarg); >> + break; >> + >> default: >> argerrs++; >> break; >> @@ -3218,6 +3243,8 @@ show_ps_data(ulong flag, struct task_context *tc, >> struct psinfo *psi) >> return; >> if ((flag & PS_KERNEL) && !is_kernel_thread(tc->task)) >> return; >> + if ((flag & PS_POLICY) && !has_sched_policy(tc->task, psi->policy)) >> + return; >> if (flag & PS_GROUP) { >> if (flag & (PS_LAST_RUN|PS_MSECS)) >> error(FATAL, "-G not supported with -%c option\n", >> @@ -3336,7 +3363,7 @@ show_ps(ulong flag, struct psinfo *psi) >> >> tc = FIRST_CONTEXT(); >> for (i = 0; i < RUNNING_TASKS(); i++, tc++) >> - show_ps_data(flag, tc, NULL); >> + show_ps_data(flag, tc, psi); >> >> return; >> } >> @@ -3391,7 +3418,7 @@ show_ps(ulong flag, struct psinfo *psi) >> if (flag & PS_TIMES) >> show_task_times(tc, flag); >> else >> - show_ps_data(flag, tc, NULL); >> + show_ps_data(flag, tc, psi); >> } >> } >> } >> @@ -3546,7 +3573,7 @@ show_milliseconds(struct task_context *tc, struct >> psinfo *psi) >> sprintf(format, "[%c%dll%c] ", '%', c, >> pc->output_radix == 10 ? 'u' : 'x'); >> >> - if (psi) { >> + if (psi && psi->cpus) { >> for (c = others = 0; c < kt->cpus; c++) { >> if (!NUM_IN_BITMAP(psi->cpus, c)) >> continue; >> @@ -5365,6 +5392,27 @@ task_flags(ulong task) >> return flags; >> } >> >> +/* >> + * Return task's policy as bitmask bit. >> + */ >> +static ulong >> +task_policy(ulong task) >> +{ >> + ulong policy = 0; >> + >> + fill_task_struct(task); >> + >> + if (!tt->last_task_read) >> + return policy; >> + >> + if (SIZE(task_struct_policy) == sizeof(unsigned int)) >> + policy = 1 << UINT(tt->task_struct + OFFSET(task_struct_policy)); >> + else >> + policy = 1 << ULONG(tt->task_struct + OFFSET(task_struct_policy)); >> + >> + return policy; >> +} >> + >> /* >> * Return a task's tgid. >> */ >> @@ -5797,7 +5845,7 @@ cmd_foreach(void) >> BZERO(&foreach_data, sizeof(struct foreach_data)); >> fd = &foreach_data; >> >> - while ((c = getopt(argcnt, args, "R:vomlgersStTpukcfFxhdaG")) != >> EOF) { >> + while ((c = getopt(argcnt, args, "R:vomlgersStTpukcfFxhdaGy:")) != >> EOF) { >> switch(c) >> { >> case 'R': >> @@ -5892,6 +5940,11 @@ cmd_foreach(void) >> fd->flags |= FOREACH_G_FLAG; >> break; >> >> + case 'y': >> + fd->flags |= FOREACH_y_FLAG; >> + fd->policy = make_sched_policy(optarg); >> + break; >> + >> default: >> argerrs++; >> break; >> @@ -6554,6 +6607,10 @@ foreach(struct foreach_data *fd) >> cmdflags |= PS_GROUP; >> if (fd->flags & FOREACH_s_FLAG) >> cmdflags |= PS_KSTACKP; >> + if (fd->flags & FOREACH_y_FLAG) { >> + cmdflags |= PS_POLICY; >> + psinfo.policy = fd->policy; >> + } >> /* >> * mutually exclusive flags >> */ >> @@ -7388,6 +7445,74 @@ is_kernel_thread(ulong task) >> return FALSE; >> } >> >> +/* >> + * Checks if task policy corresponds to given mask. >> + */ >> +static int >> +has_sched_policy(ulong task, ulong policy) >> +{ >> + return !!(task_policy(task) & policy); >> +} >> + >> +/* >> + * Converts sched policy name into mask bit. >> + */ >> +static ulong >> +sched_policy_bit_from_str(const char *policy_str) >> +{ >> + struct sched_policy_info *info = NULL; >> + ulong policy = 0; >> + int found = 0; >> + char *upper = NULL; >> + char digit[2] = { 0, 0 }; >> + >> + upper = calloc(1, strlen(policy_str) + 1); >> + upper_case(policy_str, upper); >> + >> + for (info = sched_policy_info; info->name; info++) { >> + snprintf(digit, sizeof digit, "%u", info->value); >> + if (strncmp(upper, info->name, strlen(info->name)) == 0 || >> + strncmp(upper, digit, sizeof digit) == 0) { >> + policy = 1 << info->value; >> + found = 1; >> + break; >> + } >> + } >> + >> + if (!found) { >> + error(INFO, >> + "Scheduling policy \"%s\" is incorrect, defaulting to %s\n", >> + policy_str, sched_policy_info[0].name); >> + policy = 1 << sched_policy_info[0].value; >> + } >> + >> + free(upper); >> + >> + return policy; >> +} >> + >> +/* >> + * Converts sched policy string set into bitmask. >> + */ >> +static ulong >> +make_sched_policy(const char *policy_str) >> +{ >> + ulong policy = 0; >> + char *iter = NULL; >> + char *orig = NULL; >> + char *cur = NULL; >> + >> + iter = strdup(policy_str); >> + orig = iter; >> + >> + while ((cur = strsep(&iter, ","))) >> + policy |= sched_policy_bit_from_str(cur); >> + >> + free(orig); >> + >> + return policy; >> +} >> + >> /* >> * Gather an arry of pointers to the per-cpu idle tasks. The tasklist >> * argument must be at least the size of ulong[NR_CPUS]. There may be >> diff --git a/tools.c b/tools.c >> index 886d7fb..186b703 100644 >> --- a/tools.c >> +++ b/tools.c >> @@ -423,9 +423,10 @@ strip_hex(char *line) >> * Turn a string into upper-case. >> */ >> char * >> -upper_case(char *s, char *buf) >> +upper_case(const char *s, char *buf) >> { >> - char *p1, *p2; >> + const char *p1; >> + char *p2; >> >> p1 = s; >> p2 = buf; >> -- >> 2.14.2 >> >> -- Best regards, Oleksandr Natalenko (post-factum) Software Maintenance Engineer -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility