Re: adding semaphores to my device driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



HI Greg.

On Wed, Sep 15, 2010 at 5:57 AM, Greg Freemyer <greg.freemyer@xxxxxxxxx> wrote:
> <snip>
>>
>> I generally use spinlocks for protecting my shared data.
>
> Reasonable, but IMHO a mutex should be used to protect a hardware
> device.  I know James is not you working with real hardware, but since
> he's trying to learn good habits it seems more logical to protect his
> buffer as if it were real hardware.

Generally, when "protecting" a hardware device, what you're really
trying to do is prevent the ISR and non-ISR contexts from both
accessing the device at the same time. This can't be accomplished
using a mutex.

If the only thing accessing the hardware is thread context, then you
can use a mutex.

> The reason I dislike spin locks for real hardware is if the hardware
> is slow to respond for whatever reason.  Let's assume you have a fast
> device that should complete the transaction in microseconds, so you
> decide to protect it with a spin lock.

spinlocks are generally much faster than using mutexes.

> It seems reasonable to spin for microseconds waiting for another
> process to release the lock, but then consider the malfunction
> situation where the device never completes the transaction.  Waiting
> on a spin lock basically forever is going to drastically affect the
> performance of the machine.  And if 9 additional tasks find themselves
> spinning on the one spin lock because of a hardware failure, you
> basically have a dead machine.

It sounds to me like you don't really understand what spinlocks are
and how they're used.

First of all, spinlocks are typically used in conjunction with
disabling interrupts. So the normal use goes something like this:

unsigned long flags;
spin_lock_irqsave( &lock, flags );
... do protected stuff ...
spin_lock_irqrestore( &lock, flags );

On a uniprocessor system, the spinlock locking/unlocking becomes a
no-op, and you essentially get the equivalent sequence of:

unsigned long flags;
local_irq_save( flags );
... do protected stuff ...
local_irq_restore( flags );

Spinlocks in conjunction with disabling interrupts are intended to be
used as a protection mechanism between ISRs and non-ISR context.
They're not intended to be used between processes.

The spinlock portion only really makes sense on a multi-CPU scenario,
since disabling interrupts only disables interrupts on your CPU, not
globally across all CPUs.

> A mutex would not have the same negative impact.  Obviously the dead
> device would be INOP, but the rest of the system would still work
> fine.
>
> Thus I would avoid spin locks when protecting devices, even conceptual
> ones.  It leads to what I consider bad practice when you move to real
> hardware.

spinlocks should be used where they were intended to be used, and
mutexes should be used where they're supposed to be used.

spinlocks/disabling IRQs are intended to be used between ISRs and
non-ISR context.
mutexes are designed to be used in thread context and cannot be used
in ISR context.

mutexes are definitely heavier than spinlocks, and if you look at the
implementation of mutexes, you'll find that they actually use
spinlocks (because it is OK to unlock a mutex from an ISR, it just
isn't OK to lock a mutex from an ISR).

-- 
Dave Hylands
Shuswap, BC, Canada
http://www.DaveHylands.com/

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux