diff options
Diffstat (limited to 'kernel/irq')
| -rw-r--r-- | kernel/irq/manage.c | 22 | ||||
| -rw-r--r-- | kernel/irq/proc.c | 39 |
2 files changed, 61 insertions, 0 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 444d5a81a209..3164ba7ce151 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -138,6 +138,22 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
| 138 | return 0; | 138 | return 0; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) | ||
| 142 | { | ||
| 143 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 144 | unsigned long flags; | ||
| 145 | |||
| 146 | if (!desc) | ||
| 147 | return -EINVAL; | ||
| 148 | |||
| 149 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
| 150 | desc->affinity_hint = m; | ||
| 151 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | EXPORT_SYMBOL_GPL(irq_set_affinity_hint); | ||
| 156 | |||
| 141 | #ifndef CONFIG_AUTO_IRQ_AFFINITY | 157 | #ifndef CONFIG_AUTO_IRQ_AFFINITY |
| 142 | /* | 158 | /* |
| 143 | * Generic version of the affinity autoselector. | 159 | * Generic version of the affinity autoselector. |
| @@ -906,6 +922,12 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
| 906 | desc->chip->disable(irq); | 922 | desc->chip->disable(irq); |
| 907 | } | 923 | } |
| 908 | 924 | ||
| 925 | #ifdef CONFIG_SMP | ||
| 926 | /* make sure affinity_hint is cleaned up */ | ||
| 927 | if (WARN_ON_ONCE(desc->affinity_hint)) | ||
| 928 | desc->affinity_hint = NULL; | ||
| 929 | #endif | ||
| 930 | |||
| 909 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 931 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
| 910 | 932 | ||
| 911 | unregister_handler_proc(irq, action); | 933 | unregister_handler_proc(irq, action); |
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index fe92dc5190dd..4f9427a30e14 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
| @@ -32,6 +32,29 @@ static int irq_affinity_proc_show(struct seq_file *m, void *v) | |||
| 32 | return 0; | 32 | return 0; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | static int irq_affinity_hint_proc_show(struct seq_file *m, void *v) | ||
| 36 | { | ||
| 37 | struct irq_desc *desc = irq_to_desc((long)m->private); | ||
| 38 | unsigned long flags; | ||
| 39 | cpumask_var_t mask; | ||
| 40 | |||
| 41 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
| 42 | return -ENOMEM; | ||
| 43 | |||
| 44 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
| 45 | if (desc->affinity_hint) | ||
| 46 | cpumask_copy(mask, desc->affinity_hint); | ||
| 47 | else | ||
| 48 | cpumask_setall(mask); | ||
| 49 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
| 50 | |||
| 51 | seq_cpumask(m, mask); | ||
| 52 | seq_putc(m, '\n'); | ||
| 53 | free_cpumask_var(mask); | ||
| 54 | |||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 35 | #ifndef is_affinity_mask_valid | 58 | #ifndef is_affinity_mask_valid |
| 36 | #define is_affinity_mask_valid(val) 1 | 59 | #define is_affinity_mask_valid(val) 1 |
| 37 | #endif | 60 | #endif |
| @@ -84,6 +107,11 @@ static int irq_affinity_proc_open(struct inode *inode, struct file *file) | |||
| 84 | return single_open(file, irq_affinity_proc_show, PDE(inode)->data); | 107 | return single_open(file, irq_affinity_proc_show, PDE(inode)->data); |
| 85 | } | 108 | } |
| 86 | 109 | ||
| 110 | static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file) | ||
| 111 | { | ||
| 112 | return single_open(file, irq_affinity_hint_proc_show, PDE(inode)->data); | ||
| 113 | } | ||
| 114 | |||
| 87 | static const struct file_operations irq_affinity_proc_fops = { | 115 | static const struct file_operations irq_affinity_proc_fops = { |
| 88 | .open = irq_affinity_proc_open, | 116 | .open = irq_affinity_proc_open, |
| 89 | .read = seq_read, | 117 | .read = seq_read, |
| @@ -92,6 +120,13 @@ static const struct file_operations irq_affinity_proc_fops = { | |||
| 92 | .write = irq_affinity_proc_write, | 120 | .write = irq_affinity_proc_write, |
| 93 | }; | 121 | }; |
| 94 | 122 | ||
| 123 | static const struct file_operations irq_affinity_hint_proc_fops = { | ||
| 124 | .open = irq_affinity_hint_proc_open, | ||
| 125 | .read = seq_read, | ||
| 126 | .llseek = seq_lseek, | ||
| 127 | .release = single_release, | ||
| 128 | }; | ||
| 129 | |||
| 95 | static int default_affinity_show(struct seq_file *m, void *v) | 130 | static int default_affinity_show(struct seq_file *m, void *v) |
| 96 | { | 131 | { |
| 97 | seq_cpumask(m, irq_default_affinity); | 132 | seq_cpumask(m, irq_default_affinity); |
| @@ -252,6 +287,10 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc) | |||
| 252 | proc_create_data("smp_affinity", 0600, desc->dir, | 287 | proc_create_data("smp_affinity", 0600, desc->dir, |
| 253 | &irq_affinity_proc_fops, (void *)(long)irq); | 288 | &irq_affinity_proc_fops, (void *)(long)irq); |
| 254 | 289 | ||
| 290 | /* create /proc/irq/<irq>/affinity_hint */ | ||
| 291 | proc_create_data("affinity_hint", 0400, desc->dir, | ||
| 292 | &irq_affinity_hint_proc_fops, (void *)(long)irq); | ||
| 293 | |||
| 255 | proc_create_data("node", 0444, desc->dir, | 294 | proc_create_data("node", 0444, desc->dir, |
| 256 | &irq_node_proc_fops, (void *)(long)irq); | 295 | &irq_node_proc_fops, (void *)(long)irq); |
| 257 | #endif | 296 | #endif |
