irq.c 11.9 KB
Newer Older
1 2 3 4 5 6
/*
 * Common interrupt code for 32 and 64 bit
 */
#include <linux/cpu.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
7
#include <linux/of.h>
8
#include <linux/seq_file.h>
9
#include <linux/smp.h>
J
Jeremy Fitzhardinge 已提交
10
#include <linux/ftrace.h>
11
#include <linux/delay.h>
12
#include <linux/export.h>
13

I
Ingo Molnar 已提交
14
#include <asm/apic.h>
15
#include <asm/io_apic.h>
16
#include <asm/irq.h>
J
Jeremy Fitzhardinge 已提交
17
#include <asm/idle.h>
18
#include <asm/mce.h>
19
#include <asm/hw_irq.h>
20 21

#define CREATE_TRACE_POINTS
22
#include <asm/trace/irq_vectors.h>
23 24 25

atomic_t irq_err_count;

26
/* Function pointer for generic interrupt vector handling */
27
void (*x86_platform_ipi_callback)(void) = NULL;
28

T
Thomas Gleixner 已提交
29 30 31 32 33 34
/*
 * 'what should we do if we get a hw irq event on an illegal vector'.
 * each architecture has to answer this themselves.
 */
void ack_bad_irq(unsigned int irq)
{
C
Cyrill Gorcunov 已提交
35 36
	if (printk_ratelimit())
		pr_err("unexpected IRQ trap at vector %02x\n", irq);
T
Thomas Gleixner 已提交
37 38 39 40 41 42 43 44 45 46

	/*
	 * Currently unexpected vectors happen only on SMP and APIC.
	 * We _must_ ack these because every local APIC has only N
	 * irq slots per priority level, and a 'hanging, unacked' IRQ
	 * holds up an irq slot - in excessive cases (when multiple
	 * unexpected vectors occur) that might lock up the APIC
	 * completely.
	 * But only ack when the APIC is enabled -AK
	 */
47
	ack_APIC_irq();
T
Thomas Gleixner 已提交
48 49
}

50
#define irq_stats(x)		(&per_cpu(irq_stat, x))
51
/*
52
 * /proc/interrupts printing for arch specific interrupts
53
 */
54
int arch_show_interrupts(struct seq_file *p, int prec)
55 56 57
{
	int j;

58
	seq_printf(p, "%*s: ", prec, "NMI");
59 60 61 62
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
	seq_printf(p, "  Non-maskable interrupts\n");
#ifdef CONFIG_X86_LOCAL_APIC
63
	seq_printf(p, "%*s: ", prec, "LOC");
64 65 66
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
	seq_printf(p, "  Local timer interrupts\n");
67 68 69 70 71

	seq_printf(p, "%*s: ", prec, "SPU");
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
	seq_printf(p, "  Spurious interrupts\n");
72
	seq_printf(p, "%*s: ", prec, "PMI");
I
Ingo Molnar 已提交
73 74
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
75
	seq_printf(p, "  Performance monitoring interrupts\n");
76
	seq_printf(p, "%*s: ", prec, "IWI");
77
	for_each_online_cpu(j)
78 79
		seq_printf(p, "%10u ", irq_stats(j)->apic_irq_work_irqs);
	seq_printf(p, "  IRQ work interrupts\n");
80 81
	seq_printf(p, "%*s: ", prec, "RTR");
	for_each_online_cpu(j)
82
		seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count);
83
	seq_printf(p, "  APIC ICR read retries\n");
84
#endif
85
	if (x86_platform_ipi_callback) {
86
		seq_printf(p, "%*s: ", prec, "PLT");
87
		for_each_online_cpu(j)
88
			seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis);
89 90
		seq_printf(p, "  Platform interrupts\n");
	}
91
#ifdef CONFIG_SMP
92
	seq_printf(p, "%*s: ", prec, "RES");
93 94 95
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
	seq_printf(p, "  Rescheduling interrupts\n");
96
	seq_printf(p, "%*s: ", prec, "CAL");
97
	for_each_online_cpu(j)
98 99
		seq_printf(p, "%10u ", irq_stats(j)->irq_call_count -
					irq_stats(j)->irq_tlb_count);
100
	seq_printf(p, "  Function call interrupts\n");
101
	seq_printf(p, "%*s: ", prec, "TLB");
102 103 104 105
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
	seq_printf(p, "  TLB shootdowns\n");
#endif
106
#ifdef CONFIG_X86_THERMAL_VECTOR
107
	seq_printf(p, "%*s: ", prec, "TRM");
108 109 110
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
	seq_printf(p, "  Thermal event interrupts\n");
111 112
#endif
#ifdef CONFIG_X86_MCE_THRESHOLD
113
	seq_printf(p, "%*s: ", prec, "THR");
114 115 116
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
	seq_printf(p, "  Threshold APIC interrupts\n");
117
#endif
118
#ifdef CONFIG_X86_MCE
119 120 121 122
	seq_printf(p, "%*s: ", prec, "MCE");
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", per_cpu(mce_exception_count, j));
	seq_printf(p, "  Machine check exceptions\n");
123 124 125 126
	seq_printf(p, "%*s: ", prec, "MCP");
	for_each_online_cpu(j)
		seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
	seq_printf(p, "  Machine check polls\n");
127
#endif
128
	seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
129
#if defined(CONFIG_X86_IO_APIC)
130
	seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
131 132 133 134 135 136 137 138 139 140 141 142 143
#endif
	return 0;
}

/*
 * /proc/stat helpers
 */
u64 arch_irq_stat_cpu(unsigned int cpu)
{
	u64 sum = irq_stats(cpu)->__nmi_count;

#ifdef CONFIG_X86_LOCAL_APIC
	sum += irq_stats(cpu)->apic_timer_irqs;
144
	sum += irq_stats(cpu)->irq_spurious_count;
I
Ingo Molnar 已提交
145
	sum += irq_stats(cpu)->apic_perf_irqs;
146
	sum += irq_stats(cpu)->apic_irq_work_irqs;
147
	sum += irq_stats(cpu)->icr_read_retry_count;
148
#endif
149 150
	if (x86_platform_ipi_callback)
		sum += irq_stats(cpu)->x86_platform_ipis;
151 152 153 154
#ifdef CONFIG_SMP
	sum += irq_stats(cpu)->irq_resched_count;
	sum += irq_stats(cpu)->irq_call_count;
#endif
155
#ifdef CONFIG_X86_THERMAL_VECTOR
156
	sum += irq_stats(cpu)->irq_thermal_count;
157 158
#endif
#ifdef CONFIG_X86_MCE_THRESHOLD
159
	sum += irq_stats(cpu)->irq_threshold_count;
H
Hidetoshi Seto 已提交
160
#endif
161
#ifdef CONFIG_X86_MCE
H
Hidetoshi Seto 已提交
162 163
	sum += per_cpu(mce_exception_count, cpu);
	sum += per_cpu(mce_poll_count, cpu);
164 165 166 167 168 169 170 171 172
#endif
	return sum;
}

u64 arch_irq_stat(void)
{
	u64 sum = atomic_read(&irq_err_count);
	return sum;
}
173

J
Jeremy Fitzhardinge 已提交
174 175 176 177 178 179

/*
 * do_IRQ handles all normal device IRQ's (the special
 * SMP cross-CPU interrupts have their own specific
 * handlers).
 */
180
__visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
J
Jeremy Fitzhardinge 已提交
181 182 183 184 185 186 187 188
{
	struct pt_regs *old_regs = set_irq_regs(regs);

	/* high bit used in ret_from_ code  */
	unsigned vector = ~regs->orig_ax;
	unsigned irq;

	irq_enter();
189
	exit_idle();
J
Jeremy Fitzhardinge 已提交
190

T
Tejun Heo 已提交
191
	irq = __this_cpu_read(vector_irq[vector]);
J
Jeremy Fitzhardinge 已提交
192 193

	if (!handle_irq(irq, regs)) {
194
		ack_APIC_irq();
J
Jeremy Fitzhardinge 已提交
195

196 197 198 199 200 201 202
		if (irq != VECTOR_RETRIGGERED) {
			pr_emerg_ratelimited("%s: %d.%d No irq handler for vector (irq %d)\n",
					     __func__, smp_processor_id(),
					     vector, irq);
		} else {
			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
		}
J
Jeremy Fitzhardinge 已提交
203 204 205 206 207 208 209 210
	}

	irq_exit();

	set_irq_regs(old_regs);
	return 1;
}

211
/*
212
 * Handler for X86_PLATFORM_IPI_VECTOR.
213
 */
214
void __smp_x86_platform_ipi(void)
215
{
216
	inc_irq_stat(x86_platform_ipis);
217

218 219
	if (x86_platform_ipi_callback)
		x86_platform_ipi_callback();
220
}
221

222
__visible void smp_x86_platform_ipi(struct pt_regs *regs)
223 224
{
	struct pt_regs *old_regs = set_irq_regs(regs);
225

226 227 228
	entering_ack_irq();
	__smp_x86_platform_ipi();
	exiting_irq();
229 230 231
	set_irq_regs(old_regs);
}

232 233 234 235
#ifdef CONFIG_HAVE_KVM
/*
 * Handler for POSTED_INTERRUPT_VECTOR.
 */
236
__visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
{
	struct pt_regs *old_regs = set_irq_regs(regs);

	ack_APIC_irq();

	irq_enter();

	exit_idle();

	inc_irq_stat(kvm_posted_intr_ipis);

	irq_exit();

	set_irq_regs(old_regs);
}
#endif

254
__visible void smp_trace_x86_platform_ipi(struct pt_regs *regs)
255 256 257 258 259 260 261 262 263 264 265
{
	struct pt_regs *old_regs = set_irq_regs(regs);

	entering_ack_irq();
	trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR);
	__smp_x86_platform_ipi();
	trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR);
	exiting_irq();
	set_irq_regs(old_regs);
}

266
EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
267 268

#ifdef CONFIG_HOTPLUG_CPU
269 270 271 272 273 274 275 276

/* These two declarations are only used in check_irq_vectors_for_cpu_disable()
 * below, which is protected by stop_machine().  Putting them on the stack
 * results in a stack frame overflow.  Dynamically allocating could result in a
 * failure so declare these two cpumasks as global.
 */
static struct cpumask affinity_new, online_new;

277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
/*
 * This cpu is going to be removed and its vectors migrated to the remaining
 * online cpus.  Check to see if there are enough vectors in the remaining cpus.
 * This function is protected by stop_machine().
 */
int check_irq_vectors_for_cpu_disable(void)
{
	int irq, cpu;
	unsigned int this_cpu, vector, this_count, count;
	struct irq_desc *desc;
	struct irq_data *data;

	this_cpu = smp_processor_id();
	cpumask_copy(&online_new, cpu_online_mask);
	cpu_clear(this_cpu, online_new);

	this_count = 0;
	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
		irq = __this_cpu_read(vector_irq[vector]);
		if (irq >= 0) {
			desc = irq_to_desc(irq);
			data = irq_desc_get_irq_data(desc);
			cpumask_copy(&affinity_new, data->affinity);
			cpu_clear(this_cpu, affinity_new);

			/* Do not count inactive or per-cpu irqs. */
			if (!irq_has_action(irq) || irqd_is_per_cpu(data))
				continue;

			/*
			 * A single irq may be mapped to multiple
			 * cpu's vector_irq[] (for example IOAPIC cluster
			 * mode).  In this case we have two
			 * possibilities:
			 *
			 * 1) the resulting affinity mask is empty; that is
			 * this the down'd cpu is the last cpu in the irq's
			 * affinity mask, or
			 *
			 * 2) the resulting affinity mask is no longer
			 * a subset of the online cpus but the affinity
			 * mask is not zero; that is the down'd cpu is the
			 * last online cpu in a user set affinity mask.
			 */
			if (cpumask_empty(&affinity_new) ||
			    !cpumask_subset(&affinity_new, &online_new))
				this_count++;
		}
	}

	count = 0;
	for_each_online_cpu(cpu) {
		if (cpu == this_cpu)
			continue;
		for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
		     vector++) {
			if (per_cpu(vector_irq, cpu)[vector] < 0)
				count++;
		}
	}

	if (count < this_count) {
		pr_warn("CPU %d disable failed: CPU has %u vectors assigned and there are only %u available.\n",
			this_cpu, this_count, count);
		return -ERANGE;
	}
	return 0;
}

346 347 348
/* A cpu has been removed from cpu_online_mask.  Reset irq affinities. */
void fixup_irqs(void)
{
349
	unsigned int irq, vector;
350 351
	static int warned;
	struct irq_desc *desc;
352
	struct irq_data *data;
353
	struct irq_chip *chip;
354 355 356 357 358 359 360 361 362 363 364 365

	for_each_irq_desc(irq, desc) {
		int break_affinity = 0;
		int set_affinity = 1;
		const struct cpumask *affinity;

		if (!desc)
			continue;
		if (irq == 2)
			continue;

		/* interrupt's are disabled at this point */
366
		raw_spin_lock(&desc->lock);
367

368
		data = irq_desc_get_irq_data(desc);
369
		affinity = data->affinity;
370
		if (!irq_has_action(irq) || irqd_is_per_cpu(data) ||
371
		    cpumask_subset(affinity, cpu_online_mask)) {
372
			raw_spin_unlock(&desc->lock);
373 374 375
			continue;
		}

376 377 378 379 380 381 382
		/*
		 * Complete the irq move. This cpu is going down and for
		 * non intr-remapping case, we can't wait till this interrupt
		 * arrives at this cpu before completing the irq move.
		 */
		irq_force_complete_move(irq);

383 384
		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
			break_affinity = 1;
385
			affinity = cpu_online_mask;
386 387
		}

388 389 390
		chip = irq_data_get_irq_chip(data);
		if (!irqd_can_move_in_process_context(data) && chip->irq_mask)
			chip->irq_mask(data);
391

392 393
		if (chip->irq_set_affinity)
			chip->irq_set_affinity(data, affinity, true);
394 395 396
		else if (!(warned++))
			set_affinity = 0;

397 398 399 400 401
		/*
		 * We unmask if the irq was not marked masked by the
		 * core code. That respects the lazy irq disable
		 * behaviour.
		 */
402
		if (!irqd_can_move_in_process_context(data) &&
403
		    !irqd_irq_masked(data) && chip->irq_unmask)
404
			chip->irq_unmask(data);
405

406
		raw_spin_unlock(&desc->lock);
407 408

		if (break_affinity && set_affinity)
409
			pr_notice("Broke affinity for irq %i\n", irq);
410
		else if (!set_affinity)
411
			pr_notice("Cannot set affinity for irq %i\n", irq);
412 413
	}

414 415 416 417 418 419 420 421 422
	/*
	 * We can remove mdelay() and then send spuriuous interrupts to
	 * new cpu targets for all the irqs that were handled previously by
	 * this cpu. While it works, I have seen spurious interrupt messages
	 * (nothing wrong but still...).
	 *
	 * So for now, retain mdelay(1) and check the IRR and then send those
	 * interrupts to new targets as this cpu is already offlined...
	 */
423
	mdelay(1);
424 425 426 427

	for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
		unsigned int irr;

428
		if (__this_cpu_read(vector_irq[vector]) <= VECTOR_UNDEFINED)
429 430 431 432
			continue;

		irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
		if (irr  & (1 << (vector % 32))) {
T
Tejun Heo 已提交
433
			irq = __this_cpu_read(vector_irq[vector]);
434

435
			desc = irq_to_desc(irq);
436 437
			data = irq_desc_get_irq_data(desc);
			chip = irq_data_get_irq_chip(data);
438
			raw_spin_lock(&desc->lock);
439
			if (chip->irq_retrigger) {
440
				chip->irq_retrigger(data);
441 442
				__this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);
			}
443
			raw_spin_unlock(&desc->lock);
444
		}
445 446
		if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
			__this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);
447
	}
448 449
}
#endif