[parisc-linux] [PATCH] timer_interrupt and gettimeoffset.

Grant Grundler grundler at parisc-linux.org
Sun Sep 3 18:09:37 MDT 2006


On Sun, Sep 03, 2006 at 03:59:34PM -0400, John David Anglin wrote:
> > Is it ok if I only add the irqsave/restore to my current patch?
> > I also like the "avoid div/mul ops" test too.
> 
> I agree on that.  They are very expensive, especially in 64-bit code.
> 
> I'm playing with the patch below.  The main thing I tried to do is
> reduce the amount of code in the irqsave/restore.

I've not applied the irqsave/restore since I don't think it does anything.
do_cpu_irq_mask() doesn't allow nested external interrupts.

> GCC didn't do a great job of optimizing the code.  I think we would
> get better code if clocktick and halftick were copied to temps before
> the irqsave.

hrm...I would expect the same result from __read_mostly but can understand
why that's not as useful as I hoped.

Can we tell GCC that clocktick doesn't change during execution of this code?
ie despite being a global, it's a "constant" and doesn't need to be
reloaded on each loop iteration?


> I was also concerned about nticks not being unsigned long.

I agree. I'm leaning very strongly in favor of the unsigned version
of the code. Even though I think Carlos demonstrated the signed
math is correct. So unless someone objects to the unsigned version
I posted earlier soon (assuming I address all bug fixes), I'd like
to commit that in the next couple of days.

thanks,
grant

> 
> Dave
> -- 
> J. David Anglin                                  dave.anglin at nrc-cnrc.gc.ca
> National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)
> 
> Index: time.c
> ===================================================================
> RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/time.c,v
> retrieving revision 1.16
> diff -u -p -u -r1.16 time.c
> --- time.c	24 Jun 2006 16:05:18 -0000	1.16
> +++ time.c	3 Sep 2006 19:42:24 -0000
> @@ -47,29 +47,34 @@ irqreturn_t timer_interrupt(int irq, voi
>  {
>  	long now;
>  	long next_tick;
> -	int nticks;
> +	unsigned long nticks = 0;
>  	int cpu = smp_processor_id();
> +	long flags;
>  
>  	profile_tick(CPU_PROFILING, regs);
>  
> -	now = mfctl(16);
> -	/* initialize next_tick to time at last clocktick */
> +	/* Initialize next_tick to time at last clocktick */
>  	next_tick = cpu_data[cpu].it_value;
>  
> -	/* since time passes between the interrupt and the mfctl()
> -	 * above, it is never true that last_tick + clocktick == now.  If we
> -	 * never miss a clocktick, we could set next_tick = last_tick + clocktick
> -	 * but maybe we'll miss ticks, hence the loop.
> +	/* Since time passes between the interrupt and the mfctl(),
> +	 * it is never true that last_tick + clocktick == now.
> +	 * If we never miss a clocktick, we could set
> +	 * next_tick = last_tick + clocktick, * but maybe we'll miss
> +	 * ticks, hence the loop.
>  	 *
>  	 * Variables are *signed*.
>  	 */
>  
> -	nticks = 0;
> +	/* Don't want to be interrupted while calculating
> +	 * the time for the next tick.  */
> +	local_irq_save(flags);
> +	now = mfctl(16);
>  	while((next_tick - now) < halftick) {
>  		next_tick += clocktick;
>  		nticks++;
>  	}
>  	mtctl(next_tick, 16);
> +	local_irq_restore(flags);
>  	cpu_data[cpu].it_value = next_tick;
>  
>  	while (nticks--) {



More information about the parisc-linux mailing list