diff options
Diffstat (limited to 'lib/cpu_rmap.c')
| -rw-r--r-- | lib/cpu_rmap.c | 57 | 
1 files changed, 46 insertions, 11 deletions
diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index f08d9c56f712..73c1636b927b 100644 --- a/lib/cpu_rmap.c +++ b/lib/cpu_rmap.c @@ -128,19 +128,31 @@ debug_print_rmap(const struct cpu_rmap *rmap, const char *prefix)  }  #endif +static int get_free_index(struct cpu_rmap *rmap) +{ +	int i; + +	for (i = 0; i < rmap->size; i++) +		if (!rmap->obj[i]) +			return i; + +	return -ENOSPC; +} +  /**   * cpu_rmap_add - add object to a rmap   * @rmap: CPU rmap allocated with alloc_cpu_rmap()   * @obj: Object to add to rmap   * - * Return index of object. + * Return index of object or -ENOSPC if no free entry was found   */  int cpu_rmap_add(struct cpu_rmap *rmap, void *obj)  { -	u16 index; +	int index = get_free_index(rmap); + +	if (index < 0) +		return index; -	BUG_ON(rmap->used >= rmap->size); -	index = rmap->used++;  	rmap->obj[index] = obj;  	return index;  } @@ -230,9 +242,10 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap)  	if (!rmap)  		return; -	for (index = 0; index < rmap->used; index++) { +	for (index = 0; index < rmap->size; index++) {  		glue = rmap->obj[index]; -		irq_set_affinity_notifier(glue->notify.irq, NULL); +		if (glue) +			irq_set_affinity_notifier(glue->notify.irq, NULL);  	}  	cpu_rmap_put(rmap); @@ -268,10 +281,22 @@ static void irq_cpu_rmap_release(struct kref *ref)  		container_of(ref, struct irq_glue, notify.kref);  	cpu_rmap_put(glue->rmap); +	glue->rmap->obj[glue->index] = NULL;  	kfree(glue);  }  /** + * irq_cpu_rmap_remove - remove an IRQ from a CPU affinity reverse-map + * @rmap: The reverse-map + * @irq: The IRQ number + */ +int irq_cpu_rmap_remove(struct cpu_rmap *rmap, int irq) +{ +	return irq_set_affinity_notifier(irq, NULL); +} +EXPORT_SYMBOL(irq_cpu_rmap_remove); + +/**   * irq_cpu_rmap_add - add an IRQ to a CPU affinity reverse-map   * @rmap: The reverse-map   * @irq: The IRQ number @@ -293,12 +318,22 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)  	glue->notify.release = irq_cpu_rmap_release;  	glue->rmap = rmap;  	cpu_rmap_get(rmap); -	glue->index = cpu_rmap_add(rmap, glue); +	rc = cpu_rmap_add(rmap, glue); +	if (rc < 0) +		goto err_add; + +	glue->index = rc;  	rc = irq_set_affinity_notifier(irq, &glue->notify); -	if (rc) { -		cpu_rmap_put(glue->rmap); -		kfree(glue); -	} +	if (rc) +		goto err_set; + +	return rc; + +err_set: +	rmap->obj[glue->index] = NULL; +err_add: +	cpu_rmap_put(glue->rmap); +	kfree(glue);  	return rc;  }  EXPORT_SYMBOL(irq_cpu_rmap_add);  |