race condition in char driver

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I'm implementing a character driver simulating of MDIO/MDC functionality
(IEEE 802.3 clause 22) with GPIO pins; so what I do is write/read to/from
GPIO registers. The driver will provide /dev/my_dev, 'open' and 'release' as
usual, and also expose 'ioctl' interface to the user space, I/O control will
invoke driver functions mdio_read, mdio_write.

Now I wonder what happens when two or more processes simultaneously open
/dev/my_dev and try to read and write GPIO lines at once. Will it cause race
condition situation? As far as I understand, RC comes about when a shared
resource is accessed by two or more callers at once. But in my case, I
basically do not have a shared resource; or I'm wrong ?

Thanks.

--
Mark


Re: race condition in char driver
On Fri, 9 Apr 2010 11:24:26 +0900, "Mark"

Quoted text here. Click to load it

It's contention possible, but only a race condition if there is
actually a "race".  Two readers probably don't cause contention or
race, but two writers probabaly do, and simultaneous read/write
might.

Do you want this gadget to be a shared resource?  Do you care?  Will
your application code ever try to do two things at once?

If it is sufficient to just prevent two processes/applications from
opening the device at tha same time, use an exclusive open flat.  Set
it on open, clear it on release, and if a process calls open when it
is already set, return an error.  That handles contention.

Proctect the exclusive open flag with some kind of locking mechanism,
like a semaphore, for instance.  That handles the race.

You can do this separately for open for read and for write if that's
useful.

I do it thusly in one of my drivers:

http://www.tahomatech.com/downloads/drivers/linux_2.6/pci/x86/files/hardcopy/ihcp_driver.c

(init code)

spin_lock_init(&unit_p->open_lock);

<and init the rest of the flags and stuff>


(open)

/*
 * Only allow a single open
 */

spin_lock(&unit_p->open_lock);
if (unit_p->unit_open != 0) {
    DPRINTI("open called when already open!");
    spin_unlock(&unit_p->open_lock);
    return -EBUSY;
}

unit_p->unit_open = 1;
spin_unlock(&unit_p->open_lock);


(close)

unit_p->unit_open = 0;


Is that what you had in mind?

Bill
--
William D Waddington
snipped-for-privacy@beezmo.com
We've slightly trimmed the long signature. Click to see the full one.
Re: race condition in char driver
On Fri, 09 Apr 2010 06:45:58 -0700, Bill Waddington

[Reposting with _some_ of the typos corrected.  Sorry about that!]


Quoted text here. Click to load it

It's contention possibly, but only a race condition if there is
actually a "race".  Two readers probably don't cause contention or
race, but two writers probabaly do, and simultaneous read/write
might.

Do you want this gadget to be a shared resource?  Do you care?  Will
your application code ever try to do two things at once?

If it is sufficient to just prevent two processes/applications from
opening the device at the same time, use an exclusive open flag.  Set
it on open, clear it on release, and if a process calls open when it
is already set, return an error.  That handles contention.

Protect the exclusive open flag with some kind of locking mechanism,
like a semaphore, for instance.  That handles the race for the open
flag.

You can do this separately for open for read and for write if that's
useful.

I do it thusly in one of my drivers:

http://www.tahomatech.com/downloads/drivers/linux_2.6/pci/x86/files/hardcopy/ihcp_driver.c

(init code)

spin_lock_init(&unit_p->open_lock);

<and init the rest of the flags and stuff>


(open)

/*
 * Only allow a single open
 */

spin_lock(&unit_p->open_lock);
if (unit_p->unit_open != 0) {
    DPRINTI("open called when already open!");
    spin_unlock(&unit_p->open_lock);
    return -EBUSY;
}

unit_p->unit_open = 1;
spin_unlock(&unit_p->open_lock);


(close)

unit_p->unit_open = 0;


Is that what you had in mind?

Bill
--
William D Waddington
snipped-for-privacy@beezmo.com
We've slightly trimmed the long signature. Click to see the full one.
Re: race condition in char driver
Quoted text here. Click to load it

[...]

Quoted text here. Click to load it

[...]

Quoted text here. Click to load it

Not really. File descriptors can be cloned with dup, dup2 and fcntl,
sent to other processes utilizing AF_UNIX sockets and inherited by
random applications via fork/exec. Arbitrating access to a particular
device is a policy descision and because of this, making the descision
in user space, for instance, with the help of fcntl-style locks, might
be a better idea.

Re: race condition in char driver
On Fri, 09 Apr 2010 16:38:40 +0200, Rainer Weikusat

Quoted text here. Click to load it

Hmmm.  Thanks for that.  I've got to contemplate what that means for
my drivers.  Probably nothing in my particular environment, but it's
something to think about.

Bill
--
William D Waddington
snipped-for-privacy@beezmo.com
We've slightly trimmed the long signature. Click to see the full one.
Re: race condition in char driver

Quoted text here. Click to load it

Arguably, the decision is made in user-space in both cases. With the
open flag method, a server specifically for this purpose can open the
device and then hand over file descriptors to it to any combination of
processes it wants to using whatever policy it is coded to use.

Which method is better depends on what you want your user-space code
to look like.

DS

Re: race condition in char driver
[skip]
Quoted text here. Click to load it

So if I understand you right, with this approach, when a user application
tries to open the device which is already locked, it will receive EBUSY
errno or the like.

Rainer's suggestion to move arbitration entirely on the user level is good
too: lock files or similar would work well too.

Thank you very much for the ideas.

--
Mark


Re: race condition in char driver
On Mon, 12 Apr 2010 11:37:21 +0900, "Mark"

Quoted text here. Click to load it

Yep.


No clue there.  I wonder about _enforcement_ at the user level.  Since
I don't have any control over the apps that use my drivers, I do what
I can at the driver level.

Kind of seems to me that the user space chosing to dup a file
descriptor is a choice to allow multiple processes to access the
device.

Use whatever suits your driver and application. I'm going to go
contemplate Rainer's comments.  Old, but not too old to learn. I
hope.

Bill
--
William D Waddington
snipped-for-privacy@beezmo.com
We've slightly trimmed the long signature. Click to see the full one.
Re: race condition in char driver
Quoted text here. Click to load it

[...]

Quoted text here. Click to load it

The point I was trying to make is that you cannot enforce a usage
policy at the driver level and that you shouldn't be trying
to, because all you can realistically achieve is to inconvenience
people trying to use your driver in ways you didn't foresee.

Re: race condition in char driver

Quoted text here. Click to load it

It will if you don't use proper locking when your driver when it is
performing multi-cycle operations that need to be atomic.

Quoted text here. Click to load it

That's when it _may_ happen.  You can prevent it with proper locking.

Quoted text here. Click to load it

How would we know what the internals of your driver look like?

Presumably the GPIO pins are "shared" (there isn't one copy of the
pins for each process that opens the device), so any operations that
need to be atomic (e.g. read/modify/write) need to properly
serialized.

--
Grant Edwards               grant.b.edwards        Yow! I didn't order any
                                  at               WOO-WOO ... Maybe a YUBBA
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline