[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Unknown HZ value



Yann Forget <yann.forget@ynternet.org> écrivait (wrote) :

> Bonsoir,
> 
> Mon serveur s'est mis à envoyer des messages de ce style
> toutes les heures.

Qu'est ce qui a changé entre temps ? Le noyau ? procps ? Juste l'uptime ?

> http://lists.sourceforge.net/archives/user-mode-linux-user/2000-October/000271.html
> ça aurait un rapport avec le 'kernel schedular' (kesako ?).
> 
> J'ai vu aussi des mails à ce sujet sur kernel-devel.
> 
> Bref, je ne comprends pas un traitre mot de ces explications.
> 
> C'est grave docteur ?

Ça n' en a pas l'air.

> # uptime
> Unknown HZ value! (0) Assume 100.
>   6:51pm  up 248 days, 17:51,  2 users,  load average: 2.02, 2.01, 2.00

Extrait de procps-2.0.7/proc/sysinfo.c (utilisé par ps, uptime, top, ...) :

static void init_Hertz_value(void){
[...]
  do{
    FILE_TO_BUF(UPTIME_FILE,uptime_fd);  sscanf(buf, "%lf", &up_1);
    /* uptime(&up_1, NULL); */
    FILE_TO_BUF(STAT_FILE,stat_fd);
    sscanf(buf, "cpu %lu %lu %lu %lu", &user_j, &nice_j, &sys_j, &other_j);
    FILE_TO_BUF(UPTIME_FILE,uptime_fd);  sscanf(buf, "%lf", &up_2);
    /* uptime(&up_2, NULL); */
  } while((long)( (up_2-up_1)*1000.0/up_1 )); /* want under 0.1% error */

On a récupéré les temps machine d'utilisation du processeur (première ligne
de /proc/stat) et deux temps d'uptime (première valeur de /proc/uptime) que 
l'on espère les plus proches possible.

  jiffies = user_j + nice_j + sys_j + other_j;

jiffies = temps machine d'utilisation des processeurs (user, nice, sys 
et idle, temps cumulés des différents procésseurs).

  seconds = (up_1 + up_2) / 2;

seconds = moyenne des deux uptime soit à peu près le temps d'uptime 
au moment de la mesure du temps d'utilisation.

  h = (unsigned long)( (double)jiffies/seconds/smp_num_cpus );

h = base de temps ordinateur = HZ

On connait quelques temps de base :

  /* actual values used by 2.4 kernels: 32 64 100 128 1000 1024 1200 */
  switch(h){
  case   30 ...   34 :  Hertz =   32; break; /* ia64 emulator */
  case   48 ...   52 :  Hertz =   50; break;
  case   58 ...   62 :  Hertz =   60; break;
  case   63 ...   65 :  Hertz =   64; break; /* StrongARM /Shark */
  case   95 ...  105 :  Hertz =  100; break; /* normal Linux */
  case  124 ...  132 :  Hertz =  128; break; /* MIPS, ARM */
  case  195 ...  204 :  Hertz =  200; break; /* normal << 1 */
  case  253 ...  260 :  Hertz =  256; break;
  case  393 ...  408 :  Hertz =  400; break; /* normal << 2 */
  case  790 ...  808 :  Hertz =  800; break; /* normal << 3 */
  case  990 ... 1010 :  Hertz = 1000; break; /* ARM */
  case 1015 ... 1035 :  Hertz = 1024; break; /* Alpha, ia64 */
  case 1180 ... 1220 :  Hertz = 1200; break; /* Alpha */

Mais chez toi, pour une raison que je ne connais pas, peut-être dû à ton 
uptime ?  à ton processeur ? à tes processeurs ? à un bug noyau ? le calcul
de h donne 0...

Voir tes /proc/stats et /proc/uptime...

Tu es donc branché sur :

  default:
#ifdef HZ
    Hertz = (unsigned long)HZ;    /* <asm/param.h> */
#else
    /* If 32-bit or big-endian (not Alpha or ia64), assume HZ is 100. */
    Hertz = (sizeof(long)==sizeof(int) || htons(999)==999) ? 100UL : 1024UL;
#endif
    fprintf(stderr, "Unknown HZ value! (%ld) Assume %ld.\n", h, Hertz);

Et paf le HZ.

A noter le commentaire présent en début de fonction :

/***********************************************************************
 * Some values in /proc are expressed in units of 1/HZ seconds, where HZ
 * is the kernel clock tick rate. One of these units is called a jiffy.
 * The HZ value used in the kernel may vary according to hacker desire.
 * According to Linus Torvalds, this is not true. He considers the values
 * in /proc as being in architecture-dependant units that have no relation
 * to the kernel clock tick rate. Examination of the kernel source code
 * reveals that opinion as wishful thinking.
 *
 * In any case, we need the HZ constant as used in /proc. (the real HZ value
 * may differ, but we don't care) There are several ways we could get HZ:
 *
 * 1. Include the kernel header file. If it changes, recompile this library.
 * 2. Use the sysconf() function. When HZ changes, recompile the C library!
 * 3. Ask the kernel. This is obviously correct...
 *
 * Linus Torvalds won't let us ask the kernel, because he thinks we should
 * not know the HZ value. Oh well, we don't have to listen to him.
 * Someone smuggled out the HZ value. :-)
 *
 * This code should work fine, even if Linus fixes the kernel to match his
 * stated behavior. The code only fails in case of a partial conversion.
 *
 */

               Jean Charles
-- 
Jean Charles Delépine - Équipe Réseaux Télécoms - Université de Picardie



Reply to: