Tuesday, 9 October 2018

Difference between 2 jiffies

What is jiffies:


  • The original kernel timer system (called the "timer wheel) was based on incrementing a kernel-internal value (jiffies) every timer interrupt.
  • The timer interrupt rate (and jiffy increment rate) is defined by a compile-time constant called HZ.
  • Different platforms use different values for HZ.
  • The kernel used 100 as the value for HZ, yielding a jiffy interval of 10 ms.
  • With 2.4, the HZ value for i386 was changed to 1000, yeilding a jiffy interval of 1 ms.
  • Process:
    • When jiffy count is incremented then a process gets time to run.
    • The jiffies are incremented by the timer interrupt that tells the scheduler to reschedule
    •  If the process calls yield() or sleep(), for example, then rescheduling takes place immediately.
    • Thus the context switch to a next available running process not necessarily occurs at the jiffy boundary.
  • It lists /proc/timer_list and /proc/timer_stats.
  • Tick generation:
    • It is updated every tick 
    • tick is triggered by timer/clock interrupt.
    • The interrupt is generated by Intel 8253 or HPET hardware
    • So it won't update until the hardware was property initialized.
  • Difference:
    • There is a better solution to ensure correct jiffy wrap handling in *ALL* kernel code: make jiffy wrap in first five minutes of uptime.
    • #define INITIAL_JIFFIES (0xffffffffUL & (unsigned long)(-300*HZ))
    • Hence jiffies is using the full 32 bit, after that overflow happen.
    • So jiffies.h file comment as maximum jiffie value is (MAX_INT >> 1) is a false comment.
    • Don't use MAX_JIFFY_OFFSET as max value since this is wrong.
    • https://lwn.net/Articles/22874/

Program:


Wrong program:

  • This below code is wrong, because jiffies is using the full 32 bit confirmed by after bootup jiffies overflow in 5 min, 
  • So after bootup just checked the jiffies value, it is using full 32 bit before overflow.
  • Hence below code is wrong, this is wrongly used in some of kernel code.

inline unsigned long jiffies_time_diff(unsigned long start, unsigned long end)
{
    if (end >= start)
        return end - start;
    return end + (MAX_JIFFY_OFFSET - start);
}

Correct program:


inline unsigned long jiffies_time_diff(unsigned long start, unsigned long end)
{  
       unsigned long diff = 0;

       /* This code is handle the overflow also, by converting to long.
            if jiffies start time is 13 and after overflowed end time is 5 then, coverting to sign
            difference value is -8, the 1st complement +1 value of -8 is stored as big value in unsiged diff.
            This is the correct difference */
       diff = (long)end - (long) start;
       return diff;
}
        

No comments:

Post a Comment