root/kernel/irq/proc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. show_irq_affinity
  2. irq_affinity_hint_proc_show
  3. irq_affinity_proc_show
  4. irq_affinity_list_proc_show
  5. irq_select_affinity_usr
  6. irq_select_affinity_usr
  7. write_irq_affinity
  8. irq_affinity_proc_write
  9. irq_affinity_list_proc_write
  10. irq_affinity_proc_open
  11. irq_affinity_list_proc_open
  12. irq_effective_aff_proc_show
  13. irq_effective_aff_list_proc_show
  14. default_affinity_show
  15. default_affinity_write
  16. default_affinity_open
  17. irq_node_proc_show
  18. irq_spurious_proc_show
  19. name_unique
  20. register_handler_proc
  21. register_irq_proc
  22. unregister_irq_proc
  23. unregister_handler_proc
  24. register_default_affinity_proc
  25. init_irq_proc
  26. arch_show_interrupts
  27. show_interrupts

   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 
  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 
  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;
 104 static int irq_affinity_proc_show(struct seq_file *m, void *v)
 105 {
 106         return show_irq_affinity(AFFINITY, m);
 107 }
 108 
 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
 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. */
 131 static inline int irq_select_affinity_usr(unsigned int irq)
 132 {
 133         return irq_select_affinity(irq);
 134 }
 135 #endif
 136 
 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 (!alloc_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 
 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 
 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 
 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 
 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 file_operations irq_affinity_proc_fops = {
 202         .open           = irq_affinity_proc_open,
 203         .read           = seq_read,
 204         .llseek         = seq_lseek,
 205         .release        = single_release,
 206         .write          = irq_affinity_proc_write,
 207 };
 208 
 209 static const struct file_operations irq_affinity_list_proc_fops = {
 210         .open           = irq_affinity_list_proc_open,
 211         .read           = seq_read,
 212         .llseek         = seq_lseek,
 213         .release        = single_release,
 214         .write          = irq_affinity_list_proc_write,
 215 };
 216 
 217 #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
 218 static int irq_effective_aff_proc_show(struct seq_file *m, void *v)
 219 {
 220         return show_irq_affinity(EFFECTIVE, m);
 221 }
 222 
 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 
 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 
 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 (!alloc_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 
 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 file_operations default_affinity_proc_fops = {
 272         .open           = default_affinity_open,
 273         .read           = seq_read,
 274         .llseek         = seq_lseek,
 275         .release        = single_release,
 276         .write          = default_affinity_write,
 277 };
 278 
 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 
 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 
 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 
 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 
 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_fops, 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_fops, 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 
 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 
 417 void unregister_handler_proc(unsigned int irq, struct irqaction *action)
 418 {
 419         proc_remove(action->dir);
 420 }
 421 
 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_fops);
 427 #endif
 428 }
 429 
 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 
 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 
 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)
 489                 goto outsparse;
 490 
 491         if (desc->kstat_irqs)
 492                 for_each_online_cpu(j)
 493                         any_count |= *per_cpu_ptr(desc->kstat_irqs, j);
 494 
 495         if ((!desc->action || irq_desc_is_chained(desc)) && !any_count)
 496                 goto outsparse;
 497 
 498         seq_printf(p, "%*d: ", prec, i);
 499         for_each_online_cpu(j)
 500                 seq_printf(p, "%10u ", desc->kstat_irqs ?
 501                                         *per_cpu_ptr(desc->kstat_irqs, j) : 0);
 502 
 503         raw_spin_lock_irqsave(&desc->lock, flags);
 504         if (desc->irq_data.chip) {
 505                 if (desc->irq_data.chip->irq_print_chip)
 506                         desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
 507                 else if (desc->irq_data.chip->name)
 508                         seq_printf(p, " %8s", desc->irq_data.chip->name);
 509                 else
 510                         seq_printf(p, " %8s", "-");
 511         } else {
 512                 seq_printf(p, " %8s", "None");
 513         }
 514         if (desc->irq_data.domain)
 515                 seq_printf(p, " %*d", prec, (int) desc->irq_data.hwirq);
 516         else
 517                 seq_printf(p, " %*s", prec, "");
 518 #ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL
 519         seq_printf(p, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge");
 520 #endif
 521         if (desc->name)
 522                 seq_printf(p, "-%-8s", desc->name);
 523 
 524         action = desc->action;
 525         if (action) {
 526                 seq_printf(p, "  %s", action->name);
 527                 while ((action = action->next) != NULL)
 528                         seq_printf(p, ", %s", action->name);
 529         }
 530 
 531         seq_putc(p, '\n');
 532         raw_spin_unlock_irqrestore(&desc->lock, flags);
 533 outsparse:
 534         rcu_read_unlock();
 535         return 0;
 536 }
 537 #endif

/* [<][>][^][v][top][bottom][index][help] */