diff options
author | Gary Hade <garyhade@us.ibm.com> | 2009-04-08 17:07:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-08 23:13:57 -0400 |
commit | e85abf8f432bb2a13733ab7609fbb8e1500af51d (patch) | |
tree | 428d78759a0a6b4782a18cf07182a1cb3a1d001b /arch/x86/kernel/apic | |
parent | 02421f98ec55c3ff118f358740ff640f096c7ad6 (diff) |
x86: consolidate SMP code in io_apic.c
Impact: Cleanup
Reorganizes the code in arch/x86/kernel/io_apic.c by
combining two '#ifdef CONFIG_SMP' regions. In addition
to making the code easier to understand the first
'#ifdef CONFIG_SMP' region is moved to a location later
in the file which will reduce the need for function
forward declarations when the code subsequently revised.
The only changes other than relocating code to a different
position in the file were the removal of the assign_irq_vector()
forward declaration which was no longer needed and some line
length reduction formatting changes.
Signed-off-by: Gary Hade <garyhade@us.ibm.com>
Cc: lcm@us.ibm.com
LKML-Reference: <20090408210725.GC11159@us.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 223 |
1 files changed, 109 insertions, 114 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 767fe7e46d68..7c9d045ac834 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -518,120 +518,6 @@ static void ioapic_mask_entry(int apic, int pin) | |||
518 | spin_unlock_irqrestore(&ioapic_lock, flags); | 518 | spin_unlock_irqrestore(&ioapic_lock, flags); |
519 | } | 519 | } |
520 | 520 | ||
521 | #ifdef CONFIG_SMP | ||
522 | static void send_cleanup_vector(struct irq_cfg *cfg) | ||
523 | { | ||
524 | cpumask_var_t cleanup_mask; | ||
525 | |||
526 | if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { | ||
527 | unsigned int i; | ||
528 | cfg->move_cleanup_count = 0; | ||
529 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
530 | cfg->move_cleanup_count++; | ||
531 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
532 | apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); | ||
533 | } else { | ||
534 | cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); | ||
535 | cfg->move_cleanup_count = cpumask_weight(cleanup_mask); | ||
536 | apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); | ||
537 | free_cpumask_var(cleanup_mask); | ||
538 | } | ||
539 | cfg->move_in_progress = 0; | ||
540 | } | ||
541 | |||
542 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
543 | { | ||
544 | int apic, pin; | ||
545 | struct irq_pin_list *entry; | ||
546 | u8 vector = cfg->vector; | ||
547 | |||
548 | entry = cfg->irq_2_pin; | ||
549 | for (;;) { | ||
550 | unsigned int reg; | ||
551 | |||
552 | if (!entry) | ||
553 | break; | ||
554 | |||
555 | apic = entry->apic; | ||
556 | pin = entry->pin; | ||
557 | /* | ||
558 | * With interrupt-remapping, destination information comes | ||
559 | * from interrupt-remapping table entry. | ||
560 | */ | ||
561 | if (!irq_remapped(irq)) | ||
562 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
563 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
564 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
565 | reg |= vector; | ||
566 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
567 | if (!entry->next) | ||
568 | break; | ||
569 | entry = entry->next; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | static int | ||
574 | assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask); | ||
575 | |||
576 | /* | ||
577 | * Either sets desc->affinity to a valid value, and returns | ||
578 | * ->cpu_mask_to_apicid of that, or returns BAD_APICID and | ||
579 | * leaves desc->affinity untouched. | ||
580 | */ | ||
581 | static unsigned int | ||
582 | set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | ||
583 | { | ||
584 | struct irq_cfg *cfg; | ||
585 | unsigned int irq; | ||
586 | |||
587 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
588 | return BAD_APICID; | ||
589 | |||
590 | irq = desc->irq; | ||
591 | cfg = desc->chip_data; | ||
592 | if (assign_irq_vector(irq, cfg, mask)) | ||
593 | return BAD_APICID; | ||
594 | |||
595 | /* check that before desc->addinity get updated */ | ||
596 | set_extra_move_desc(desc, mask); | ||
597 | |||
598 | cpumask_copy(desc->affinity, mask); | ||
599 | |||
600 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
601 | } | ||
602 | |||
603 | static void | ||
604 | set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
605 | { | ||
606 | struct irq_cfg *cfg; | ||
607 | unsigned long flags; | ||
608 | unsigned int dest; | ||
609 | unsigned int irq; | ||
610 | |||
611 | irq = desc->irq; | ||
612 | cfg = desc->chip_data; | ||
613 | |||
614 | spin_lock_irqsave(&ioapic_lock, flags); | ||
615 | dest = set_desc_affinity(desc, mask); | ||
616 | if (dest != BAD_APICID) { | ||
617 | /* Only the high 8 bits are valid. */ | ||
618 | dest = SET_APIC_LOGICAL_ID(dest); | ||
619 | __target_IO_APIC_irq(irq, dest, cfg); | ||
620 | } | ||
621 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
622 | } | ||
623 | |||
624 | static void | ||
625 | set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) | ||
626 | { | ||
627 | struct irq_desc *desc; | ||
628 | |||
629 | desc = irq_to_desc(irq); | ||
630 | |||
631 | set_ioapic_affinity_irq_desc(desc, mask); | ||
632 | } | ||
633 | #endif /* CONFIG_SMP */ | ||
634 | |||
635 | /* | 521 | /* |
636 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are | 522 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are |
637 | * shared ISA-space IRQs, so we have to support them. We are super | 523 | * shared ISA-space IRQs, so we have to support them. We are super |
@@ -2360,6 +2246,115 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
2360 | */ | 2246 | */ |
2361 | 2247 | ||
2362 | #ifdef CONFIG_SMP | 2248 | #ifdef CONFIG_SMP |
2249 | static void send_cleanup_vector(struct irq_cfg *cfg) | ||
2250 | { | ||
2251 | cpumask_var_t cleanup_mask; | ||
2252 | |||
2253 | if (unlikely(!alloc_cpumask_var(&cleanup_mask, GFP_ATOMIC))) { | ||
2254 | unsigned int i; | ||
2255 | cfg->move_cleanup_count = 0; | ||
2256 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
2257 | cfg->move_cleanup_count++; | ||
2258 | for_each_cpu_and(i, cfg->old_domain, cpu_online_mask) | ||
2259 | apic->send_IPI_mask(cpumask_of(i), IRQ_MOVE_CLEANUP_VECTOR); | ||
2260 | } else { | ||
2261 | cpumask_and(cleanup_mask, cfg->old_domain, cpu_online_mask); | ||
2262 | cfg->move_cleanup_count = cpumask_weight(cleanup_mask); | ||
2263 | apic->send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); | ||
2264 | free_cpumask_var(cleanup_mask); | ||
2265 | } | ||
2266 | cfg->move_in_progress = 0; | ||
2267 | } | ||
2268 | |||
2269 | static void | ||
2270 | __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
2271 | { | ||
2272 | int apic, pin; | ||
2273 | struct irq_pin_list *entry; | ||
2274 | u8 vector = cfg->vector; | ||
2275 | |||
2276 | entry = cfg->irq_2_pin; | ||
2277 | for (;;) { | ||
2278 | unsigned int reg; | ||
2279 | |||
2280 | if (!entry) | ||
2281 | break; | ||
2282 | |||
2283 | apic = entry->apic; | ||
2284 | pin = entry->pin; | ||
2285 | /* | ||
2286 | * With interrupt-remapping, destination information comes | ||
2287 | * from interrupt-remapping table entry. | ||
2288 | */ | ||
2289 | if (!irq_remapped(irq)) | ||
2290 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
2291 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
2292 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
2293 | reg |= vector; | ||
2294 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
2295 | if (!entry->next) | ||
2296 | break; | ||
2297 | entry = entry->next; | ||
2298 | } | ||
2299 | } | ||
2300 | |||
2301 | /* | ||
2302 | * Either sets desc->affinity to a valid value, and returns | ||
2303 | * ->cpu_mask_to_apicid of that, or returns BAD_APICID and | ||
2304 | * leaves desc->affinity untouched. | ||
2305 | */ | ||
2306 | static unsigned int | ||
2307 | set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | ||
2308 | { | ||
2309 | struct irq_cfg *cfg; | ||
2310 | unsigned int irq; | ||
2311 | |||
2312 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
2313 | return BAD_APICID; | ||
2314 | |||
2315 | irq = desc->irq; | ||
2316 | cfg = desc->chip_data; | ||
2317 | if (assign_irq_vector(irq, cfg, mask)) | ||
2318 | return BAD_APICID; | ||
2319 | |||
2320 | /* check that before desc->addinity get updated */ | ||
2321 | set_extra_move_desc(desc, mask); | ||
2322 | |||
2323 | cpumask_copy(desc->affinity, mask); | ||
2324 | |||
2325 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
2326 | } | ||
2327 | |||
2328 | static void | ||
2329 | set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | ||
2330 | { | ||
2331 | struct irq_cfg *cfg; | ||
2332 | unsigned long flags; | ||
2333 | unsigned int dest; | ||
2334 | unsigned int irq; | ||
2335 | |||
2336 | irq = desc->irq; | ||
2337 | cfg = desc->chip_data; | ||
2338 | |||
2339 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2340 | dest = set_desc_affinity(desc, mask); | ||
2341 | if (dest != BAD_APICID) { | ||
2342 | /* Only the high 8 bits are valid. */ | ||
2343 | dest = SET_APIC_LOGICAL_ID(dest); | ||
2344 | __target_IO_APIC_irq(irq, dest, cfg); | ||
2345 | } | ||
2346 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2347 | } | ||
2348 | |||
2349 | static void | ||
2350 | set_ioapic_affinity_irq(unsigned int irq, const struct cpumask *mask) | ||
2351 | { | ||
2352 | struct irq_desc *desc; | ||
2353 | |||
2354 | desc = irq_to_desc(irq); | ||
2355 | |||
2356 | set_ioapic_affinity_irq_desc(desc, mask); | ||
2357 | } | ||
2363 | 2358 | ||
2364 | #ifdef CONFIG_INTR_REMAP | 2359 | #ifdef CONFIG_INTR_REMAP |
2365 | 2360 | ||