Whamcloud - gitweb
LU-3772 ptlrpc: fix nrs cleanup
[fs/lustre-release.git] / lustre / ptlrpc / nrs.c
index 069f6a0..6d02aa5 100644 (file)
 #include <libcfs/libcfs.h>
 #include "ptlrpc_internal.h"
 
-/* XXX: This is just for liblustre. Remove the #if defined directive when the
- * "cfs_" prefix is dropped from cfs_list_head. */
-#if defined (__linux__) && defined(__KERNEL__)
 extern struct list_head ptlrpc_all_services;
-#else
-extern struct cfs_list_head ptlrpc_all_services;
-#endif
 
 /**
  * NRS core object.
@@ -206,7 +200,7 @@ static void nrs_policy_stop_primary(struct ptlrpc_nrs *nrs)
  * references on the policy to ptlrpc_nrs_pol_stae::NRS_POL_STATE_STOPPED. In
  * this case, the fallback policy is only left active in the NRS head.
  */
-static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy)
+static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy, char *arg)
 {
        struct ptlrpc_nrs      *nrs = policy->pol_nrs;
        int                     rc = 0;
@@ -276,7 +270,7 @@ static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy)
        if (policy->pol_desc->pd_ops->op_policy_start) {
                spin_unlock(&nrs->nrs_lock);
 
-               rc = policy->pol_desc->pd_ops->op_policy_start(policy);
+               rc = policy->pol_desc->pd_ops->op_policy_start(policy, arg);
 
                spin_lock(&nrs->nrs_lock);
                if (rc != 0) {
@@ -672,7 +666,7 @@ static int nrs_policy_ctl(struct ptlrpc_nrs *nrs, char *name,
                 * Start \e policy
                 */
        case PTLRPC_NRS_CTL_START:
-               rc = nrs_policy_start_locked(policy);
+               rc = nrs_policy_start_locked(policy, arg);
                break;
        }
 out:
@@ -807,7 +801,7 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs,
        nrs->nrs_num_pols++;
 
        if (policy->pol_flags & PTLRPC_NRS_FL_REG_START)
-               rc = nrs_policy_start_locked(policy);
+               rc = nrs_policy_start_locked(policy, NULL);
 
        spin_unlock(&nrs->nrs_lock);
 
@@ -954,6 +948,7 @@ static int nrs_svcpt_setup_locked0(struct ptlrpc_nrs *nrs,
        spin_lock_init(&nrs->nrs_lock);
        CFS_INIT_LIST_HEAD(&nrs->nrs_policy_list);
        CFS_INIT_LIST_HEAD(&nrs->nrs_policy_queued);
+       nrs->nrs_throttling = 0;
 
        rc = nrs_register_policies_locked(nrs);
 
@@ -1024,7 +1019,13 @@ static void nrs_svcpt_cleanup_locked(struct ptlrpc_service_part *svcpt)
        LASSERT(mutex_is_locked(&nrs_core.nrs_mutex));
 
 again:
-       nrs = nrs_svcpt2nrs(svcpt, hp);
+       /* scp_nrs_hp could be NULL due to short of memory. */
+       nrs = hp ? svcpt->scp_nrs_hp : &svcpt->scp_nrs_reg;
+       /* check the nrs_svcpt to see if nrs is initialized. */
+       if (!nrs || !nrs->nrs_svcpt) {
+               EXIT;
+               return;
+       }
        nrs->nrs_stopping = 1;
 
        cfs_list_for_each_entry_safe(policy, tmp, &nrs->nrs_policy_list,
@@ -1631,6 +1632,24 @@ bool ptlrpc_nrs_req_pending_nolock(struct ptlrpc_service_part *svcpt, bool hp)
 };
 
 /**
+ * Returns whether NRS policy is throttling reqeust
+ *
+ * \param[in] svcpt the service partition to enquire.
+ * \param[in] hp    whether the regular or high-priority NRS head is to be
+ *                 enquired.
+ *
+ * \retval false the indicated NRS head has no enqueued requests.
+ * \retval true         the indicated NRS head has some enqueued requests.
+ */
+bool ptlrpc_nrs_req_throttling_nolock(struct ptlrpc_service_part *svcpt,
+                                     bool hp)
+{
+       struct ptlrpc_nrs *nrs = nrs_svcpt2nrs(svcpt, hp);
+
+       return !!nrs->nrs_throttling;
+};
+
+/**
  * Moves request \a req from the regular to the high-priority NRS head.
  *
  * \param[in] req the request to move
@@ -1751,6 +1770,7 @@ extern struct ptlrpc_nrs_pol_conf nrs_conf_crrn;
 /* ptlrpc/nrs_orr.c */
 extern struct ptlrpc_nrs_pol_conf nrs_conf_orr;
 extern struct ptlrpc_nrs_pol_conf nrs_conf_trr;
+extern struct ptlrpc_nrs_pol_conf nrs_conf_tbf;
 #endif
 
 /**
@@ -1784,6 +1804,9 @@ int ptlrpc_nrs_init(void)
        rc = ptlrpc_nrs_policy_register(&nrs_conf_trr);
        if (rc != 0)
                GOTO(fail, rc);
+       rc = ptlrpc_nrs_policy_register(&nrs_conf_tbf);
+       if (rc != 0)
+               GOTO(fail, rc);
 #endif
 
        RETURN(rc);