race condition in char driver

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
Reply to
Mark
Loading thread data ...

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:

formatting link

(init code)

spin_lock_init(&unit_p->open_lock);

(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
william.waddington@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Reply to
Bill Waddington

On Fri, 09 Apr 2010 06:45:58 -0700, Bill Waddington

[Repost>>

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:

formatting link

(init code)

spin_lock_init(&unit_p->open_lock);

(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
william.waddington@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Reply to
Bill Waddington

[...]

[...]

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.

Reply to
Rainer Weikusat

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
william.waddington@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Reply to
Bill Waddington

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

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

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
                              gmail.com            ... But no WOO-WOO!
Reply to
Grant Edwards

Bill Waddington wrote: [skip]

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
Reply to
Mark

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
william.waddington@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Reply to
Bill Waddington

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

Reply to
David Schwartz

[...]

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.

Reply to
Rainer Weikusat

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.