]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/locking/rwsem-xadd.c
sched/wake_q: Reduce reference counting for special users
[linux.git] / kernel / locking / rwsem-xadd.c
index 09b180063ee11681f30a0f7e9b71a01acb3e7cc0..fbe96341beeed2c37f84526cb70adbe1b8734156 100644 (file)
@@ -198,15 +198,20 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem,
                woken++;
                tsk = waiter->task;
 
-               wake_q_add(wake_q, tsk);
+               get_task_struct(tsk);
                list_del(&waiter->list);
                /*
-                * Ensure that the last operation is setting the reader
+                * Ensure calling get_task_struct() before setting the reader
                 * waiter to nil such that rwsem_down_read_failed() cannot
                 * race with do_exit() by always holding a reference count
                 * to the task to wakeup.
                 */
                smp_store_release(&waiter->task, NULL);
+               /*
+                * Ensure issuing the wakeup (either by us or someone else)
+                * after setting the reader waiter to nil.
+                */
+               wake_q_add_safe(wake_q, tsk);
        }
 
        adjustment = woken * RWSEM_ACTIVE_READ_BIAS - adjustment;