Commit c2676ef8 authored by David Reynolds's avatar David Reynolds Committed by Mike Marshall

orangefs: bug fix for a race condition when getting a slot

When a slot becomes free, call wake_up_locked regardless of the number
of slots available.

Without this patch, wake_up_locked is only called when going from no
free slots to one. This means that there is a chance a waiting task
will not be woken up. In many cases, the system will bounce between 0
and 1 free slots, and the waiting tasks will be woken up. But if there
is still a waiting task and another slot becomes available before the
number of free slots reaches zero, that waiting task may never be woken
up since the number of free slots may never reach zero again.

The bug behavior is easy to reproduce with the following script,
where /mnt/orangefs is an OrangeFS file system.

for i in {1..100}; do
	for j in {1..20}; do
		dd if=/dev/zero of=/mnt/orangefs/tmp$j bs=32768 count=32 &
	done
	wait
done
Signed-off-by: default avatarDavid Reynolds <david@omnibond.com>
Reviewed-by: default avatarMartin Brandenburg <martin@omnibond.com>
Signed-off-by: default avatarMike Marshall <hubcap@omnibond.com>
parent 0adb3285
...@@ -71,9 +71,9 @@ static void put(struct slot_map *m, int slot) ...@@ -71,9 +71,9 @@ static void put(struct slot_map *m, int slot)
spin_lock(&m->q.lock); spin_lock(&m->q.lock);
__clear_bit(slot, m->map); __clear_bit(slot, m->map);
v = ++m->c; v = ++m->c;
if (unlikely(v == 1)) /* no free slots -> one free slot */ if (v > 0)
wake_up_locked(&m->q); wake_up_locked(&m->q);
else if (unlikely(v == -1)) /* finished dying */ if (unlikely(v == -1)) /* finished dying */
wake_up_all_locked(&m->q); wake_up_all_locked(&m->q);
spin_unlock(&m->q.lock); spin_unlock(&m->q.lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment