/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2015, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/ptlrpc/ptlrpcd.c
 */

/** \defgroup ptlrpcd PortalRPC daemon
 *
 * ptlrpcd is a special thread with its own set where other user might add
 * requests when they don't want to wait for their completion.
 * PtlRPCD will take care of sending such requests and then processing their
 * replies and calling completion callbacks as necessary.
 * The callbacks are called directly from ptlrpcd context.
 * It is important to never significantly block (esp. on RPCs!) within such
 * completion handler or a deadlock might occur where ptlrpcd enters some
 * callback that attempts to send another RPC and wait for it to return,
 * during which time ptlrpcd is completely blocked, so e.g. if import
 * fails, recovery cannot progress because connection requests are also
 * sent by ptlrpcd.
 *
 * @{
 */

#define DEBUG_SUBSYSTEM S_RPC

#include "../../include/linux/libcfs/libcfs.h"

#include "../include/lustre_net.h"
#include "../include/lustre_lib.h"
#include "../include/lustre_ha.h"
#include "../include/obd_class.h"	/* for obd_zombie */
#include "../include/obd_support.h"	/* for OBD_FAIL_CHECK */
#include "../include/cl_object.h"	/* cl_env_{get,put}() */
#include "../include/lprocfs_status.h"

#include "ptlrpc_internal.h"

/* One of these per CPT. */
struct ptlrpcd {
	int pd_size;
	int pd_index;
	int pd_cpt;
	int pd_cursor;
	int pd_nthreads;
	int pd_groupsize;
	struct ptlrpcd_ctl pd_threads[0];
};

/*
 * max_ptlrpcds is obsolete, but retained to ensure that the kernel
 * module will load on a system where it has been tuned.
 * A value other than 0 implies it was tuned, in which case the value
 * is used to derive a setting for ptlrpcd_per_cpt_max.
 */
static int max_ptlrpcds;
module_param(max_ptlrpcds, int, 0644);
MODULE_PARM_DESC(max_ptlrpcds, "Max ptlrpcd thread count to be started.");

/*
 * ptlrpcd_bind_policy is obsolete, but retained to ensure that
 * the kernel module will load on a system where it has been tuned.
 * A value other than 0 implies it was tuned, in which case the value
 * is used to derive a setting for ptlrpcd_partner_group_size.
 */
static int ptlrpcd_bind_policy;
module_param(ptlrpcd_bind_policy, int, 0644);
MODULE_PARM_DESC(ptlrpcd_bind_policy,
		 "Ptlrpcd threads binding mode (obsolete).");

/*
 * ptlrpcd_per_cpt_max: The maximum number of ptlrpcd threads to run
 * in a CPT.
 */
static int ptlrpcd_per_cpt_max;
module_param(ptlrpcd_per_cpt_max, int, 0644);
MODULE_PARM_DESC(ptlrpcd_per_cpt_max,
		 "Max ptlrpcd thread count to be started per cpt.");

/*
 * ptlrpcd_partner_group_size: The desired number of threads in each
 * ptlrpcd partner thread group. Default is 2, corresponding to the
 * old PDB_POLICY_PAIR. A negative value makes all ptlrpcd threads in
 * a CPT partners of each other.
 */
static int ptlrpcd_partner_group_size;
module_param(ptlrpcd_partner_group_size, int, 0644);
MODULE_PARM_DESC(ptlrpcd_partner_group_size,
		 "Number of ptlrpcd threads in a partner group.");

/*
 * ptlrpcd_cpts: A CPT string describing the CPU partitions that
 * ptlrpcd threads should run on. Used to make ptlrpcd threads run on
 * a subset of all CPTs.
 *
 * ptlrpcd_cpts=2
 * ptlrpcd_cpts=[2]
 *   run ptlrpcd threads only on CPT 2.
 *
 * ptlrpcd_cpts=0-3
 * ptlrpcd_cpts=[0-3]
 *   run ptlrpcd threads on CPTs 0, 1, 2, and 3.
 *
 * ptlrpcd_cpts=[0-3,5,7]
 *   run ptlrpcd threads on CPTS 0, 1, 2, 3, 5, and 7.
 */
static char *ptlrpcd_cpts;
module_param(ptlrpcd_cpts, charp, 0644);
MODULE_PARM_DESC(ptlrpcd_cpts,
		 "CPU partitions ptlrpcd threads should run in");

/* ptlrpcds_cpt_idx maps cpt numbers to an index in the ptlrpcds array. */
static int		*ptlrpcds_cpt_idx;

/* ptlrpcds_num is the number of entries in the ptlrpcds array. */
static int		ptlrpcds_num;
static struct ptlrpcd	**ptlrpcds;

/*
 * In addition to the regular thread pool above, there is a single
 * global recovery thread. Recovery isn't critical for performance,
 * and doesn't block, but must always be able to proceed, and it is
 * possible that all normal ptlrpcd threads are blocked. Hence the
 * need for a dedicated thread.
 */
static struct ptlrpcd_ctl ptlrpcd_rcv;

struct mutex ptlrpcd_mutex;
static int ptlrpcd_users;

void ptlrpcd_wake(struct ptlrpc_request *req)
{
	struct ptlrpc_request_set *set = req->rq_set;

	wake_up(&set->set_waitq);
}
EXPORT_SYMBOL(ptlrpcd_wake);

static struct ptlrpcd_ctl *
ptlrpcd_select_pc(struct ptlrpc_request *req)
{
	struct ptlrpcd	*pd;
	int		cpt;
	int		idx;

	if (req && req->rq_send_state != LUSTRE_IMP_FULL)
		return &ptlrpcd_rcv;

	cpt = cfs_cpt_current(cfs_cpt_table, 1);
	if (!ptlrpcds_cpt_idx)
		idx = cpt;
	else
		idx = ptlrpcds_cpt_idx[cpt];
	pd = ptlrpcds[idx];

		/* We do not care whether it is strict load balance. */
	idx = pd->pd_cursor;
	if (++idx == pd->pd_nthreads)
		idx = 0;
	pd->pd_cursor = idx;

	return &pd->pd_threads[idx];
}

/**
 * Return transferred RPCs count.
 */
static int ptlrpcd_steal_rqset(struct ptlrpc_request_set *des,
			       struct ptlrpc_request_set *src)
{
	struct list_head *tmp, *pos;
	struct ptlrpc_request *req;
	int rc = 0;

	spin_lock(&src->set_new_req_lock);
	if (likely(!list_empty(&src->set_new_requests))) {
		list_for_each_safe(pos, tmp, &src->set_new_requests) {
			req = list_entry(pos, struct ptlrpc_request,
					 rq_set_chain);
			req->rq_set = des;
		}
		list_splice_init(&src->set_new_requests, &des->set_requests);
		rc = atomic_read(&src->set_new_count);
		atomic_add(rc, &des->set_remaining);
		atomic_set(&src->set_new_count, 0);
	}
	spin_unlock(&src->set_new_req_lock);
	return rc;
}

/**
 * Requests that are added to the ptlrpcd queue are sent via
 * ptlrpcd_check->ptlrpc_check_set().
 */
void ptlrpcd_add_req(struct ptlrpc_request *req)
{
	struct ptlrpcd_ctl *pc;

	if (req->rq_reqmsg)
		lustre_msg_set_jobid(req->rq_reqmsg, NULL);

	spin_lock(&req->rq_lock);
	if (req->rq_invalid_rqset) {
		struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(5),
						     back_to_sleep, NULL);

		req->rq_invalid_rqset = 0;
		spin_unlock(&req->rq_lock);
		l_wait_event(req->rq_set_waitq, !req->rq_set, &lwi);
	} else if (req->rq_set) {
		/* If we have a valid "rq_set", just reuse it to avoid double
		 * linked.
		 */
		LASSERT(req->rq_phase == RQ_PHASE_NEW);
		LASSERT(req->rq_send_state == LUSTRE_IMP_REPLAY);

		/* ptlrpc_check_set will decrease the count */
		atomic_inc(&req->rq_set->set_remaining);
		spin_unlock(&req->rq_lock);
		wake_up(&req->rq_set->set_waitq);
		return;
	} else {
		spin_unlock(&req->rq_lock);
	}

	pc = ptlrpcd_select_pc(req);

	DEBUG_REQ(D_INFO, req, "add req [%p] to pc [%s:%d]",
		  req, pc->pc_name, pc->pc_index);

	ptlrpc_set_add_new_req(pc, req);
}
EXPORT_SYMBOL(ptlrpcd_add_req);

static inline void ptlrpc_reqset_get(struct ptlrpc_request_set *set)
{
	atomic_inc(&set->set_refcount);
}

/**
 * Check if there is more work to do on ptlrpcd set.
 * Returns 1 if yes.
 */
static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc)
{
	struct list_head *tmp, *pos;
	struct ptlrpc_request *req;
	struct ptlrpc_request_set *set = pc->pc_set;
	int rc = 0;
	int rc2;

	if (atomic_read(&set->set_new_count)) {
		spin_lock(&set->set_new_req_lock);
		if (likely(!list_empty(&set->set_new_requests))) {
			list_splice_init(&set->set_new_requests,
					 &set->set_requests);
			atomic_add(atomic_read(&set->set_new_count),
				   &set->set_remaining);
			atomic_set(&set->set_new_count, 0);
			/*
			 * Need to calculate its timeout.
			 */
			rc = 1;
		}
		spin_unlock(&set->set_new_req_lock);
	}

	/* We should call lu_env_refill() before handling new requests to make
	 * sure that env key the requests depending on really exists.
	 */
	rc2 = lu_env_refill(env);
	if (rc2 != 0) {
		/*
		 * XXX This is very awkward situation, because
		 * execution can neither continue (request
		 * interpreters assume that env is set up), nor repeat
		 * the loop (as this potentially results in a tight
		 * loop of -ENOMEM's).
		 *
		 * Fortunately, refill only ever does something when
		 * new modules are loaded, i.e., early during boot up.
		 */
		CERROR("Failure to refill session: %d\n", rc2);
		return rc;
	}

	if (atomic_read(&set->set_remaining))
		rc |= ptlrpc_check_set(env, set);

	/* NB: ptlrpc_check_set has already moved completed request at the
	 * head of seq::set_requests
	 */
	list_for_each_safe(pos, tmp, &set->set_requests) {
		req = list_entry(pos, struct ptlrpc_request, rq_set_chain);
		if (req->rq_phase != RQ_PHASE_COMPLETE)
			break;

		list_del_init(&req->rq_set_chain);
		req->rq_set = NULL;
		ptlrpc_req_finished(req);
	}

	if (rc == 0) {
		/*
		 * If new requests have been added, make sure to wake up.
		 */
		rc = atomic_read(&set->set_new_count);

		/* If we have nothing to do, check whether we can take some
		 * work from our partner threads.
		 */
		if (rc == 0 && pc->pc_npartners > 0) {
			struct ptlrpcd_ctl *partner;
			struct ptlrpc_request_set *ps;
			int first = pc->pc_cursor;

			do {
				partner = pc->pc_partners[pc->pc_cursor++];
				if (pc->pc_cursor >= pc->pc_npartners)
					pc->pc_cursor = 0;
				if (!partner)
					continue;

				spin_lock(&partner->pc_lock);
				ps = partner->pc_set;
				if (!ps) {
					spin_unlock(&partner->pc_lock);
					continue;
				}

				ptlrpc_reqset_get(ps);
				spin_unlock(&partner->pc_lock);

				if (atomic_read(&ps->set_new_count)) {
					rc = ptlrpcd_steal_rqset(set, ps);
					if (rc > 0)
						CDEBUG(D_RPCTRACE, "transfer %d async RPCs [%d->%d]\n",
						       rc, partner->pc_index,
						       pc->pc_index);
				}
				ptlrpc_reqset_put(ps);
			} while (rc == 0 && pc->pc_cursor != first);
		}
	}

	return rc;
}

/**
 * Main ptlrpcd thread.
 * ptlrpc's code paths like to execute in process context, so we have this
 * thread which spins on a set which contains the rpcs and sends them.
 *
 */
static int ptlrpcd(void *arg)
{
	struct ptlrpcd_ctl *pc = arg;
	struct ptlrpc_request_set *set;
	struct lu_context ses = { 0 };
	struct lu_env env = { .le_ses = &ses };
	int rc = 0;
	int exit = 0;

	unshare_fs_struct();
	if (cfs_cpt_bind(cfs_cpt_table, pc->pc_cpt) != 0)
		CWARN("Failed to bind %s on CPT %d\n", pc->pc_name, pc->pc_cpt);

	/*
	 * Allocate the request set after the thread has been bound
	 * above. This is safe because no requests will be queued
	 * until all ptlrpcd threads have confirmed that they have
	 * successfully started.
	 */
	set = ptlrpc_prep_set();
	if (!set) {
		rc = -ENOMEM;
		goto failed;
	}
	spin_lock(&pc->pc_lock);
	pc->pc_set = set;
	spin_unlock(&pc->pc_lock);
	/*
	 * XXX So far only "client" ptlrpcd uses an environment. In
	 * the future, ptlrpcd thread (or a thread-set) has to given
	 * an argument, describing its "scope".
	 */
	rc = lu_context_init(&env.le_ctx,
			     LCT_CL_THREAD | LCT_REMEMBER | LCT_NOREF);
	if (rc == 0) {
		rc = lu_context_init(env.le_ses,
				     LCT_SESSION | LCT_REMEMBER | LCT_NOREF);
		if (rc != 0)
			lu_context_fini(&env.le_ctx);
	}

	if (rc != 0)
		goto failed;

	complete(&pc->pc_starting);

	/*
	 * This mainloop strongly resembles ptlrpc_set_wait() except that our
	 * set never completes.  ptlrpcd_check() calls ptlrpc_check_set() when
	 * there are requests in the set. New requests come in on the set's
	 * new_req_list and ptlrpcd_check() moves them into the set.
	 */
	do {
		struct l_wait_info lwi;
		int timeout;

		timeout = ptlrpc_set_next_timeout(set);
		lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
				  ptlrpc_expired_set, set);

		lu_context_enter(&env.le_ctx);
		lu_context_enter(env.le_ses);
		l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi);
		lu_context_exit(&env.le_ctx);
		lu_context_exit(env.le_ses);

		/*
		 * Abort inflight rpcs for forced stop case.
		 */
		if (test_bit(LIOD_STOP, &pc->pc_flags)) {
			if (test_bit(LIOD_FORCE, &pc->pc_flags))
				ptlrpc_abort_set(set);
			exit++;
		}

		/*
		 * Let's make one more loop to make sure that ptlrpcd_check()
		 * copied all raced new rpcs into the set so we can kill them.
		 */
	} while (exit < 2);

	/*
	 * Wait for inflight requests to drain.
	 */
	if (!list_empty(&set->set_requests))
		ptlrpc_set_wait(set);
	lu_context_fini(&env.le_ctx);
	lu_context_fini(env.le_ses);

	complete(&pc->pc_finishing);

	return 0;
failed:
	pc->pc_error = rc;
	complete(&pc->pc_starting);
	return rc;
}

static void ptlrpcd_ctl_init(struct ptlrpcd_ctl *pc, int index, int cpt)
{
	pc->pc_index = index;
	pc->pc_cpt = cpt;
	init_completion(&pc->pc_starting);
	init_completion(&pc->pc_finishing);
	spin_lock_init(&pc->pc_lock);

	if (index < 0) {
		/* Recovery thread. */
		snprintf(pc->pc_name, sizeof(pc->pc_name), "ptlrpcd_rcv");
	} else {
		/* Regular thread. */
		snprintf(pc->pc_name, sizeof(pc->pc_name),
			 "ptlrpcd_%02d_%02d", cpt, index);
	}
}

/* XXX: We want multiple CPU cores to share the async RPC load. So we
 *	start many ptlrpcd threads. We also want to reduce the ptlrpcd
 *	overhead caused by data transfer cross-CPU cores. So we bind
 *	all ptlrpcd threads to a CPT, in the expectation that CPTs
 *	will be defined in a way that matches these boundaries. Within
 *	a CPT a ptlrpcd thread can be scheduled on any available core.
 *
 *	Each ptlrpcd thread has its own request queue. This can cause
 *	response delay if the thread is already busy. To help with
 *	this we define partner threads: these are other threads bound
 *	to the same CPT which will check for work in each other's
 *	request queues if they have no work to do.
 *
 *	The desired number of partner threads can be tuned by setting
 *	ptlrpcd_partner_group_size. The default is to create pairs of
 *	partner threads.
 */
static int ptlrpcd_partners(struct ptlrpcd *pd, int index)
{
	struct ptlrpcd_ctl *pc;
	struct ptlrpcd_ctl **ppc;
	int first;
	int i;
	int rc = 0;
	int size;

	LASSERT(index >= 0 && index < pd->pd_nthreads);
	pc = &pd->pd_threads[index];
	pc->pc_npartners = pd->pd_groupsize - 1;

	if (pc->pc_npartners <= 0)
		goto out;

	size = sizeof(struct ptlrpcd_ctl *) * pc->pc_npartners;
	pc->pc_partners = kzalloc_node(size, GFP_NOFS,
				       cfs_cpt_spread_node(cfs_cpt_table,
							   pc->pc_cpt));
	if (!pc->pc_partners) {
		pc->pc_npartners = 0;
		rc = -ENOMEM;
		goto out;
	}

	first = index - index % pd->pd_groupsize;
	ppc = pc->pc_partners;
	for (i = first; i < first + pd->pd_groupsize; i++) {
		if (i != index)
			*ppc++ = &pd->pd_threads[i];
	}
out:
	return rc;
}

int ptlrpcd_start(struct ptlrpcd_ctl *pc)
{
	struct task_struct *task;
	int rc = 0;

	/*
	 * Do not allow start second thread for one pc.
	 */
	if (test_and_set_bit(LIOD_START, &pc->pc_flags)) {
		CWARN("Starting second thread (%s) for same pc %p\n",
		      pc->pc_name, pc);
		return 0;
	}

	/*
	 * So far only "client" ptlrpcd uses an environment. In the future,
	 * ptlrpcd thread (or a thread-set) has to be given an argument,
	 * describing its "scope".
	 */
	rc = lu_context_init(&pc->pc_env.le_ctx, LCT_CL_THREAD | LCT_REMEMBER);
	if (rc != 0)
		goto out;

	task = kthread_run(ptlrpcd, pc, "%s", pc->pc_name);
	if (IS_ERR(task)) {
		rc = PTR_ERR(task);
		goto out_set;
	}

	wait_for_completion(&pc->pc_starting);
	rc = pc->pc_error;
	if (rc != 0)
		goto out_set;

	return 0;

out_set:
	if (pc->pc_set) {
		struct ptlrpc_request_set *set = pc->pc_set;

		spin_lock(&pc->pc_lock);
		pc->pc_set = NULL;
		spin_unlock(&pc->pc_lock);
		ptlrpc_set_destroy(set);
	}
	lu_context_fini(&pc->pc_env.le_ctx);

out:
	clear_bit(LIOD_START, &pc->pc_flags);
	return rc;
}

void ptlrpcd_stop(struct ptlrpcd_ctl *pc, int force)
{
	if (!test_bit(LIOD_START, &pc->pc_flags)) {
		CWARN("Thread for pc %p was not started\n", pc);
		return;
	}

	set_bit(LIOD_STOP, &pc->pc_flags);
	if (force)
		set_bit(LIOD_FORCE, &pc->pc_flags);
	wake_up(&pc->pc_set->set_waitq);
}

void ptlrpcd_free(struct ptlrpcd_ctl *pc)
{
	struct ptlrpc_request_set *set = pc->pc_set;

	if (!test_bit(LIOD_START, &pc->pc_flags)) {
		CWARN("Thread for pc %p was not started\n", pc);
		goto out;
	}

	wait_for_completion(&pc->pc_finishing);
	lu_context_fini(&pc->pc_env.le_ctx);

	spin_lock(&pc->pc_lock);
	pc->pc_set = NULL;
	spin_unlock(&pc->pc_lock);
	ptlrpc_set_destroy(set);

	clear_bit(LIOD_START, &pc->pc_flags);
	clear_bit(LIOD_STOP, &pc->pc_flags);
	clear_bit(LIOD_FORCE, &pc->pc_flags);

out:
	if (pc->pc_npartners > 0) {
		LASSERT(pc->pc_partners);

		kfree(pc->pc_partners);
		pc->pc_partners = NULL;
	}
	pc->pc_npartners = 0;
	pc->pc_error = 0;
}

static void ptlrpcd_fini(void)
{
	int i;
	int j;

	if (ptlrpcds) {
		for (i = 0; i < ptlrpcds_num; i++) {
			if (!ptlrpcds[i])
				break;
			for (j = 0; j < ptlrpcds[i]->pd_nthreads; j++)
				ptlrpcd_stop(&ptlrpcds[i]->pd_threads[j], 0);
			for (j = 0; j < ptlrpcds[i]->pd_nthreads; j++)
				ptlrpcd_free(&ptlrpcds[i]->pd_threads[j]);
			kfree(ptlrpcds[i]);
			ptlrpcds[i] = NULL;
		}
		kfree(ptlrpcds);
	}
	ptlrpcds_num = 0;

	ptlrpcd_stop(&ptlrpcd_rcv, 0);
	ptlrpcd_free(&ptlrpcd_rcv);

	kfree(ptlrpcds_cpt_idx);
	ptlrpcds_cpt_idx = NULL;
}

static int ptlrpcd_init(void)
{
	int nthreads;
	int groupsize;
	int size;
	int i;
	int j;
	int rc = 0;
	struct cfs_cpt_table *cptable;
	__u32 *cpts = NULL;
	int ncpts;
	int cpt;
	struct ptlrpcd *pd;

	/*
	 * Determine the CPTs that ptlrpcd threads will run on.
	 */
	cptable = cfs_cpt_table;
	ncpts = cfs_cpt_number(cptable);
	if (ptlrpcd_cpts) {
		struct cfs_expr_list *el;

		size = ncpts * sizeof(ptlrpcds_cpt_idx[0]);
		ptlrpcds_cpt_idx = kzalloc(size, GFP_KERNEL);
		if (!ptlrpcds_cpt_idx) {
			rc = -ENOMEM;
			goto out;
		}

		rc = cfs_expr_list_parse(ptlrpcd_cpts,
					 strlen(ptlrpcd_cpts),
					 0, ncpts - 1, &el);

		if (rc != 0) {
			CERROR("ptlrpcd_cpts: invalid CPT pattern string: %s",
			       ptlrpcd_cpts);
			rc = -EINVAL;
			goto out;
		}

		rc = cfs_expr_list_values(el, ncpts, &cpts);
		cfs_expr_list_free(el);
		if (rc <= 0) {
			CERROR("ptlrpcd_cpts: failed to parse CPT array %s: %d\n",
			       ptlrpcd_cpts, rc);
			if (rc == 0)
				rc = -EINVAL;
			goto out;
		}

		/*
		 * Create the cpt-to-index map. When there is no match
		 * in the cpt table, pick a cpt at random. This could
		 * be changed to take the topology of the system into
		 * account.
		 */
		for (cpt = 0; cpt < ncpts; cpt++) {
			for (i = 0; i < rc; i++)
				if (cpts[i] == cpt)
					break;
			if (i >= rc)
				i = cpt % rc;
			ptlrpcds_cpt_idx[cpt] = i;
		}

		cfs_expr_list_values_free(cpts, rc);
		ncpts = rc;
	}
	ptlrpcds_num = ncpts;

	size = ncpts * sizeof(ptlrpcds[0]);
	ptlrpcds = kzalloc(size, GFP_KERNEL);
	if (!ptlrpcds) {
		rc = -ENOMEM;
		goto out;
	}

	/*
	 * The max_ptlrpcds parameter is obsolete, but do something
	 * sane if it has been tuned, and complain if
	 * ptlrpcd_per_cpt_max has also been tuned.
	 */
	if (max_ptlrpcds != 0) {
		CWARN("max_ptlrpcds is obsolete.\n");
		if (ptlrpcd_per_cpt_max == 0) {
			ptlrpcd_per_cpt_max = max_ptlrpcds / ncpts;
			/* Round up if there is a remainder. */
			if (max_ptlrpcds % ncpts != 0)
				ptlrpcd_per_cpt_max++;
			CWARN("Setting ptlrpcd_per_cpt_max = %d\n",
			      ptlrpcd_per_cpt_max);
		} else {
			CWARN("ptlrpd_per_cpt_max is also set!\n");
		}
	}

	/*
	 * The ptlrpcd_bind_policy parameter is obsolete, but do
	 * something sane if it has been tuned, and complain if
	 * ptlrpcd_partner_group_size is also tuned.
	 */
	if (ptlrpcd_bind_policy != 0) {
		CWARN("ptlrpcd_bind_policy is obsolete.\n");
		if (ptlrpcd_partner_group_size == 0) {
			switch (ptlrpcd_bind_policy) {
			case 1: /* PDB_POLICY_NONE */
			case 2: /* PDB_POLICY_FULL */
				ptlrpcd_partner_group_size = 1;
				break;
			case 3: /* PDB_POLICY_PAIR */
				ptlrpcd_partner_group_size = 2;
				break;
			case 4: /* PDB_POLICY_NEIGHBOR */
#ifdef CONFIG_NUMA
				ptlrpcd_partner_group_size = -1; /* CPT */
#else
				ptlrpcd_partner_group_size = 3; /* Triplets */
#endif
				break;
			default: /* Illegal value, use the default. */
				ptlrpcd_partner_group_size = 2;
				break;
			}
			CWARN("Setting ptlrpcd_partner_group_size = %d\n",
			      ptlrpcd_partner_group_size);
		} else {
			CWARN("ptlrpcd_partner_group_size is also set!\n");
		}
	}

	if (ptlrpcd_partner_group_size == 0)
		ptlrpcd_partner_group_size = 2;
	else if (ptlrpcd_partner_group_size < 0)
		ptlrpcd_partner_group_size = -1;
	else if (ptlrpcd_per_cpt_max > 0 &&
		 ptlrpcd_partner_group_size > ptlrpcd_per_cpt_max)
		ptlrpcd_partner_group_size = ptlrpcd_per_cpt_max;

	/*
	 * Start the recovery thread first.
	 */
	set_bit(LIOD_RECOVERY, &ptlrpcd_rcv.pc_flags);
	ptlrpcd_ctl_init(&ptlrpcd_rcv, -1, CFS_CPT_ANY);
	rc = ptlrpcd_start(&ptlrpcd_rcv);
	if (rc < 0)
		goto out;

	for (i = 0; i < ncpts; i++) {
		if (!cpts)
			cpt = i;
		else
			cpt = cpts[i];

		nthreads = cfs_cpt_weight(cptable, cpt);
		if (ptlrpcd_per_cpt_max > 0 && ptlrpcd_per_cpt_max < nthreads)
			nthreads = ptlrpcd_per_cpt_max;
		if (nthreads < 2)
			nthreads = 2;

		if (ptlrpcd_partner_group_size <= 0) {
			groupsize = nthreads;
		} else if (nthreads <= ptlrpcd_partner_group_size) {
			groupsize = nthreads;
		} else {
			groupsize = ptlrpcd_partner_group_size;
			if (nthreads % groupsize != 0)
				nthreads += groupsize - (nthreads % groupsize);
		}

		size = offsetof(struct ptlrpcd, pd_threads[nthreads]);
		pd = kzalloc_node(size, GFP_NOFS,
				  cfs_cpt_spread_node(cfs_cpt_table, cpt));
		if (!pd) {
			rc = -ENOMEM;
			goto out;
		}
		pd->pd_size = size;
		pd->pd_index = i;
		pd->pd_cpt = cpt;
		pd->pd_cursor = 0;
		pd->pd_nthreads = nthreads;
		pd->pd_groupsize = groupsize;
		ptlrpcds[i] = pd;

		/*
		 * The ptlrpcd threads in a partner group can access
		 * each other's struct ptlrpcd_ctl, so these must be
		 * initialized before any thread is started.
		 */
		for (j = 0; j < nthreads; j++) {
			ptlrpcd_ctl_init(&pd->pd_threads[j], j, cpt);
			rc = ptlrpcd_partners(pd, j);
			if (rc < 0)
				goto out;
		}

		/* XXX: We start nthreads ptlrpc daemons.
		 *	Each of them can process any non-recovery
		 *	async RPC to improve overall async RPC
		 *	efficiency.
		 *
		 *	But there are some issues with async I/O RPCs
		 *	and async non-I/O RPCs processed in the same
		 *	set under some cases. The ptlrpcd may be
		 *	blocked by some async I/O RPC(s), then will
		 *	cause other async non-I/O RPC(s) can not be
		 *	processed in time.
		 *
		 *	Maybe we should distinguish blocked async RPCs
		 *	from non-blocked async RPCs, and process them
		 *	in different ptlrpcd sets to avoid unnecessary
		 *	dependency. But how to distribute async RPCs
		 *	load among all the ptlrpc daemons becomes
		 *	another trouble.
		 */
		for (j = 0; j < nthreads; j++) {
			rc = ptlrpcd_start(&pd->pd_threads[j]);
			if (rc < 0)
				goto out;
		}
	}
out:
	if (rc != 0)
		ptlrpcd_fini();

	return rc;
}

int ptlrpcd_addref(void)
{
	int rc = 0;

	mutex_lock(&ptlrpcd_mutex);
	if (++ptlrpcd_users == 1) {
		rc = ptlrpcd_init();
		if (rc < 0)
			ptlrpcd_users--;
	}
	mutex_unlock(&ptlrpcd_mutex);
	return rc;
}
EXPORT_SYMBOL(ptlrpcd_addref);

void ptlrpcd_decref(void)
{
	mutex_lock(&ptlrpcd_mutex);
	if (--ptlrpcd_users == 0)
		ptlrpcd_fini();
	mutex_unlock(&ptlrpcd_mutex);
}
EXPORT_SYMBOL(ptlrpcd_decref);
/** @} ptlrpcd */
