|
51 | 51 | #define COMM_LEN 20
|
52 | 52 | #define SYM_LEN 129
|
53 | 53 | #define MAX_PID 1024000
|
| 54 | +#define MAX_PRIO 140 |
54 | 55 |
|
55 | 56 | static const char *cpu_list;
|
56 | 57 | static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
|
@@ -234,6 +235,8 @@ struct perf_sched {
|
234 | 235 | struct perf_time_interval ptime;
|
235 | 236 | struct perf_time_interval hist_time;
|
236 | 237 | volatile bool thread_funcs_exit;
|
| 238 | + const char *prio_str; |
| 239 | + DECLARE_BITMAP(prio_bitmap, MAX_PRIO); |
237 | 240 | };
|
238 | 241 |
|
239 | 242 | /* per thread run time data */
|
@@ -2504,12 +2507,33 @@ static bool timehist_skip_sample(struct perf_sched *sched,
|
2504 | 2507 | struct perf_sample *sample)
|
2505 | 2508 | {
|
2506 | 2509 | bool rc = false;
|
| 2510 | + int prio = -1; |
| 2511 | + struct thread_runtime *tr = NULL; |
2507 | 2512 |
|
2508 | 2513 | if (thread__is_filtered(thread)) {
|
2509 | 2514 | rc = true;
|
2510 | 2515 | sched->skipped_samples++;
|
2511 | 2516 | }
|
2512 | 2517 |
|
| 2518 | + if (sched->prio_str) { |
| 2519 | + /* |
| 2520 | + * Because priority may be changed during task execution, |
| 2521 | + * first read priority from prev sched_in event for current task. |
| 2522 | + * If prev sched_in event is not saved, then read priority from |
| 2523 | + * current task sched_out event. |
| 2524 | + */ |
| 2525 | + tr = thread__get_runtime(thread); |
| 2526 | + if (tr && tr->prio != -1) |
| 2527 | + prio = tr->prio; |
| 2528 | + else if (evsel__name_is(evsel, "sched:sched_switch")) |
| 2529 | + prio = evsel__intval(evsel, sample, "prev_prio"); |
| 2530 | + |
| 2531 | + if (prio != -1 && !test_bit(prio, sched->prio_bitmap)) { |
| 2532 | + rc = true; |
| 2533 | + sched->skipped_samples++; |
| 2534 | + } |
| 2535 | + } |
| 2536 | + |
2513 | 2537 | if (sched->idle_hist) {
|
2514 | 2538 | if (!evsel__name_is(evsel, "sched:sched_switch"))
|
2515 | 2539 | rc = true;
|
@@ -2723,7 +2747,7 @@ static int timehist_sched_change_event(const struct perf_tool *tool,
|
2723 | 2747 | goto out;
|
2724 | 2748 | }
|
2725 | 2749 |
|
2726 |
| - if (sched->show_prio) |
| 2750 | + if (sched->show_prio || sched->prio_str) |
2727 | 2751 | timehist_update_task_prio(evsel, sample, machine);
|
2728 | 2752 |
|
2729 | 2753 | thread = timehist_get_thread(sched, sample, machine, evsel);
|
@@ -3143,6 +3167,47 @@ static int timehist_check_attr(struct perf_sched *sched,
|
3143 | 3167 | return 0;
|
3144 | 3168 | }
|
3145 | 3169 |
|
| 3170 | +static int timehist_parse_prio_str(struct perf_sched *sched) |
| 3171 | +{ |
| 3172 | + char *p; |
| 3173 | + unsigned long start_prio, end_prio; |
| 3174 | + const char *str = sched->prio_str; |
| 3175 | + |
| 3176 | + if (!str) |
| 3177 | + return 0; |
| 3178 | + |
| 3179 | + while (isdigit(*str)) { |
| 3180 | + p = NULL; |
| 3181 | + start_prio = strtoul(str, &p, 0); |
| 3182 | + if (start_prio >= MAX_PRIO || (*p != '\0' && *p != ',' && *p != '-')) |
| 3183 | + return -1; |
| 3184 | + |
| 3185 | + if (*p == '-') { |
| 3186 | + str = ++p; |
| 3187 | + p = NULL; |
| 3188 | + end_prio = strtoul(str, &p, 0); |
| 3189 | + |
| 3190 | + if (end_prio >= MAX_PRIO || (*p != '\0' && *p != ',')) |
| 3191 | + return -1; |
| 3192 | + |
| 3193 | + if (end_prio < start_prio) |
| 3194 | + return -1; |
| 3195 | + } else { |
| 3196 | + end_prio = start_prio; |
| 3197 | + } |
| 3198 | + |
| 3199 | + for (; start_prio <= end_prio; start_prio++) |
| 3200 | + __set_bit(start_prio, sched->prio_bitmap); |
| 3201 | + |
| 3202 | + if (*p) |
| 3203 | + ++p; |
| 3204 | + |
| 3205 | + str = p; |
| 3206 | + } |
| 3207 | + |
| 3208 | + return 0; |
| 3209 | +} |
| 3210 | + |
3146 | 3211 | static int perf_sched__timehist(struct perf_sched *sched)
|
3147 | 3212 | {
|
3148 | 3213 | struct evsel_str_handler handlers[] = {
|
@@ -3204,6 +3269,11 @@ static int perf_sched__timehist(struct perf_sched *sched)
|
3204 | 3269 | if (timehist_check_attr(sched, evlist) != 0)
|
3205 | 3270 | goto out;
|
3206 | 3271 |
|
| 3272 | + if (timehist_parse_prio_str(sched) != 0) { |
| 3273 | + pr_err("Invalid prio string\n"); |
| 3274 | + goto out; |
| 3275 | + } |
| 3276 | + |
3207 | 3277 | setup_pager();
|
3208 | 3278 |
|
3209 | 3279 | /* prefer sched_waking if it is captured */
|
@@ -3761,6 +3831,8 @@ int cmd_sched(int argc, const char **argv)
|
3761 | 3831 | "analyze events only for given thread id(s)"),
|
3762 | 3832 | OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
|
3763 | 3833 | OPT_BOOLEAN(0, "show-prio", &sched.show_prio, "Show task priority"),
|
| 3834 | + OPT_STRING(0, "prio", &sched.prio_str, "prio", |
| 3835 | + "analyze events only for given task priority(ies)"), |
3764 | 3836 | OPT_PARENT(sched_options)
|
3765 | 3837 | };
|
3766 | 3838 |
|
|
0 commit comments