Whamcloud - gitweb
LU-17197 obdclass: preserve fairness when waiting for rpc slot
authorShaun Tancheff <shaun.tancheff@hpe.com>
Wed, 18 Oct 2023 03:54:59 +0000 (22:54 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 9 Nov 2023 08:42:52 +0000 (08:42 +0000)
When obd_get_mod_rpc_slot() waits for an available slot it places the
waiting thread at the HEAD of the queue, so it will be woken before
anything else that is already queued.  This is clearly unfair and can
hurt performance.

So change to always add to the tail to ensure a FIFO ordering (except
that CLOSE might sometimes be woken a bit early).

This regression was introduced in a rewrite that was supposed to make
waiting more fair - by avoiding a broadcast wakeup for "close"
requests.

Also fix some stale comments and expose __add_wait_queue_entry_tail

Running mdtest with the patch applied shows about a 3% improvement:

                             master            patched
  mdtest-easy-write      350.585906 kIOPS   353.783545 kIOPS
   mdtest-easy-stat     1320.329353 kIOPS  1408.320419 kIOPS
 mdtest-easy-delete      285.084103 kIOPS   289.625900 kIOPS
            [SCORE]      509.115803 kiops   524.516113 kiops

Lustre-change: https://review.whamcloud.com/52738
Lustre-commit: TBD (from 7e28964085a4d98111b926fe125abc7f815e70be)

Fixes: 5243630b09d2 ("LU-15947 obdclass: improve precision of wakeups for mod_rpcs")
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: If767c4299bcbab71589b0f3c01e85bf461686ca5
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52886
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
libcfs/include/libcfs/linux/linux-wait.h
libcfs/libcfs/linux/linux-wait.c
lustre/obdclass/genops.c

index 8ab89f0..93461d1 100644 (file)
 #define wait_queue_entry_t wait_queue_t
 #endif
 
+#ifndef HAVE_PREPARE_TO_WAIT_EVENT
+#define __add_wait_queue_entry_tail __add_wait_queue_tail
+#endif
+
 #ifndef HAVE_WAIT_BIT_HEADER_H
 struct wait_bit_queue_entry {
        struct wait_bit_key     key;
index 5843d80..ad10521 100644 (file)
@@ -10,8 +10,6 @@
 
 #ifndef HAVE_PREPARE_TO_WAIT_EVENT
 
-#define __add_wait_queue_entry_tail __add_wait_queue_tail
-
 long prepare_to_wait_event(wait_queue_head_t *wq_head,
                           wait_queue_entry_t *wq_entry, int state)
 {
index 10a0a5d..b6ebc82 100644 (file)
@@ -2306,13 +2306,12 @@ __u16 obd_get_mod_rpc_slot(struct client_obd *cli, __u32 opc)
        wait.wqe.func = claim_mod_rpc_function;
 
        spin_lock_irq(&cli->cl_mod_rpcs_waitq.lock);
-       __add_wait_queue(&cli->cl_mod_rpcs_waitq, &wait.wqe);
+       __add_wait_queue_entry_tail(&cli->cl_mod_rpcs_waitq, &wait.wqe);
        /* This wakeup will only succeed if the maximums haven't
-        * been reached.  If that happens, WQ_FLAG_WOKEN will be cleared
+        * been reached.  If that happens, wait.woken will be set
         * and there will be no need to wait.
         */
        wake_up_locked(&cli->cl_mod_rpcs_waitq);
-       /* XXX: handle spurious wakeups (from unknown yet source */
        while (wait.woken == false) {
                spin_unlock_irq(&cli->cl_mod_rpcs_waitq.lock);
                wait_woken(&wait.wqe, TASK_UNINTERRUPTIBLE,