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]