Skip to contentSkip to conversation

PROBLEM SOLVED: 2.4.x SPINLOCKS behave differently then 2.2.x

DISCUSSION Alex Ivchenko 3 participants 3 messages Jul 18, 2001 – Jul 19, 2001

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw
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

#2 lore raw
In reply to Alex Ivchenko
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.