On 04.09.2005 [23:44:16 -0700], Nishanth Aravamudan wrote:
> On 05.09.2005 [12:02:29 +0530], Srivatsa Vaddagiri wrote:
> > On Sun, Sep 04, 2005 at 10:48:13PM -0700, Nishanth Aravamudan wrote:
> > > Admittedly, I don't think SMP ARM has been around all that long?
> > > Maybe the existing code just has not been extended.
> > 
> > Yeah, maybe ARM never cared for SMP. But we do care :)
> 
> I just took a look at arm/Kconfig and SMP is marked as EXPERIMENTAL &&
> BROKEN. So I'm guessing that is the only reason for some of the
> differences you mentioned (the differences are of course, valid and the
> x86 SMP implementation makes sense to me to extend arch-independently).
> 
> > > I'm not sure on this. It's going to be NULL for other architectures,
> > > or end up being called by the reprogram() call for the last CPU to
> > > go idle, right (presuming there isn't a separate TOD source, like in
> > > x86). I think it is better to be in the reprogram() interface.
> > 
> > Non-x86 could have it set to NULL, in which case it doesn't get
> > called.  (I know the current code does not take care of this
> > situation).  But having an explicit 'all_cpus_idle' interface may be
> > good, since Tony talked of idling some devices when all CPUs are idle.
> > So it probably has non-x86/PIT uses too.
> 
> OK, not a problem. I'll try and write up a general intsource.h file
> (interrupt source header) tonight and tomorrow and send it to this list
> to see if everybody agrees on what's in the structure and where the
> arch-independent/dependent line lies.

Sigh, later than I had hoped, but here is what I have hashed out so far.
Does it seem like a step in the right direction? Rather hand-wavy, but I
think it's mostly correct ;)

Thanks,
Nish


- include/linux/intsource.h
        with definitions in kernel/intsource.c

#define DYN_TICK_ENABLED        (1 << 1)
#define DYN_TICK_SUITABLE       (1 << 0)

#define DYN_TICK_MIN_SKIP       2

/* Abstraction of an interrupt source
 * @state: current state
 * @max_skip: current maximum number of ticks to skip
 * @arch_init: initialization routine
 * @arch_enable_dyn_tick: called via sysfs to enable interrupt skipping
 * @arch_disable_dyn_tick: called via sysfs to disable interrupt
 *                              skipping
 * @arch_set_all_cpus_idle: last cpu to go idle calls this, which should
 *                              disable any timesource (e.g. PIT on x86)
 * @arch_recover_time: handler for returning from skipped ticks and keeping
 *                              time consistent
 */
struct interrupt_source {
        unsigned int state;
        unsigned long max_skip;
        int (*arch_init) (void);
        void (*arch_enable_dyn_tick) (void);
        void (*arch_disable_dyn_tick) (void);
        unsigned long (*arch_reprogram) (unsigned long); /* return number of 
ticks skipped */
        unsigned long (*arch_recover_time) (int, void *, struct pt_regs *); /* 
handler in arm */
        /* following empty in UP */
        void (*arch_set_all_cpus_idle) (int);
        spinlock_t lock;
};

extern void interrupt_source_register(struct interrupt_source 
*new_interrupt_source);
extern struct interrupt_source *current_intsource;

#ifdef CONFIG_NO_IDLE_HZ
extern void set_interrupt_max_skip(unsigned long max_skip);
/* idle_reprogram_interrupt calls reprogram_interrupt calls 
current_intsource->arch_reprogram()
 * do we really need the first step? */
extern void idle_reprogram_interrupt(void);
/* return number of ticks skipped, potentially for accounting purposes? */
extern unsigned long reprogram_interrupt(void);

extern struct interrupt_source * __init arch_select_interrupt_source(void);
extern void __init dyn_tick_init(void); /* calls select_interrupt_source(), 
verifies source is usable, then calls interrupt_source_register() */

static inline int dyn_tick_enabled(void)
{
        return (current_intsource->state & DYN_TICK_ENABLED);
}

#else   /* CONFIG_NO_IDLE_HZ */
static inline void set_interrupt_max_skip(unsigned long max_skip)
{
}

static inline void idle_reprogram_interrupt(void)
{
}

static inline unsigned long reprogram_interrupt(void)
{
        return 0;
}

static inline void dyn_tick_init(void)
{
}

static inline int dyn_tick_enabled(void)
{
        return 0;
}
#endif  /* CONFIG_NO_IDLE_HZ */

/* Pick up arch specific header */
#include <asm/intsource.h>

#endif  /* _DYN_TICK_TIMER_H */

- sched.c / sched.h
        /* do we want these elsewhere? */
        cpumask_t no_idle_hz_cpumask;

* each arch-specific file pair needs to provide:
        arch_select_interrupt_source();
        appropriate struct interrupt_source definitions, functions, etc.

- include/asm-i386/intsource.h
        with defines in arch/i386/intsource.c

- include/asm-arm/arch-omap/intsource.h
        with definitions in arch/arm/mach-omap/intsource.c

- include/asm-s390/intsource.h
        with definitions in arch/s390/intsource.c

- include/asm-generic/intsource.h
        do I need something here?
-
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/

Reply via email to