]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
tools/power turbostat: prevent infinite loop on migration error path
authorLen Brown <len.brown@intel.com>
Fri, 9 Nov 2012 03:38:05 +0000 (22:38 -0500)
committerLen Brown <len.brown@intel.com>
Tue, 27 Nov 2012 05:03:06 +0000 (00:03 -0500)
Turbostat assumed if it can't migrate to a CPU, then the CPU
must have gone off-line and turbostat should re-initialize
with the new topology.

But if turbostat can not migrate because it is restricted by
a cpuset, then it will fail to migrate even after re-initialization,
resulting in an infinite loop.

Spit out a warning when we can't migrate
and endure only 2 re-initialize cycles in a row
before giving up and exiting.

Signed-off-by: Len Brown <len.brown@intel.com>
tools/power/x86/turbostat/turbostat.c

index 3c063a00f3bf46f214b94fb8e5c30d525cb6dfe7..77e76b11382fed14a18af16e2313a4446d4cf9f4 100644 (file)
@@ -656,8 +656,10 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
 {
        int cpu = t->cpu_id;
 
 {
        int cpu = t->cpu_id;
 
-       if (cpu_migrate(cpu))
+       if (cpu_migrate(cpu)) {
+               fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
                return -1;
                return -1;
+       }
 
        t->tsc = rdtsc();       /* we are running on local CPU of interest */
 
 
        t->tsc = rdtsc();       /* we are running on local CPU of interest */
 
@@ -1088,15 +1090,22 @@ int mark_cpu_present(int cpu)
 void turbostat_loop()
 {
        int retval;
 void turbostat_loop()
 {
        int retval;
+       int restarted = 0;
 
 restart:
 
 restart:
+       restarted++;
+
        retval = for_all_cpus(get_counters, EVEN_COUNTERS);
        if (retval < -1) {
                exit(retval);
        } else if (retval == -1) {
        retval = for_all_cpus(get_counters, EVEN_COUNTERS);
        if (retval < -1) {
                exit(retval);
        } else if (retval == -1) {
+               if (restarted > 1) {
+                       exit(retval);
+               }
                re_initialize();
                goto restart;
        }
                re_initialize();
                goto restart;
        }
+       restarted = 0;
        gettimeofday(&tv_even, (struct timezone *)NULL);
 
        while (1) {
        gettimeofday(&tv_even, (struct timezone *)NULL);
 
        while (1) {