#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.
* 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;
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) {
* Start \e policy
*/
case PTLRPC_NRS_CTL_START:
- rc = nrs_policy_start_locked(policy);
+ rc = nrs_policy_start_locked(policy, arg);
break;
}
out:
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);
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);
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);
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,
if (desc == NULL)
GOTO(fail, rc = -ENOMEM);
- strncpy(desc->pd_name, conf->nc_name, NRS_POL_NAME_MAX);
+ if (strlcpy(desc->pd_name, conf->nc_name, sizeof(desc->pd_name)) >=
+ sizeof(desc->pd_name)) {
+ OBD_FREE_PTR(desc);
+ GOTO(fail, rc = -E2BIG);
+ }
desc->pd_ops = conf->nc_ops;
desc->pd_compat = conf->nc_compat;
desc->pd_compat_svc_name = conf->nc_compat_svc_name;
};
/**
+ * 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
/* 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
/**
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);