Re: Fix for binfmt_misc / Question about locking [PATCH]

Gordon Oliver (gordo@telsur.cl)
Fri, 8 Aug 1997 13:43:26 -0400 (CST)


...Richard Guenther says...:
> My question now is: Is it ok to do no locking at all, if we can sure,
> that only root could trigger a race condition (which could cause an
> oops, of cause)??

NO! doing a reasonable thing should _never_ cause an oops.

> Or do we have to avoid every race condition we know
> of, regardless what cost it has?

It really isn't that expensive. Only lock for writes.

So the algorithm goes like so:
read:
[SMP]atomic_increment reader counter
walk list, looking for format.
if found
use it.
[SMP]atomic decrement reader counter
[SMP]if reader counter == 0 wake up wait queue

add:
down write semaphore.
walk list to appropriate spot.
insert element. (elem->next = insert_point->next;
insert_point->next = elem)
up write semaphore.

delete:
down write semaphore.
find element.
link around element (prev->next = elem->next)
_don't_ change next pointer on element until it is deleted
the safety here is that if someone is looking at
the element you just deleted, they will either
use the element, or will go down the next pointer.
If you change the next pointer, sometimes a format
will fail to work.
if reader_counter == 0
delete element;
else
wait in wait queue
delete element;

The counter is actually safer if it is on all systems, and only does the
atomic increment if it is SMP. That way it doesn't even matter if the
code sleeps while accessing the queue. Assuming of course that this
code is never accessed from interrupts

Note that the insertion/deletion operations are atomic as long as the
write to the next pointer is atomic. (I presume that this is safe
in the linux kernel, if not you need a kernel lock to change it)
Does someone somewhere guarantee that
ptr = val;
is atomic? If not you need to use xchg to write the pointer.

You could probably avoid even the write lock, but it also probably
isn't worth the bother.
-gordo