/*
 * 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).
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 *
 * Copyright (c) 2012, 2015 Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * Author: liang@whamcloud.com
 */

#define DEBUG_SUBSYSTEM S_LNET

#include <linux/cpu.h>
#include <linux/sched.h>
#include "../../../include/linux/libcfs/libcfs.h"

#ifdef CONFIG_SMP

/**
 * modparam for setting number of partitions
 *
 *  0 : estimate best value based on cores or NUMA nodes
 *  1 : disable multiple partitions
 * >1 : specify number of partitions
 */
static int	cpu_npartitions;
module_param(cpu_npartitions, int, 0444);
MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions");

/**
 * modparam for setting CPU partitions patterns:
 *
 * i.e: "0[0,1,2,3] 1[4,5,6,7]", number before bracket is CPU partition ID,
 *      number in bracket is processor ID (core or HT)
 *
 * i.e: "N 0[0,1] 1[2,3]" the first character 'N' means numbers in bracket
 *       are NUMA node ID, number before bracket is CPU partition ID.
 *
 * NB: If user specified cpu_pattern, cpu_npartitions will be ignored
 */
static char	*cpu_pattern = "";
module_param(cpu_pattern, charp, 0444);
MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern");

struct cfs_cpt_data {
	/* serialize hotplug etc */
	spinlock_t		cpt_lock;
	/* reserved for hotplug */
	unsigned long		cpt_version;
	/* mutex to protect cpt_cpumask */
	struct mutex		cpt_mutex;
	/* scratch buffer for set/unset_node */
	cpumask_t		*cpt_cpumask;
};

static struct cfs_cpt_data	cpt_data;

static void
cfs_node_to_cpumask(int node, cpumask_t *mask)
{
	const cpumask_t *tmp = cpumask_of_node(node);

	if (tmp)
		cpumask_copy(mask, tmp);
	else
		cpumask_clear(mask);
}

void
cfs_cpt_table_free(struct cfs_cpt_table *cptab)
{
	int	i;

	if (cptab->ctb_cpu2cpt) {
		LIBCFS_FREE(cptab->ctb_cpu2cpt,
			    num_possible_cpus() *
			    sizeof(cptab->ctb_cpu2cpt[0]));
	}

	for (i = 0; cptab->ctb_parts && i < cptab->ctb_nparts; i++) {
		struct cfs_cpu_partition *part = &cptab->ctb_parts[i];

		if (part->cpt_nodemask) {
			LIBCFS_FREE(part->cpt_nodemask,
				    sizeof(*part->cpt_nodemask));
		}

		if (part->cpt_cpumask)
			LIBCFS_FREE(part->cpt_cpumask, cpumask_size());
	}

	if (cptab->ctb_parts) {
		LIBCFS_FREE(cptab->ctb_parts,
			    cptab->ctb_nparts * sizeof(cptab->ctb_parts[0]));
	}

	if (cptab->ctb_nodemask)
		LIBCFS_FREE(cptab->ctb_nodemask, sizeof(*cptab->ctb_nodemask));
	if (cptab->ctb_cpumask)
		LIBCFS_FREE(cptab->ctb_cpumask, cpumask_size());

	LIBCFS_FREE(cptab, sizeof(*cptab));
}
EXPORT_SYMBOL(cfs_cpt_table_free);

struct cfs_cpt_table *
cfs_cpt_table_alloc(unsigned int ncpt)
{
	struct cfs_cpt_table *cptab;
	int	i;

	LIBCFS_ALLOC(cptab, sizeof(*cptab));
	if (!cptab)
		return NULL;

	cptab->ctb_nparts = ncpt;

	LIBCFS_ALLOC(cptab->ctb_cpumask, cpumask_size());
	LIBCFS_ALLOC(cptab->ctb_nodemask, sizeof(*cptab->ctb_nodemask));

	if (!cptab->ctb_cpumask || !cptab->ctb_nodemask)
		goto failed;

	LIBCFS_ALLOC(cptab->ctb_cpu2cpt,
		     num_possible_cpus() * sizeof(cptab->ctb_cpu2cpt[0]));
	if (!cptab->ctb_cpu2cpt)
		goto failed;

	memset(cptab->ctb_cpu2cpt, -1,
	       num_possible_cpus() * sizeof(cptab->ctb_cpu2cpt[0]));

	LIBCFS_ALLOC(cptab->ctb_parts, ncpt * sizeof(cptab->ctb_parts[0]));
	if (!cptab->ctb_parts)
		goto failed;

	for (i = 0; i < ncpt; i++) {
		struct cfs_cpu_partition *part = &cptab->ctb_parts[i];

		LIBCFS_ALLOC(part->cpt_cpumask, cpumask_size());
		LIBCFS_ALLOC(part->cpt_nodemask, sizeof(*part->cpt_nodemask));
		if (!part->cpt_cpumask || !part->cpt_nodemask)
			goto failed;
	}

	spin_lock(&cpt_data.cpt_lock);
	/* Reserved for hotplug */
	cptab->ctb_version = cpt_data.cpt_version;
	spin_unlock(&cpt_data.cpt_lock);

	return cptab;

 failed:
	cfs_cpt_table_free(cptab);
	return NULL;
}
EXPORT_SYMBOL(cfs_cpt_table_alloc);

int
cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len)
{
	char	*tmp = buf;
	int	rc = 0;
	int	i;
	int	j;

	for (i = 0; i < cptab->ctb_nparts; i++) {
		if (len > 0) {
			rc = snprintf(tmp, len, "%d\t: ", i);
			len -= rc;
		}

		if (len <= 0) {
			rc = -EFBIG;
			goto out;
		}

		tmp += rc;
		for_each_cpu(j, cptab->ctb_parts[i].cpt_cpumask) {
			rc = snprintf(tmp, len, "%d ", j);
			len -= rc;
			if (len <= 0) {
				rc = -EFBIG;
				goto out;
			}
			tmp += rc;
		}

		*tmp = '\n';
		tmp++;
		len--;
	}

 out:
	if (rc < 0)
		return rc;

	return tmp - buf;
}
EXPORT_SYMBOL(cfs_cpt_table_print);

int
cfs_cpt_number(struct cfs_cpt_table *cptab)
{
	return cptab->ctb_nparts;
}
EXPORT_SYMBOL(cfs_cpt_number);

int
cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt)
{
	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	return cpt == CFS_CPT_ANY ?
	       cpumask_weight(cptab->ctb_cpumask) :
	       cpumask_weight(cptab->ctb_parts[cpt].cpt_cpumask);
}
EXPORT_SYMBOL(cfs_cpt_weight);

int
cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt)
{
	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	return cpt == CFS_CPT_ANY ?
	       cpumask_any_and(cptab->ctb_cpumask,
			       cpu_online_mask) < nr_cpu_ids :
	       cpumask_any_and(cptab->ctb_parts[cpt].cpt_cpumask,
			       cpu_online_mask) < nr_cpu_ids;
}
EXPORT_SYMBOL(cfs_cpt_online);

cpumask_t *
cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt)
{
	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	return cpt == CFS_CPT_ANY ?
	       cptab->ctb_cpumask : cptab->ctb_parts[cpt].cpt_cpumask;
}
EXPORT_SYMBOL(cfs_cpt_cpumask);

nodemask_t *
cfs_cpt_nodemask(struct cfs_cpt_table *cptab, int cpt)
{
	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	return cpt == CFS_CPT_ANY ?
	       cptab->ctb_nodemask : cptab->ctb_parts[cpt].cpt_nodemask;
}
EXPORT_SYMBOL(cfs_cpt_nodemask);

int
cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu)
{
	int	node;

	LASSERT(cpt >= 0 && cpt < cptab->ctb_nparts);

	if (cpu < 0 || cpu >= nr_cpu_ids || !cpu_online(cpu)) {
		CDEBUG(D_INFO, "CPU %d is invalid or it's offline\n", cpu);
		return 0;
	}

	if (cptab->ctb_cpu2cpt[cpu] != -1) {
		CDEBUG(D_INFO, "CPU %d is already in partition %d\n",
		       cpu, cptab->ctb_cpu2cpt[cpu]);
		return 0;
	}

	cptab->ctb_cpu2cpt[cpu] = cpt;

	LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_cpumask));
	LASSERT(!cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask));

	cpumask_set_cpu(cpu, cptab->ctb_cpumask);
	cpumask_set_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask);

	node = cpu_to_node(cpu);

	/* first CPU of @node in this CPT table */
	if (!node_isset(node, *cptab->ctb_nodemask))
		node_set(node, *cptab->ctb_nodemask);

	/* first CPU of @node in this partition */
	if (!node_isset(node, *cptab->ctb_parts[cpt].cpt_nodemask))
		node_set(node, *cptab->ctb_parts[cpt].cpt_nodemask);

	return 1;
}
EXPORT_SYMBOL(cfs_cpt_set_cpu);

void
cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu)
{
	int	node;
	int	i;

	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	if (cpu < 0 || cpu >= nr_cpu_ids) {
		CDEBUG(D_INFO, "Invalid CPU id %d\n", cpu);
		return;
	}

	if (cpt == CFS_CPT_ANY) {
		/* caller doesn't know the partition ID */
		cpt = cptab->ctb_cpu2cpt[cpu];
		if (cpt < 0) { /* not set in this CPT-table */
			CDEBUG(D_INFO, "Try to unset cpu %d which is not in CPT-table %p\n",
			       cpt, cptab);
			return;
		}

	} else if (cpt != cptab->ctb_cpu2cpt[cpu]) {
		CDEBUG(D_INFO,
		       "CPU %d is not in cpu-partition %d\n", cpu, cpt);
		return;
	}

	LASSERT(cpumask_test_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask));
	LASSERT(cpumask_test_cpu(cpu, cptab->ctb_cpumask));

	cpumask_clear_cpu(cpu, cptab->ctb_parts[cpt].cpt_cpumask);
	cpumask_clear_cpu(cpu, cptab->ctb_cpumask);
	cptab->ctb_cpu2cpt[cpu] = -1;

	node = cpu_to_node(cpu);

	LASSERT(node_isset(node, *cptab->ctb_parts[cpt].cpt_nodemask));
	LASSERT(node_isset(node, *cptab->ctb_nodemask));

	for_each_cpu(i, cptab->ctb_parts[cpt].cpt_cpumask) {
		/* this CPT has other CPU belonging to this node? */
		if (cpu_to_node(i) == node)
			break;
	}

	if (i >= nr_cpu_ids)
		node_clear(node, *cptab->ctb_parts[cpt].cpt_nodemask);

	for_each_cpu(i, cptab->ctb_cpumask) {
		/* this CPT-table has other CPU belonging to this node? */
		if (cpu_to_node(i) == node)
			break;
	}

	if (i >= nr_cpu_ids)
		node_clear(node, *cptab->ctb_nodemask);
}
EXPORT_SYMBOL(cfs_cpt_unset_cpu);

int
cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask)
{
	int	i;

	if (cpumask_weight(mask) == 0 ||
	    cpumask_any_and(mask, cpu_online_mask) >= nr_cpu_ids) {
		CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n",
		       cpt);
		return 0;
	}

	for_each_cpu(i, mask) {
		if (!cfs_cpt_set_cpu(cptab, cpt, i))
			return 0;
	}

	return 1;
}
EXPORT_SYMBOL(cfs_cpt_set_cpumask);

void
cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask)
{
	int	i;

	for_each_cpu(i, mask)
		cfs_cpt_unset_cpu(cptab, cpt, i);
}
EXPORT_SYMBOL(cfs_cpt_unset_cpumask);

int
cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node)
{
	cpumask_t	*mask;
	int		rc;

	if (node < 0 || node >= MAX_NUMNODES) {
		CDEBUG(D_INFO,
		       "Invalid NUMA id %d for CPU partition %d\n", node, cpt);
		return 0;
	}

	mutex_lock(&cpt_data.cpt_mutex);

	mask = cpt_data.cpt_cpumask;
	cfs_node_to_cpumask(node, mask);

	rc = cfs_cpt_set_cpumask(cptab, cpt, mask);

	mutex_unlock(&cpt_data.cpt_mutex);

	return rc;
}
EXPORT_SYMBOL(cfs_cpt_set_node);

void
cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node)
{
	cpumask_t *mask;

	if (node < 0 || node >= MAX_NUMNODES) {
		CDEBUG(D_INFO,
		       "Invalid NUMA id %d for CPU partition %d\n", node, cpt);
		return;
	}

	mutex_lock(&cpt_data.cpt_mutex);

	mask = cpt_data.cpt_cpumask;
	cfs_node_to_cpumask(node, mask);

	cfs_cpt_unset_cpumask(cptab, cpt, mask);

	mutex_unlock(&cpt_data.cpt_mutex);
}
EXPORT_SYMBOL(cfs_cpt_unset_node);

int
cfs_cpt_set_nodemask(struct cfs_cpt_table *cptab, int cpt, nodemask_t *mask)
{
	int	i;

	for_each_node_mask(i, *mask) {
		if (!cfs_cpt_set_node(cptab, cpt, i))
			return 0;
	}

	return 1;
}
EXPORT_SYMBOL(cfs_cpt_set_nodemask);

void
cfs_cpt_unset_nodemask(struct cfs_cpt_table *cptab, int cpt, nodemask_t *mask)
{
	int	i;

	for_each_node_mask(i, *mask)
		cfs_cpt_unset_node(cptab, cpt, i);
}
EXPORT_SYMBOL(cfs_cpt_unset_nodemask);

void
cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt)
{
	int	last;
	int	i;

	if (cpt == CFS_CPT_ANY) {
		last = cptab->ctb_nparts - 1;
		cpt = 0;
	} else {
		last = cpt;
	}

	for (; cpt <= last; cpt++) {
		for_each_cpu(i, cptab->ctb_parts[cpt].cpt_cpumask)
			cfs_cpt_unset_cpu(cptab, cpt, i);
	}
}
EXPORT_SYMBOL(cfs_cpt_clear);

int
cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt)
{
	nodemask_t	*mask;
	int		weight;
	int		rotor;
	int		node;

	/* convert CPU partition ID to HW node id */

	if (cpt < 0 || cpt >= cptab->ctb_nparts) {
		mask = cptab->ctb_nodemask;
		rotor = cptab->ctb_spread_rotor++;
	} else {
		mask = cptab->ctb_parts[cpt].cpt_nodemask;
		rotor = cptab->ctb_parts[cpt].cpt_spread_rotor++;
	}

	weight = nodes_weight(*mask);
	LASSERT(weight > 0);

	rotor %= weight;

	for_each_node_mask(node, *mask) {
		if (rotor-- == 0)
			return node;
	}

	LBUG();
	return 0;
}
EXPORT_SYMBOL(cfs_cpt_spread_node);

int
cfs_cpt_current(struct cfs_cpt_table *cptab, int remap)
{
	int	cpu = smp_processor_id();
	int	cpt = cptab->ctb_cpu2cpt[cpu];

	if (cpt < 0) {
		if (!remap)
			return cpt;

		/* don't return negative value for safety of upper layer,
		 * instead we shadow the unknown cpu to a valid partition ID
		 */
		cpt = cpu % cptab->ctb_nparts;
	}

	return cpt;
}
EXPORT_SYMBOL(cfs_cpt_current);

int
cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu)
{
	LASSERT(cpu >= 0 && cpu < nr_cpu_ids);

	return cptab->ctb_cpu2cpt[cpu];
}
EXPORT_SYMBOL(cfs_cpt_of_cpu);

int
cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt)
{
	cpumask_t	*cpumask;
	nodemask_t	*nodemask;
	int		rc;
	int		i;

	LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts));

	if (cpt == CFS_CPT_ANY) {
		cpumask = cptab->ctb_cpumask;
		nodemask = cptab->ctb_nodemask;
	} else {
		cpumask = cptab->ctb_parts[cpt].cpt_cpumask;
		nodemask = cptab->ctb_parts[cpt].cpt_nodemask;
	}

	if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) {
		CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n",
		       cpt);
		return -EINVAL;
	}

	for_each_online_cpu(i) {
		if (cpumask_test_cpu(i, cpumask))
			continue;

		rc = set_cpus_allowed_ptr(current, cpumask);
		set_mems_allowed(*nodemask);
		if (rc == 0)
			schedule(); /* switch to allowed CPU */

		return rc;
	}

	/* don't need to set affinity because all online CPUs are covered */
	return 0;
}
EXPORT_SYMBOL(cfs_cpt_bind);

/**
 * Choose max to \a number CPUs from \a node and set them in \a cpt.
 * We always prefer to choose CPU in the same core/socket.
 */
static int
cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt,
		     cpumask_t *node, int number)
{
	cpumask_t	*socket = NULL;
	cpumask_t	*core = NULL;
	int		rc = 0;
	int		cpu;

	LASSERT(number > 0);

	if (number >= cpumask_weight(node)) {
		while (!cpumask_empty(node)) {
			cpu = cpumask_first(node);

			rc = cfs_cpt_set_cpu(cptab, cpt, cpu);
			if (!rc)
				return -EINVAL;
			cpumask_clear_cpu(cpu, node);
		}
		return 0;
	}

	/* allocate scratch buffer */
	LIBCFS_ALLOC(socket, cpumask_size());
	LIBCFS_ALLOC(core, cpumask_size());
	if (!socket || !core) {
		rc = -ENOMEM;
		goto out;
	}

	while (!cpumask_empty(node)) {
		cpu = cpumask_first(node);

		/* get cpumask for cores in the same socket */
		cpumask_copy(socket, topology_core_cpumask(cpu));
		cpumask_and(socket, socket, node);

		LASSERT(!cpumask_empty(socket));

		while (!cpumask_empty(socket)) {
			int     i;

			/* get cpumask for hts in the same core */
			cpumask_copy(core, topology_sibling_cpumask(cpu));
			cpumask_and(core, core, node);

			LASSERT(!cpumask_empty(core));

			for_each_cpu(i, core) {
				cpumask_clear_cpu(i, socket);
				cpumask_clear_cpu(i, node);

				rc = cfs_cpt_set_cpu(cptab, cpt, i);
				if (!rc) {
					rc = -EINVAL;
					goto out;
				}

				if (--number == 0)
					goto out;
			}
			cpu = cpumask_first(socket);
		}
	}

 out:
	if (socket)
		LIBCFS_FREE(socket, cpumask_size());
	if (core)
		LIBCFS_FREE(core, cpumask_size());
	return rc;
}

#define CPT_WEIGHT_MIN  4u

static unsigned int
cfs_cpt_num_estimate(void)
{
	unsigned nnode = num_online_nodes();
	unsigned ncpu  = num_online_cpus();
	unsigned ncpt;

	if (ncpu <= CPT_WEIGHT_MIN) {
		ncpt = 1;
		goto out;
	}

	/* generate reasonable number of CPU partitions based on total number
	 * of CPUs, Preferred N should be power2 and match this condition:
	 * 2 * (N - 1)^2 < NCPUS <= 2 * N^2
	 */
	for (ncpt = 2; ncpu > 2 * ncpt * ncpt; ncpt <<= 1)
		;

	if (ncpt <= nnode) { /* fat numa system */
		while (nnode > ncpt)
			nnode >>= 1;

	} else { /* ncpt > nnode */
		while ((nnode << 1) <= ncpt)
			nnode <<= 1;
	}

	ncpt = nnode;

 out:
#if (BITS_PER_LONG == 32)
	/* config many CPU partitions on 32-bit system could consume
	 * too much memory
	 */
	ncpt = min(2U, ncpt);
#endif
	while (ncpu % ncpt != 0)
		ncpt--; /* worst case is 1 */

	return ncpt;
}

static struct cfs_cpt_table *
cfs_cpt_table_create(int ncpt)
{
	struct cfs_cpt_table *cptab = NULL;
	cpumask_t	*mask = NULL;
	int		cpt = 0;
	int		num;
	int		rc;
	int		i;

	rc = cfs_cpt_num_estimate();
	if (ncpt <= 0)
		ncpt = rc;

	if (ncpt > num_online_cpus() || ncpt > 4 * rc) {
		CWARN("CPU partition number %d is larger than suggested value (%d), your system may have performance issue or run out of memory while under pressure\n",
		      ncpt, rc);
	}

	if (num_online_cpus() % ncpt != 0) {
		CERROR("CPU number %d is not multiple of cpu_npartition %d, please try different cpu_npartitions value or set pattern string by cpu_pattern=STRING\n",
		       (int)num_online_cpus(), ncpt);
		goto failed;
	}

	cptab = cfs_cpt_table_alloc(ncpt);
	if (!cptab) {
		CERROR("Failed to allocate CPU map(%d)\n", ncpt);
		goto failed;
	}

	num = num_online_cpus() / ncpt;
	if (num == 0) {
		CERROR("CPU changed while setting CPU partition\n");
		goto failed;
	}

	LIBCFS_ALLOC(mask, cpumask_size());
	if (!mask) {
		CERROR("Failed to allocate scratch cpumask\n");
		goto failed;
	}

	for_each_online_node(i) {
		cfs_node_to_cpumask(i, mask);

		while (!cpumask_empty(mask)) {
			struct cfs_cpu_partition *part;
			int    n;

			/*
			 * Each emulated NUMA node has all allowed CPUs in
			 * the mask.
			 * End loop when all partitions have assigned CPUs.
			 */
			if (cpt == ncpt)
				break;

			part = &cptab->ctb_parts[cpt];

			n = num - cpumask_weight(part->cpt_cpumask);
			LASSERT(n > 0);

			rc = cfs_cpt_choose_ncpus(cptab, cpt, mask, n);
			if (rc < 0)
				goto failed;

			LASSERT(num >= cpumask_weight(part->cpt_cpumask));
			if (num == cpumask_weight(part->cpt_cpumask))
				cpt++;
		}
	}

	if (cpt != ncpt ||
	    num != cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)) {
		CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n",
		       cptab->ctb_nparts, num, cpt,
		       cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask));
		goto failed;
	}

	LIBCFS_FREE(mask, cpumask_size());

	return cptab;

 failed:
	CERROR("Failed to setup CPU-partition-table with %d CPU-partitions, online HW nodes: %d, HW cpus: %d.\n",
	       ncpt, num_online_nodes(), num_online_cpus());

	if (mask)
		LIBCFS_FREE(mask, cpumask_size());

	if (cptab)
		cfs_cpt_table_free(cptab);

	return NULL;
}

static struct cfs_cpt_table *
cfs_cpt_table_create_pattern(char *pattern)
{
	struct cfs_cpt_table	*cptab;
	char			*str	= pattern;
	int			node	= 0;
	int			high;
	int			ncpt;
	int			c;

	for (ncpt = 0;; ncpt++) { /* quick scan bracket */
		str = strchr(str, '[');
		if (!str)
			break;
		str++;
	}

	str = cfs_trimwhite(pattern);
	if (*str == 'n' || *str == 'N') {
		pattern = str + 1;
		node = 1;
	}

	if (ncpt == 0 ||
	    (node && ncpt > num_online_nodes()) ||
	    (!node && ncpt > num_online_cpus())) {
		CERROR("Invalid pattern %s, or too many partitions %d\n",
		       pattern, ncpt);
		return NULL;
	}

	high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1;

	cptab = cfs_cpt_table_alloc(ncpt);
	if (!cptab) {
		CERROR("Failed to allocate cpu partition table\n");
		return NULL;
	}

	for (str = cfs_trimwhite(pattern), c = 0;; c++) {
		struct cfs_range_expr	*range;
		struct cfs_expr_list	*el;
		char			*bracket = strchr(str, '[');
		int			cpt;
		int			rc;
		int			i;
		int			n;

		if (!bracket) {
			if (*str != 0) {
				CERROR("Invalid pattern %s\n", str);
				goto failed;
			}
			if (c != ncpt) {
				CERROR("expect %d partitions but found %d\n",
				       ncpt, c);
				goto failed;
			}
			break;
		}

		if (sscanf(str, "%d%n", &cpt, &n) < 1) {
			CERROR("Invalid cpu pattern %s\n", str);
			goto failed;
		}

		if (cpt < 0 || cpt >= ncpt) {
			CERROR("Invalid partition id %d, total partitions %d\n",
			       cpt, ncpt);
			goto failed;
		}

		if (cfs_cpt_weight(cptab, cpt) != 0) {
			CERROR("Partition %d has already been set.\n", cpt);
			goto failed;
		}

		str = cfs_trimwhite(str + n);
		if (str != bracket) {
			CERROR("Invalid pattern %s\n", str);
			goto failed;
		}

		bracket = strchr(str, ']');
		if (!bracket) {
			CERROR("missing right bracket for cpt %d, %s\n",
			       cpt, str);
			goto failed;
		}

		if (cfs_expr_list_parse(str, (bracket - str) + 1,
					0, high, &el) != 0) {
			CERROR("Can't parse number range: %s\n", str);
			goto failed;
		}

		list_for_each_entry(range, &el->el_exprs, re_link) {
			for (i = range->re_lo; i <= range->re_hi; i++) {
				if ((i - range->re_lo) % range->re_stride != 0)
					continue;

				rc = node ? cfs_cpt_set_node(cptab, cpt, i) :
					    cfs_cpt_set_cpu(cptab, cpt, i);
				if (!rc) {
					cfs_expr_list_free(el);
					goto failed;
				}
			}
		}

		cfs_expr_list_free(el);

		if (!cfs_cpt_online(cptab, cpt)) {
			CERROR("No online CPU is found on partition %d\n", cpt);
			goto failed;
		}

		str = cfs_trimwhite(bracket + 1);
	}

	return cptab;

 failed:
	cfs_cpt_table_free(cptab);
	return NULL;
}

#ifdef CONFIG_HOTPLUG_CPU
static int
cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
{
	unsigned int  cpu = (unsigned long)hcpu;
	bool	     warn;

	switch (action) {
	case CPU_DEAD:
	case CPU_DEAD_FROZEN:
	case CPU_ONLINE:
	case CPU_ONLINE_FROZEN:
		spin_lock(&cpt_data.cpt_lock);
		cpt_data.cpt_version++;
		spin_unlock(&cpt_data.cpt_lock);
		/* Fall through */
	default:
		if (action != CPU_DEAD && action != CPU_DEAD_FROZEN) {
			CDEBUG(D_INFO, "CPU changed [cpu %u action %lx]\n",
			       cpu, action);
			break;
		}

		mutex_lock(&cpt_data.cpt_mutex);
		/* if all HTs in a core are offline, it may break affinity */
		cpumask_copy(cpt_data.cpt_cpumask,
			     topology_sibling_cpumask(cpu));
		warn = cpumask_any_and(cpt_data.cpt_cpumask,
				       cpu_online_mask) >= nr_cpu_ids;
		mutex_unlock(&cpt_data.cpt_mutex);
		CDEBUG(warn ? D_WARNING : D_INFO,
		       "Lustre: can't support CPU plug-out well now, performance and stability could be impacted [CPU %u action: %lx]\n",
		       cpu, action);
	}

	return NOTIFY_OK;
}

static struct notifier_block cfs_cpu_notifier = {
	.notifier_call	= cfs_cpu_notify,
	.priority	= 0
};

#endif

void
cfs_cpu_fini(void)
{
	if (cfs_cpt_table)
		cfs_cpt_table_free(cfs_cpt_table);

#ifdef CONFIG_HOTPLUG_CPU
	unregister_hotcpu_notifier(&cfs_cpu_notifier);
#endif
	if (cpt_data.cpt_cpumask)
		LIBCFS_FREE(cpt_data.cpt_cpumask, cpumask_size());
}

int
cfs_cpu_init(void)
{
	LASSERT(!cfs_cpt_table);

	memset(&cpt_data, 0, sizeof(cpt_data));

	LIBCFS_ALLOC(cpt_data.cpt_cpumask, cpumask_size());
	if (!cpt_data.cpt_cpumask) {
		CERROR("Failed to allocate scratch buffer\n");
		return -1;
	}

	spin_lock_init(&cpt_data.cpt_lock);
	mutex_init(&cpt_data.cpt_mutex);

#ifdef CONFIG_HOTPLUG_CPU
	register_hotcpu_notifier(&cfs_cpu_notifier);
#endif

	if (*cpu_pattern != 0) {
		cfs_cpt_table = cfs_cpt_table_create_pattern(cpu_pattern);
		if (!cfs_cpt_table) {
			CERROR("Failed to create cptab from pattern %s\n",
			       cpu_pattern);
			goto failed;
		}

	} else {
		cfs_cpt_table = cfs_cpt_table_create(cpu_npartitions);
		if (!cfs_cpt_table) {
			CERROR("Failed to create ptable with npartitions %d\n",
			       cpu_npartitions);
			goto failed;
		}
	}

	spin_lock(&cpt_data.cpt_lock);
	if (cfs_cpt_table->ctb_version != cpt_data.cpt_version) {
		spin_unlock(&cpt_data.cpt_lock);
		CERROR("CPU hotplug/unplug during setup\n");
		goto failed;
	}
	spin_unlock(&cpt_data.cpt_lock);

	LCONSOLE(0, "HW CPU cores: %d, npartitions: %d\n",
		 num_online_cpus(), cfs_cpt_number(cfs_cpt_table));
	return 0;

 failed:
	cfs_cpu_fini();
	return -1;
}

#endif
