• NeilBrown's avatar
    SUNRPC: only have one thread waking up at a time · 5b80147e
    NeilBrown authored
    Currently if several items of work become available in quick succession,
    that number of threads (if available) will be woken.  By the time some
    of them wake up another thread that was already cache-warm might have
    come along and completed the work.  Anecdotal evidence suggests as many
    as 15% of wakes find nothing to do once they get to the point of
    looking.
    
    This patch changes svc_pool_wake_idle_thread() to wake the first thread
    on the queue but NOT remove it.  Subsequent calls will wake the same
    thread.  Once that thread starts it will dequeue itself and after
    dequeueing some work to do, it will wake the next thread if there is more
    work ready.  This results in a more orderly increase in the number of
    busy threads.
    
    As a bonus, this allows us to reduce locking around the idle queue.
    svc_pool_wake_idle_thread() no longer needs to take a lock (beyond
    rcu_read_lock()) as it doesn't manipulate the queue, it just looks at
    the first item.
    
    The thread itself can avoid locking by using the new
    llist_del_first_this() interface.  This will safely remove the thread
    itself if it is the head.  If it isn't the head, it will do nothing.
    If multiple threads call this concurrently only one will succeed.  The
    others will do nothing, so no corruption can result.
    
    If a thread wakes up and finds that it cannot dequeue itself that means
    either
    - that it wasn't woken because it was the head of the queue.  Maybe the
      freezer woke it.  In that case it can go back to sleep (after trying
      to freeze of course).
    - some other thread found there was nothing to do very recently, and
      placed itself on the head of the queue in front of this thread.
      It must check again after placing itself there, so it can be deemed to
      be responsible for any pending work, and this thread can go back to
      sleep until woken.
    
    No code ever tests for busy threads any more.  Only each thread itself
    cares if it is busy.  So svc_thread_busy() is no longer needed.
    Signed-off-by: default avatarNeilBrown <neilb@suse.de>
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    5b80147e
svc.c 42.5 KB