Re: TODO: drivers/pcmcia/ds.c: ds_read

From: manfred (manfred@colorfullife.com)
Date: Thu Oct 12 2000 - 12:05:52 EST


Yong Chi wrote:
> Hopefully this will do for SMP locks. =)

You must not hold a spinlock across put_user - instead you must copy the
get_queued_event(user) into a local variable, spinunlock and then copy
it to userspace.

Compare drivers/sbus/char/sunkbd.c, function kbd_read from 2.2 and 2.4:
2.2.17 is bad, 2.4.0 is fixed.

>
> Todo list also said that on UP, sleep_on() use is unsafe. It uses
> "interruptible_sleep_on()" and "wake_up_interruptible()" calls. Are they
> not safe on UP?
>

I depends: there are exactly 2 safe uses for sleep_on(), all other
combinations can lock up:

1) The wake-up occurs from process context (neither bh nor interrupt),
and _both_ the thread that goes to sleep and the thread that wakes up
use lock_kernel().

2) If the wake-up occurs from interrupt context (only real interrupt or
bottom half, NOT from tasklet/softirq), then the thread that goes to
sleep must protect itself with the global cli lock.

wake_up_sleeper()
{
        new_data = 1;
        wake_up(&wait_queue);
}

go_to_sleep()
{
        /* local interrupts must be enabled */
        cli();
        if(!new_data) {
                sleep_on(&wait_queue);
        }
        sti();
}

IIRC handle_event is called from interrupt context, thus a wake-up can
happen from within an interrupt, but there is no cli() before the
sleep_on() --> lock-up, even on UP possible.

But do not add cli() - remove sleep_on() and replace it with something
like wait_event_irq() [from include/linux/raid/md_k.h]

--
	Manfred

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 15 2000 - 21:00:23 EST