diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-01 23:48:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-01 23:48:54 -0400 |
commit | 1ed4395035a6791ebbbf618429a58ab9c207cc83 (patch) | |
tree | a34158c5dd3c4ca70f140da5a484ca6142a3b8c3 /arch/ia64/kernel | |
parent | 878701db07db3f0b59f14f0c525b681e4ca81551 (diff) | |
parent | b718f91c14604e4ab5cdfe8d3baff8111425ea7d (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
[IA64] ITC: Reduce rating for ITC clock if ITCs are drifty
[IA64] SN2: Fix up sn2_rtc clock
[IA64] Fix wrong access to irq_desc[] in iosapic_register_intr().
[IA64] Fix possible race in destroy_and_reserve_irq()
[IA64] Fix registered interrupt check
[IA64] Remove a few duplicate includes
[IA64] Allow smp_call_function_single() to current cpu
[IA64] fix a few section mismatch warnings
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 19 | ||||
-rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 17 | ||||
-rw-r--r-- | arch/ia64/kernel/mca.c | 17 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/smp.c | 8 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 16 |
6 files changed, 47 insertions, 31 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 91e6dc1e7baf..cfe4654838f4 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -142,7 +142,7 @@ struct iosapic_rte_info { | |||
142 | static struct iosapic_intr_info { | 142 | static struct iosapic_intr_info { |
143 | struct list_head rtes; /* RTEs using this vector (empty => | 143 | struct list_head rtes; /* RTEs using this vector (empty => |
144 | * not an IOSAPIC interrupt) */ | 144 | * not an IOSAPIC interrupt) */ |
145 | int count; /* # of RTEs that shares this vector */ | 145 | int count; /* # of registered RTEs */ |
146 | u32 low32; /* current value of low word of | 146 | u32 low32; /* current value of low word of |
147 | * Redirection table entry */ | 147 | * Redirection table entry */ |
148 | unsigned int dest; /* destination CPU physical ID */ | 148 | unsigned int dest; /* destination CPU physical ID */ |
@@ -313,7 +313,7 @@ mask_irq (unsigned int irq) | |||
313 | int rte_index; | 313 | int rte_index; |
314 | struct iosapic_rte_info *rte; | 314 | struct iosapic_rte_info *rte; |
315 | 315 | ||
316 | if (list_empty(&iosapic_intr_info[irq].rtes)) | 316 | if (!iosapic_intr_info[irq].count) |
317 | return; /* not an IOSAPIC interrupt! */ | 317 | return; /* not an IOSAPIC interrupt! */ |
318 | 318 | ||
319 | /* set only the mask bit */ | 319 | /* set only the mask bit */ |
@@ -331,7 +331,7 @@ unmask_irq (unsigned int irq) | |||
331 | int rte_index; | 331 | int rte_index; |
332 | struct iosapic_rte_info *rte; | 332 | struct iosapic_rte_info *rte; |
333 | 333 | ||
334 | if (list_empty(&iosapic_intr_info[irq].rtes)) | 334 | if (!iosapic_intr_info[irq].count) |
335 | return; /* not an IOSAPIC interrupt! */ | 335 | return; /* not an IOSAPIC interrupt! */ |
336 | 336 | ||
337 | low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; | 337 | low32 = iosapic_intr_info[irq].low32 &= ~IOSAPIC_MASK; |
@@ -363,7 +363,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) | |||
363 | 363 | ||
364 | dest = cpu_physical_id(first_cpu(mask)); | 364 | dest = cpu_physical_id(first_cpu(mask)); |
365 | 365 | ||
366 | if (list_empty(&iosapic_intr_info[irq].rtes)) | 366 | if (!iosapic_intr_info[irq].count) |
367 | return; /* not an IOSAPIC interrupt */ | 367 | return; /* not an IOSAPIC interrupt */ |
368 | 368 | ||
369 | set_irq_affinity_info(irq, dest, redir); | 369 | set_irq_affinity_info(irq, dest, redir); |
@@ -542,7 +542,7 @@ iosapic_reassign_vector (int irq) | |||
542 | { | 542 | { |
543 | int new_irq; | 543 | int new_irq; |
544 | 544 | ||
545 | if (!list_empty(&iosapic_intr_info[irq].rtes)) { | 545 | if (iosapic_intr_info[irq].count) { |
546 | new_irq = create_irq(); | 546 | new_irq = create_irq(); |
547 | if (new_irq < 0) | 547 | if (new_irq < 0) |
548 | panic("%s: out of interrupt vectors!\n", __FUNCTION__); | 548 | panic("%s: out of interrupt vectors!\n", __FUNCTION__); |
@@ -560,7 +560,7 @@ iosapic_reassign_vector (int irq) | |||
560 | } | 560 | } |
561 | } | 561 | } |
562 | 562 | ||
563 | static struct iosapic_rte_info *iosapic_alloc_rte (void) | 563 | static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void) |
564 | { | 564 | { |
565 | int i; | 565 | int i; |
566 | struct iosapic_rte_info *rte; | 566 | struct iosapic_rte_info *rte; |
@@ -677,7 +677,7 @@ get_target_cpu (unsigned int gsi, int irq) | |||
677 | * In case of vector shared by multiple RTEs, all RTEs that | 677 | * In case of vector shared by multiple RTEs, all RTEs that |
678 | * share the vector need to use the same destination CPU. | 678 | * share the vector need to use the same destination CPU. |
679 | */ | 679 | */ |
680 | if (!list_empty(&iosapic_intr_info[irq].rtes)) | 680 | if (iosapic_intr_info[irq].count) |
681 | return iosapic_intr_info[irq].dest; | 681 | return iosapic_intr_info[irq].dest; |
682 | 682 | ||
683 | /* | 683 | /* |
@@ -794,8 +794,9 @@ iosapic_register_intr (unsigned int gsi, | |||
794 | err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, | 794 | err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, |
795 | polarity, trigger); | 795 | polarity, trigger); |
796 | if (err < 0) { | 796 | if (err < 0) { |
797 | spin_unlock(&irq_desc[irq].lock); | ||
797 | irq = err; | 798 | irq = err; |
798 | goto unlock_all; | 799 | goto unlock_iosapic_lock; |
799 | } | 800 | } |
800 | 801 | ||
801 | /* | 802 | /* |
@@ -811,7 +812,7 @@ iosapic_register_intr (unsigned int gsi, | |||
811 | gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), | 812 | gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), |
812 | (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), | 813 | (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), |
813 | cpu_logical_id(dest), dest, irq_to_vector(irq)); | 814 | cpu_logical_id(dest), dest, irq_to_vector(irq)); |
814 | unlock_all: | 815 | |
815 | spin_unlock(&irq_desc[irq].lock); | 816 | spin_unlock(&irq_desc[irq].lock); |
816 | unlock_iosapic_lock: | 817 | unlock_iosapic_lock: |
817 | spin_unlock_irqrestore(&iosapic_lock, flags); | 818 | spin_unlock_irqrestore(&iosapic_lock, flags); |
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9386b955eed1..c47c8acc96e3 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
@@ -101,15 +101,6 @@ int check_irq_used(int irq) | |||
101 | return -1; | 101 | return -1; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void reserve_irq(unsigned int irq) | ||
105 | { | ||
106 | unsigned long flags; | ||
107 | |||
108 | spin_lock_irqsave(&vector_lock, flags); | ||
109 | irq_status[irq] = IRQ_RSVD; | ||
110 | spin_unlock_irqrestore(&vector_lock, flags); | ||
111 | } | ||
112 | |||
113 | static inline int find_unassigned_irq(void) | 104 | static inline int find_unassigned_irq(void) |
114 | { | 105 | { |
115 | int irq; | 106 | int irq; |
@@ -302,10 +293,14 @@ static cpumask_t vector_allocation_domain(int cpu) | |||
302 | 293 | ||
303 | void destroy_and_reserve_irq(unsigned int irq) | 294 | void destroy_and_reserve_irq(unsigned int irq) |
304 | { | 295 | { |
296 | unsigned long flags; | ||
297 | |||
305 | dynamic_irq_cleanup(irq); | 298 | dynamic_irq_cleanup(irq); |
306 | 299 | ||
307 | clear_irq_vector(irq); | 300 | spin_lock_irqsave(&vector_lock, flags); |
308 | reserve_irq(irq); | 301 | __clear_irq_vector(irq); |
302 | irq_status[irq] = IRQ_RSVD; | ||
303 | spin_unlock_irqrestore(&vector_lock, flags); | ||
309 | } | 304 | } |
310 | 305 | ||
311 | static int __reassign_irq_vector(int irq, int cpu) | 306 | static int __reassign_irq_vector(int irq, int cpu) |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4b5daa3cc0fe..ff28620cb992 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1750,8 +1750,17 @@ format_mca_init_stack(void *mca_data, unsigned long offset, | |||
1750 | strncpy(p->comm, type, sizeof(p->comm)-1); | 1750 | strncpy(p->comm, type, sizeof(p->comm)-1); |
1751 | } | 1751 | } |
1752 | 1752 | ||
1753 | /* Do per-CPU MCA-related initialization. */ | 1753 | /* Caller prevents this from being called after init */ |
1754 | static void * __init_refok mca_bootmem(void) | ||
1755 | { | ||
1756 | void *p; | ||
1754 | 1757 | ||
1758 | p = alloc_bootmem(sizeof(struct ia64_mca_cpu) * NR_CPUS + | ||
1759 | KERNEL_STACK_SIZE); | ||
1760 | return (void *)ALIGN((unsigned long)p, KERNEL_STACK_SIZE); | ||
1761 | } | ||
1762 | |||
1763 | /* Do per-CPU MCA-related initialization. */ | ||
1755 | void __cpuinit | 1764 | void __cpuinit |
1756 | ia64_mca_cpu_init(void *cpu_data) | 1765 | ia64_mca_cpu_init(void *cpu_data) |
1757 | { | 1766 | { |
@@ -1763,11 +1772,7 @@ ia64_mca_cpu_init(void *cpu_data) | |||
1763 | int cpu; | 1772 | int cpu; |
1764 | 1773 | ||
1765 | first_time = 0; | 1774 | first_time = 0; |
1766 | mca_data = alloc_bootmem(sizeof(struct ia64_mca_cpu) | 1775 | mca_data = mca_bootmem(); |
1767 | * NR_CPUS + KERNEL_STACK_SIZE); | ||
1768 | mca_data = (void *)(((unsigned long)mca_data + | ||
1769 | KERNEL_STACK_SIZE - 1) & | ||
1770 | (-KERNEL_STACK_SIZE)); | ||
1771 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 1776 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
1772 | format_mca_init_stack(mca_data, | 1777 | format_mca_init_stack(mca_data, |
1773 | offsetof(struct ia64_mca_cpu, mca_stack), | 1778 | offsetof(struct ia64_mca_cpu, mca_stack), |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 7cecd2964200..cd9a37a552c3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include <asm/smp.h> | 60 | #include <asm/smp.h> |
61 | #include <asm/system.h> | 61 | #include <asm/system.h> |
62 | #include <asm/unistd.h> | 62 | #include <asm/unistd.h> |
63 | #include <asm/system.h> | ||
64 | 63 | ||
65 | #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) | 64 | #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) |
66 | # error "struct cpuinfo_ia64 too big!" | 65 | # error "struct cpuinfo_ia64 too big!" |
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 0982882bfb80..4e446aa5f4ac 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c | |||
@@ -346,7 +346,7 @@ smp_flush_tlb_mm (struct mm_struct *mm) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* | 348 | /* |
349 | * Run a function on another CPU | 349 | * Run a function on a specific CPU |
350 | * <func> The function to run. This must be fast and non-blocking. | 350 | * <func> The function to run. This must be fast and non-blocking. |
351 | * <info> An arbitrary pointer to pass to the function. | 351 | * <info> An arbitrary pointer to pass to the function. |
352 | * <nonatomic> Currently unused. | 352 | * <nonatomic> Currently unused. |
@@ -366,9 +366,11 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int | |||
366 | int me = get_cpu(); /* prevent preemption and reschedule on another processor */ | 366 | int me = get_cpu(); /* prevent preemption and reschedule on another processor */ |
367 | 367 | ||
368 | if (cpuid == me) { | 368 | if (cpuid == me) { |
369 | printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__); | 369 | local_irq_disable(); |
370 | func(info); | ||
371 | local_irq_enable(); | ||
370 | put_cpu(); | 372 | put_cpu(); |
371 | return -EBUSY; | 373 | return 0; |
372 | } | 374 | } |
373 | 375 | ||
374 | data.func = func; | 376 | data.func = func; |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 6c0e9e2e1b82..98cfc90cab1d 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -240,7 +240,21 @@ ia64_init_itm (void) | |||
240 | if (!nojitter) | 240 | if (!nojitter) |
241 | itc_jitter_data.itc_jitter = 1; | 241 | itc_jitter_data.itc_jitter = 1; |
242 | #endif | 242 | #endif |
243 | } | 243 | } else |
244 | /* | ||
245 | * ITC is drifty and we have not synchronized the ITCs in smpboot.c. | ||
246 | * ITC values may fluctuate significantly between processors. | ||
247 | * Clock should not be used for hrtimers. Mark itc as only | ||
248 | * useful for boot and testing. | ||
249 | * | ||
250 | * Note that jitter compensation is off! There is no point of | ||
251 | * synchronizing ITCs since they may be large differentials | ||
252 | * that change over time. | ||
253 | * | ||
254 | * The only way to fix this would be to repeatedly sync the | ||
255 | * ITCs. Until that time we have to avoid ITC. | ||
256 | */ | ||
257 | clocksource_itc.rating = 50; | ||
244 | 258 | ||
245 | /* Setup the CPU local timer tick */ | 259 | /* Setup the CPU local timer tick */ |
246 | ia64_cpu_local_tick(); | 260 | ia64_cpu_local_tick(); |