Whamcloud - gitweb
LU-6864 mdc: move RPC semaphore code to lustre/osp 12/32412/3
authorAndreas Dilger <andreas.dilger@intel.com>
Tue, 15 May 2018 21:42:27 +0000 (15:42 -0600)
committerOleg Drokin <green@whamcloud.com>
Mon, 1 Oct 2018 14:00:26 +0000 (14:00 +0000)
The "MDC RPC semaphore" is no longer used by MDC code since patch
http://review.whamcloud.com/14374 "LU-5319 mdc: manage number of
modify RPCs in flight" landed.  It is only still used by the OSP
currently.  While there are plans to remove this from the OSP as
well, it makes sense to move all of this code from MDC to OSP so
that it will also be cleaned up when that functionality lands.

Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Change-Id: I1c4c9a45f308a29600631ac7fed40e592b3ebbe5
Reviewed-on: https://review.whamcloud.com/32412
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_mdc.h
lustre/include/obd.h
lustre/include/obd_support.h
lustre/osp/osp_dev.c
lustre/osp/osp_internal.h

index de7bc74..ac7b0d5 100644 (file)
@@ -63,104 +63,6 @@ struct obd_export;
 struct ptlrpc_request;
 struct obd_device;
 
-/**
- * Serializes in-flight MDT-modifying RPC requests to preserve idempotency.
- *
- * This mutex is used to implement execute-once semantics on the MDT.
- * The MDT stores the last transaction ID and result for every client in
- * its last_rcvd file. If the client doesn't get a reply, it can safely
- * resend the request and the MDT will reconstruct the reply being aware
- * that the request has already been executed. Without this lock,
- * execution status of concurrent in-flight requests would be
- * overwritten.
- *
- * This design limits the extent to which we can keep a full pipeline of
- * in-flight requests from a single client.  This limitation could be
- * overcome by allowing multiple slots per client in the last_rcvd file.
- */
-struct mdc_rpc_lock {
-       /** Lock protecting in-flight RPC concurrency. */
-       struct mutex            rpcl_mutex;
-       /** Intent associated with currently executing request. */
-       struct lookup_intent    *rpcl_it;
-       /** Used for MDS/RPC load testing purposes. */
-       int                     rpcl_fakes;
-};
-
-#define MDC_FAKE_RPCL_IT ((void *)0x2c0012bfUL)
-
-static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
-{
-       mutex_init(&lck->rpcl_mutex);
-        lck->rpcl_it = NULL;
-}
-
-static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
-                                   struct lookup_intent *it)
-{
-       ENTRY;
-
-       if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
-                          it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
-               return;
-
-       /* This would normally block until the existing request finishes.
-        * If fail_loc is set it will block until the regular request is
-        * done, then set rpcl_it to MDC_FAKE_RPCL_IT.  Once that is set
-        * it will only be cleared when all fake requests are finished.
-        * Only when all fake requests are finished can normal requests
-        * be sent, to ensure they are recoverable again. */
- again:
-       mutex_lock(&lck->rpcl_mutex);
-
-       if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM)) {
-               lck->rpcl_it = MDC_FAKE_RPCL_IT;
-               lck->rpcl_fakes++;
-               mutex_unlock(&lck->rpcl_mutex);
-               return;
-       }
-
-       /* This will only happen when the CFS_FAIL_CHECK() was
-        * just turned off but there are still requests in progress.
-        * Wait until they finish.  It doesn't need to be efficient
-        * in this extremely rare case, just have low overhead in
-        * the common case when it isn't true. */
-       while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) {
-               mutex_unlock(&lck->rpcl_mutex);
-               schedule_timeout(cfs_time_seconds(1) / 4);
-               goto again;
-       }
-
-       LASSERT(lck->rpcl_it == NULL);
-       lck->rpcl_it = it;
-}
-
-static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck,
-                                   struct lookup_intent *it)
-{
-       if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP ||
-                          it->it_op == IT_LAYOUT || it->it_op == IT_READDIR))
-               goto out;
-
-       if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */
-               mutex_lock(&lck->rpcl_mutex);
-
-               LASSERTF(lck->rpcl_fakes > 0, "%d\n", lck->rpcl_fakes);
-               lck->rpcl_fakes--;
-
-               if (lck->rpcl_fakes == 0)
-                       lck->rpcl_it = NULL;
-
-       } else {
-               LASSERTF(it == lck->rpcl_it, "%p != %p\n", it, lck->rpcl_it);
-               lck->rpcl_it = NULL;
-       }
-
-       mutex_unlock(&lck->rpcl_mutex);
- out:
-       EXIT;
-}
-
 static inline void mdc_get_mod_rpc_slot(struct ptlrpc_request *req,
                                        struct lookup_intent *it)
 {
index 6fe934f..20d9773 100644 (file)
@@ -306,8 +306,6 @@ struct client_obd {
        atomic_t                 cl_destroy_in_flight;
        wait_queue_head_t        cl_destroy_waitq;
 
-        struct mdc_rpc_lock     *cl_rpc_lock;
-
        /* modify rpcs in flight
         * currently used for metadata only */
        spinlock_t               cl_mod_rpcs_lock;
index 01e0b96..77157fc 100644 (file)
@@ -472,7 +472,7 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_MDC_ENQUEUE_PAUSE       0x801
 #define OBD_FAIL_MDC_OLD_EXT_FLAGS       0x802
 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
-#define OBD_FAIL_MDC_RPCS_SEM           0x804
+#define OBD_FAIL_MDC_RPCS_SEM           0x804 /* deprecated */
 #define OBD_FAIL_MDC_LIGHTWEIGHT        0x805
 #define OBD_FAIL_MDC_CLOSE              0x806
 #define OBD_FAIL_MDC_MERGE              0x807
@@ -657,6 +657,7 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_OSP_CHECK_INVALID_REC         0x2100
 #define OBD_FAIL_OSP_CHECK_ENOMEM              0x2101
 #define OBD_FAIL_OSP_FAKE_PRECREATE            0x2102
+#define OBD_FAIL_OSP_RPCS_SEM                  0x2104
 
  /* barrier */
 #define OBD_FAIL_MGS_BARRIER_READ_NET          0x2200
index f471022..bc5c7ed 100644 (file)
@@ -1133,14 +1133,7 @@ static int osp_init0(const struct lu_env *env, struct osp_device *osp,
        strcat(osdname, "-osd");
        CDEBUG(D_HA, "%s: connect to %s (%s)\n", obd->obd_name, osdname, src);
 
-       if (osp->opd_connect_mdt) {
-               struct client_obd *cli = &osp->opd_obd->u.cli;
-
-               OBD_ALLOC(cli->cl_rpc_lock, sizeof(*cli->cl_rpc_lock));
-               if (!cli->cl_rpc_lock)
-                       GOTO(out_fini, rc = -ENOMEM);
-               osp_init_rpc_lock(cli->cl_rpc_lock);
-       }
+       osp_init_rpc_lock(osp);
 
        osp->opd_dt_dev.dd_lu_dev.ld_ops = &osp_lu_ops;
        osp->opd_dt_dev.dd_ops = &osp_dt_ops;
@@ -1244,13 +1237,6 @@ out_proc:
 out_ref:
        ptlrpcd_decref();
 out_disconnect:
-       if (osp->opd_connect_mdt) {
-               struct client_obd *cli = &osp->opd_obd->u.cli;
-               if (cli->cl_rpc_lock != NULL) {
-                       OBD_FREE_PTR(cli->cl_rpc_lock);
-                       cli->cl_rpc_lock = NULL;
-               }
-       }
        obd_disconnect(osp->opd_storage_exp);
 out_fini:
        if (osdname)
@@ -1356,14 +1342,6 @@ static struct lu_device *osp_device_fini(const struct lu_env *env,
        LASSERT(osp->opd_obd);
        osp_tunables_fini(osp);
 
-       if (osp->opd_connect_mdt) {
-               struct client_obd *cli = &osp->opd_obd->u.cli;
-               if (cli->cl_rpc_lock != NULL) {
-                       OBD_FREE_PTR(cli->cl_rpc_lock);
-                       cli->cl_rpc_lock = NULL;
-               }
-       }
-
        rc = client_obd_cleanup(osp->opd_obd);
        if (rc != 0) {
                ptlrpcd_decref();
index ce8734c..f5f44c5 100644 (file)
@@ -44,7 +44,6 @@
 #include <lustre_fid.h>
 #include <lustre_update.h>
 #include <lu_target.h>
-#include <lustre_mdc.h>
 
 /*
  * Infrastructure to support tracking of last committed llog record
@@ -145,6 +144,13 @@ struct osp_updates {
        __u64                   ou_generation;
 };
 
+struct osp_rpc_lock {
+       /** Lock protecting in-flight RPC concurrency. */
+       struct mutex            rpcl_mutex;
+       /** Used for MDS/RPC load testing purposes. */
+       unsigned int            rpcl_fakes;
+};
+
 struct osp_device {
        struct dt_device                 opd_dt_dev;
        /* corresponded OST index */
@@ -166,6 +172,7 @@ struct osp_device {
        struct lu_fid                   opd_gap_start_fid;
        int                              opd_gap_count;
        /* connection to OST */
+       struct osp_rpc_lock              opd_rpc_lock;
        struct obd_device               *opd_obd;
        struct obd_export               *opd_exp;
        struct obd_uuid                  opd_cluuid;
@@ -503,20 +510,79 @@ static inline struct seq_server_site *osp_seq_site(struct osp_device *osp)
        return osp->opd_dt_dev.dd_lu_dev.ld_site->ld_seq_site;
 }
 
-#define osp_init_rpc_lock(lck) mdc_init_rpc_lock(lck)
+/**
+ * Serializes in-flight MDT-modifying RPC requests to preserve idempotency.
+ *
+ * This mutex is used to implement execute-once semantics on the MDT.
+ * The MDT stores the last transaction ID and result for every client in
+ * its last_rcvd file. If the client doesn't get a reply, it can safely
+ * resend the request and the MDT will reconstruct the reply being aware
+ * that the request has already been executed. Without this lock,
+ * execution status of concurrent in-flight requests would be
+ * overwritten.
+ *
+ * This imlpementation limits the extent to which we can keep a full pipeline
+ * of in-flight requests from a single client.  This limitation can be
+ * overcome by allowing multiple slots per client in the last_rcvd file,
+ * see LU-6864.
+ */
+#define OSP_FAKE_RPCL_IT ((void *)0x2c0012bfUL)
+
+static inline void osp_init_rpc_lock(struct osp_device *osp)
+{
+       struct osp_rpc_lock *lck = &osp->opd_rpc_lock;
+
+       mutex_init(&lck->rpcl_mutex);
+       lck->rpcl_fakes = 0;
+}
 
 static inline void osp_get_rpc_lock(struct osp_device *osp)
 {
-       struct mdc_rpc_lock *rpc_lock = osp->opd_obd->u.cli.cl_rpc_lock;
+       struct osp_rpc_lock *lck = &osp->opd_rpc_lock;
+
+       /* This would normally block until the existing request finishes.
+        * If fail_loc is set it will block until the regular request is
+        * done, then increment rpcl_fakes.  Once that is non-zero it
+        * will only be cleared when all fake requests are finished.
+        * Only when all fake requests are finished can normal requests
+        * be sent, to ensure they are recoverable again.
+        */
+ again:
+       mutex_lock(&lck->rpcl_mutex);
+
+       if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM) ||
+           CFS_FAIL_CHECK_QUIET(OBD_FAIL_OSP_RPCS_SEM)) {
+               lck->rpcl_fakes++;
+               mutex_unlock(&lck->rpcl_mutex);
+
+               return;
+       }
+
+       /* This will only happen when the CFS_FAIL_CHECK() was just turned
+        * off but there are still requests in progress.  Wait until they
+        * finish.  It doesn't need to be efficient in this extremely rare
+        * case, just have low overhead in the common case when it isn't true.
+        */
+       if (unlikely(lck->rpcl_fakes)) {
+               mutex_unlock(&lck->rpcl_mutex);
+               schedule_timeout(cfs_time_seconds(1) / 4);
 
-       mdc_get_rpc_lock(rpc_lock, NULL);
+               goto again;
+       }
 }
 
 static inline void osp_put_rpc_lock(struct osp_device *osp)
 {
-       struct mdc_rpc_lock *rpc_lock = osp->opd_obd->u.cli.cl_rpc_lock;
+       struct osp_rpc_lock *lck = &osp->opd_rpc_lock;
+
+       if (lck->rpcl_fakes) { /* OBD_FAIL_OSP_RPCS_SEM */
+               mutex_lock(&lck->rpcl_mutex);
+
+               if (lck->rpcl_fakes) /* check again under lock */
+                       lck->rpcl_fakes--;
+       }
 
-       mdc_put_rpc_lock(rpc_lock, NULL);
+       mutex_unlock(&lck->rpcl_mutex);
 }
 
 static inline int osp_fid_diff(const struct lu_fid *fid1,