Friday, October 22, 2010

top failed ro read /proc/stat

Just noticed that top utiliy fails to read /proc/stat after
cpu offline.

The problem is that Cpu_tot is not updated before calling
cpus_refresh.

In cpus_refresh we're trying to read and sscanf Cpu_tot times /proc/stat

   for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) {
      if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");
      cpus[i].x = 0;  // FIXME: can't tell by kernel version number
      cpus[i].y = 0;  // FIXME: can't tell by kernel version number
      cpus[i].z = 0;  // FIXME: can't tell by kernel version number
      num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
         &cpus[i].id,
         &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z
      );
      if (num < 4)
          std_err("failed /proc/stat read");
   }


Which is wrong, since:
cat /proc/stat
cpu  5700 0 1474 271836 3554 0 41 0 0 0
cpu0 2167 0 565 66945 974 0 13 0 0 0
cpu1 2600 0 507 66512 1030 0 11 0 0 0
cpu2 518 0 214 69082 810 0 5 0 0 0
cpu3 413 0 186 69296 738 0 9 0 0 0
intr ....


echo 0 > /sys/devices/system/cpu/cpu3/online
cat /proc/stat
cpu  5831 0 1531 292475 3592 0 43 0 0 0
cpu0 2236 0 591 72477 979 0 14 0 0 0
cpu1 2647 0 531 72052 1051 0 12 0 0 0
cpu2 527 0 217 74713 821 0 6 0 0 0
intr ...


(note absent cpu3 line).


The solution may look similar to this one:

      smp_num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
      if(smp_num_cpus<1) smp_num_cpus=1;
      Cpu_tot = smp_num_cpus;


Before cpus_refresh call.

No comments:

Post a Comment