LCOV - code coverage report
Current view: top level - kernel/sched - wait.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 152 30.3 %
Date: 2023-08-24 13:40:31 Functions: 8 25 32.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * Generic waiting primitives.
       4             :  *
       5             :  * (C) 2004 Nadia Yvette Chambers, Oracle
       6             :  */
       7             : 
       8        1447 : void __init_waitqueue_head(struct wait_queue_head *wq_head, const char *name, struct lock_class_key *key)
       9             : {
      10        1703 :         spin_lock_init(&wq_head->lock);
      11             :         lockdep_set_class_and_name(&wq_head->lock, key, name);
      12        3406 :         INIT_LIST_HEAD(&wq_head->head);
      13        1447 : }
      14             : 
      15             : EXPORT_SYMBOL(__init_waitqueue_head);
      16             : 
      17           0 : void add_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry)
      18             : {
      19             :         unsigned long flags;
      20             : 
      21           0 :         wq_entry->flags &= ~WQ_FLAG_EXCLUSIVE;
      22           0 :         spin_lock_irqsave(&wq_head->lock, flags);
      23           0 :         __add_wait_queue(wq_head, wq_entry);
      24           0 :         spin_unlock_irqrestore(&wq_head->lock, flags);
      25           0 : }
      26             : EXPORT_SYMBOL(add_wait_queue);
      27             : 
      28           0 : void add_wait_queue_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry)
      29             : {
      30             :         unsigned long flags;
      31             : 
      32           0 :         wq_entry->flags |= WQ_FLAG_EXCLUSIVE;
      33           0 :         spin_lock_irqsave(&wq_head->lock, flags);
      34           0 :         __add_wait_queue_entry_tail(wq_head, wq_entry);
      35           0 :         spin_unlock_irqrestore(&wq_head->lock, flags);
      36           0 : }
      37             : EXPORT_SYMBOL(add_wait_queue_exclusive);
      38             : 
      39           0 : void add_wait_queue_priority(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry)
      40             : {
      41             :         unsigned long flags;
      42             : 
      43           0 :         wq_entry->flags |= WQ_FLAG_EXCLUSIVE | WQ_FLAG_PRIORITY;
      44           0 :         spin_lock_irqsave(&wq_head->lock, flags);
      45           0 :         __add_wait_queue(wq_head, wq_entry);
      46           0 :         spin_unlock_irqrestore(&wq_head->lock, flags);
      47           0 : }
      48             : EXPORT_SYMBOL_GPL(add_wait_queue_priority);
      49             : 
      50           0 : void remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry)
      51             : {
      52             :         unsigned long flags;
      53             : 
      54           0 :         spin_lock_irqsave(&wq_head->lock, flags);
      55           0 :         __remove_wait_queue(wq_head, wq_entry);
      56           0 :         spin_unlock_irqrestore(&wq_head->lock, flags);
      57           0 : }
      58             : EXPORT_SYMBOL(remove_wait_queue);
      59             : 
      60             : /*
      61             :  * Scan threshold to break wait queue walk.
      62             :  * This allows a waker to take a break from holding the
      63             :  * wait queue lock during the wait queue walk.
      64             :  */
      65             : #define WAITQUEUE_WALK_BREAK_CNT 64
      66             : 
      67             : /*
      68             :  * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just
      69             :  * wake everything up. If it's an exclusive wakeup (nr_exclusive == small +ve
      70             :  * number) then we wake that number of exclusive tasks, and potentially all
      71             :  * the non-exclusive tasks. Normally, exclusive tasks will be at the end of
      72             :  * the list and any non-exclusive tasks will be woken first. A priority task
      73             :  * may be at the head of the list, and can consume the event without any other
      74             :  * tasks being woken.
      75             :  *
      76             :  * There are circumstances in which we can try to wake a task which has already
      77             :  * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns
      78             :  * zero in this (rare) case, and we handle it by continuing to scan the queue.
      79             :  */
      80         327 : static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode,
      81             :                         int nr_exclusive, int wake_flags, void *key,
      82             :                         wait_queue_entry_t *bookmark)
      83             : {
      84             :         wait_queue_entry_t *curr, *next;
      85         327 :         int cnt = 0;
      86             : 
      87             :         lockdep_assert_held(&wq_head->lock);
      88             : 
      89         327 :         if (bookmark && (bookmark->flags & WQ_FLAG_BOOKMARK)) {
      90           0 :                 curr = list_next_entry(bookmark, entry);
      91             : 
      92           0 :                 list_del(&bookmark->entry);
      93           0 :                 bookmark->flags = 0;
      94             :         } else
      95         327 :                 curr = list_first_entry(&wq_head->head, wait_queue_entry_t, entry);
      96             : 
      97         327 :         if (&curr->entry == &wq_head->head)
      98             :                 return nr_exclusive;
      99             : 
     100           0 :         list_for_each_entry_safe_from(curr, next, &wq_head->head, entry) {
     101           0 :                 unsigned flags = curr->flags;
     102             :                 int ret;
     103             : 
     104           0 :                 if (flags & WQ_FLAG_BOOKMARK)
     105           0 :                         continue;
     106             : 
     107           0 :                 ret = curr->func(curr, mode, wake_flags, key);
     108           0 :                 if (ret < 0)
     109             :                         break;
     110           0 :                 if (ret && (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
     111             :                         break;
     112             : 
     113           0 :                 if (bookmark && (++cnt > WAITQUEUE_WALK_BREAK_CNT) &&
     114           0 :                                 (&next->entry != &wq_head->head)) {
     115           0 :                         bookmark->flags = WQ_FLAG_BOOKMARK;
     116           0 :                         list_add_tail(&bookmark->entry, &next->entry);
     117             :                         break;
     118             :                 }
     119             :         }
     120             : 
     121             :         return nr_exclusive;
     122             : }
     123             : 
     124         327 : static int __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int mode,
     125             :                         int nr_exclusive, int wake_flags, void *key)
     126             : {
     127             :         unsigned long flags;
     128             :         wait_queue_entry_t bookmark;
     129         327 :         int remaining = nr_exclusive;
     130             : 
     131         327 :         bookmark.flags = 0;
     132         327 :         bookmark.private = NULL;
     133         327 :         bookmark.func = NULL;
     134             :         INIT_LIST_HEAD(&bookmark.entry);
     135             : 
     136             :         do {
     137         327 :                 spin_lock_irqsave(&wq_head->lock, flags);
     138         327 :                 remaining = __wake_up_common(wq_head, mode, remaining,
     139             :                                                 wake_flags, key, &bookmark);
     140         654 :                 spin_unlock_irqrestore(&wq_head->lock, flags);
     141         327 :         } while (bookmark.flags & WQ_FLAG_BOOKMARK);
     142             : 
     143         327 :         return nr_exclusive - remaining;
     144             : }
     145             : 
     146             : /**
     147             :  * __wake_up - wake up threads blocked on a waitqueue.
     148             :  * @wq_head: the waitqueue
     149             :  * @mode: which threads
     150             :  * @nr_exclusive: how many wake-one or wake-many threads to wake up
     151             :  * @key: is directly passed to the wakeup function
     152             :  *
     153             :  * If this function wakes up a task, it executes a full memory barrier
     154             :  * before accessing the task state.  Returns the number of exclusive
     155             :  * tasks that were awaken.
     156             :  */
     157         167 : int __wake_up(struct wait_queue_head *wq_head, unsigned int mode,
     158             :               int nr_exclusive, void *key)
     159             : {
     160         167 :         return __wake_up_common_lock(wq_head, mode, nr_exclusive, 0, key);
     161             : }
     162             : EXPORT_SYMBOL(__wake_up);
     163             : 
     164             : /*
     165             :  * Same as __wake_up but called with the spinlock in wait_queue_head_t held.
     166             :  */
     167           0 : void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr)
     168             : {
     169           0 :         __wake_up_common(wq_head, mode, nr, 0, NULL, NULL);
     170           0 : }
     171             : EXPORT_SYMBOL_GPL(__wake_up_locked);
     172             : 
     173           0 : void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key)
     174             : {
     175           0 :         __wake_up_common(wq_head, mode, 1, 0, key, NULL);
     176           0 : }
     177             : EXPORT_SYMBOL_GPL(__wake_up_locked_key);
     178             : 
     179           0 : void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head,
     180             :                 unsigned int mode, void *key, wait_queue_entry_t *bookmark)
     181             : {
     182           0 :         __wake_up_common(wq_head, mode, 1, 0, key, bookmark);
     183           0 : }
     184             : EXPORT_SYMBOL_GPL(__wake_up_locked_key_bookmark);
     185             : 
     186             : /**
     187             :  * __wake_up_sync_key - wake up threads blocked on a waitqueue.
     188             :  * @wq_head: the waitqueue
     189             :  * @mode: which threads
     190             :  * @key: opaque value to be passed to wakeup targets
     191             :  *
     192             :  * The sync wakeup differs that the waker knows that it will schedule
     193             :  * away soon, so while the target thread will be woken up, it will not
     194             :  * be migrated to another CPU - ie. the two threads are 'synchronized'
     195             :  * with each other. This can prevent needless bouncing between CPUs.
     196             :  *
     197             :  * On UP it can prevent extra preemption.
     198             :  *
     199             :  * If this function wakes up a task, it executes a full memory barrier before
     200             :  * accessing the task state.
     201             :  */
     202         160 : void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode,
     203             :                         void *key)
     204             : {
     205         160 :         if (unlikely(!wq_head))
     206             :                 return;
     207             : 
     208         160 :         __wake_up_common_lock(wq_head, mode, 1, WF_SYNC, key);
     209             : }
     210             : EXPORT_SYMBOL_GPL(__wake_up_sync_key);
     211             : 
     212             : /**
     213             :  * __wake_up_locked_sync_key - wake up a thread blocked on a locked waitqueue.
     214             :  * @wq_head: the waitqueue
     215             :  * @mode: which threads
     216             :  * @key: opaque value to be passed to wakeup targets
     217             :  *
     218             :  * The sync wakeup differs in that the waker knows that it will schedule
     219             :  * away soon, so while the target thread will be woken up, it will not
     220             :  * be migrated to another CPU - ie. the two threads are 'synchronized'
     221             :  * with each other. This can prevent needless bouncing between CPUs.
     222             :  *
     223             :  * On UP it can prevent extra preemption.
     224             :  *
     225             :  * If this function wakes up a task, it executes a full memory barrier before
     226             :  * accessing the task state.
     227             :  */
     228           0 : void __wake_up_locked_sync_key(struct wait_queue_head *wq_head,
     229             :                                unsigned int mode, void *key)
     230             : {
     231           0 :         __wake_up_common(wq_head, mode, 1, WF_SYNC, key, NULL);
     232           0 : }
     233             : EXPORT_SYMBOL_GPL(__wake_up_locked_sync_key);
     234             : 
     235             : /*
     236             :  * __wake_up_sync - see __wake_up_sync_key()
     237             :  */
     238           0 : void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode)
     239             : {
     240           0 :         __wake_up_sync_key(wq_head, mode, NULL);
     241           0 : }
     242             : EXPORT_SYMBOL_GPL(__wake_up_sync);      /* For internal use only */
     243             : 
     244           0 : void __wake_up_pollfree(struct wait_queue_head *wq_head)
     245             : {
     246           0 :         __wake_up(wq_head, TASK_NORMAL, 0, poll_to_key(EPOLLHUP | POLLFREE));
     247             :         /* POLLFREE must have cleared the queue. */
     248           0 :         WARN_ON_ONCE(waitqueue_active(wq_head));
     249           0 : }
     250             : 
     251             : /*
     252             :  * Note: we use "set_current_state()" _after_ the wait-queue add,
     253             :  * because we need a memory barrier there on SMP, so that any
     254             :  * wake-function that tests for the wait-queue being active
     255             :  * will be guaranteed to see waitqueue addition _or_ subsequent
     256             :  * tests in this thread will see the wakeup having taken place.
     257             :  *
     258             :  * The spin_unlock() itself is semi-permeable and only protects
     259             :  * one way (it only protects stuff inside the critical region and
     260             :  * stops them from bleeding out - it would still allow subsequent
     261             :  * loads to move into the critical region).
     262             :  */
     263             : void
     264           1 : prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
     265             : {
     266             :         unsigned long flags;
     267             : 
     268           1 :         wq_entry->flags &= ~WQ_FLAG_EXCLUSIVE;
     269           1 :         spin_lock_irqsave(&wq_head->lock, flags);
     270           2 :         if (list_empty(&wq_entry->entry))
     271             :                 __add_wait_queue(wq_head, wq_entry);
     272           1 :         set_current_state(state);
     273           2 :         spin_unlock_irqrestore(&wq_head->lock, flags);
     274           1 : }
     275             : EXPORT_SYMBOL(prepare_to_wait);
     276             : 
     277             : /* Returns true if we are the first waiter in the queue, false otherwise. */
     278             : bool
     279           0 : prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
     280             : {
     281             :         unsigned long flags;
     282           0 :         bool was_empty = false;
     283             : 
     284           0 :         wq_entry->flags |= WQ_FLAG_EXCLUSIVE;
     285           0 :         spin_lock_irqsave(&wq_head->lock, flags);
     286           0 :         if (list_empty(&wq_entry->entry)) {
     287           0 :                 was_empty = list_empty(&wq_head->head);
     288             :                 __add_wait_queue_entry_tail(wq_head, wq_entry);
     289             :         }
     290           0 :         set_current_state(state);
     291           0 :         spin_unlock_irqrestore(&wq_head->lock, flags);
     292           0 :         return was_empty;
     293             : }
     294             : EXPORT_SYMBOL(prepare_to_wait_exclusive);
     295             : 
     296           2 : void init_wait_entry(struct wait_queue_entry *wq_entry, int flags)
     297             : {
     298           2 :         wq_entry->flags = flags;
     299           2 :         wq_entry->private = current;
     300           2 :         wq_entry->func = autoremove_wake_function;
     301           4 :         INIT_LIST_HEAD(&wq_entry->entry);
     302           2 : }
     303             : EXPORT_SYMBOL(init_wait_entry);
     304             : 
     305           2 : long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
     306             : {
     307             :         unsigned long flags;
     308           2 :         long ret = 0;
     309             : 
     310           2 :         spin_lock_irqsave(&wq_head->lock, flags);
     311           2 :         if (signal_pending_state(state, current)) {
     312             :                 /*
     313             :                  * Exclusive waiter must not fail if it was selected by wakeup,
     314             :                  * it should "consume" the condition we were waiting for.
     315             :                  *
     316             :                  * The caller will recheck the condition and return success if
     317             :                  * we were already woken up, we can not miss the event because
     318             :                  * wakeup locks/unlocks the same wq_head->lock.
     319             :                  *
     320             :                  * But we need to ensure that set-condition + wakeup after that
     321             :                  * can't see us, it should wake up another exclusive waiter if
     322             :                  * we fail.
     323             :                  */
     324           0 :                 list_del_init(&wq_entry->entry);
     325           0 :                 ret = -ERESTARTSYS;
     326             :         } else {
     327           4 :                 if (list_empty(&wq_entry->entry)) {
     328           2 :                         if (wq_entry->flags & WQ_FLAG_EXCLUSIVE)
     329             :                                 __add_wait_queue_entry_tail(wq_head, wq_entry);
     330             :                         else
     331             :                                 __add_wait_queue(wq_head, wq_entry);
     332             :                 }
     333           2 :                 set_current_state(state);
     334             :         }
     335           4 :         spin_unlock_irqrestore(&wq_head->lock, flags);
     336             : 
     337           2 :         return ret;
     338             : }
     339             : EXPORT_SYMBOL(prepare_to_wait_event);
     340             : 
     341             : /*
     342             :  * Note! These two wait functions are entered with the
     343             :  * wait-queue lock held (and interrupts off in the _irq
     344             :  * case), so there is no race with testing the wakeup
     345             :  * condition in the caller before they add the wait
     346             :  * entry to the wake queue.
     347             :  */
     348           0 : int do_wait_intr(wait_queue_head_t *wq, wait_queue_entry_t *wait)
     349             : {
     350           0 :         if (likely(list_empty(&wait->entry)))
     351             :                 __add_wait_queue_entry_tail(wq, wait);
     352             : 
     353           0 :         set_current_state(TASK_INTERRUPTIBLE);
     354           0 :         if (signal_pending(current))
     355             :                 return -ERESTARTSYS;
     356             : 
     357           0 :         spin_unlock(&wq->lock);
     358           0 :         schedule();
     359           0 :         spin_lock(&wq->lock);
     360             : 
     361           0 :         return 0;
     362             : }
     363             : EXPORT_SYMBOL(do_wait_intr);
     364             : 
     365           0 : int do_wait_intr_irq(wait_queue_head_t *wq, wait_queue_entry_t *wait)
     366             : {
     367           0 :         if (likely(list_empty(&wait->entry)))
     368             :                 __add_wait_queue_entry_tail(wq, wait);
     369             : 
     370           0 :         set_current_state(TASK_INTERRUPTIBLE);
     371           0 :         if (signal_pending(current))
     372             :                 return -ERESTARTSYS;
     373             : 
     374           0 :         spin_unlock_irq(&wq->lock);
     375           0 :         schedule();
     376           0 :         spin_lock_irq(&wq->lock);
     377             : 
     378           0 :         return 0;
     379             : }
     380             : EXPORT_SYMBOL(do_wait_intr_irq);
     381             : 
     382             : /**
     383             :  * finish_wait - clean up after waiting in a queue
     384             :  * @wq_head: waitqueue waited on
     385             :  * @wq_entry: wait descriptor
     386             :  *
     387             :  * Sets current thread back to running state and removes
     388             :  * the wait descriptor from the given waitqueue if still
     389             :  * queued.
     390             :  */
     391           0 : void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry)
     392             : {
     393             :         unsigned long flags;
     394             : 
     395           0 :         __set_current_state(TASK_RUNNING);
     396             :         /*
     397             :          * We can check for list emptiness outside the lock
     398             :          * IFF:
     399             :          *  - we use the "careful" check that verifies both
     400             :          *    the next and prev pointers, so that there cannot
     401             :          *    be any half-pending updates in progress on other
     402             :          *    CPU's that we haven't seen yet (and that might
     403             :          *    still change the stack area.
     404             :          * and
     405             :          *  - all other users take the lock (ie we can only
     406             :          *    have _one_ other CPU that looks at or modifies
     407             :          *    the list).
     408             :          */
     409           0 :         if (!list_empty_careful(&wq_entry->entry)) {
     410           0 :                 spin_lock_irqsave(&wq_head->lock, flags);
     411           0 :                 list_del_init(&wq_entry->entry);
     412           0 :                 spin_unlock_irqrestore(&wq_head->lock, flags);
     413             :         }
     414           0 : }
     415             : EXPORT_SYMBOL(finish_wait);
     416             : 
     417           0 : int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key)
     418             : {
     419           0 :         int ret = default_wake_function(wq_entry, mode, sync, key);
     420             : 
     421           0 :         if (ret)
     422           0 :                 list_del_init_careful(&wq_entry->entry);
     423             : 
     424           0 :         return ret;
     425             : }
     426             : EXPORT_SYMBOL(autoremove_wake_function);
     427             : 
     428             : /*
     429             :  * DEFINE_WAIT_FUNC(wait, woken_wake_func);
     430             :  *
     431             :  * add_wait_queue(&wq_head, &wait);
     432             :  * for (;;) {
     433             :  *     if (condition)
     434             :  *         break;
     435             :  *
     436             :  *     // in wait_woken()                       // in woken_wake_function()
     437             :  *
     438             :  *     p->state = mode;                              wq_entry->flags |= WQ_FLAG_WOKEN;
     439             :  *     smp_mb(); // A                           try_to_wake_up():
     440             :  *     if (!(wq_entry->flags & WQ_FLAG_WOKEN))      <full barrier>
     441             :  *         schedule()                              if (p->state & mode)
     442             :  *     p->state = TASK_RUNNING;                            p->state = TASK_RUNNING;
     443             :  *     wq_entry->flags &= ~WQ_FLAG_WOKEN;        ~~~~~~~~~~~~~~~~~~
     444             :  *     smp_mb(); // B                           condition = true;
     445             :  * }                                            smp_mb(); // C
     446             :  * remove_wait_queue(&wq_head, &wait);          wq_entry->flags |= WQ_FLAG_WOKEN;
     447             :  */
     448           0 : long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout)
     449             : {
     450             :         /*
     451             :          * The below executes an smp_mb(), which matches with the full barrier
     452             :          * executed by the try_to_wake_up() in woken_wake_function() such that
     453             :          * either we see the store to wq_entry->flags in woken_wake_function()
     454             :          * or woken_wake_function() sees our store to current->state.
     455             :          */
     456           0 :         set_current_state(mode); /* A */
     457           0 :         if (!(wq_entry->flags & WQ_FLAG_WOKEN) && !kthread_should_stop_or_park())
     458           0 :                 timeout = schedule_timeout(timeout);
     459           0 :         __set_current_state(TASK_RUNNING);
     460             : 
     461             :         /*
     462             :          * The below executes an smp_mb(), which matches with the smp_mb() (C)
     463             :          * in woken_wake_function() such that either we see the wait condition
     464             :          * being true or the store to wq_entry->flags in woken_wake_function()
     465             :          * follows ours in the coherence order.
     466             :          */
     467           0 :         smp_store_mb(wq_entry->flags, wq_entry->flags & ~WQ_FLAG_WOKEN); /* B */
     468             : 
     469           0 :         return timeout;
     470             : }
     471             : EXPORT_SYMBOL(wait_woken);
     472             : 
     473           0 : int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key)
     474             : {
     475             :         /* Pairs with the smp_store_mb() in wait_woken(). */
     476           0 :         smp_mb(); /* C */
     477           0 :         wq_entry->flags |= WQ_FLAG_WOKEN;
     478             : 
     479           0 :         return default_wake_function(wq_entry, mode, sync, key);
     480             : }
     481             : EXPORT_SYMBOL(woken_wake_function);

Generated by: LCOV version 1.14