Get a reference count on the the sleeper, so that
it can't possibly go away before we've sent it the
wakeup event.
Noted by Nick Piggin <nickpiggin@yahoo.com.au>
David Howells <dhowells@redhat.com>
if (waiter->flags & RWSEM_WAITING_FOR_WRITE) {
sem->activity = -1;
list_del(&waiter->list);
- mb();
tsk = waiter->task;
+ mb();
waiter->task = NULL;
wake_up_process(tsk);
+ put_task_struct(tsk);
goto out;
}
struct list_head *next = waiter->list.next;
list_del(&waiter->list);
- mb();
tsk = waiter->task;
+ mb();
waiter->task = NULL;
wake_up_process(tsk);
+ put_task_struct(tsk);
woken++;
if (list_empty(&sem->wait_list))
break;
waiter = list_entry(sem->wait_list.next,struct rwsem_waiter,list);
list_del(&waiter->list);
- mb();
tsk = waiter->task;
+ mb();
waiter->task = NULL;
wake_up_process(tsk);
+ put_task_struct(tsk);
return sem;
}
/* set up my own style of waitqueue */
waiter.task = tsk;
waiter.flags = RWSEM_WAITING_FOR_READ;
+ get_task_struct(tsk);
list_add_tail(&waiter.list,&sem->wait_list);
/* set up my own style of waitqueue */
waiter.task = tsk;
waiter.flags = RWSEM_WAITING_FOR_WRITE;
+ get_task_struct(tsk);
list_add_tail(&waiter.list,&sem->wait_list);
goto readers_only;
list_del(&waiter->list);
- mb();
tsk = waiter->task;
+ mb();
waiter->task = NULL;
wake_up_process(tsk);
+ put_task_struct(tsk);
goto out;
/* don't want to wake any writers */
for (; loop>0; loop--) {
waiter = list_entry(next,struct rwsem_waiter,list);
next = waiter->list.next;
- mb();
tsk = waiter->task;
+ mb();
waiter->task = NULL;
wake_up_process(tsk);
+ put_task_struct(tsk);
}
sem->wait_list.next = next;
/* set up my own style of waitqueue */
spin_lock(&sem->wait_lock);
waiter->task = tsk;
+ get_task_struct(tsk);
list_add_tail(&waiter->list,&sem->wait_list);