lkcd
[Top] [All Lists]

Re: Non disruptive dumps -- current work.

To: Keith Owens <kaos@xxxxxxxxxx>, lkcd@xxxxxxxxxxx
Subject: Re: Non disruptive dumps -- current work.
From: "Matt D. Robinson" <yakker@xxxxxxxxxxxxxx>
Date: Mon, 17 Sep 2001 16:44:56 -0700
Organization: Alacritech, Inc.
References: <20778.1000544488@ocs3.intra.ocs.com.au> <3BA3DB73.F731D08F@alacritech.com>
Sender: owner-lkcd@xxxxxxxxxxx
"Matt D. Robinson" wrote:
> 
> Keith Owens wrote:
> >
> > On Sat, 15 Sep 2001 01:43:45 -0700,
> > "Matt D. Robinson" <yakker@xxxxxxxxxxxxxx> wrote:
> > >       cli();
> > >       saved_cpu_online_map = cpu_online_map;
> > >       cpu_online_map = smp_processor_id();
> > >       setup_IO_APIC_irqs();
> > >       cpu_online_map = saved_cpu_online_map;
> > >       sti();
> >
> > setup_IO_APIC_irqs() is defined __init, the code does not exist after
> > boot.  Sounds like you need Rusty Russell's hot swap cpu code,
> > http://sourceforge.net/projects/lhcs/.
> 
> Easy enough to remove the __init ... :)
> 
> Rusty's code is close to what want, but doesn't do enough with the
> IO-APIC (directly).  It's a combination of both, I think.
> 
> Time to read more of Rusty's code.  It looks like most of the
> __cpu_disable() function can be used, but changed to only go to
> the dumping CPU (not any active CPU).
> 
> --Matt

Just an FYI for folks following this, the setup_IO_APIC_irqs()
mechanism doesn't work (it fails miserably, actually).  I'm going
to try something similar to the following:

int __dump_cpu_disable(unsigned int dumping_cpu)
{
    int i;
    unsigned long val, cpu = smp_processor_id();
    if ((cpu == 0) || (cpu == dumping_cpu)) return -EINVAL;
    clear_bit(cpu, &cpu_online_map);
    mb();
    /* first, move everyone to the dumping CPU */
    for (i = 0; i < NR_IRQS; i++) {
        if (irq_desc[i].handler == NULL) continue;
        val = irq_affinity[i];
        if (val & (1 << cpu)) {
            if (!(val & cpu_online_map))
                val = (1 << dumping_cpu);
            else
                val = val & ~(1 << cpu);
            irq_affinity[i] = val;
            if (irq_desc[i].handler->set_affinity != NULL)
                irq_desc[i].handler->set_affinity(i, val);
        }
    }
 
    cli();
    sti();
    return 0;
}

That last wierd cli()/sti() is supposed to catch a case where
IRQs may be running with interrupts disabled, and they haven't
quite flushed out yet.

Note that this doesn't take care of spinning the CPUs.
Something else has to be added for that case.  Most of this
comes from Rusty's __cpu_disable(), but changed so that it
doesn't randomly pass irqs to any CPU, and takes a dumping
CPU argument.

--Matt

<Prev in Thread] Current Thread [Next in Thread>