Re: [PATCH] No idle HZ aka dynticks i386 for 2.6.16-rc4

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

 



On Sat, Feb 25, 2006 at 03:30:57PM +1100, Con Kolivas wrote:
> +struct dyntick_timer {
> +	spinlock_t lock;
> +
> +	/* dyntick init */
> +	int (*arch_init)(void);
> +	/* Enables dynamic tick */
> +	int (*arch_enable)(void);
> +	/* Disables dynamic tick */
> +	int (*arch_disable)(void);
> +	/* Reprograms the timer */
> +	void (*arch_reprogram)(unsigned long);
> +	/* Function called when all cpus are idle, passing the idle duration */
> +	void (*arch_all_cpus_idle)(unsigned int);
> +
> +	unsigned short state;		/* Current state */
> +	unsigned int min_skip;		/* Min number of ticks to skip */
> +	unsigned int max_skip;		/* Max number of ticks to skip */
> +	unsigned long tick;		/* The next earliest tick */
> +};

If you make min_skip a short here, the structure will pack nicely and 
save 6 bytes of padding on 64 bit machines.  Alternatively, keep it an 
int and put it in the padding following the spinlock to save the whole 
8 bytes.

> +int dyntick_skipping(void)
> +{
> +	int ret = (get_cpu_var(dyn_cpu).next_tick > jiffies);
> +
> +	put_cpu_var(dyn_cpu);
> +	return ret;
>

This looks wrong...  Shouldn't it be time_after()?  Otherwise it seems to 
not work when jiffies wraps.

> +int dyntick_current_skip(void)
> +{
> +	int ret = 0;
> +
> +	if (get_cpu_var(dyn_cpu).next_tick > jiffies)
> +		ret = __get_cpu_var(dyn_cpu).skip;
> +	put_cpu_var(dyn_cpu);
> +	return ret;
> +}

Ditto.


> +/*
> + * Returns the next scheduled dyntick if we are skipping ticks.
> + */
> +unsigned long dyntick_next_tick(void)
> +{
> +	unsigned long next = 0;
> +
> +	if (get_cpu_var(dyn_cpu).next_tick > jiffies)
> +		next = __get_cpu_var(dyn_cpu).next_tick;
> +	put_cpu_var(dyn_cpu);
> +	return next;
> +}

Ditto.

> +/*
> + * dyn_early_reprogram is used to reprogram an earlier tick than is currently
> + * set by timer_dyn_reprogram.
> + * dyn_early_reprogram allows other code such as the acpi idle code to
> + * program an earlier tick than the one already chosen by timer_dyn_reprogram.
> + * It only reprograms it if the tick is earlier than the next one planned.
> + */
> +void dyn_early_reprogram(unsigned int delta)
> +{
> +	unsigned long flags, tick = jiffies + delta;
> +
> +	if (tick >= get_cpu_var(dyn_cpu).next_tick &&
> +		__get_cpu_var(dyn_cpu).next_tick > jiffies)
> +			goto put_out;

Ditto.

The SMP case requires a bit more thorough reading...  It seems there 
are a few places that call test_nohz_cpu() without taking the spinlock.  
That could be the race causing missed ticks on smp.  Cheers,

		-ben
-- 
"Ladies and gentlemen, I'm sorry to interrupt, but the police are here 
and they've asked us to stop the party."  Don't Email: <[email protected]>.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux