PROBLEM SOLVED: 2.4.x SPINLOCKS behave differently then 2.2.x
Richard,
Quoted 10 lines · Linus Torvalds
Quoted 3 lines · Richard B. Johnson
ticks = 1 * HZ; /* For 1 second */
while((ticks = interruptible_sleep_on_timeout(&wqhead, ticks)) > 0);Don't do this.
Imagine what happens if a signal comes in and wakes you up? The signal will continue to be pending, which will make your "sleep loop" be a busy loop as you can never go to sleep interruptibly with a pending signal.
Well, the problem was quite different compare to what I thought.
Our hardware requires that once you start talking to firmware you cannot let anybody to interrupt you.
Thus, I lazily put in all "magic" handlers (read, write, ioctl):
my_ioctl() {
... do entry stuff_fw_spinlock // = spin_lock_irqsave(...);
.. do my stuff (nobody could interrupt me)
_fw_spinunlock // = spin_lock_irqrestore(...);
}
Everything worked fine under 2.2.x (I knew that this was a shortcut!!!) In 2.4.x I could not call wake_up_interruptible() while in spinlock (and it's clearly understandable).
Now it seems that I have to grab and release spinlock each time I talk to the board, exactly as I did in NT:
KeAcquireSpinLock(&Adapter->DeviceLock, &oldIrql);
if (KeSynchronizeExecution(Adapter->InterruptObject, PdAdapterEnableInterrupt, &Context));
KeReleaseSpinLock(&Adapter->DeviceLock, oldIrql);What d'u think?
Signature · 12 lines
Regards, Alex -- Alex Ivchenko, Ph.D. United Electronic Industries, Inc. "The High-Performance Alternative (tm)" -- 10 Dexter Avenue Watertown, Massachusetts 02472 Tel: (617) 924-1155 x 222 Fax: (617) 924-1441 http://www.ueidaq.com
Quoted 5 lines · Alex Ivchenko
Our hardware requires that once you start talking to firmware you cannot let anybody to interrupt you.
Thus, I lazily put in all "magic" handlers (read, write, ioctl):
Quoted 8 lines
my_ioctl(){
... do entry stuff_fw_spinlock// =spin_lock_irqsave(...);.. do my stuff (nobody could interrupt me)
_fw_spinunlock// =spin_lock_irqrestore(...);
}
This should be ok, but ONLY if you don't sleep or do anything that could sleep (or are otherwise bad) inside the spinlocks. The things you must not have inside spinlocks are
- global cli/sti
- scheduling calls (and things that call them - sleep etc)
- user memory access (get_user/put_user etc)
But a wake_up() should be fine.
Linus
Quoted 24 lines · Alex Ivchenko
Richard,
Quoted 10 lines · Linus Torvalds
Quoted 3 lines · Richard B. Johnson
ticks = 1 * HZ; /* For 1 second */
while((ticks = interruptible_sleep_on_timeout(&wqhead, ticks)) > 0);Don't do this.
Imagine what happens if a signal comes in and wakes you up? The signal will continue to be pending, which will make your "sleep loop" be a busy loop as you can never go to sleep interruptibly with a pending signal.
Well, the problem was quite different compare to what I thought.
Our hardware requires that once you start talking to firmware you cannot let anybody to interrupt you.
Thus, I lazily put in all "magic" handlers (read, write, ioctl):
my_ioctl(){
... do entry stuff_fw_spinlock// =spin_lock_irqsave(...);
Quoted 9 lines
.. do my stuff (nobody could interrupt me)
_fw_spinunlock// =spin_lock_irqrestore(...);
}Everything worked fine under 2.2.x (I knew that this was a shortcut!!!) In 2.4.x I could not call
wake_up_interruptible()while in spinlock (and it's clearly understandable).
Errm... You should be able to execute wake_up_interruptible() while in a spin-lock! It's callable from within ISRs, etc., and is how you tell poll() that some I/O condition as changed.
Just don't expect the wakeup to occur until after you release the spin-lock unless you have more than one CPU.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).
I was going to compile a list of innovations that could be attributed to Microsoft. Once I realized that Ctrl-Alt-Del was handled in the BIOS, I found that there aren't any.