cpumask: for_each_cpu_both() / cpumask_first_both() / cpumask_next_both()

A common reason that temporary cpumasks are created is to iterate over
the intersection of that and cpu_online_map.  An iterator which does
this implicitly reduces that need.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 include/linux/cpumask.h |   12 ++++++++++++
 lib/cpumask.c           |   20 ++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff -r e426d5ec9f9f include/linux/cpumask.h
--- a/include/linux/cpumask.h	Sun Sep 28 19:54:07 2008 +1000
+++ b/include/linux/cpumask.h	Sun Sep 28 21:49:41 2008 +1000
@@ -48,6 +48,8 @@
  *
  * int cpumask_first(mask)		Number lowest set bit, or nr_cpu_ids
  * int cpumask_next(cpu, mask)		Next cpu past 'cpu', or nr_cpu_ids
+ * int cpumask_first_both(mask1, mask2)	Lowest set bit in mask1 & mask2
+ * int cpumask_next_both(cpu, m1, m2)	Next set bit in mask1 & mask2
  *
  * void cpumask_copy(dmask, smask)	dmask = smask
  *
@@ -417,14 +419,20 @@ extern const struct cpumask cpu_mask_all
 
 #define cpumask_first(src)	({ (void)(src); 0; })
 #define cpumask_next(n, src)	({ (void)(src); 1; })
+#define cpumask_first_both(src1, src2)	({ (void)(src1); (void)(src2); 0; })
+#define cpumask_next(n, src1, src2)	({ (void)(src1); (void)(src2); 1; })
 #define any_online_cpu(mask)	0
 #define for_each_cpu(cpu, mask)	\
 	for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
+#define for_each_cpu_both(cpu, mask1, mask2) \
+	for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask1, (void)mask2)
 
 #else /* NR_CPUS > 1 */
 
 int cpumask_first(const cpumask_t *srcp);
 int cpumask_next(int n, const cpumask_t *srcp);
+int cpumask_first_both(const cpumask_t *src1, const cpumask_t *src2);
+int cpumask_next_both(int n, const cpumask_t *src1, const cpumask_t *src2);
 int __any_online_cpu(const cpumask_t *mask);
 
 #define any_online_cpu(mask) __any_online_cpu(&(mask))
@@ -432,6 +440,10 @@ int __any_online_cpu(const cpumask_t *ma
 	for ((cpu) = cpumask_first(mask);		\
 	     (cpu) < nr_cpu_ids;			\
 	     (cpu) = cpumask_next((cpu), (mask)))
+#define for_each_cpu_both(cpu, mask1, mask2)			\
+	for ((cpu) = cpumask_first_both((mask1), (mask2));	\
+	     (cpu) < nr_cpu_ids;				\
+	     (cpu) = cpumask_next((cpu), (mask1), (mask2)))
 #endif
 
 /*
diff -r e426d5ec9f9f lib/cpumask.c
--- a/lib/cpumask.c	Sun Sep 28 19:54:07 2008 +1000
+++ b/lib/cpumask.c	Sun Sep 28 21:49:41 2008 +1000
@@ -14,6 +14,26 @@ int cpumask_next(int n, const struct cpu
 	return find_next_bit(cpumask_bits(srcp), nr_cpu_ids, n+1);
 }
 EXPORT_SYMBOL(cpumask_next);
+
+int cpumask_first_both(const cpumask_t *src1, const cpumask_t *src2)
+{
+	unsigned int i;
+
+	for_each_cpu(i, src1)
+		if (cpumask_test_cpu(i, src2))
+			break;
+	return i;
+}
+EXPORT_SYMBOL(cpumask_first_both);
+
+int cpumask_next_both(int n, const cpumask_t *src1, const cpumask_t *src2)
+{
+	while ((n = cpumask_next(n+1, src1)) < nr_cpu_ids)
+		if (cpumask_test_cpu(n, src2))
+			break;
+	return n;
+}
+EXPORT_SYMBOL(cpumask_next_both);
 
 int __any_online_cpu(const cpumask_t *mask)
 {
