Re: [RFC/PATCH 3/4] genirq: system set irq affinities

From: Max Krasnyanskiy
Date: Wed Feb 27 2008 - 19:10:46 EST


Besides the notifier stuff it's identical to my genirq patch that I sent to Thomas and you for the review ~5 days ago.
There are a couple of things you missed.
Current call site for select_smp_affinity() inside request_irq() is incorrect. It ends up moving irq each time requires_irq() is called, and it is called multiple times for the shared irqs. My patch moves it into setup_irq() under if(!shared) check.

Also the following part is unsafe

+#ifdef CONFIG_CPUSETS
+static int system_irq_notifier(struct notifier_block *nb,
+ unsigned long action, void *cpus)
+{
+ cpumask_t *new_system_map = (cpumask_t *)cpus;
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ struct irq_desc *desc = &irq_desc[i];
+
+ if (desc->chip == &no_irq_chip || !irq_can_set_affinity(i))
+ continue;
+
+ if (cpus_match_system(desc->affinity)) {
+ cpumask_t online_system;
+
+ cpus_and(online_system, new_system_map, cpu_online_map);
+
+ set_balance_irq_affinity(i, online_system);
+
+ desc->affinity = online_system;
+ desc->chip->set_affinity(i, online_system);
Two lines above should be
irq_set_affinity(i, online_system);

If you look at how irq_set_affinity() is implemented, you'll see this

#ifdef CONFIG_GENERIC_PENDING_IRQ
set_pending_irq(irq, cpumask);
#else
desc->affinity = cpumask;
desc->chip->set_affinity(irq, cpumask);
#endif

set_pending_irq() is the safe way to move pending irqs.

btw It should be ok to call chip->set_affinity() directly from select_smp_affinity() because in my patch is is guarantied to be called only for the first handler registration.

Max
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/