diff options
Diffstat (limited to 'kernel/irq/numa_migrate.c')
| -rw-r--r-- | kernel/irq/numa_migrate.c | 30 | 
1 files changed, 19 insertions, 11 deletions
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c index acd88356ac7..243d6121e50 100644 --- a/kernel/irq/numa_migrate.c +++ b/kernel/irq/numa_migrate.c @@ -17,16 +17,11 @@ static void init_copy_kstat_irqs(struct irq_desc *old_desc,  				 struct irq_desc *desc,  				 int cpu, int nr)  { -	unsigned long bytes; -  	init_kstat_irqs(desc, cpu, nr); -	if (desc->kstat_irqs != old_desc->kstat_irqs) { -		/* Compute how many bytes we need per irq and allocate them */ -		bytes = nr * sizeof(unsigned int); - -		memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes); -	} +	if (desc->kstat_irqs != old_desc->kstat_irqs) +		memcpy(desc->kstat_irqs, old_desc->kstat_irqs, +			 nr * sizeof(*desc->kstat_irqs));  }  static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc) @@ -38,15 +33,22 @@ static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)  	old_desc->kstat_irqs = NULL;  } -static void init_copy_one_irq_desc(int irq, struct irq_desc *old_desc, +static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,  		 struct irq_desc *desc, int cpu)  {  	memcpy(desc, old_desc, sizeof(struct irq_desc)); +	if (!init_alloc_desc_masks(desc, cpu, false)) { +		printk(KERN_ERR "irq %d: can not get new irq_desc cpumask " +				"for migration.\n", irq); +		return false; +	}  	spin_lock_init(&desc->lock);  	desc->cpu = cpu;  	lockdep_set_class(&desc->lock, &irq_desc_lock_class);  	init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids); +	init_copy_desc_masks(old_desc, desc);  	arch_init_copy_chip_data(old_desc, desc, cpu); +	return true;  }  static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc) @@ -76,12 +78,18 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,  	node = cpu_to_node(cpu);  	desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);  	if (!desc) { -		printk(KERN_ERR "irq %d: can not get new irq_desc for migration.\n", irq); +		printk(KERN_ERR "irq %d: can not get new irq_desc " +				"for migration.\n", irq); +		/* still use old one */ +		desc = old_desc; +		goto out_unlock; +	} +	if (!init_copy_one_irq_desc(irq, old_desc, desc, cpu)) {  		/* still use old one */ +		kfree(desc);  		desc = old_desc;  		goto out_unlock;  	} -	init_copy_one_irq_desc(irq, old_desc, desc, cpu);  	irq_desc_ptrs[irq] = desc;  	spin_unlock_irqrestore(&sparse_irq_lock, flags);  |