On Thu, Sep 01, 2016 at 10:24:10AM -0400, Keith Busch wrote: > On Thu, Sep 01, 2016 at 10:46:24AM +0200, Christoph Hellwig wrote: > > On Wed, Aug 31, 2016 at 12:38:53PM -0400, Keith Busch wrote: > > > This can't be right. We have a single affinity mask for the entire > > > set, but what I think we want is an one affinity mask for each > > > nr_io_queues. The irq_create_affinity_mask should then create an array > > > of cpumasks based on nr_vecs.. > > > > Nah, this is Thomas' creating abuse of the cpumask type. Every bit set > > in the affinity_mask means this is a cpu we allocate a vector / queue to. > > Yeah, I gathered that's what it was providing, but that's just barely > not enough information to do something useful. The CPUs that aren't set > have to use a previously assigned vector/queue, but which one? Always the previous one. Below is a patch to get us back to the previous behavior: diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 32f6cfc..09d4407 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c @@ -29,6 +29,8 @@ struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs) { struct cpumask *affinity_mask; unsigned int max_vecs = *nr_vecs; + unsigned int nr_cpus = 0, nr_uniq_cpus = 0, cpu; + unsigned int vec = 0, prev = -1, idx = 0; if (max_vecs == 1) return NULL; @@ -40,24 +42,27 @@ struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs) } get_online_cpus(); - if (max_vecs >= num_online_cpus()) { - cpumask_copy(affinity_mask, cpu_online_mask); - *nr_vecs = num_online_cpus(); - } else { - unsigned int vecs = 0, cpu; - - for_each_online_cpu(cpu) { - if (cpu == get_first_sibling(cpu)) { - cpumask_set_cpu(cpu, affinity_mask); - vecs++; - } - - if (--max_vecs == 0) - break; - } - *nr_vecs = vecs; + for_each_online_cpu(cpu) { + nr_cpus++; + if (cpu == get_first_sibling(cpu)) + nr_uniq_cpus++; + } + + for_each_online_cpu(cpu) { + if (max_vecs >= nr_cpus || nr_cpus == nr_uniq_cpus) + vec = idx * max_vecs / nr_cpus; + else if (cpu == get_first_sibling(cpu)) + vec = idx * max_vecs / nr_uniq_cpus; + else + continue; + + if (vec != prev) + cpumask_set_cpu(cpu, affinity_mask); + prev = vec; + idx++; } put_online_cpus(); + *nr_vecs = idx; return affinity_mask; } -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html