diff options
Diffstat (limited to 'kernel/irq/proc.c')
| -rw-r--r-- | kernel/irq/proc.c | 110 | 
1 files changed, 94 insertions, 16 deletions
| diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index c53edad7b459..7f9642a1e267 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -37,19 +37,47 @@ static struct proc_dir_entry *root_irq_dir;  #ifdef CONFIG_SMP -static int show_irq_affinity(int type, struct seq_file *m, void *v) +enum { +	AFFINITY, +	AFFINITY_LIST, +	EFFECTIVE, +	EFFECTIVE_LIST, +}; + +static int show_irq_affinity(int type, struct seq_file *m)  {  	struct irq_desc *desc = irq_to_desc((long)m->private); -	const struct cpumask *mask = desc->irq_common_data.affinity; +	const struct cpumask *mask; +	switch (type) { +	case AFFINITY: +	case AFFINITY_LIST: +		mask = desc->irq_common_data.affinity;  #ifdef CONFIG_GENERIC_PENDING_IRQ -	if (irqd_is_setaffinity_pending(&desc->irq_data)) -		mask = desc->pending_mask; +		if (irqd_is_setaffinity_pending(&desc->irq_data)) +			mask = desc->pending_mask;  #endif -	if (type) +		break; +	case EFFECTIVE: +	case EFFECTIVE_LIST: +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK +		mask = desc->irq_common_data.effective_affinity; +		break; +#else +		return -EINVAL; +#endif +	}; + +	switch (type) { +	case AFFINITY_LIST: +	case EFFECTIVE_LIST:  		seq_printf(m, "%*pbl\n", cpumask_pr_args(mask)); -	else +		break; +	case AFFINITY: +	case EFFECTIVE:  		seq_printf(m, "%*pb\n", cpumask_pr_args(mask)); +		break; +	}  	return 0;  } @@ -80,12 +108,12 @@ static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)  int no_irq_affinity;  static int irq_affinity_proc_show(struct seq_file *m, void *v)  { -	return show_irq_affinity(0, m, v); +	return show_irq_affinity(AFFINITY, m);  }  static int irq_affinity_list_proc_show(struct seq_file *m, void *v)  { -	return show_irq_affinity(1, m, v); +	return show_irq_affinity(AFFINITY_LIST, m);  } @@ -120,9 +148,11 @@ static ssize_t write_irq_affinity(int type, struct file *file,  	 * one online CPU still has to be targeted.  	 */  	if (!cpumask_intersects(new_value, cpu_online_mask)) { -		/* Special case for empty set - allow the architecture -		   code to set default SMP affinity. */ -		err = irq_select_affinity_usr(irq, new_value) ? -EINVAL : count; +		/* +		 * Special case for empty set - allow the architecture code +		 * to set default SMP affinity. +		 */ +		err = irq_select_affinity_usr(irq) ? -EINVAL : count;  	} else {  		irq_set_affinity(irq, new_value);  		err = count; @@ -183,6 +213,44 @@ static const struct file_operations irq_affinity_list_proc_fops = {  	.write		= irq_affinity_list_proc_write,  }; +#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK +static int irq_effective_aff_proc_show(struct seq_file *m, void *v) +{ +	return show_irq_affinity(EFFECTIVE, m); +} + +static int irq_effective_aff_list_proc_show(struct seq_file *m, void *v) +{ +	return show_irq_affinity(EFFECTIVE_LIST, m); +} + +static int irq_effective_aff_proc_open(struct inode *inode, struct file *file) +{ +	return single_open(file, irq_effective_aff_proc_show, PDE_DATA(inode)); +} + +static int irq_effective_aff_list_proc_open(struct inode *inode, +					    struct file *file) +{ +	return single_open(file, irq_effective_aff_list_proc_show, +			   PDE_DATA(inode)); +} + +static const struct file_operations irq_effective_aff_proc_fops = { +	.open		= irq_effective_aff_proc_open, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; + +static const struct file_operations irq_effective_aff_list_proc_fops = { +	.open		= irq_effective_aff_list_proc_open, +	.read		= seq_read, +	.llseek		= seq_lseek, +	.release	= single_release, +}; +#endif +  static int default_affinity_show(struct seq_file *m, void *v)  {  	seq_printf(m, "%*pb\n", cpumask_pr_args(irq_default_affinity)); @@ -324,6 +392,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)  void register_irq_proc(unsigned int irq, struct irq_desc *desc)  {  	static DEFINE_MUTEX(register_lock); +	void __maybe_unused *irqp = (void *)(unsigned long) irq;  	char name [MAX_NAMELEN];  	if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) @@ -349,20 +418,25 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)  #ifdef CONFIG_SMP  	/* create /proc/irq/<irq>/smp_affinity */  	proc_create_data("smp_affinity", 0644, desc->dir, -			 &irq_affinity_proc_fops, (void *)(long)irq); +			 &irq_affinity_proc_fops, irqp);  	/* create /proc/irq/<irq>/affinity_hint */  	proc_create_data("affinity_hint", 0444, desc->dir, -			 &irq_affinity_hint_proc_fops, (void *)(long)irq); +			 &irq_affinity_hint_proc_fops, irqp);  	/* create /proc/irq/<irq>/smp_affinity_list */  	proc_create_data("smp_affinity_list", 0644, desc->dir, -			 &irq_affinity_list_proc_fops, (void *)(long)irq); +			 &irq_affinity_list_proc_fops, irqp);  	proc_create_data("node", 0444, desc->dir, -			 &irq_node_proc_fops, (void *)(long)irq); +			 &irq_node_proc_fops, irqp); +# ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK +	proc_create_data("effective_affinity", 0444, desc->dir, +			 &irq_effective_aff_proc_fops, irqp); +	proc_create_data("effective_affinity_list", 0444, desc->dir, +			 &irq_effective_aff_list_proc_fops, irqp); +# endif  #endif -  	proc_create_data("spurious", 0444, desc->dir,  			 &irq_spurious_proc_fops, (void *)(long)irq); @@ -381,6 +455,10 @@ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)  	remove_proc_entry("affinity_hint", desc->dir);  	remove_proc_entry("smp_affinity_list", desc->dir);  	remove_proc_entry("node", desc->dir); +# ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK +	remove_proc_entry("effective_affinity", desc->dir); +	remove_proc_entry("effective_affinity_list", desc->dir); +# endif  #endif  	remove_proc_entry("spurious", desc->dir); |