xref: /linux/kernel/irq/proc.c (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
4  *
5  * This file contains the /proc/irq/ handling code.
6  */
7 
8 #include <linux/irq.h>
9 #include <linux/gfp.h>
10 #include <linux/proc_fs.h>
11 #include <linux/seq_file.h>
12 #include <linux/interrupt.h>
13 #include <linux/kernel_stat.h>
14 #include <linux/mutex.h>
15 
16 #include "internals.h"
17 
18 /*
19  * Access rules:
20  *
21  * procfs protects read/write of /proc/irq/N/ files against a
22  * concurrent free of the interrupt descriptor. remove_proc_entry()
23  * immediately prevents new read/writes to happen and waits for
24  * already running read/write functions to complete.
25  *
26  * We remove the proc entries first and then delete the interrupt
27  * descriptor from the radix tree and free it. So it is guaranteed
28  * that irq_to_desc(N) is valid as long as the read/writes are
29  * permitted by procfs.
30  *
31  * The read from /proc/interrupts is a different problem because there
32  * is no protection. So the lookup and the access to irqdesc
33  * information must be protected by sparse_irq_lock.
34  */
35 static struct proc_dir_entry *root_irq_dir;
36 
37 #ifdef CONFIG_SMP
38 
39 enum {
40 	AFFINITY,
41 	AFFINITY_LIST,
42 	EFFECTIVE,
43 	EFFECTIVE_LIST,
44 };
45 
show_irq_affinity(int type,struct seq_file * m)46 static int show_irq_affinity(int type, struct seq_file *m)
47 {
48 	struct irq_desc *desc = irq_to_desc((long)m->private);
49 	const struct cpumask *mask;
50 
51 	switch (type) {
52 	case AFFINITY:
53 	case AFFINITY_LIST:
54 		mask = desc->irq_common_data.affinity;
55 #ifdef CONFIG_GENERIC_PENDING_IRQ
56 		if (irqd_is_setaffinity_pending(&desc->irq_data))
57 			mask = desc->pending_mask;
58 #endif
59 		break;
60 	case EFFECTIVE:
61 	case EFFECTIVE_LIST:
62 #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
63 		mask = irq_data_get_effective_affinity_mask(&desc->irq_data);
64 		break;
65 #endif
66 	default:
67 		return -EINVAL;
68 	}
69 
70 	switch (type) {
71 	case AFFINITY_LIST:
72 	case EFFECTIVE_LIST:
73 		seq_printf(m, "%*pbl\n", cpumask_pr_args(mask));
74 		break;
75 	case AFFINITY:
76 	case EFFECTIVE:
77 		seq_printf(m, "%*pb\n", cpumask_pr_args(mask));
78 		break;
79 	}
80 	return 0;
81 }
82 
irq_affinity_hint_proc_show(struct seq_file * m,void * v)83 static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
84 {
85 	struct irq_desc *desc = irq_to_desc((long)m->private);
86 	unsigned long flags;
87 	cpumask_var_t mask;
88 
89 	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
90 		return -ENOMEM;
91 
92 	raw_spin_lock_irqsave(&desc->lock, flags);
93 	if (desc->affinity_hint)
94 		cpumask_copy(mask, desc->affinity_hint);
95 	raw_spin_unlock_irqrestore(&desc->lock, flags);
96 
97 	seq_printf(m, "%*pb\n", cpumask_pr_args(mask));
98 	free_cpumask_var(mask);
99 
100 	return 0;
101 }
102 
103 int no_irq_affinity;
irq_affinity_proc_show(struct seq_file * m,void * v)104 static int irq_affinity_proc_show(struct seq_file *m, void *v)
105 {
106 	return show_irq_affinity(AFFINITY, m);
107 }
108 
irq_affinity_list_proc_show(struct seq_file * m,void * v)109 static int irq_affinity_list_proc_show(struct seq_file *m, void *v)
110 {
111 	return show_irq_affinity(AFFINITY_LIST, m);
112 }
113 
114 #ifndef CONFIG_AUTO_IRQ_AFFINITY
irq_select_affinity_usr(unsigned int irq)115 static inline int irq_select_affinity_usr(unsigned int irq)
116 {
117 	/*
118 	 * If the interrupt is started up already then this fails. The
119 	 * interrupt is assigned to an online CPU already. There is no
120 	 * point to move it around randomly. Tell user space that the
121 	 * selected mask is bogus.
122 	 *
123 	 * If not then any change to the affinity is pointless because the
124 	 * startup code invokes irq_setup_affinity() which will select
125 	 * a online CPU anyway.
126 	 */
127 	return -EINVAL;
128 }
129 #else
130 /* ALPHA magic affinity auto selector. Keep it for historical reasons. */
irq_select_affinity_usr(unsigned int irq)131 static inline int irq_select_affinity_usr(unsigned int irq)
132 {
133 	return irq_select_affinity(irq);
134 }
135 #endif
136 
write_irq_affinity(int type,struct file * file,const char __user * buffer,size_t count,loff_t * pos)137 static ssize_t write_irq_affinity(int type, struct file *file,
138 		const char __user *buffer, size_t count, loff_t *pos)
139 {
140 	unsigned int irq = (int)(long)pde_data(file_inode(file));
141 	cpumask_var_t new_value;
142 	int err;
143 
144 	if (!irq_can_set_affinity_usr(irq) || no_irq_affinity)
145 		return -EIO;
146 
147 	if (!zalloc_cpumask_var(&new_value, GFP_KERNEL))
148 		return -ENOMEM;
149 
150 	if (type)
151 		err = cpumask_parselist_user(buffer, count, new_value);
152 	else
153 		err = cpumask_parse_user(buffer, count, new_value);
154 	if (err)
155 		goto free_cpumask;
156 
157 	/*
158 	 * Do not allow disabling IRQs completely - it's a too easy
159 	 * way to make the system unusable accidentally :-) At least
160 	 * one online CPU still has to be targeted.
161 	 */
162 	if (!cpumask_intersects(new_value, cpu_online_mask)) {
163 		/*
164 		 * Special case for empty set - allow the architecture code
165 		 * to set default SMP affinity.
166 		 */
167 		err = irq_select_affinity_usr(irq) ? -EINVAL : count;
168 	} else {
169 		err = irq_set_affinity(irq, new_value);
170 		if (!err)
171 			err = count;
172 	}
173 
174 free_cpumask:
175 	free_cpumask_var(new_value);
176 	return err;
177 }
178 
irq_affinity_proc_write(struct file * file,const char __user * buffer,size_t count,loff_t * pos)179 static ssize_t irq_affinity_proc_write(struct file *file,
180 		const char __user *buffer, size_t count, loff_t *pos)
181 {
182 	return write_irq_affinity(0, file, buffer, count, pos);
183 }
184 
irq_affinity_list_proc_write(struct file * file,const char __user * buffer,size_t count,loff_t * pos)185 static ssize_t irq_affinity_list_proc_write(struct file *file,
186 		const char __user *buffer, size_t count, loff_t *pos)
187 {
188 	return write_irq_affinity(1, file, buffer, count, pos);
189 }
190 
irq_affinity_proc_open(struct inode * inode,struct file * file)191 static int irq_affinity_proc_open(struct inode *inode, struct file *file)
192 {
193 	return single_open(file, irq_affinity_proc_show, pde_data(inode));
194 }
195 
irq_affinity_list_proc_open(struct inode * inode,struct file * file)196 static int irq_affinity_list_proc_open(struct inode *inode, struct file *file)
197 {
198 	return single_open(file, irq_affinity_list_proc_show, pde_data(inode));
199 }
200 
201 static const struct proc_ops irq_affinity_proc_ops = {
202 	.proc_open	= irq_affinity_proc_open,
203 	.proc_read	= seq_read,
204 	.proc_lseek	= seq_lseek,
205 	.proc_release	= single_release,
206 	.proc_write	= irq_affinity_proc_write,
207 };
208 
209 static const struct proc_ops irq_affinity_list_proc_ops = {
210 	.proc_open	= irq_affinity_list_proc_open,
211 	.proc_read	= seq_read,
212 	.proc_lseek	= seq_lseek,
213 	.proc_release	= single_release,
214 	.proc_write	= irq_affinity_list_proc_write,
215 };
216 
217 #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
irq_effective_aff_proc_show(struct seq_file * m,void * v)218 static int irq_effective_aff_proc_show(struct seq_file *m, void *v)
219 {
220 	return show_irq_affinity(EFFECTIVE, m);
221 }
222 
irq_effective_aff_list_proc_show(struct seq_file * m,void * v)223 static int irq_effective_aff_list_proc_show(struct seq_file *m, void *v)
224 {
225 	return show_irq_affinity(EFFECTIVE_LIST, m);
226 }
227 #endif
228 
default_affinity_show(struct seq_file * m,void * v)229 static int default_affinity_show(struct seq_file *m, void *v)
230 {
231 	seq_printf(m, "%*pb\n", cpumask_pr_args(irq_default_affinity));
232 	return 0;
233 }
234 
default_affinity_write(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)235 static ssize_t default_affinity_write(struct file *file,
236 		const char __user *buffer, size_t count, loff_t *ppos)
237 {
238 	cpumask_var_t new_value;
239 	int err;
240 
241 	if (!zalloc_cpumask_var(&new_value, GFP_KERNEL))
242 		return -ENOMEM;
243 
244 	err = cpumask_parse_user(buffer, count, new_value);
245 	if (err)
246 		goto out;
247 
248 	/*
249 	 * Do not allow disabling IRQs completely - it's a too easy
250 	 * way to make the system unusable accidentally :-) At least
251 	 * one online CPU still has to be targeted.
252 	 */
253 	if (!cpumask_intersects(new_value, cpu_online_mask)) {
254 		err = -EINVAL;
255 		goto out;
256 	}
257 
258 	cpumask_copy(irq_default_affinity, new_value);
259 	err = count;
260 
261 out:
262 	free_cpumask_var(new_value);
263 	return err;
264 }
265 
default_affinity_open(struct inode * inode,struct file * file)266 static int default_affinity_open(struct inode *inode, struct file *file)
267 {
268 	return single_open(file, default_affinity_show, pde_data(inode));
269 }
270 
271 static const struct proc_ops default_affinity_proc_ops = {
272 	.proc_open	= default_affinity_open,
273 	.proc_read	= seq_read,
274 	.proc_lseek	= seq_lseek,
275 	.proc_release	= single_release,
276 	.proc_write	= default_affinity_write,
277 };
278 
irq_node_proc_show(struct seq_file * m,void * v)279 static int irq_node_proc_show(struct seq_file *m, void *v)
280 {
281 	struct irq_desc *desc = irq_to_desc((long) m->private);
282 
283 	seq_printf(m, "%d\n", irq_desc_get_node(desc));
284 	return 0;
285 }
286 #endif
287 
irq_spurious_proc_show(struct seq_file * m,void * v)288 static int irq_spurious_proc_show(struct seq_file *m, void *v)
289 {
290 	struct irq_desc *desc = irq_to_desc((long) m->private);
291 
292 	seq_printf(m, "count %u\n" "unhandled %u\n" "last_unhandled %u ms\n",
293 		   desc->irq_count, desc->irqs_unhandled,
294 		   jiffies_to_msecs(desc->last_unhandled));
295 	return 0;
296 }
297 
298 #define MAX_NAMELEN 128
299 
name_unique(unsigned int irq,struct irqaction * new_action)300 static int name_unique(unsigned int irq, struct irqaction *new_action)
301 {
302 	struct irq_desc *desc = irq_to_desc(irq);
303 	struct irqaction *action;
304 	unsigned long flags;
305 	int ret = 1;
306 
307 	raw_spin_lock_irqsave(&desc->lock, flags);
308 	for_each_action_of_desc(desc, action) {
309 		if ((action != new_action) && action->name &&
310 				!strcmp(new_action->name, action->name)) {
311 			ret = 0;
312 			break;
313 		}
314 	}
315 	raw_spin_unlock_irqrestore(&desc->lock, flags);
316 	return ret;
317 }
318 
register_handler_proc(unsigned int irq,struct irqaction * action)319 void register_handler_proc(unsigned int irq, struct irqaction *action)
320 {
321 	char name [MAX_NAMELEN];
322 	struct irq_desc *desc = irq_to_desc(irq);
323 
324 	if (!desc->dir || action->dir || !action->name ||
325 					!name_unique(irq, action))
326 		return;
327 
328 	snprintf(name, MAX_NAMELEN, "%s", action->name);
329 
330 	/* create /proc/irq/1234/handler/ */
331 	action->dir = proc_mkdir(name, desc->dir);
332 }
333 
334 #undef MAX_NAMELEN
335 
336 #define MAX_NAMELEN 10
337 
register_irq_proc(unsigned int irq,struct irq_desc * desc)338 void register_irq_proc(unsigned int irq, struct irq_desc *desc)
339 {
340 	static DEFINE_MUTEX(register_lock);
341 	void __maybe_unused *irqp = (void *)(unsigned long) irq;
342 	char name [MAX_NAMELEN];
343 
344 	if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
345 		return;
346 
347 	/*
348 	 * irq directories are registered only when a handler is
349 	 * added, not when the descriptor is created, so multiple
350 	 * tasks might try to register at the same time.
351 	 */
352 	mutex_lock(&register_lock);
353 
354 	if (desc->dir)
355 		goto out_unlock;
356 
357 	sprintf(name, "%d", irq);
358 
359 	/* create /proc/irq/1234 */
360 	desc->dir = proc_mkdir(name, root_irq_dir);
361 	if (!desc->dir)
362 		goto out_unlock;
363 
364 #ifdef CONFIG_SMP
365 	/* create /proc/irq/<irq>/smp_affinity */
366 	proc_create_data("smp_affinity", 0644, desc->dir,
367 			 &irq_affinity_proc_ops, irqp);
368 
369 	/* create /proc/irq/<irq>/affinity_hint */
370 	proc_create_single_data("affinity_hint", 0444, desc->dir,
371 			irq_affinity_hint_proc_show, irqp);
372 
373 	/* create /proc/irq/<irq>/smp_affinity_list */
374 	proc_create_data("smp_affinity_list", 0644, desc->dir,
375 			 &irq_affinity_list_proc_ops, irqp);
376 
377 	proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show,
378 			irqp);
379 # ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
380 	proc_create_single_data("effective_affinity", 0444, desc->dir,
381 			irq_effective_aff_proc_show, irqp);
382 	proc_create_single_data("effective_affinity_list", 0444, desc->dir,
383 			irq_effective_aff_list_proc_show, irqp);
384 # endif
385 #endif
386 	proc_create_single_data("spurious", 0444, desc->dir,
387 			irq_spurious_proc_show, (void *)(long)irq);
388 
389 out_unlock:
390 	mutex_unlock(&register_lock);
391 }
392 
unregister_irq_proc(unsigned int irq,struct irq_desc * desc)393 void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
394 {
395 	char name [MAX_NAMELEN];
396 
397 	if (!root_irq_dir || !desc->dir)
398 		return;
399 #ifdef CONFIG_SMP
400 	remove_proc_entry("smp_affinity", desc->dir);
401 	remove_proc_entry("affinity_hint", desc->dir);
402 	remove_proc_entry("smp_affinity_list", desc->dir);
403 	remove_proc_entry("node", desc->dir);
404 # ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
405 	remove_proc_entry("effective_affinity", desc->dir);
406 	remove_proc_entry("effective_affinity_list", desc->dir);
407 # endif
408 #endif
409 	remove_proc_entry("spurious", desc->dir);
410 
411 	sprintf(name, "%u", irq);
412 	remove_proc_entry(name, root_irq_dir);
413 }
414 
415 #undef MAX_NAMELEN
416 
unregister_handler_proc(unsigned int irq,struct irqaction * action)417 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
418 {
419 	proc_remove(action->dir);
420 }
421 
register_default_affinity_proc(void)422 static void register_default_affinity_proc(void)
423 {
424 #ifdef CONFIG_SMP
425 	proc_create("irq/default_smp_affinity", 0644, NULL,
426 		    &default_affinity_proc_ops);
427 #endif
428 }
429 
init_irq_proc(void)430 void init_irq_proc(void)
431 {
432 	unsigned int irq;
433 	struct irq_desc *desc;
434 
435 	/* create /proc/irq */
436 	root_irq_dir = proc_mkdir("irq", NULL);
437 	if (!root_irq_dir)
438 		return;
439 
440 	register_default_affinity_proc();
441 
442 	/*
443 	 * Create entries for all existing IRQs.
444 	 */
445 	for_each_irq_desc(irq, desc)
446 		register_irq_proc(irq, desc);
447 }
448 
449 #ifdef CONFIG_GENERIC_IRQ_SHOW
450 
arch_show_interrupts(struct seq_file * p,int prec)451 int __weak arch_show_interrupts(struct seq_file *p, int prec)
452 {
453 	return 0;
454 }
455 
456 #ifndef ACTUAL_NR_IRQS
457 # define ACTUAL_NR_IRQS nr_irqs
458 #endif
459 
show_interrupts(struct seq_file * p,void * v)460 int show_interrupts(struct seq_file *p, void *v)
461 {
462 	static int prec;
463 
464 	unsigned long flags, any_count = 0;
465 	int i = *(loff_t *) v, j;
466 	struct irqaction *action;
467 	struct irq_desc *desc;
468 
469 	if (i > ACTUAL_NR_IRQS)
470 		return 0;
471 
472 	if (i == ACTUAL_NR_IRQS)
473 		return arch_show_interrupts(p, prec);
474 
475 	/* print header and calculate the width of the first column */
476 	if (i == 0) {
477 		for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
478 			j *= 10;
479 
480 		seq_printf(p, "%*s", prec + 8, "");
481 		for_each_online_cpu(j)
482 			seq_printf(p, "CPU%-8d", j);
483 		seq_putc(p, '\n');
484 	}
485 
486 	rcu_read_lock();
487 	desc = irq_to_desc(i);
488 	if (!desc || irq_settings_is_hidden(desc))
489 		goto outsparse;
490 
491 	if (desc->kstat_irqs)
492 		any_count = kstat_irqs_desc(desc, cpu_online_mask);
493 
494 	if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)
495 		goto outsparse;
496 
497 	seq_printf(p, "%*d: ", prec, i);
498 	for_each_online_cpu(j)
499 		seq_printf(p, "%10u ", desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, j) : 0);
500 
501 	raw_spin_lock_irqsave(&desc->lock, flags);
502 	if (desc->irq_data.chip) {
503 		if (desc->irq_data.chip->irq_print_chip)
504 			desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
505 		else if (desc->irq_data.chip->name)
506 			seq_printf(p, " %8s", desc->irq_data.chip->name);
507 		else
508 			seq_printf(p, " %8s", "-");
509 	} else {
510 		seq_printf(p, " %8s", "None");
511 	}
512 	if (desc->irq_data.domain)
513 		seq_printf(p, " %*lu", prec, desc->irq_data.hwirq);
514 	else
515 		seq_printf(p, " %*s", prec, "");
516 #ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL
517 	seq_printf(p, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge");
518 #endif
519 	if (desc->name)
520 		seq_printf(p, "-%-8s", desc->name);
521 
522 	action = desc->action;
523 	if (action) {
524 		seq_printf(p, "  %s", action->name);
525 		while ((action = action->next) != NULL)
526 			seq_printf(p, ", %s", action->name);
527 	}
528 
529 	seq_putc(p, '\n');
530 	raw_spin_unlock_irqrestore(&desc->lock, flags);
531 outsparse:
532 	rcu_read_unlock();
533 	return 0;
534 }
535 #endif
536