Commit 944c417d authored by Yury Norov's avatar Yury Norov
Browse files

cpumask: add cpumask_nth_{,and,andnot}



Add cpumask_nth_{,and,andnot} as wrappers around corresponding
find functions, and use it in cpumask_local_spread().

Signed-off-by: default avatarYury Norov <yury.norov@gmail.com>
parent 97848c10
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -337,6 +337,50 @@ unsigned int cpumask_any_but(const struct cpumask *mask, unsigned int cpu)
	return i;
}

/**
 * cpumask_nth - get the first cpu in a cpumask
 * @srcp: the cpumask pointer
 * @cpu: the N'th cpu to find, starting from 0
 *
 * Returns >= nr_cpu_ids if such cpu doesn't exist.
 */
static inline unsigned int cpumask_nth(unsigned int cpu, const struct cpumask *srcp)
{
	return find_nth_bit(cpumask_bits(srcp), nr_cpumask_bits, cpumask_check(cpu));
}

/**
 * cpumask_nth_and - get the first cpu in 2 cpumasks
 * @srcp1: the cpumask pointer
 * @srcp2: the cpumask pointer
 * @cpu: the N'th cpu to find, starting from 0
 *
 * Returns >= nr_cpu_ids if such cpu doesn't exist.
 */
static inline
unsigned int cpumask_nth_and(unsigned int cpu, const struct cpumask *srcp1,
							const struct cpumask *srcp2)
{
	return find_nth_and_bit(cpumask_bits(srcp1), cpumask_bits(srcp2),
				nr_cpumask_bits, cpumask_check(cpu));
}

/**
 * cpumask_nth_andnot - get the first cpu set in 1st cpumask, and clear in 2nd.
 * @srcp1: the cpumask pointer
 * @srcp2: the cpumask pointer
 * @cpu: the N'th cpu to find, starting from 0
 *
 * Returns >= nr_cpu_ids if such cpu doesn't exist.
 */
static inline
unsigned int cpumask_nth_andnot(unsigned int cpu, const struct cpumask *srcp1,
							const struct cpumask *srcp2)
{
	return find_nth_andnot_bit(cpumask_bits(srcp1), cpumask_bits(srcp2),
				nr_cpumask_bits, cpumask_check(cpu));
}

#define CPU_BITS_NONE						\
{								\
	[0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL			\
+13 −15
Original line number Diff line number Diff line
@@ -128,24 +128,22 @@ unsigned int cpumask_local_spread(unsigned int i, int node)
	i %= num_online_cpus();

	if (node == NUMA_NO_NODE) {
		for_each_cpu(cpu, cpu_online_mask)
			if (i-- == 0)
		cpu = cpumask_nth(i, cpu_online_mask);
		if (cpu < nr_cpu_ids)
			return cpu;
	} else {
		/* NUMA first. */
		for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask)
			if (i-- == 0)
		cpu = cpumask_nth_and(i, cpu_online_mask, cpumask_of_node(node));
		if (cpu < nr_cpu_ids)
			return cpu;

		for_each_cpu(cpu, cpu_online_mask) {
			/* Skip NUMA nodes, done above. */
			if (cpumask_test_cpu(cpu, cpumask_of_node(node)))
				continue;
		i -= cpumask_weight_and(cpu_online_mask, cpumask_of_node(node));

			if (i-- == 0)
		/* Skip NUMA nodes, done above. */
		cpu = cpumask_nth_andnot(i, cpu_online_mask, cpumask_of_node(node));
		if (cpu < nr_cpu_ids)
			return cpu;
	}
	}
	BUG();
}
EXPORT_SYMBOL(cpumask_local_spread);