Whamcloud - gitweb
LU-13004 ptlrpc: Allow BULK_BUF_KIOV to accept a kvec
[fs/lustre-release.git] / lustre / ptlrpc / nrs.c
index 4a3c976..52d3225 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2011 Intel Corporation
+ * Copyright (c) 2014, 2016, Intel Corporation.
  *
  * Copyright 2012 Xyratex Technology Limited
  */
@@ -40,9 +40,6 @@
  */
 
 #define DEBUG_SUBSYSTEM S_RPC
-#ifndef __KERNEL__
-#include <liblustre.h>
-#endif
 #include <obd_support.h>
 #include <obd_class.h>
 #include <lustre_net.h>
@@ -50,8 +47,6 @@
 #include <libcfs/libcfs.h>
 #include "ptlrpc_internal.h"
 
-extern struct list_head ptlrpc_all_services;
-
 /**
  * NRS core object.
  */
@@ -91,18 +86,12 @@ static int nrs_policy_ctl_locked(struct ptlrpc_nrs_policy *policy,
 
 static void nrs_policy_stop0(struct ptlrpc_nrs_policy *policy)
 {
-       struct ptlrpc_nrs *nrs = policy->pol_nrs;
        ENTRY;
 
-       if (policy->pol_desc->pd_ops->op_policy_stop != NULL) {
-               spin_unlock(&nrs->nrs_lock);
-
+       if (policy->pol_desc->pd_ops->op_policy_stop != NULL)
                policy->pol_desc->pd_ops->op_policy_stop(policy);
 
-               spin_lock(&nrs->nrs_lock);
-       }
-
-       LASSERT(cfs_list_empty(&policy->pol_list_queued));
+       LASSERT(list_empty(&policy->pol_list_queued));
        LASSERT(policy->pol_req_queued == 0 &&
                policy->pol_req_started == 0);
 
@@ -110,7 +99,7 @@ static void nrs_policy_stop0(struct ptlrpc_nrs_policy *policy)
 
        policy->pol_state = NRS_POL_STATE_STOPPED;
 
-       if (cfs_atomic_dec_and_test(&policy->pol_desc->pd_refs))
+       if (atomic_dec_and_test(&policy->pol_desc->pd_refs))
                module_put(policy->pol_desc->pd_owner);
 
        EXIT;
@@ -244,17 +233,32 @@ static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy, char *arg)
                if (nrs->nrs_policy_fallback == NULL)
                        RETURN(-EPERM);
 
-               if (policy->pol_state == NRS_POL_STATE_STARTED)
-                       RETURN(0);
+               if (policy->pol_state == NRS_POL_STATE_STARTED) {
+                       /**
+                        * If the policy argument now is different from the last time,
+                        * stop the policy first and start it again with the new
+                        * argument.
+                        */
+                       if ((arg != NULL) && (strlen(arg) >= NRS_POL_ARG_MAX))
+                               return -EINVAL;
+
+                       if ((arg == NULL && strlen(policy->pol_arg) == 0) ||
+                           (arg != NULL && strcmp(policy->pol_arg, arg) == 0))
+                               RETURN(0);
+
+                       rc = nrs_policy_stop_locked(policy);
+                       if (rc)
+                               RETURN(-EAGAIN);
+               }
        }
 
        /**
         * Increase the module usage count for policies registering from other
         * modules.
         */
-       if (cfs_atomic_inc_return(&policy->pol_desc->pd_refs) == 1 &&
+       if (atomic_inc_return(&policy->pol_desc->pd_refs) == 1 &&
            !try_module_get(policy->pol_desc->pd_owner)) {
-               cfs_atomic_dec(&policy->pol_desc->pd_refs);
+               atomic_dec(&policy->pol_desc->pd_refs);
                CERROR("NRS: cannot get module for policy %s; is it alive?\n",
                       policy->pol_desc->pd_name);
                RETURN(-ENODEV);
@@ -274,7 +278,7 @@ static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy, char *arg)
 
                spin_lock(&nrs->nrs_lock);
                if (rc != 0) {
-                       if (cfs_atomic_dec_and_test(&policy->pol_desc->pd_refs))
+                       if (atomic_dec_and_test(&policy->pol_desc->pd_refs))
                                module_put(policy->pol_desc->pd_owner);
 
                        policy->pol_state = NRS_POL_STATE_STOPPED;
@@ -282,6 +286,16 @@ static int nrs_policy_start_locked(struct ptlrpc_nrs_policy *policy, char *arg)
                }
        }
 
+       if (arg != NULL) {
+               if (strlcpy(policy->pol_arg, arg, sizeof(policy->pol_arg)) >=
+                   sizeof(policy->pol_arg)) {
+                       CERROR("NRS: arg '%s' is too long\n", arg);
+                       GOTO(out, rc = -E2BIG);
+               }
+       } else {
+               policy->pol_arg[0] = '\0';
+       }
+
        policy->pol_state = NRS_POL_STATE_STARTED;
 
        if (policy->pol_flags & PTLRPC_NRS_FL_FALLBACK) {
@@ -346,7 +360,7 @@ static struct ptlrpc_nrs_policy * nrs_policy_find_locked(struct ptlrpc_nrs *nrs,
 {
        struct ptlrpc_nrs_policy *tmp;
 
-       cfs_list_for_each_entry(tmp, &nrs->nrs_policy_list, pol_list) {
+       list_for_each_entry(tmp, &nrs->nrs_policy_list, pol_list) {
                if (strncmp(tmp->pol_desc->pd_name, name,
                            NRS_POL_NAME_MAX) == 0) {
                        nrs_policy_get_locked(tmp);
@@ -653,6 +667,10 @@ static int nrs_policy_ctl(struct ptlrpc_nrs *nrs, char *name,
        if (policy == NULL)
                GOTO(out, rc = -ENOENT);
 
+       if (policy->pol_state != NRS_POL_STATE_STARTED &&
+           policy->pol_state != NRS_POL_STATE_STOPPED)
+               GOTO(out, rc = -EAGAIN);
+
        switch (opc) {
                /**
                 * Unknown opcode, pass it down to the policy-specific control
@@ -720,7 +738,7 @@ static int nrs_policy_unregister(struct ptlrpc_nrs *nrs, char *name)
                LASSERT(policy->pol_state == NRS_POL_STATE_STOPPED);
        }
 
-       cfs_list_del(&policy->pol_list);
+       list_del(&policy->pol_list);
        nrs->nrs_num_pols--;
 
        nrs_policy_put_locked(policy);
@@ -763,7 +781,7 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs,
        LASSERT(desc->pd_compat != NULL);
 
        OBD_CPT_ALLOC_GFP(policy, svcpt->scp_service->srv_cptable,
-                         svcpt->scp_cpt, sizeof(*policy), __GFP_IO);
+                         svcpt->scp_cpt, sizeof(*policy), GFP_NOFS);
        if (policy == NULL)
                RETURN(-ENOMEM);
 
@@ -772,8 +790,8 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs,
        policy->pol_state   = NRS_POL_STATE_STOPPED;
        policy->pol_flags   = desc->pd_flags;
 
-       CFS_INIT_LIST_HEAD(&policy->pol_list);
-       CFS_INIT_LIST_HEAD(&policy->pol_list_queued);
+       INIT_LIST_HEAD(&policy->pol_list);
+       INIT_LIST_HEAD(&policy->pol_list_queued);
 
        rc = nrs_policy_init(policy);
        if (rc != 0) {
@@ -797,7 +815,7 @@ static int nrs_policy_register(struct ptlrpc_nrs *nrs,
                RETURN(-EEXIST);
        }
 
-       cfs_list_add_tail(&policy->pol_list, &nrs->nrs_policy_list);
+       list_add_tail(&policy->pol_list, &nrs->nrs_policy_list);
        nrs->nrs_num_pols++;
 
        if (policy->pol_flags & PTLRPC_NRS_FL_REG_START)
@@ -832,8 +850,8 @@ static void ptlrpc_nrs_req_add_nolock(struct ptlrpc_request *req)
         * Add the policy to the NRS head's list of policies with enqueued
         * requests, if it has not been added there.
         */
-       if (unlikely(cfs_list_empty(&policy->pol_list_queued)))
-               cfs_list_add_tail(&policy->pol_list_queued,
+       if (unlikely(list_empty(&policy->pol_list_queued)))
+               list_add_tail(&policy->pol_list_queued,
                                  &policy->pol_nrs->nrs_policy_queued);
 }
 
@@ -896,7 +914,7 @@ static int nrs_register_policies_locked(struct ptlrpc_nrs *nrs)
 
        LASSERT(mutex_is_locked(&nrs_core.nrs_mutex));
 
-       cfs_list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
+       list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
                if (nrs_policy_compatible(svc, desc)) {
                        rc = nrs_policy_register(nrs, desc);
                        if (rc != 0) {
@@ -946,8 +964,8 @@ static int nrs_svcpt_setup_locked0(struct ptlrpc_nrs *nrs,
        nrs->nrs_svcpt = svcpt;
        nrs->nrs_queue_type = queue;
        spin_lock_init(&nrs->nrs_lock);
-       CFS_INIT_LIST_HEAD(&nrs->nrs_policy_list);
-       CFS_INIT_LIST_HEAD(&nrs->nrs_policy_queued);
+       INIT_LIST_HEAD(&nrs->nrs_policy_list);
+       INIT_LIST_HEAD(&nrs->nrs_policy_queued);
        nrs->nrs_throttling = 0;
 
        rc = nrs_register_policies_locked(nrs);
@@ -1019,10 +1037,16 @@ 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,
+       list_for_each_entry_safe(policy, tmp, &nrs->nrs_policy_list,
                                     pol_list) {
                rc = nrs_policy_unregister(nrs, policy->pol_desc->pd_name);
                LASSERT(rc == 0);
@@ -1055,7 +1079,7 @@ static struct ptlrpc_nrs_pol_desc *nrs_policy_find_desc_locked(const char *name)
        struct ptlrpc_nrs_pol_desc     *tmp;
        ENTRY;
 
-       cfs_list_for_each_entry(tmp, &nrs_core.nrs_policies, pd_list) {
+       list_for_each_entry(tmp, &nrs_core.nrs_policies, pd_list) {
                if (strncmp(tmp->pd_name, name, NRS_POL_NAME_MAX) == 0)
                        RETURN(tmp);
        }
@@ -1086,7 +1110,7 @@ static int nrs_policy_unregister_locked(struct ptlrpc_nrs_pol_desc *desc)
        LASSERT(mutex_is_locked(&nrs_core.nrs_mutex));
        LASSERT(mutex_is_locked(&ptlrpc_all_services_mutex));
 
-       cfs_list_for_each_entry(svc, &ptlrpc_all_services, srv_list) {
+       list_for_each_entry(svc, &ptlrpc_all_services, srv_list) {
 
                if (!nrs_policy_compatible(svc, desc) ||
                    unlikely(svc->srv_is_stopping))
@@ -1200,7 +1224,7 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf)
        if ((conf->nc_flags & PTLRPC_NRS_FL_REG_EXTERN) != 0)
                desc->pd_owner   = conf->nc_owner;
        desc->pd_flags           = conf->nc_flags;
-       cfs_atomic_set(&desc->pd_refs, 0);
+       atomic_set(&desc->pd_refs, 0);
 
        /**
         * For policies that are held in the same module as NRS (currently
@@ -1218,7 +1242,7 @@ int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf)
         */
        mutex_lock(&ptlrpc_all_services_mutex);
 
-       cfs_list_for_each_entry(svc, &ptlrpc_all_services, srv_list) {
+       list_for_each_entry(svc, &ptlrpc_all_services, srv_list) {
                struct ptlrpc_service_part     *svcpt;
                int                             i;
                int                             rc2;
@@ -1276,7 +1300,7 @@ again:
 
        mutex_unlock(&ptlrpc_all_services_mutex);
 internal:
-       cfs_list_add_tail(&desc->pd_list, &nrs_core.nrs_policies);
+       list_add_tail(&desc->pd_list, &nrs_core.nrs_policies);
 fail:
        mutex_unlock(&nrs_core.nrs_mutex);
 
@@ -1338,7 +1362,7 @@ int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf)
        CDEBUG(D_INFO, "Unregistering policy %s from NRS core.\n",
               conf->nc_name);
 
-       cfs_list_del(&desc->pd_list);
+       list_del(&desc->pd_list);
        OBD_FREE_PTR(desc);
 
 fail:
@@ -1387,7 +1411,7 @@ int ptlrpc_service_nrs_setup(struct ptlrpc_service *svc)
         * Set up lprocfs interfaces for all supported policies for the
         * service.
         */
-       cfs_list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
+       list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
                if (!nrs_policy_compatible(svc, desc))
                        continue;
 
@@ -1428,7 +1452,7 @@ void ptlrpc_service_nrs_cleanup(struct ptlrpc_service *svc)
         * Clean up lprocfs interfaces for all supported policies for the
         * service.
         */
-       cfs_list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
+       list_for_each_entry(desc, &nrs_core.nrs_policies, pd_list) {
                if (!nrs_policy_compatible(svc, desc))
                        continue;
 
@@ -1525,7 +1549,7 @@ static void nrs_request_removed(struct ptlrpc_nrs_policy *policy)
         * ptlrpc_nrs::nrs_policy_queued.
         */
        if (unlikely(policy->pol_req_queued == 0)) {
-               cfs_list_del_init(&policy->pol_list_queued);
+               list_del_init(&policy->pol_list_queued);
 
                /**
                 * If there are other policies with queued requests, move the
@@ -1536,7 +1560,7 @@ static void nrs_request_removed(struct ptlrpc_nrs_policy *policy)
                LASSERT(policy->pol_req_queued <
                        policy->pol_nrs->nrs_req_queued);
 
-               cfs_list_move_tail(&policy->pol_list_queued,
+               list_move_tail(&policy->pol_list_queued,
                                   &policy->pol_nrs->nrs_policy_queued);
        }
 }
@@ -1569,7 +1593,7 @@ ptlrpc_nrs_req_get_nolock0(struct ptlrpc_service_part *svcpt, bool hp,
         * Always try to drain requests from all NRS polices even if they are
         * inactive, because the user can change policy status at runtime.
         */
-       cfs_list_for_each_entry(policy, &nrs->nrs_policy_queued,
+       list_for_each_entry(policy, &nrs->nrs_policy_queued,
                                pol_list_queued) {
                nrq = nrs_request_get(policy, peek, force);
                if (nrq != NULL) {
@@ -1755,18 +1779,6 @@ out:
        RETURN(rc);
 }
 
-
-/* ptlrpc/nrs_fifo.c */
-extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo;
-#if defined HAVE_SERVER_SUPPORT && defined(__KERNEL__)
-/* ptlrpc/nrs_crr.c */
-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
-
 /**
  * Adds all policies that ship with the ptlrpc module, to NRS core's list of
  * policies \e nrs_core.nrs_policies.
@@ -1780,13 +1792,13 @@ int ptlrpc_nrs_init(void)
        ENTRY;
 
        mutex_init(&nrs_core.nrs_mutex);
-       CFS_INIT_LIST_HEAD(&nrs_core.nrs_policies);
+       INIT_LIST_HEAD(&nrs_core.nrs_policies);
 
        rc = ptlrpc_nrs_policy_register(&nrs_conf_fifo);
        if (rc != 0)
                GOTO(fail, rc);
 
-#if defined HAVE_SERVER_SUPPORT && defined(__KERNEL__)
+#ifdef HAVE_SERVER_SUPPORT
        rc = ptlrpc_nrs_policy_register(&nrs_conf_crrn);
        if (rc != 0)
                GOTO(fail, rc);
@@ -1801,7 +1813,11 @@ int ptlrpc_nrs_init(void)
        rc = ptlrpc_nrs_policy_register(&nrs_conf_tbf);
        if (rc != 0)
                GOTO(fail, rc);
-#endif
+
+       rc = ptlrpc_nrs_policy_register(&nrs_conf_delay);
+       if (rc != 0)
+               GOTO(fail, rc);
+#endif /* HAVE_SERVER_SUPPORT */
 
        RETURN(rc);
 fail:
@@ -1815,7 +1831,7 @@ fail:
 }
 
 /**
- * Removes all policy desciptors from nrs_core::nrs_policies, and frees the
+ * Removes all policy descriptors from nrs_core::nrs_policies, and frees the
  * policy descriptors.
  *
  * Since all PTLRPC services are stopped at this point, there are no more
@@ -1828,9 +1844,9 @@ void ptlrpc_nrs_fini(void)
        struct ptlrpc_nrs_pol_desc *desc;
        struct ptlrpc_nrs_pol_desc *tmp;
 
-       cfs_list_for_each_entry_safe(desc, tmp, &nrs_core.nrs_policies,
+       list_for_each_entry_safe(desc, tmp, &nrs_core.nrs_policies,
                                     pd_list) {
-               cfs_list_del_init(&desc->pd_list);
+               list_del_init(&desc->pd_list);
                OBD_FREE_PTR(desc);
        }
 }