diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 15:19:36 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 15:19:36 -0400 |
| commit | bd3e57f9132ac55e2848aa10cf50341de2508e1d (patch) | |
| tree | 3633129fe02e804852a18c8e9b3045f35db6db0b | |
| parent | 3fad0953a12f92289f1e35f091c4fa09d8e1884e (diff) | |
| parent | 36d93d88a5396baa135f8bcde7b8501dfe3b8e53 (diff) | |
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 platform changes from Ingo Molnar:
"This tree mostly involves various APIC driver cleanups/robustization,
and vSMP motivated platform callback improvements/cleanups"
Fix up trivial conflict due to printk cleanup right next to return value
change.
* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (29 commits)
Revert "x86/early_printk: Replace obsolete simple_strtoul() usage with kstrtoint()"
x86/apic/x2apic: Use multiple cluster members for the irq destination only with the explicit affinity
x86/apic/x2apic: Limit the vector reservation to the user specified mask
x86/apic: Optimize cpu traversal in __assign_irq_vector() using domain membership
x86/vsmp: Fix vector_allocation_domain's return value
irq/apic: Use config_enabled(CONFIG_SMP) checks to clean up irq_set_affinity() for UP
x86/vsmp: Fix linker error when CONFIG_PROC_FS is not set
x86/apic/es7000: Make apicid of a cluster (not CPU) from a cpumask
x86/apic/es7000+summit: Always make valid apicid from a cpumask
x86/apic/es7000+summit: Fix compile warning in cpu_mask_to_apicid()
x86/apic: Fix ugly casting and branching in cpu_mask_to_apicid_and()
x86/apic: Eliminate cpu_mask_to_apicid() operation
x86/x2apic/cluster: Vector_allocation_domain() should return a value
x86/apic/irq_remap: Silence a bogus pr_err()
x86/vsmp: Ignore IOAPIC IRQ affinity if possible
x86/apic: Make cpu_mask_to_apicid() operations check cpu_online_mask
x86/apic: Make cpu_mask_to_apicid() operations return error code
x86/apic: Avoid useless scanning thru a cpumask in assign_irq_vector()
x86/apic: Try to spread IRQ vectors to different priority levels
x86/apic: Factor out default vector_allocation_domain() operation
...
25 files changed, 429 insertions, 581 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..88093c1d44fd 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -306,7 +306,8 @@ struct apic { | |||
| 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); | 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); |
| 307 | unsigned long (*check_apicid_present)(int apicid); | 307 | unsigned long (*check_apicid_present)(int apicid); |
| 308 | 308 | ||
| 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); | 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask, |
| 310 | const struct cpumask *mask); | ||
| 310 | void (*init_apic_ldr)(void); | 311 | void (*init_apic_ldr)(void); |
| 311 | 312 | ||
| 312 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); | 313 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); |
| @@ -331,9 +332,9 @@ struct apic { | |||
| 331 | unsigned long (*set_apic_id)(unsigned int id); | 332 | unsigned long (*set_apic_id)(unsigned int id); |
| 332 | unsigned long apic_id_mask; | 333 | unsigned long apic_id_mask; |
| 333 | 334 | ||
| 334 | unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); | 335 | int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, |
| 335 | unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, | 336 | const struct cpumask *andmask, |
| 336 | const struct cpumask *andmask); | 337 | unsigned int *apicid); |
| 337 | 338 | ||
| 338 | /* ipi */ | 339 | /* ipi */ |
| 339 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); | 340 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); |
| @@ -537,6 +538,11 @@ static inline const struct cpumask *default_target_cpus(void) | |||
| 537 | #endif | 538 | #endif |
| 538 | } | 539 | } |
| 539 | 540 | ||
| 541 | static inline const struct cpumask *online_target_cpus(void) | ||
| 542 | { | ||
| 543 | return cpu_online_mask; | ||
| 544 | } | ||
| 545 | |||
| 540 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 546 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); |
| 541 | 547 | ||
| 542 | 548 | ||
| @@ -586,21 +592,50 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) | |||
| 586 | 592 | ||
| 587 | #endif | 593 | #endif |
| 588 | 594 | ||
| 589 | static inline unsigned int | 595 | static inline int |
| 590 | default_cpu_mask_to_apicid(const struct cpumask *cpumask) | 596 | flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
| 597 | const struct cpumask *andmask, | ||
| 598 | unsigned int *apicid) | ||
| 591 | { | 599 | { |
| 592 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | 600 | unsigned long cpu_mask = cpumask_bits(cpumask)[0] & |
| 601 | cpumask_bits(andmask)[0] & | ||
| 602 | cpumask_bits(cpu_online_mask)[0] & | ||
| 603 | APIC_ALL_CPUS; | ||
| 604 | |||
| 605 | if (likely(cpu_mask)) { | ||
| 606 | *apicid = (unsigned int)cpu_mask; | ||
| 607 | return 0; | ||
| 608 | } else { | ||
| 609 | return -EINVAL; | ||
| 610 | } | ||
| 593 | } | 611 | } |
| 594 | 612 | ||
| 595 | static inline unsigned int | 613 | extern int |
| 596 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 614 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
| 597 | const struct cpumask *andmask) | 615 | const struct cpumask *andmask, |
| 616 | unsigned int *apicid); | ||
| 617 | |||
| 618 | static inline void | ||
| 619 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
| 620 | const struct cpumask *mask) | ||
| 598 | { | 621 | { |
| 599 | unsigned long mask1 = cpumask_bits(cpumask)[0]; | 622 | /* Careful. Some cpus do not strictly honor the set of cpus |
| 600 | unsigned long mask2 = cpumask_bits(andmask)[0]; | 623 | * specified in the interrupt destination when using lowest |
| 601 | unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; | 624 | * priority interrupt delivery mode. |
| 625 | * | ||
| 626 | * In particular there was a hyperthreading cpu observed to | ||
| 627 | * deliver interrupts to the wrong hyperthread when only one | ||
| 628 | * hyperthread was specified in the interrupt desitination. | ||
| 629 | */ | ||
| 630 | cpumask_clear(retmask); | ||
| 631 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
| 632 | } | ||
| 602 | 633 | ||
| 603 | return (unsigned int)(mask1 & mask2 & mask3); | 634 | static inline void |
| 635 | default_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
| 636 | const struct cpumask *mask) | ||
| 637 | { | ||
| 638 | cpumask_copy(retmask, cpumask_of(cpu)); | ||
| 604 | } | 639 | } |
| 605 | 640 | ||
| 606 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) | 641 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) |
diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index 92e54abf89e0..f90f0a587c66 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h | |||
| @@ -9,15 +9,6 @@ | |||
| 9 | #include <asm/ipi.h> | 9 | #include <asm/ipi.h> |
| 10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
| 11 | 11 | ||
| 12 | /* | ||
| 13 | * Need to use more than cpu 0, because we need more vectors | ||
| 14 | * when MSI-X are used. | ||
| 15 | */ | ||
| 16 | static const struct cpumask *x2apic_target_cpus(void) | ||
| 17 | { | ||
| 18 | return cpu_online_mask; | ||
| 19 | } | ||
| 20 | |||
| 21 | static int x2apic_apic_id_valid(int apicid) | 12 | static int x2apic_apic_id_valid(int apicid) |
| 22 | { | 13 | { |
| 23 | return 1; | 14 | return 1; |
| @@ -28,15 +19,6 @@ static int x2apic_apic_id_registered(void) | |||
| 28 | return 1; | 19 | return 1; |
| 29 | } | 20 | } |
| 30 | 21 | ||
| 31 | /* | ||
| 32 | * For now each logical cpu is in its own vector allocation domain. | ||
| 33 | */ | ||
| 34 | static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
| 35 | { | ||
| 36 | cpumask_clear(retmask); | ||
| 37 | cpumask_set_cpu(cpu, retmask); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void | 22 | static void |
| 41 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) | 23 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) |
| 42 | { | 24 | { |
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c090af10ac7d..38155f667144 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
| @@ -156,7 +156,6 @@ struct x86_cpuinit_ops { | |||
