From: Rusty Russell <rusty@rustcorp.com.au>
To: Mike Travis <travis@sgi.com>
Cc: Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
Thomas Gleixner <tglx@linutronix.de>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/4] x86: fix cpu_mask_to_apicid_and to include cpu_online_mask
Date: Sat, 13 Dec 2008 22:33:48 +1030 [thread overview]
Message-ID: <200812132233.48858.rusty@rustcorp.com.au> (raw)
In-Reply-To: <49429332.8030105@sgi.com>
On Saturday 13 December 2008 03:07:06 Mike Travis wrote:
> Rusty Russell wrote:
> > On Thursday 11 December 2008 21:58:08 Mike Travis wrote:
> >> Impact: fix potential problem.
> >>
> >> In determining the destination apicid, there are usually three cpumasks
> >> that are considered: the incoming cpumask arg, cfg->domain and the
> >> cpu_online_mask. Since we are just introducing the cpu_mask_to_apicid_and
> >> function, make sure it includes the cpu_online_mask in it's evaluation.
> >
> > Yerk. Can we really "fail" cpu_mask_to_apicid_and with no repercussions?
> > And does it make sense to try to fix this there?
>
> Fail? The only failure is if there is not a cpu that satisfies the conjunction
> of the three masks, in which case it returns BAD_APICID.
That patch showed cpumask_alloc_var in some implementations of
cpu_mask_to_apicid_and. This is bad.
> The old procedure was to:
>
> function(..., cpumask_t mask)
> {
> cpumask_t tmp;
>
> cpus_and(tmp, mask, cfg->domain);
> ...
> cpus_and(tmp, tmp, cpu_online_map);
> dest = cpu_mask_to_apicid(tmp);
> ...
> }
>
> So making cpu_mask_to_apicid_and return:
>
> dest = cpu_mask_to_apicid(mask1 & mask2 & cpu_online_mask);
>
> maintains this compatibility.
But that was the purpose of x86:set_desc_affinity.patch. It centralized
those conventions, and other than being a nice cleanup, it got that right.
See below.
Now, there are some places which call cpu_mask_to_apicid_and() and don't
include the online mask, but I checked: they were that way before. Possibly
an existing bug?
Otherwise, it could be that setting the desc->affinity earlier (as this patch
does) has caused a problem. Which of these code paths were you running?
Cheers,
Rusty.
===
x86: centralize common code for set_affinity variants.
Impact: cleanup, remove on-stack cpumasks
Everyone checks that a cpu is online, calls assign_irq_vector, and
also uses a temporary cpumask.
I *think* it's legal to set the desc->affinity in place in all cases,
so I avoid the temporary cpumask.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@redhat.com>
---
arch/x86/kernel/io_apic.c | 112 ++++++++++++++--------------------------------
1 file changed, 36 insertions(+), 76 deletions(-)
diff -r 07e2723b2a5d arch/x86/kernel/io_apic.c
--- a/arch/x86/kernel/io_apic.c Tue Nov 18 11:20:08 2008 +1030
+++ b/arch/x86/kernel/io_apic.c Tue Nov 18 11:40:35 2008 +1030
@@ -361,33 +361,38 @@
static int assign_irq_vector(int irq, const struct cpumask *mask);
+/* Either sets desc->affinity to a valid value, and returns cpu_mask_to_apicid
+ * of that, or returns BAD_APICID and leaves desc->affinity untouched. */
+static unsigned int set_desc_affinity(unsigned irq, const struct cpumask *mask)
+{
+ struct irq_cfg *cfg;
+ struct irq_desc *desc;
+
+ if (!cpumask_intersects(mask, cpu_online_mask))
+ return BAD_APICID;
+
+ cfg = irq_cfg(irq);
+ if (assign_irq_vector(irq, mask))
+ return BAD_APICID;
+
+ desc = irq_to_desc(irq);
+ cpumask_and(&desc->affinity, to_cpumask(cfg->domain), mask);
+ return cpu_mask_to_apicid(&desc->affinity);
+}
+
static void set_ioapic_affinity_irq(unsigned int irq,
const struct cpumask *mask)
{
- struct irq_cfg *cfg;
unsigned long flags;
unsigned int dest;
- cpumask_t tmp;
- struct irq_desc *desc;
- if (!cpumask_intersects(mask, cpu_online_mask))
- return;
-
- cfg = irq_cfg(irq);
- if (assign_irq_vector(irq, mask))
- return;
-
- cpumask_and(&tmp, &cfg->domain, mask);
- dest = cpu_mask_to_apicid(&tmp);
- /*
- * Only the high 8 bits are valid.
- */
- dest = SET_APIC_LOGICAL_ID(dest);
-
- desc = irq_to_desc(irq);
spin_lock_irqsave(&ioapic_lock, flags);
- __target_IO_APIC_irq(irq, dest, cfg->vector);
- cpumask_copy(&desc->affinity, mask);
+ dest = set_desc_affinity(irq, mask);
+ if (dest != BAD_APICID) {
+ /* Only the high 8 bits are valid. */
+ dest = SET_APIC_LOGICAL_ID(dest);
+ __target_IO_APIC_irq(irq, dest, irq_cfg(irq)->vector);
+ }
spin_unlock_irqrestore(&ioapic_lock, flags);
}
#endif /* CONFIG_SMP */
@@ -3017,32 +3022,21 @@
#ifdef CONFIG_SMP
static void set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
{
- struct irq_cfg *cfg;
struct msi_msg msg;
unsigned int dest;
- cpumask_t tmp;
- struct irq_desc *desc;
- if (!cpumask_intersects(mask, cpu_online_mask))
+ dest = set_desc_affinity(irq, mask);
+ if (dest == BAD_APICID)
return;
-
- if (assign_irq_vector(irq, mask))
- return;
-
- cfg = irq_cfg(irq);
- cpumask_and(&tmp, &cfg->domain, mask);
- dest = cpu_mask_to_apicid(&tmp);
read_msi_msg(irq, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
- msg.data |= MSI_DATA_VECTOR(cfg->vector);
+ msg.data |= MSI_DATA_VECTOR(irq_cfg(irq)->vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
write_msi_msg(irq, &msg);
- desc = irq_to_desc(irq);
- cpumask_copy(&desc->affinity, mask);
}
#ifdef CONFIG_INTR_REMAP
@@ -3055,23 +3049,17 @@
{
struct irq_cfg *cfg;
unsigned int dest;
- cpumask_t tmp;
struct irte irte;
struct irq_desc *desc;
-
- if (!cpumask_intersects(mask, cpu_online_mask))
- return;
if (get_irte(irq, &irte))
return;
- if (assign_irq_vector(irq, mask))
+ dest = set_desc_affinity(irq, mask);
+ if (dest == BAD_APICID)
return;
cfg = irq_cfg(irq);
- cpumask_and(&tmp, to_cpumask(cfg->domain), mask);
- dest = cpu_mask_to_apicid(&tmp);
-
irte.vector = cfg->vector;
irte.dest_id = IRTE_DEST(dest);
@@ -3106,9 +3094,6 @@
}
cfg->move_in_progress = 0;
}
-
- desc = irq_to_desc(irq);
- cpumask_copy(&desc->affinity, mask);
}
#endif
#endif /* CONFIG_SMP */
@@ -3315,19 +3300,12 @@
struct irq_cfg *cfg;
struct msi_msg msg;
unsigned int dest;
- cpumask_t tmp;
- struct irq_desc *desc;
- if (!cpumask_intersects(mask, cpu_online_mask))
- return;
-
- if (assign_irq_vector(irq, mask))
+ dest = set_desc_affinity(irq, mask);
+ if (dest == BAD_APICID)
return;
cfg = irq_cfg(irq);
- cpumask_and(&tmp, &cfg->domain, mask);
- dest = cpu_mask_to_apicid(&tmp);
-
dmar_msi_read(irq, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
@@ -3336,8 +3314,6 @@
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
dmar_msi_write(irq, &msg);
- desc = irq_to_desc(irq);
- cpumask_copy(&desc->affinity, mask);
}
#endif /* CONFIG_SMP */
@@ -3373,20 +3349,14 @@
static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
{
struct irq_cfg *cfg;
- struct irq_desc *desc;
struct msi_msg msg;
unsigned int dest;
- cpumask_t tmp;
- if (!cpumask_intersects(mask, cpu_online_mask))
- return;
-
- if (assign_irq_vector(irq, mask))
+ dest = set_desc_affinity(irq, mask);
+ if (dest == BAD_APICID)
return;
cfg = irq_cfg(irq);
- cpumask_and(&tmp, to_cpumask(cfg->domain), mask);
- dest = cpu_mask_to_apicid(&tmp);
hpet_msi_read(irq, &msg);
@@ -3396,8 +3366,6 @@
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
hpet_msi_write(irq, &msg);
- desc = irq_to_desc(irq);
- cpumask_copy(&desc->affinity, mask);
}
#endif /* CONFIG_SMP */
@@ -3455,22 +3423,14 @@
{
struct irq_cfg *cfg;
unsigned int dest;
- cpumask_t tmp;
- struct irq_desc *desc;
- if (!cpumask_intersects(mask, cpu_online_mask))
- return;
-
- if (assign_irq_vector(irq, mask))
+ dest = set_desc_affinity(irq, mask);
+ if (dest == BAD_APICID)
return;
cfg = irq_cfg(irq);
- cpumask_and(&tmp, to_cpumask(cfg->domain), mask);
- dest = cpu_mask_to_apicid(&tmp);
target_ht_irq(irq, dest, cfg->vector);
- desc = irq_to_desc(irq);
- cpumask_copy(&desc->affinity, mask);
}
#endif
next prev parent reply other threads:[~2008-12-13 12:04 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-11 11:28 [PATCH 0/4] cpumask: fixups and additions Mike Travis
2008-12-11 11:28 ` [PATCH 1/4] x86: fix assign_irq_vector boot up problem Mike Travis
2008-12-12 8:27 ` Rusty Russell
2008-12-12 9:20 ` Ingo Molnar
2008-12-12 18:10 ` Mike Travis
2008-12-12 19:06 ` Mike Travis
2008-12-11 11:28 ` [PATCH 2/4] x86: fix cpu_mask_to_apicid_and to include cpu_online_mask Mike Travis
2008-12-12 11:06 ` Rusty Russell
2008-12-12 16:37 ` Mike Travis
2008-12-13 12:03 ` Rusty Russell [this message]
2008-12-11 11:28 ` [PATCH 3/4] cpumask: use maxcpus=NUM to extend the cpu limit as well as restrict the limit Mike Travis
2008-12-11 13:41 ` Heiko Carstens
2008-12-11 18:19 ` Mike Travis
2008-12-12 10:03 ` Heiko Carstens
2008-12-12 11:41 ` Rusty Russell
2008-12-12 15:38 ` Mike Travis
2008-12-11 11:28 ` [PATCH 4/4] cpumask: add sysfs displays for configured and disabled cpu maps Mike Travis
2008-12-12 11:44 ` Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200812132233.48858.rusty@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=travis@sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox