genirq/affinity: Improve __irq_build_affinity_masks()
[linux-2.6-microblaze.git] / kernel / irq / affinity.c
index 6fef480..c7cca94 100644 (file)
@@ -129,14 +129,26 @@ static int __irq_build_affinity_masks(unsigned int startvec,
        for_each_node_mask(n, nodemsk) {
                unsigned int ncpus, v, vecs_to_assign, vecs_per_node;
 
-               /* Spread the vectors per node */
-               vecs_per_node = (numvecs - (curvec - firstvec)) / nodes;
-
                /* Get the cpus on this node which are in the mask */
                cpumask_and(nmsk, cpu_mask, node_to_cpumask[n]);
-
-               /* Calculate the number of cpus per vector */
                ncpus = cpumask_weight(nmsk);
+               if (!ncpus)
+                       continue;
+
+               /*
+                * Calculate the number of cpus per vector
+                *
+                * Spread the vectors evenly per node. If the requested
+                * vector number has been reached, simply allocate one
+                * vector for each remaining node so that all nodes can
+                * be covered
+                */
+               if (numvecs > done)
+                       vecs_per_node = max_t(unsigned,
+                                       (numvecs - done) / nodes, 1);
+               else
+                       vecs_per_node = 1;
+
                vecs_to_assign = min(vecs_per_node, ncpus);
 
                /* Account for rounding errors */
@@ -156,13 +168,11 @@ static int __irq_build_affinity_masks(unsigned int startvec,
                }
 
                done += v;
-               if (done >= numvecs)
-                       break;
                if (curvec >= last_affv)
                        curvec = firstvec;
                --nodes;
        }
-       return done;
+       return done < numvecs ? done : numvecs;
 }
 
 /*