LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   rtc_interrupt() code ... "+ HZ/rtc_freq +" (https://www.linuxquestions.org/questions/linux-kernel-70/rtc_interrupt-code-hz-rtc_freq-736236/)

JimHughen 06-28-2009 01:13 PM

rtc_interrupt() code ... "+ HZ/rtc_freq +"
 
In the file: "linux-2.6.30/drivers/char/rtc.c"
in the interrupt handler at:

static irqreturn_t rtc_interrupt(int irq, void *dev_id)
{
...
if (rtc_status & RTC_TIMER_ON)
mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
...
return IRQ_HANDLED;
}

In particular "+ HZ/rtc_freq +".

Notice this expression has a non-constant divide, which begs
close inspection because this is in an important interrupt handler.

So...
HZ is a constant with apparent values of
100, 1000, 1024, or CONFIG_HZ.
(I can't find a definition of CONFIG_HZ in a *.h file)
rtc_freq is a "static unsigned long rtc_freq;"
defined in this module.
rtc_freq gets its value from
static int rtc_do_ioctl(RTC_IRQP_SET,unsigned long arg,...)

If 'unsigned long' is more a single 'div' instruction
(seems possible in some configurations), a multiple precision divide
routine might be called from this interrupt handler,
which would not be good.

If a single precision divide is used (more likely), something like
40 instruction cycles could be used.

Since this quotient (and subsequent constant addition
in this expression) does not change, wouldn't the performance
of this ISR be significantly improved if this math is done
outside of the ISR?

Maybe the correct terminology is to move these instructions to the
'Bottom Half' or equivalent.

JimHughen 06-29-2009 07:15 AM

I hope replying to one's own thread is allowed...

You may guess that I am learning Linux Kernel Development and
reading Robert Love's book by that name.

Quote:

Maybe the correct terminology is to move these instructions to the
'Bottom Half' or equivalent.
The previous 'Bottom Half' reference was, of course, not used correctly.

These little math expressions would be calculated/reduced at
(or just prior to) the interrupt handler being enabled.

This Bottom Half mechanism looks really nice, especially in networking
where message processing has a tendency to get into an interrupt handler.
With BH mechanisms, the interrupt handler can detect a special event
(say an inquire message to this terminal on a large network), respond
quickly to that event, without creating additional interrupt latency.

... good stuff this ...

lmaza 06-29-2009 12:54 PM

Re-CONFIG_HZ
 
Hello

I am a Linux Device Drivers 3rd Edition (LDD3) reader
In that book on chapter 7 Time, Delays, and Deferred Work says:

"Measuring Time Lapses
...
Timer interrupts are generated by the system's timing hardware at regular intervals; this interval is programmed at boot time by the kernel according to the value of HZ, which is an architecture-dependent value defined in <linux/param.h> or a subplataform file included by it."

The variable CONFIG_HZ does not seem to be included in the LDD3 book.
Maybe this could help.



Quote:

Originally Posted by JimHughen (Post 3589082)
In the file: "linux-2.6.30/drivers/char/rtc.c"
in the interrupt handler at:

static irqreturn_t rtc_interrupt(int irq, void *dev_id)
{
...
if (rtc_status & RTC_TIMER_ON)
mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
...
return IRQ_HANDLED;
}

In particular "+ HZ/rtc_freq +".

Notice this expression has a non-constant divide, which begs
close inspection because this is in an important interrupt handler.

So...
HZ is a constant with apparent values of
100, 1000, 1024, or CONFIG_HZ.
(I can't find a definition of CONFIG_HZ in a *.h file)
rtc_freq is a "static unsigned long rtc_freq;"
defined in this module.
rtc_freq gets its value from
static int rtc_do_ioctl(RTC_IRQP_SET,unsigned long arg,...)

If 'unsigned long' is more a single 'div' instruction
(seems possible in some configurations), a multiple precision divide
routine might be called from this interrupt handler,
which would not be good.

If a single precision divide is used (more likely), something like
40 instruction cycles could be used.

Since this quotient (and subsequent constant addition
in this expression) does not change, wouldn't the performance
of this ISR be significantly improved if this math is done
outside of the ISR?

Maybe the correct terminology is to move these instructions to the
'Bottom Half' or equivalent.


JimHughen 06-29-2009 02:08 PM

Thanks lmaza for responding.

I am very excited about learning this Linux kernel.
The Linux initiative is very important (even historically)
at this time. The ability to collaborate on such a scale is
tremendous.

Code:

  mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
The analysis of this expression is not primarily to detail
the 2nd parameter of the mod_timer() call. It is to predict
what code the compiler might generate. Of course, this type
of analysis is normally somewhat bizarre. However, consider
the side effect of an unnecessary multi-precision or
floating point expression in this interrupt handler.
Any reasonable optimization is advisable, if it improves the
system wide interrupt latency.

The term "+ HZ/rtc_freq +" appears to be a constant divided
by an 'unsigned long'. It looks like the preprocessor will
not be able to perform this division, so run time execution
will result.

I am in the habit of holding my interrupt handlers to very
tight scrutiny for execution cycles.


All times are GMT -5. The time now is 12:17 PM.