Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tools/power turbostat: Harden against unexpected values

Divide-by-zero resulted if LLC references == 0

Pull the percentage division into pct() to centralize sanity checks there.

Fixes: 8808292799b0 ("tools/power turbostat: Print "nan" for out of range percentages")

Signed-off-by: Len Brown <len.brown@intel.com>

Len Brown d0f7093a 61764831

+51 -43
+51 -43
tools/power/x86/turbostat/turbostat.c
··· 3002 3002 } 3003 3003 3004 3004 /* 3005 - * pct() 3005 + * pct(numerator, denominator) 3006 3006 * 3007 - * If absolute value is < 1.1, return percentage 3008 - * otherwise, return nan 3007 + * Return sanity checked percentage (100.0 * numerator/denominotor) 3009 3008 * 3010 - * return value is appropriate for printing percentages with %f 3011 - * while flagging some obvious erroneous values. 3009 + * n < 0: nan 3010 + * d <= 0: nan 3011 + * n/d > 1.1: nan 3012 3012 */ 3013 - double pct(double d) 3013 + double pct(double numerator, double denominator) 3014 3014 { 3015 + double retval; 3015 3016 3016 - double abs = fabs(d); 3017 + if (numerator < 0) 3018 + return nan(""); 3017 3019 3018 - if (abs < 1.10) 3019 - return (100.0 * d); 3020 - return nan(""); 3020 + if (denominator <= 0) 3021 + return nan(""); 3022 + 3023 + retval = 100.0 * numerator / denominator; 3024 + 3025 + if (retval > 110.0) 3026 + return nan(""); 3027 + 3028 + return retval; 3021 3029 } 3022 3030 3023 3031 int dump_counters(PER_THREAD_PARAMS) ··· 3055 3047 3056 3048 outp += sprintf(outp, "LLC refs: %lld", t->llc.references); 3057 3049 outp += sprintf(outp, "LLC miss: %lld", t->llc.misses); 3058 - outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses) / t->llc.references)); 3050 + outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references)); 3059 3051 3060 3052 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 3061 3053 outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path); ··· 3270 3262 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float); 3271 3263 3272 3264 if (DO_BIC(BIC_Busy)) 3273 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf / tsc)); 3265 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc)); 3274 3266 3275 3267 if (DO_BIC(BIC_Bzy_MHz)) { 3276 3268 if (has_base_hz) ··· 3311 3303 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000); 3312 3304 3313 3305 if (DO_BIC(BIC_LLC_HIT)) 3314 - outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses) / t->llc.references)); 3306 + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references)); 3315 3307 } 3316 3308 3317 3309 /* Added Thread Counters */ ··· 3324 3316 if (mp->type == COUNTER_USEC) 3325 3317 outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000); 3326 3318 else 3327 - outp += print_float_value(&printed, delim, pct(t->counter[i] / tsc)); 3319 + outp += print_float_value(&printed, delim, pct(t->counter[i], tsc)); 3328 3320 } 3329 3321 } 3330 3322 ··· 3338 3330 if (pp->type == COUNTER_USEC) 3339 3331 outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000); 3340 3332 else 3341 - outp += print_float_value(&printed, delim, pct(t->perf_counter[i] / tsc)); 3333 + outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc)); 3342 3334 } 3343 3335 } 3344 3336 ··· 3352 3344 break; 3353 3345 3354 3346 case PMT_TYPE_XTAL_TIME: 3355 - value_converted = pct(value_raw / crystal_hz / interval_float); 3347 + value_converted = pct(value_raw / crystal_hz, interval_float); 3356 3348 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); 3357 3349 break; 3358 3350 3359 3351 case PMT_TYPE_TCORE_CLOCK: 3360 - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); 3352 + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); 3361 3353 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); 3362 3354 } 3363 3355 } 3364 3356 3365 3357 /* C1 */ 3366 3358 if (DO_BIC(BIC_CPU_c1)) 3367 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1 / tsc)); 3359 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc)); 3368 3360 3369 3361 /* print per-core data only for 1st thread in core */ 3370 3362 if (!is_cpu_first_thread_in_core(t, c)) 3371 3363 goto done; 3372 3364 3373 3365 if (DO_BIC(BIC_CPU_c3)) 3374 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3 / tsc)); 3366 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc)); 3375 3367 if (DO_BIC(BIC_CPU_c6)) 3376 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6 / tsc)); 3368 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc)); 3377 3369 if (DO_BIC(BIC_CPU_c7)) 3378 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7 / tsc)); 3370 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc)); 3379 3371 3380 3372 /* Mod%c6 */ 3381 3373 if (DO_BIC(BIC_Mod_c6)) 3382 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us / tsc)); 3374 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc)); 3383 3375 3384 3376 if (DO_BIC(BIC_CoreTmp)) 3385 3377 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c); ··· 3395 3387 else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) 3396 3388 outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]); 3397 3389 else if (mp->format == FORMAT_PERCENT) 3398 - outp += print_float_value(&printed, delim, pct(c->counter[i] / tsc)); 3390 + outp += print_float_value(&printed, delim, pct(c->counter[i], tsc)); 3399 3391 } 3400 3392 3401 3393 /* Added perf Core counters */ ··· 3405 3397 else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) 3406 3398 outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]); 3407 3399 else if (pp->format == FORMAT_PERCENT) 3408 - outp += print_float_value(&printed, delim, pct(c->perf_counter[i] / tsc)); 3400 + outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc)); 3409 3401 } 3410 3402 3411 3403 /* Added PMT Core counters */ ··· 3418 3410 break; 3419 3411 3420 3412 case PMT_TYPE_XTAL_TIME: 3421 - value_converted = pct(value_raw / crystal_hz / interval_float); 3413 + value_converted = pct(value_raw / crystal_hz, interval_float); 3422 3414 outp += print_float_value(&printed, delim, value_converted); 3423 3415 break; 3424 3416 3425 3417 case PMT_TYPE_TCORE_CLOCK: 3426 - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); 3418 + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); 3427 3419 outp += print_float_value(&printed, delim, value_converted); 3428 3420 } 3429 3421 } ··· 3479 3471 if (DO_BIC(BIC_Totl_c0)) 3480 3472 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc); /* can exceed 100% */ 3481 3473 if (DO_BIC(BIC_Any_c0)) 3482 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0 / tsc)); 3474 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc)); 3483 3475 if (DO_BIC(BIC_GFX_c0)) 3484 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0 / tsc)); 3476 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc)); 3485 3477 if (DO_BIC(BIC_CPUGFX)) 3486 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0 / tsc)); 3478 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc)); 3487 3479 3488 3480 if (DO_BIC(BIC_Pkgpc2)) 3489 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2 / tsc)); 3481 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc)); 3490 3482 if (DO_BIC(BIC_Pkgpc3)) 3491 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3 / tsc)); 3483 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc)); 3492 3484 if (DO_BIC(BIC_Pkgpc6)) 3493 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6 / tsc)); 3485 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc)); 3494 3486 if (DO_BIC(BIC_Pkgpc7)) 3495 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7 / tsc)); 3487 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc)); 3496 3488 if (DO_BIC(BIC_Pkgpc8)) 3497 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8 / tsc)); 3489 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc)); 3498 3490 if (DO_BIC(BIC_Pkgpc9)) 3499 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9 / tsc)); 3491 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc)); 3500 3492 if (DO_BIC(BIC_Pkgpc10)) 3501 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10 / tsc)); 3493 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc)); 3502 3494 3503 3495 if (DO_BIC(BIC_Diec6)) 3504 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz / interval_float)); 3496 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float)); 3505 3497 3506 3498 if (DO_BIC(BIC_CPU_LPI)) { 3507 3499 if (p->cpu_lpi >= 0) 3508 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0 / interval_float)); 3500 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float)); 3509 3501 else 3510 3502 outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); 3511 3503 } 3512 3504 if (DO_BIC(BIC_SYS_LPI)) { 3513 3505 if (p->sys_lpi >= 0) 3514 - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0 / interval_float)); 3506 + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float)); 3515 3507 else 3516 3508 outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); 3517 3509 } ··· 3551 3543 else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) 3552 3544 outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]); 3553 3545 else if (mp->format == FORMAT_PERCENT) 3554 - outp += print_float_value(&printed, delim, pct(p->counter[i] / tsc)); 3546 + outp += print_float_value(&printed, delim, pct(p->counter[i], tsc)); 3555 3547 } 3556 3548 3557 3549 /* Added perf Package Counters */ ··· 3563 3555 else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) 3564 3556 outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]); 3565 3557 else if (pp->format == FORMAT_PERCENT) 3566 - outp += print_float_value(&printed, delim, pct(p->perf_counter[i] / tsc)); 3558 + outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc)); 3567 3559 } 3568 3560 3569 3561 /* Added PMT Package Counters */ ··· 3576 3568 break; 3577 3569 3578 3570 case PMT_TYPE_XTAL_TIME: 3579 - value_converted = pct(value_raw / crystal_hz / interval_float); 3571 + value_converted = pct(value_raw / crystal_hz, interval_float); 3580 3572 outp += print_float_value(&printed, delim, value_converted); 3581 3573 break; 3582 3574 3583 3575 case PMT_TYPE_TCORE_CLOCK: 3584 - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); 3576 + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); 3585 3577 outp += print_float_value(&printed, delim, value_converted); 3586 3578 } 3587 3579 }