/*
* Copyright (C) 2013 DataDirect Networks, Inc.
*
+ * Copyright (c) 2014, Intel Corporation.
*/
/*
* lustre/ptlrpc/nrs_tbf.c
*/
#define DEBUG_SUBSYSTEM S_RPC
-#ifndef __KERNEL__
-#include <liblustre.h>
-#endif
#include <obd_support.h>
#include <obd_class.h>
#include <libcfs/libcfs.h>
#define NRS_POL_NAME_TBF "tbf"
-int tbf_jobid_cache_size = 8192;
+static int tbf_jobid_cache_size = 8192;
CFS_MODULE_PARM(tbf_jobid_cache_size, "i", int, 0644,
"The size of jobid cache");
-int tbf_rate = 10000;
+static int tbf_rate = 10000;
CFS_MODULE_PARM(tbf_rate, "i", int, 0644,
"Default rate limit in RPCs/s");
-int tbf_depth = 3;
+static int tbf_depth = 3;
CFS_MODULE_PARM(tbf_depth, "i", int, 0644,
"How many tokens that a client can save up");
struct ptlrpc_nrs *nrs = head->th_res.res_policy->pol_nrs;
struct ptlrpc_service_part *svcpt = nrs->nrs_svcpt;
- spin_lock(&nrs->nrs_lock);
nrs->nrs_throttling = 0;
- spin_unlock(&nrs->nrs_lock);
wake_up(&svcpt->scp_waitq);
return HRTIMER_NORESTART;
{
LASSERT(!list_empty(&cli->tc_linkage));
LASSERT(cli->tc_rule);
+ spin_lock(&cli->tc_rule->tr_rule_lock);
list_del_init(&cli->tc_linkage);
+ spin_unlock(&cli->tc_rule->tr_rule_lock);
nrs_tbf_rule_put(cli->tc_rule);
cli->tc_rule = NULL;
}
struct nrs_tbf_rule *rule,
struct nrs_tbf_client *cli)
{
- if (!list_empty(&cli->tc_linkage)) {
+ spin_lock(&cli->tc_rule_lock);
+ if (cli->tc_rule != NULL && !list_empty(&cli->tc_linkage)) {
LASSERT(rule != cli->tc_rule);
nrs_tbf_cli_rule_put(cli);
}
LASSERT(list_empty(&cli->tc_linkage));
/* Rule's ref is added before called */
cli->tc_rule = rule;
+ spin_lock(&rule->tr_rule_lock);
list_add_tail(&cli->tc_linkage, &rule->tr_cli_list);
+ spin_unlock(&rule->tr_rule_lock);
+ spin_unlock(&cli->tc_rule_lock);
nrs_tbf_cli_reset_value(head, cli);
}
head->th_ops->o_cli_init(cli, req);
INIT_LIST_HEAD(&cli->tc_list);
INIT_LIST_HEAD(&cli->tc_linkage);
+ spin_lock_init(&cli->tc_rule_lock);
atomic_set(&cli->tc_ref, 1);
rule = nrs_tbf_rule_match(head, cli);
nrs_tbf_cli_reset(head, rule, cli);
LASSERT(list_empty(&cli->tc_list));
LASSERT(!cli->tc_in_heap);
LASSERT(atomic_read(&cli->tc_ref) == 0);
+ spin_lock(&cli->tc_rule_lock);
nrs_tbf_cli_rule_put(cli);
+ spin_unlock(&cli->tc_rule_lock);
OBD_FREE_PTR(cli);
}
atomic_set(&rule->tr_ref, 1);
INIT_LIST_HEAD(&rule->tr_cli_list);
INIT_LIST_HEAD(&rule->tr_nids);
+ INIT_LIST_HEAD(&rule->tr_linkage);
+ spin_lock_init(&rule->tr_rule_lock);
+ rule->tr_head = head;
rc = head->th_ops->o_rule_init(policy, rule, start);
if (rc) {
return -EEXIST;
}
list_add(&rule->tr_linkage, &head->th_list);
- rule->tr_head = head;
spin_unlock(&head->th_rule_lock);
atomic_inc(&head->th_rule_sequence);
if (start->tc_rule_flags & NTRS_DEFAULT) {
.hop_compare = tbf_cli_compare,
};
-static unsigned nrs_tbf_jobid_hop_hash(cfs_hash_t *hs, const void *key,
+static unsigned nrs_tbf_jobid_hop_hash(struct cfs_hash *hs, const void *key,
unsigned mask)
{
return cfs_hash_djb2_hash(key, strlen(key), mask);
return hlist_entry(hnode, struct nrs_tbf_client, tc_hnode);
}
-static void nrs_tbf_jobid_hop_get(cfs_hash_t *hs, struct hlist_node *hnode)
+static void nrs_tbf_jobid_hop_get(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
struct nrs_tbf_client,
atomic_inc(&cli->tc_ref);
}
-static void nrs_tbf_jobid_hop_put(cfs_hash_t *hs, struct hlist_node *hnode)
+static void nrs_tbf_jobid_hop_put(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
struct nrs_tbf_client,
atomic_dec(&cli->tc_ref);
}
-static void nrs_tbf_jobid_hop_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+static void
+nrs_tbf_jobid_hop_exit(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
- struct nrs_tbf_client,
- tc_hnode);
+ struct nrs_tbf_client,
+ tc_hnode);
LASSERT(atomic_read(&cli->tc_ref) == 0);
nrs_tbf_cli_fini(cli);
}
-static cfs_hash_ops_t nrs_tbf_jobid_hash_ops = {
+static struct cfs_hash_ops nrs_tbf_jobid_hash_ops = {
.hs_hash = nrs_tbf_jobid_hop_hash,
.hs_keycmp = nrs_tbf_jobid_hop_keycmp,
.hs_key = nrs_tbf_jobid_hop_key,
CFS_HASH_DEPTH)
static struct nrs_tbf_client *
-nrs_tbf_jobid_hash_lookup(cfs_hash_t *hs,
- cfs_hash_bd_t *bd,
+nrs_tbf_jobid_hash_lookup(struct cfs_hash *hs,
+ struct cfs_hash_bd *bd,
const char *jobid)
{
struct hlist_node *hnode;
{
const char *jobid;
struct nrs_tbf_client *cli;
- cfs_hash_t *hs = head->th_cli_hash;
- cfs_hash_bd_t bd;
+ struct cfs_hash *hs = head->th_cli_hash;
+ struct cfs_hash_bd bd;
jobid = lustre_msg_get_jobid(req->rq_reqmsg);
if (jobid == NULL)
{
const char *jobid;
struct nrs_tbf_client *ret;
- cfs_hash_t *hs = head->th_cli_hash;
- cfs_hash_bd_t bd;
+ struct cfs_hash *hs = head->th_cli_hash;
+ struct cfs_hash_bd bd;
jobid = cli->tc_jobid;
cfs_hash_bd_get_and_lock(hs, (void *)jobid, &bd, 1);
nrs_tbf_jobid_cli_put(struct nrs_tbf_head *head,
struct nrs_tbf_client *cli)
{
- cfs_hash_bd_t bd;
- cfs_hash_t *hs = head->th_cli_hash;
+ struct cfs_hash_bd bd;
+ struct cfs_hash *hs = head->th_cli_hash;
struct nrs_tbf_bucket *bkt;
int hw;
struct list_head zombies;
if (jobid == NULL)
jobid = NRS_TBF_JOBID_NULL;
- LASSERT(strlen(jobid) < JOBSTATS_JOBID_SIZE);
+ LASSERT(strlen(jobid) < LUSTRE_JOBID_SIZE);
INIT_LIST_HEAD(&cli->tc_lru);
memcpy(cli->tc_jobid, jobid, strlen(jobid));
}
int bits;
int i;
int rc;
- cfs_hash_bd_t bd;
+ struct cfs_hash_bd bd;
bits = nrs_tbf_jobid_hash_order();
if (bits < NRS_TBF_JOBID_BKT_BITS)
OBD_FREE(rule->tr_jobids_str, strlen(rule->tr_jobids_str) + 1);
}
-struct nrs_tbf_ops nrs_tbf_jobid_ops = {
+static struct nrs_tbf_ops nrs_tbf_jobid_ops = {
.o_name = NRS_TBF_TYPE_JOBID,
.o_startup = nrs_tbf_jobid_startup,
.o_cli_find = nrs_tbf_jobid_cli_find,
#define NRS_TBF_NID_BKT_BITS 8
#define NRS_TBF_NID_BITS 16
-static unsigned nrs_tbf_nid_hop_hash(cfs_hash_t *hs, const void *key,
+static unsigned nrs_tbf_nid_hop_hash(struct cfs_hash *hs, const void *key,
unsigned mask)
{
return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask);
return hlist_entry(hnode, struct nrs_tbf_client, tc_hnode);
}
-static void nrs_tbf_nid_hop_get(cfs_hash_t *hs, struct hlist_node *hnode)
+static void nrs_tbf_nid_hop_get(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
struct nrs_tbf_client,
atomic_inc(&cli->tc_ref);
}
-static void nrs_tbf_nid_hop_put(cfs_hash_t *hs, struct hlist_node *hnode)
+static void nrs_tbf_nid_hop_put(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
struct nrs_tbf_client,
atomic_dec(&cli->tc_ref);
}
-static void nrs_tbf_nid_hop_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+static void nrs_tbf_nid_hop_exit(struct cfs_hash *hs, struct hlist_node *hnode)
{
struct nrs_tbf_client *cli = hlist_entry(hnode,
struct nrs_tbf_client,
nrs_tbf_cli_fini(cli);
}
-static cfs_hash_ops_t nrs_tbf_nid_hash_ops = {
+static struct cfs_hash_ops nrs_tbf_nid_hash_ops = {
.hs_hash = nrs_tbf_nid_hop_hash,
.hs_keycmp = nrs_tbf_nid_hop_keycmp,
.hs_key = nrs_tbf_nid_hop_key,
return 0;
}
-struct nrs_tbf_ops nrs_tbf_nid_ops = {
+static struct nrs_tbf_ops nrs_tbf_nid_ops = {
.o_name = NRS_TBF_TYPE_NID,
.o_startup = nrs_tbf_nid_startup,
.o_cli_find = nrs_tbf_nid_cli_find,
LASSERT(cfs_binheap_is_empty(head->th_binheap));
cfs_binheap_destroy(head->th_binheap);
OBD_FREE_PTR(head);
- spin_lock(&nrs->nrs_lock);
nrs->nrs_throttling = 0;
- spin_unlock(&nrs->nrs_lock);
wake_up(&policy->pol_nrs->nrs_svcpt->scp_waitq);
}
* \retval 0 operation carried out successfully
* \retval -ve error
*/
-int nrs_tbf_ctl(struct ptlrpc_nrs_policy *policy, enum ptlrpc_nrs_ctl opc,
- void *arg)
+static int nrs_tbf_ctl(struct ptlrpc_nrs_policy *policy,
+ enum ptlrpc_nrs_ctl opc,
+ void *arg)
{
int rc = 0;
ENTRY;
} else {
ktime_t time;
- spin_lock(&policy->pol_nrs->nrs_lock);
policy->pol_nrs->nrs_throttling = 1;
- spin_unlock(&policy->pol_nrs->nrs_lock);
head->th_deadline = deadline;
time = ktime_set(0, 0);
time = ktime_add_ns(time, deadline);
nrq->nr_u.tbf.tr_sequence);
}
-#ifdef LPROCFS
+#ifdef CONFIG_PROC_FS
/**
* lprocfs interface
false, m);
if (rc == 0) {
/**
+ * -ENOSPC means buf in the parameter m is overflow, return 0
+ * here to let upper layer function seq_read alloc a larger
+ * memory area and do this process again.
+ */
+ } else if (rc == -ENOSPC) {
+ return 0;
+
+ /**
* Ignore -ENODEV as the regular NRS head's policy may be in the
* ptlrpc_nrs_pol_state::NRS_POL_STATE_STOPPED state.
*/
false, m);
if (rc == 0) {
/**
- * Ignore -ENODEV as the high priority NRS head's policy may be
- * in the ptlrpc_nrs_pol_state::NRS_POL_STATE_STOPPED state.
+ * -ENOSPC means buf in the parameter m is overflow, return 0
+ * here to let upper layer function seq_read alloc a larger
+ * memory area and do this process again.
*/
- } else if (rc != -ENODEV) {
- return rc;
+ } else if (rc == -ENOSPC) {
+ return 0;
}
no_hp:
extern struct nrs_core nrs_core;
#define LPROCFS_WR_NRS_TBF_MAX_CMD (4096)
static ssize_t
-ptlrpc_lprocfs_nrs_tbf_rule_seq_write(struct file *file, const char *buffer,
+ptlrpc_lprocfs_nrs_tbf_rule_seq_write(struct file *file,
+ const char __user *buffer,
size_t count, loff_t *off)
{
struct seq_file *m = file->private_data;
* \retval 0 success
* \retval != 0 error
*/
-int nrs_tbf_lprocfs_init(struct ptlrpc_service *svc)
+static int nrs_tbf_lprocfs_init(struct ptlrpc_service *svc)
{
- struct lprocfs_seq_vars nrs_tbf_lprocfs_vars[] = {
+ struct lprocfs_vars nrs_tbf_lprocfs_vars[] = {
{ .name = "nrs_tbf_rule",
.fops = &ptlrpc_lprocfs_nrs_tbf_rule_fops,
.data = svc },
if (svc->srv_procroot == NULL)
return 0;
- return lprocfs_seq_add_vars(svc->srv_procroot, nrs_tbf_lprocfs_vars,
- NULL);
+ return lprocfs_add_vars(svc->srv_procroot, nrs_tbf_lprocfs_vars, NULL);
}
/**
*
* \param[in] svc the service
*/
-void nrs_tbf_lprocfs_fini(struct ptlrpc_service *svc)
+static void nrs_tbf_lprocfs_fini(struct ptlrpc_service *svc)
{
if (svc->srv_procroot == NULL)
return;
lprocfs_remove_proc_entry("nrs_tbf_rule", svc->srv_procroot);
}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
/**
* TBF policy operations
.op_req_enqueue = nrs_tbf_req_add,
.op_req_dequeue = nrs_tbf_req_del,
.op_req_stop = nrs_tbf_req_stop,
-#ifdef LPROCFS
+#ifdef CONFIG_PROC_FS
.op_lprocfs_init = nrs_tbf_lprocfs_init,
.op_lprocfs_fini = nrs_tbf_lprocfs_fini,
#endif