Skip to content

Commit d0f7093

Browse files
committed
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: 8808292 ("tools/power turbostat: Print "nan" for out of range percentages") Signed-off-by: Len Brown <len.brown@intel.com>
1 parent 6176483 commit d0f7093

1 file changed

Lines changed: 51 additions & 43 deletions

File tree

tools/power/x86/turbostat/turbostat.c

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3002,22 +3002,30 @@ void print_header(char *delim)
30023002
}
30033003

30043004
/*
3005-
* pct()
3005+
* pct(numerator, denominator)
30063006
*
3007-
* If absolute value is < 1.1, return percentage
3008-
* otherwise, return nan
3007+
* Return sanity checked percentage (100.0 * numerator/denominotor)
30093008
*
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
30123012
*/
3013-
double pct(double d)
3013+
double pct(double numerator, double denominator)
30143014
{
3015+
double retval;
30153016

3016-
double abs = fabs(d);
3017+
if (numerator < 0)
3018+
return nan("");
30173019

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;
30213029
}
30223030

30233031
int dump_counters(PER_THREAD_PARAMS)
@@ -3047,7 +3055,7 @@ int dump_counters(PER_THREAD_PARAMS)
30473055

30483056
outp += sprintf(outp, "LLC refs: %lld", t->llc.references);
30493057
outp += sprintf(outp, "LLC miss: %lld", t->llc.misses);
3050-
outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses) / t->llc.references));
3058+
outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references));
30513059

30523060
for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
30533061
outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path);
@@ -3262,7 +3270,7 @@ int format_counters(PER_THREAD_PARAMS)
32623270
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float);
32633271

32643272
if (DO_BIC(BIC_Busy))
3265-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf / tsc));
3273+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc));
32663274

32673275
if (DO_BIC(BIC_Bzy_MHz)) {
32683276
if (has_base_hz)
@@ -3303,7 +3311,7 @@ int format_counters(PER_THREAD_PARAMS)
33033311
outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000);
33043312

33053313
if (DO_BIC(BIC_LLC_HIT))
3306-
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses) / t->llc.references));
3314+
outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references));
33073315
}
33083316

33093317
/* Added Thread Counters */
@@ -3316,7 +3324,7 @@ int format_counters(PER_THREAD_PARAMS)
33163324
if (mp->type == COUNTER_USEC)
33173325
outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000);
33183326
else
3319-
outp += print_float_value(&printed, delim, pct(t->counter[i] / tsc));
3327+
outp += print_float_value(&printed, delim, pct(t->counter[i], tsc));
33203328
}
33213329
}
33223330

@@ -3330,7 +3338,7 @@ int format_counters(PER_THREAD_PARAMS)
33303338
if (pp->type == COUNTER_USEC)
33313339
outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000);
33323340
else
3333-
outp += print_float_value(&printed, delim, pct(t->perf_counter[i] / tsc));
3341+
outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc));
33343342
}
33353343
}
33363344

@@ -3344,34 +3352,34 @@ int format_counters(PER_THREAD_PARAMS)
33443352
break;
33453353

33463354
case PMT_TYPE_XTAL_TIME:
3347-
value_converted = pct(value_raw / crystal_hz / interval_float);
3355+
value_converted = pct(value_raw / crystal_hz, interval_float);
33483356
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
33493357
break;
33503358

33513359
case PMT_TYPE_TCORE_CLOCK:
3352-
value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
3360+
value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
33533361
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
33543362
}
33553363
}
33563364

33573365
/* C1 */
33583366
if (DO_BIC(BIC_CPU_c1))
3359-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1 / tsc));
3367+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc));
33603368

33613369
/* print per-core data only for 1st thread in core */
33623370
if (!is_cpu_first_thread_in_core(t, c))
33633371
goto done;
33643372

33653373
if (DO_BIC(BIC_CPU_c3))
3366-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3 / tsc));
3374+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc));
33673375
if (DO_BIC(BIC_CPU_c6))
3368-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6 / tsc));
3376+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc));
33693377
if (DO_BIC(BIC_CPU_c7))
3370-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7 / tsc));
3378+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc));
33713379

33723380
/* Mod%c6 */
33733381
if (DO_BIC(BIC_Mod_c6))
3374-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us / tsc));
3382+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc));
33753383

33763384
if (DO_BIC(BIC_CoreTmp))
33773385
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
@@ -3387,7 +3395,7 @@ int format_counters(PER_THREAD_PARAMS)
33873395
else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
33883396
outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]);
33893397
else if (mp->format == FORMAT_PERCENT)
3390-
outp += print_float_value(&printed, delim, pct(c->counter[i] / tsc));
3398+
outp += print_float_value(&printed, delim, pct(c->counter[i], tsc));
33913399
}
33923400

33933401
/* Added perf Core counters */
@@ -3397,7 +3405,7 @@ int format_counters(PER_THREAD_PARAMS)
33973405
else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
33983406
outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]);
33993407
else if (pp->format == FORMAT_PERCENT)
3400-
outp += print_float_value(&printed, delim, pct(c->perf_counter[i] / tsc));
3408+
outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc));
34013409
}
34023410

34033411
/* Added PMT Core counters */
@@ -3410,12 +3418,12 @@ int format_counters(PER_THREAD_PARAMS)
34103418
break;
34113419

34123420
case PMT_TYPE_XTAL_TIME:
3413-
value_converted = pct(value_raw / crystal_hz / interval_float);
3421+
value_converted = pct(value_raw / crystal_hz, interval_float);
34143422
outp += print_float_value(&printed, delim, value_converted);
34153423
break;
34163424

34173425
case PMT_TYPE_TCORE_CLOCK:
3418-
value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
3426+
value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
34193427
outp += print_float_value(&printed, delim, value_converted);
34203428
}
34213429
}
@@ -3471,39 +3479,39 @@ int format_counters(PER_THREAD_PARAMS)
34713479
if (DO_BIC(BIC_Totl_c0))
34723480
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc); /* can exceed 100% */
34733481
if (DO_BIC(BIC_Any_c0))
3474-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0 / tsc));
3482+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc));
34753483
if (DO_BIC(BIC_GFX_c0))
3476-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0 / tsc));
3484+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc));
34773485
if (DO_BIC(BIC_CPUGFX))
3478-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0 / tsc));
3486+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc));
34793487

34803488
if (DO_BIC(BIC_Pkgpc2))
3481-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2 / tsc));
3489+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc));
34823490
if (DO_BIC(BIC_Pkgpc3))
3483-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3 / tsc));
3491+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc));
34843492
if (DO_BIC(BIC_Pkgpc6))
3485-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6 / tsc));
3493+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc));
34863494
if (DO_BIC(BIC_Pkgpc7))
3487-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7 / tsc));
3495+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc));
34883496
if (DO_BIC(BIC_Pkgpc8))
3489-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8 / tsc));
3497+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc));
34903498
if (DO_BIC(BIC_Pkgpc9))
3491-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9 / tsc));
3499+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc));
34923500
if (DO_BIC(BIC_Pkgpc10))
3493-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10 / tsc));
3501+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc));
34943502

34953503
if (DO_BIC(BIC_Diec6))
3496-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz / interval_float));
3504+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float));
34973505

34983506
if (DO_BIC(BIC_CPU_LPI)) {
34993507
if (p->cpu_lpi >= 0)
3500-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0 / interval_float));
3508+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float));
35013509
else
35023510
outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
35033511
}
35043512
if (DO_BIC(BIC_SYS_LPI)) {
35053513
if (p->sys_lpi >= 0)
3506-
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0 / interval_float));
3514+
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float));
35073515
else
35083516
outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
35093517
}
@@ -3543,7 +3551,7 @@ int format_counters(PER_THREAD_PARAMS)
35433551
else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
35443552
outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]);
35453553
else if (mp->format == FORMAT_PERCENT)
3546-
outp += print_float_value(&printed, delim, pct(p->counter[i] / tsc));
3554+
outp += print_float_value(&printed, delim, pct(p->counter[i], tsc));
35473555
}
35483556

35493557
/* Added perf Package Counters */
@@ -3555,7 +3563,7 @@ int format_counters(PER_THREAD_PARAMS)
35553563
else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
35563564
outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]);
35573565
else if (pp->format == FORMAT_PERCENT)
3558-
outp += print_float_value(&printed, delim, pct(p->perf_counter[i] / tsc));
3566+
outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc));
35593567
}
35603568

35613569
/* Added PMT Package Counters */
@@ -3568,12 +3576,12 @@ int format_counters(PER_THREAD_PARAMS)
35683576
break;
35693577

35703578
case PMT_TYPE_XTAL_TIME:
3571-
value_converted = pct(value_raw / crystal_hz / interval_float);
3579+
value_converted = pct(value_raw / crystal_hz, interval_float);
35723580
outp += print_float_value(&printed, delim, value_converted);
35733581
break;
35743582

35753583
case PMT_TYPE_TCORE_CLOCK:
3576-
value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
3584+
value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
35773585
outp += print_float_value(&printed, delim, value_converted);
35783586
}
35793587
}

0 commit comments

Comments
 (0)