]> granicus.if.org Git - zfs/commitdiff
Call commit callbacks from the tail of the list
authorlidongyang <gnaygnodil@gmail.com>
Fri, 22 Dec 2017 18:19:51 +0000 (05:19 +1100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 22 Dec 2017 18:19:51 +0000 (10:19 -0800)
Our zfs backed Lustre MDT had soft lockups while under heavy metadata
workloads while handling transaction callbacks from osd_zfs.

The problem is zfs is not taking advantage of the fast path in
Lustre's trans callback handling, where Lustre will skip the calls
to ptlrpc_commit_replies() when it already saw a higher transaction
number.

This patch corrects this, it also has a positive impact on metadata
performance on Lustre with osd_zfs, plus some cleanup in the headers.

A similar issue for ext4/ldiskfs is described on:
https://jira.hpdd.intel.com/browse/LU-6527

Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Li Dongyang <dongyang.li@anu.edu.au>
Closes #6986

include/sys/dmu.h
include/sys/dmu_tx.h
module/zfs/dmu_tx.c

index f252a9cb63c0d6b897c455707004bd669402200c..61c02e8a7683bc1dd334baa867f5ca61272ac4e2 100644 (file)
@@ -748,11 +748,16 @@ void dmu_tx_mark_netfree(dmu_tx_t *tx);
  * to stable storage and will also be called if the dmu_tx is aborted.
  * If there is any error which prevents the transaction from being committed to
  * disk, the callback will be called with a value of error != 0.
+ *
+ * When multiple callbacks are registered to the transaction, the callbacks
+ * will be called in reverse order to let Lustre, the only user of commit
+ * callback currently, take the fast path of its commit callback handling.
  */
 typedef void dmu_tx_callback_func_t(void *dcb_data, int error);
 
 void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
     void *dcb_data);
+void dmu_tx_do_callbacks(list_t *cb_list, int error);
 
 /*
  * Free up the data blocks for a defined range of a file.  If size is
index f16e1e858041aa48ba51ccd602c3c9a0dbe04f98..d82a79310db69339f03da1ef684671382f7d2b9d 100644 (file)
@@ -145,10 +145,6 @@ uint64_t dmu_tx_get_txg(dmu_tx_t *tx);
 struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx);
 void dmu_tx_wait(dmu_tx_t *tx);
 
-void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
-    void *dcb_data);
-void dmu_tx_do_callbacks(list_t *cb_list, int error);
-
 /*
  * These routines are defined in dmu_spa.h, and are called by the SPA.
  */
index 2bb2026478ba0dcb124b2a6e1cda1c9c71cb3472..6408837d2adc06ac1fc19c1d85ad59a4c9bc4408 100644 (file)
@@ -1197,7 +1197,7 @@ dmu_tx_do_callbacks(list_t *cb_list, int error)
 {
        dmu_tx_callback_t *dcb;
 
-       while ((dcb = list_head(cb_list)) != NULL) {
+       while ((dcb = list_tail(cb_list)) != NULL) {
                list_remove(cb_list, dcb);
                dcb->dcb_func(dcb->dcb_data, error);
                kmem_free(dcb, sizeof (dmu_tx_callback_t));