Messages in this thread |  | | Date | Thu, 12 Oct 2000 19:05:52 +0200 | From | manfred <> | Subject | Re: TODO: drivers/pcmcia/ds.c: ds_read |
| |
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/
|  |