X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fnrs_crr.c;h=41d0cb6a83643ea4b5f7301dab3d7531622ce51e;hb=HEAD;hp=bf16216459fb4a1e2c157663871baf64f52e6c5d;hpb=b1e595c09e1b07a6840142b3ae015b8a5a8affeb;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/nrs_crr.c b/lustre/ptlrpc/nrs_crr.c index bf16216..73606e4 100644 --- a/lustre/ptlrpc/nrs_crr.c +++ b/lustre/ptlrpc/nrs_crr.c @@ -20,7 +20,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2011 Intel Corporation + * Copyright (c) 2013, 2017, Intel Corporation. * * Copyright 2012 Xyratex Technology Limited */ @@ -38,7 +38,6 @@ * \addtogoup nrs * @{ */ -#ifdef HAVE_SERVER_SUPPORT #define DEBUG_SUBSYSTEM S_RPC #include @@ -72,7 +71,8 @@ * \retval 0 e1 > e2 * \retval 1 e1 <= e2 */ -static int crrn_req_compare(cfs_binheap_node_t *e1, cfs_binheap_node_t *e2) +static int +crrn_req_compare(struct binheap_node *e1, struct binheap_node *e2) { struct ptlrpc_nrs_request *nrq1; struct ptlrpc_nrs_request *nrq2; @@ -88,88 +88,52 @@ static int crrn_req_compare(cfs_binheap_node_t *e1, cfs_binheap_node_t *e2) return nrq1->nr_u.crr.cr_sequence < nrq2->nr_u.crr.cr_sequence; } -static cfs_binheap_ops_t nrs_crrn_heap_ops = { +static struct binheap_ops nrs_crrn_heap_ops = { .hop_enter = NULL, .hop_exit = NULL, .hop_compare = crrn_req_compare, }; /** - * libcfs_hash operations for nrs_crrn_net::cn_cli_hash + * rhashtable operations for nrs_crrn_net::cn_cli_hash * - * This uses ptlrpc_request::rq_peer.nid as its key, in order to hash + * This uses ptlrpc_request::rq_peer.nid (as nid4) as its key, in order to hash * nrs_crrn_client objects. */ -#define NRS_NID_BKT_BITS 8 -#define NRS_NID_BITS 16 - -static unsigned nrs_crrn_hop_hash(cfs_hash_t *hs, const void *key, - unsigned mask) +static u32 nrs_crrn_hashfn(const void *data, u32 len, u32 seed) { - return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask); -} + const struct lnet_nid *nid = data; -static int nrs_crrn_hop_keycmp(const void *key, struct hlist_node *hnode) -{ - lnet_nid_t *nid = (lnet_nid_t *)key; - struct nrs_crrn_client *cli = hlist_entry(hnode, - struct nrs_crrn_client, - cc_hnode); - return *nid == cli->cc_nid; + return cfs_hash_32(nidhash(nid) ^ seed, 32); } -static void *nrs_crrn_hop_key(struct hlist_node *hnode) +static int nrs_crrn_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) { - struct nrs_crrn_client *cli = hlist_entry(hnode, - struct nrs_crrn_client, - cc_hnode); - return &cli->cc_nid; -} + const struct nrs_crrn_client *cli = obj; + const struct lnet_nid *nid = arg->key; -static void *nrs_crrn_hop_object(struct hlist_node *hnode) -{ - return hlist_entry(hnode, struct nrs_crrn_client, cc_hnode); + return nid_same(nid, &cli->cc_nid) ? 0 : -ESRCH; } -static void nrs_crrn_hop_get(cfs_hash_t *hs, struct hlist_node *hnode) -{ - struct nrs_crrn_client *cli = hlist_entry(hnode, - struct nrs_crrn_client, - cc_hnode); - atomic_inc(&cli->cc_ref); -} +static const struct rhashtable_params nrs_crrn_hash_params = { + .key_len = sizeof(struct lnet_nid), + .key_offset = offsetof(struct nrs_crrn_client, cc_nid), + .head_offset = offsetof(struct nrs_crrn_client, cc_rhead), + .hashfn = nrs_crrn_hashfn, + .obj_cmpfn = nrs_crrn_cmpfn, +}; -static void nrs_crrn_hop_put(cfs_hash_t *hs, struct hlist_node *hnode) +static void nrs_crrn_exit(void *vcli, void *data) { - struct nrs_crrn_client *cli = hlist_entry(hnode, - struct nrs_crrn_client, - cc_hnode); - atomic_dec(&cli->cc_ref); -} + struct nrs_crrn_client *cli = vcli; -static void nrs_crrn_hop_exit(cfs_hash_t *hs, struct hlist_node *hnode) -{ - struct nrs_crrn_client *cli = hlist_entry(hnode, - struct nrs_crrn_client, - cc_hnode); LASSERTF(atomic_read(&cli->cc_ref) == 0, "Busy CRR-N object from client with NID %s, with %d refs\n", - libcfs_nid2str(cli->cc_nid), atomic_read(&cli->cc_ref)); + libcfs_nidstr(&cli->cc_nid), atomic_read(&cli->cc_ref)); OBD_FREE_PTR(cli); } -static cfs_hash_ops_t nrs_crrn_hash_ops = { - .hs_hash = nrs_crrn_hop_hash, - .hs_keycmp = nrs_crrn_hop_keycmp, - .hs_key = nrs_crrn_hop_key, - .hs_object = nrs_crrn_hop_object, - .hs_get = nrs_crrn_hop_get, - .hs_put = nrs_crrn_hop_put, - .hs_put_locked = nrs_crrn_hop_put, - .hs_exit = nrs_crrn_hop_exit, -}; - /** * Called when a CRR-N policy instance is started. * @@ -188,22 +152,16 @@ static int nrs_crrn_start(struct ptlrpc_nrs_policy *policy, char *arg) if (net == NULL) RETURN(-ENOMEM); - net->cn_binheap = cfs_binheap_create(&nrs_crrn_heap_ops, + net->cn_binheap = binheap_create(&nrs_crrn_heap_ops, CBH_FLAG_ATOMIC_GROW, 4096, NULL, nrs_pol2cptab(policy), nrs_pol2cptid(policy)); if (net->cn_binheap == NULL) - GOTO(failed, rc = -ENOMEM); - - net->cn_cli_hash = cfs_hash_create("nrs_crrn_nid_hash", - NRS_NID_BITS, NRS_NID_BITS, - NRS_NID_BKT_BITS, 0, - CFS_HASH_MIN_THETA, - CFS_HASH_MAX_THETA, - &nrs_crrn_hash_ops, - CFS_HASH_RW_BKTLOCK); - if (net->cn_cli_hash == NULL) - GOTO(failed, rc = -ENOMEM); + GOTO(out_net, rc = -ENOMEM); + + rc = rhashtable_init(&net->cn_cli_hash, &nrs_crrn_hash_params); + if (rc) + GOTO(out_binheap, rc); /** * Set default quantum value to max_rpcs_in_flight for non-MDS OSCs; @@ -222,10 +180,9 @@ static int nrs_crrn_start(struct ptlrpc_nrs_policy *policy, char *arg) RETURN(rc); -failed: - if (net->cn_binheap != NULL) - cfs_binheap_destroy(net->cn_binheap); - +out_binheap: + binheap_destroy(net->cn_binheap); +out_net: OBD_FREE_PTR(net); RETURN(rc); @@ -247,11 +204,10 @@ static void nrs_crrn_stop(struct ptlrpc_nrs_policy *policy) LASSERT(net != NULL); LASSERT(net->cn_binheap != NULL); - LASSERT(net->cn_cli_hash != NULL); - LASSERT(cfs_binheap_is_empty(net->cn_binheap)); + LASSERT(binheap_is_empty(net->cn_binheap)); - cfs_binheap_destroy(net->cn_binheap); - cfs_hash_putref(net->cn_cli_hash); + rhashtable_free_and_destroy(&net->cn_cli_hash, nrs_crrn_exit, NULL); + binheap_destroy(net->cn_binheap); OBD_FREE_PTR(net); } @@ -270,12 +226,13 @@ static void nrs_crrn_stop(struct ptlrpc_nrs_policy *policy) * \retval 0 operation carried out successfully * \retval -ve error */ -int nrs_crrn_ctl(struct ptlrpc_nrs_policy *policy, enum ptlrpc_nrs_ctl opc, - void *arg) +static int nrs_crrn_ctl(struct ptlrpc_nrs_policy *policy, + enum ptlrpc_nrs_ctl opc, + void *arg) { assert_spin_locked(&policy->pol_nrs->nrs_lock); - switch((enum nrs_ctl_crr)opc) { + switch (opc) { default: RETURN(-EINVAL); @@ -326,10 +283,10 @@ int nrs_crrn_ctl(struct ptlrpc_nrs_policy *policy, enum ptlrpc_nrs_ctl opc, * * \see nrs_resource_get_safe() */ -int nrs_crrn_res_get(struct ptlrpc_nrs_policy *policy, - struct ptlrpc_nrs_request *nrq, - const struct ptlrpc_nrs_resource *parent, - struct ptlrpc_nrs_resource **resp, bool moving_req) +static int nrs_crrn_res_get(struct ptlrpc_nrs_policy *policy, + struct ptlrpc_nrs_request *nrq, + const struct ptlrpc_nrs_resource *parent, + struct ptlrpc_nrs_resource **resp, bool moving_req) { struct nrs_crrn_net *net; struct nrs_crrn_client *cli; @@ -343,9 +300,9 @@ int nrs_crrn_res_get(struct ptlrpc_nrs_policy *policy, net = container_of(parent, struct nrs_crrn_net, cn_res); req = container_of(nrq, struct ptlrpc_request, rq_nrq); - - cli = cfs_hash_lookup(net->cn_cli_hash, &req->rq_peer.nid); - if (cli != NULL) + cli = rhashtable_lookup_fast(&net->cn_cli_hash, &req->rq_peer.nid, + nrs_crrn_hash_params); + if (cli) goto out; OBD_CPT_ALLOC_GFP(cli, nrs_pol2cptab(policy), nrs_pol2cptid(policy), @@ -355,14 +312,20 @@ int nrs_crrn_res_get(struct ptlrpc_nrs_policy *policy, cli->cc_nid = req->rq_peer.nid; - atomic_set(&cli->cc_ref, 1); - tmp = cfs_hash_findadd_unique(net->cn_cli_hash, &cli->cc_nid, - &cli->cc_hnode); - if (tmp != cli) { + atomic_set(&cli->cc_ref, 0); + + tmp = rhashtable_lookup_get_insert_fast(&net->cn_cli_hash, + &cli->cc_rhead, + nrs_crrn_hash_params); + if (tmp) { + /* insertion failed */ OBD_FREE_PTR(cli); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); cli = tmp; } out: + atomic_inc(&cli->cc_ref); *resp = &cli->cc_res; return 1; @@ -378,8 +341,7 @@ out: static void nrs_crrn_res_put(struct ptlrpc_nrs_policy *policy, const struct ptlrpc_nrs_resource *res) { - struct nrs_crrn_net *net; - struct nrs_crrn_client *cli; + struct nrs_crrn_client *cli; /** * Do nothing for freeing parent, nrs_crrn_net resources @@ -388,9 +350,8 @@ static void nrs_crrn_res_put(struct ptlrpc_nrs_policy *policy, return; cli = container_of(res, struct nrs_crrn_client, cc_res); - net = container_of(res->res_parent, struct nrs_crrn_net, cn_res); - cfs_hash_put(net->cn_cli_hash, &cli->cc_hnode); + atomic_dec(&cli->cc_ref); } /** @@ -413,7 +374,7 @@ struct ptlrpc_nrs_request *nrs_crrn_req_get(struct ptlrpc_nrs_policy *policy, bool peek, bool force) { struct nrs_crrn_net *net = policy->pol_private; - cfs_binheap_node_t *node = cfs_binheap_root(net->cn_binheap); + struct binheap_node *node = binheap_root(net->cn_binheap); struct ptlrpc_nrs_request *nrq; nrq = unlikely(node == NULL) ? NULL : @@ -430,16 +391,16 @@ struct ptlrpc_nrs_request *nrs_crrn_req_get(struct ptlrpc_nrs_policy *policy, LASSERT(nrq->nr_u.crr.cr_round <= cli->cc_round); - cfs_binheap_remove(net->cn_binheap, &nrq->nr_node); + binheap_remove(net->cn_binheap, &nrq->nr_node); cli->cc_active--; CDEBUG(D_RPCTRACE, "NRS: starting to handle %s request from %s, with round " - LPU64"\n", NRS_POL_NAME_CRRN, - libcfs_id2str(req->rq_peer), nrq->nr_u.crr.cr_round); + "%llu\n", NRS_POL_NAME_CRRN, + libcfs_idstr(&req->rq_peer), nrq->nr_u.crr.cr_round); /** Peek at the next request to be served */ - node = cfs_binheap_root(net->cn_binheap); + node = binheap_root(net->cn_binheap); /** No more requests */ if (unlikely(node == NULL)) { @@ -534,7 +495,7 @@ static int nrs_crrn_req_add(struct ptlrpc_nrs_policy *policy, nrq->nr_u.crr.cr_round = cli->cc_round; nrq->nr_u.crr.cr_sequence = cli->cc_sequence; - rc = cfs_binheap_insert(net->cn_binheap, &nrq->nr_node); + rc = binheap_insert(net->cn_binheap, &nrq->nr_node); if (rc == 0) { cli->cc_active++; if (--cli->cc_quantum == 0) @@ -564,9 +525,9 @@ static void nrs_crrn_req_del(struct ptlrpc_nrs_policy *policy, LASSERT(nrq->nr_u.crr.cr_round <= cli->cc_round); - is_root = &nrq->nr_node == cfs_binheap_root(net->cn_binheap); + is_root = &nrq->nr_node == binheap_root(net->cn_binheap); - cfs_binheap_remove(net->cn_binheap, &nrq->nr_node); + binheap_remove(net->cn_binheap, &nrq->nr_node); cli->cc_active--; /** @@ -575,7 +536,7 @@ static void nrs_crrn_req_del(struct ptlrpc_nrs_policy *policy, */ if (unlikely(is_root)) { /** Peek at the next request to be served */ - cfs_binheap_node_t *node = cfs_binheap_root(net->cn_binheap); + struct binheap_node *node = binheap_root(net->cn_binheap); /** No more requests */ if (unlikely(node == NULL)) { @@ -604,15 +565,13 @@ static void nrs_crrn_req_stop(struct ptlrpc_nrs_policy *policy, rq_nrq); CDEBUG(D_RPCTRACE, - "NRS: finished handling %s request from %s, with round "LPU64 + "NRS: finished handling %s request from %s, with round %llu" "\n", NRS_POL_NAME_CRRN, - libcfs_id2str(req->rq_peer), nrq->nr_u.crr.cr_round); + libcfs_idstr(&req->rq_peer), nrq->nr_u.crr.cr_round); } -#ifdef LPROCFS - /** - * lprocfs interface + * debugfs interface */ /** @@ -699,10 +658,12 @@ no_hp: */ static ssize_t ptlrpc_lprocfs_nrs_crrn_quantum_seq_write(struct file *file, - const char *buffer, size_t count, + const char __user *buffer, + size_t count, loff_t *off) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct ptlrpc_service *svc = m->private; enum ptlrpc_nrs_queue_type queue = 0; char kernbuf[LPROCFS_NRS_WR_QUANTUM_MAX_CMD]; char *val; @@ -729,7 +690,9 @@ ptlrpc_lprocfs_nrs_crrn_quantum_seq_write(struct file *file, val = lprocfs_find_named_value(kernbuf, NRS_LPROCFS_QUANTUM_NAME_REG, &count_copy); if (val != kernbuf) { - quantum_reg = simple_strtol(val, NULL, 10); + rc = kstrtol(val, 10, &quantum_reg); + if (rc) + return rc; queue |= PTLRPC_NRS_QUEUE_REG; } @@ -745,7 +708,9 @@ ptlrpc_lprocfs_nrs_crrn_quantum_seq_write(struct file *file, if (!nrs_svc_has_hp(svc)) return -ENODEV; - quantum_hp = simple_strtol(val, NULL, 10); + rc = kstrtol(val, 10, &quantum_hp); + if (rc) + return rc; queue |= PTLRPC_NRS_QUEUE_HP; } @@ -755,10 +720,9 @@ ptlrpc_lprocfs_nrs_crrn_quantum_seq_write(struct file *file, * value */ if (queue == 0) { - if (!isdigit(kernbuf[0])) - return -EINVAL; - - quantum_reg = simple_strtol(kernbuf, NULL, 10); + rc = kstrtol(kernbuf, 10, &quantum_reg); + if (rc) + return rc; queue = PTLRPC_NRS_QUEUE_REG; @@ -806,7 +770,8 @@ ptlrpc_lprocfs_nrs_crrn_quantum_seq_write(struct file *file, return rc == -ENODEV && rc2 == -ENODEV ? -ENODEV : count; } -LPROC_SEQ_FOPS(ptlrpc_lprocfs_nrs_crrn_quantum); + +LDEBUGFS_SEQ_FOPS(ptlrpc_lprocfs_nrs_crrn_quantum); /** * Initializes a CRR-N policy's lprocfs interface for service \a svc @@ -816,37 +781,23 @@ LPROC_SEQ_FOPS(ptlrpc_lprocfs_nrs_crrn_quantum); * \retval 0 success * \retval != 0 error */ -int nrs_crrn_lprocfs_init(struct ptlrpc_service *svc) +static int nrs_crrn_lprocfs_init(struct ptlrpc_service *svc) { - struct lprocfs_seq_vars nrs_crrn_lprocfs_vars[] = { + struct ldebugfs_vars nrs_crrn_lprocfs_vars[] = { { .name = "nrs_crrn_quantum", .fops = &ptlrpc_lprocfs_nrs_crrn_quantum_fops, .data = svc }, { NULL } }; - if (svc->srv_procroot == NULL) + if (!svc->srv_debugfs_entry) return 0; - return lprocfs_seq_add_vars(svc->srv_procroot, nrs_crrn_lprocfs_vars, - NULL); -} + ldebugfs_add_vars(svc->srv_debugfs_entry, nrs_crrn_lprocfs_vars, NULL); -/** - * Cleans up a CRR-N policy's lprocfs interface for service \a svc - * - * \param[in] svc the service - */ -void nrs_crrn_lprocfs_fini(struct ptlrpc_service *svc) -{ - if (svc->srv_procroot == NULL) - return; - - lprocfs_remove_proc_entry("nrs_crrn_quantum", svc->srv_procroot); + return 0; } -#endif /* LPROCFS */ - /** * CRR-N policy operations */ @@ -860,10 +811,7 @@ static const struct ptlrpc_nrs_pol_ops nrs_crrn_ops = { .op_req_enqueue = nrs_crrn_req_add, .op_req_dequeue = nrs_crrn_req_del, .op_req_stop = nrs_crrn_req_stop, -#ifdef LPROCFS .op_lprocfs_init = nrs_crrn_lprocfs_init, - .op_lprocfs_fini = nrs_crrn_lprocfs_fini, -#endif }; /** @@ -878,5 +826,3 @@ struct ptlrpc_nrs_pol_conf nrs_conf_crrn = { /** @} CRR-N policy */ /** @} nrs */ - -#endif /* HAVE_SERVER_SUPPORT */