diff options
| author | Olof Johansson <olof@lixom.net> | 2013-01-27 22:07:11 -0800 | 
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2013-01-27 22:07:20 -0800 | 
| commit | 6b914c998787d65022e80d6262dfd0edef58cadb (patch) | |
| tree | ec9d9605ae08e6e40664c4302a181979ab4fe1d3 /lib | |
| parent | 1f87a404d02a96519284e1928445ca5cfe9667db (diff) | |
| parent | 949db153b6466c6f7cad5a427ecea94985927311 (diff) | |
| download | olio-linux-3.10-6b914c998787d65022e80d6262dfd0edef58cadb.tar.xz olio-linux-3.10-6b914c998787d65022e80d6262dfd0edef58cadb.zip  | |
Merge tag 'v3.8-rc5' into next/cleanup
Linux 3.8-rc5
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bug.c | 1 | ||||
| -rw-r--r-- | lib/cpu_rmap.c | 54 | ||||
| -rw-r--r-- | lib/rbtree.c | 20 | 
3 files changed, 67 insertions, 8 deletions
diff --git a/lib/bug.c b/lib/bug.c index a28c1415357..d0cdf14c651 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -55,6 +55,7 @@ static inline unsigned long bug_addr(const struct bug_entry *bug)  }  #ifdef CONFIG_MODULES +/* Updates are protected by module mutex */  static LIST_HEAD(module_bug_list);  static const struct bug_entry *module_find_bug(unsigned long bugaddr) diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index 145dec5267c..5fbed5caba6 100644 --- a/lib/cpu_rmap.c +++ b/lib/cpu_rmap.c @@ -45,6 +45,7 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags)  	if (!rmap)  		return NULL; +	kref_init(&rmap->refcount);  	rmap->obj = (void **)((char *)rmap + obj_offset);  	/* Initially assign CPUs to objects on a rota, since we have @@ -63,6 +64,35 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags)  }  EXPORT_SYMBOL(alloc_cpu_rmap); +/** + * cpu_rmap_release - internal reclaiming helper called from kref_put + * @ref: kref to struct cpu_rmap + */ +static void cpu_rmap_release(struct kref *ref) +{ +	struct cpu_rmap *rmap = container_of(ref, struct cpu_rmap, refcount); +	kfree(rmap); +} + +/** + * cpu_rmap_get - internal helper to get new ref on a cpu_rmap + * @rmap: reverse-map allocated with alloc_cpu_rmap() + */ +static inline void cpu_rmap_get(struct cpu_rmap *rmap) +{ +	kref_get(&rmap->refcount); +} + +/** + * cpu_rmap_put - release ref on a cpu_rmap + * @rmap: reverse-map allocated with alloc_cpu_rmap() + */ +int cpu_rmap_put(struct cpu_rmap *rmap) +{ +	return kref_put(&rmap->refcount, cpu_rmap_release); +} +EXPORT_SYMBOL(cpu_rmap_put); +  /* Reevaluate nearest object for given CPU, comparing with the given   * neighbours at the given distance.   */ @@ -197,8 +227,7 @@ struct irq_glue {   * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs   * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL   * - * Must be called in process context, before freeing the IRQs, and - * without holding any locks required by global workqueue items. + * Must be called in process context, before freeing the IRQs.   */  void free_irq_cpu_rmap(struct cpu_rmap *rmap)  { @@ -212,12 +241,18 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap)  		glue = rmap->obj[index];  		irq_set_affinity_notifier(glue->notify.irq, NULL);  	} -	irq_run_affinity_notifiers(); -	kfree(rmap); +	cpu_rmap_put(rmap);  }  EXPORT_SYMBOL(free_irq_cpu_rmap); +/** + * irq_cpu_rmap_notify - callback for IRQ subsystem when IRQ affinity updated + * @notify: struct irq_affinity_notify passed by irq/manage.c + * @mask: cpu mask for new SMP affinity + * + * This is executed in workqueue context. + */  static void  irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask)  { @@ -230,10 +265,16 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask)  		pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc);  } +/** + * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem + * @ref: kref to struct irq_affinity_notify passed by irq/manage.c + */  static void irq_cpu_rmap_release(struct kref *ref)  {  	struct irq_glue *glue =  		container_of(ref, struct irq_glue, notify.kref); + +	cpu_rmap_put(glue->rmap);  	kfree(glue);  } @@ -258,10 +299,13 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)  	glue->notify.notify = irq_cpu_rmap_notify;  	glue->notify.release = irq_cpu_rmap_release;  	glue->rmap = rmap; +	cpu_rmap_get(rmap);  	glue->index = cpu_rmap_add(rmap, glue);  	rc = irq_set_affinity_notifier(irq, &glue->notify); -	if (rc) +	if (rc) { +		cpu_rmap_put(glue->rmap);  		kfree(glue); +	}  	return rc;  }  EXPORT_SYMBOL(irq_cpu_rmap_add); diff --git a/lib/rbtree.c b/lib/rbtree.c index 4f56a11d67f..c0e31fe2fab 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c @@ -194,8 +194,12 @@ __rb_insert(struct rb_node *node, struct rb_root *root,  	}  } -__always_inline void -__rb_erase_color(struct rb_node *parent, struct rb_root *root, +/* + * Inline version for rb_erase() use - we want to be able to inline + * and eliminate the dummy_rotate callback there + */ +static __always_inline void +____rb_erase_color(struct rb_node *parent, struct rb_root *root,  	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))  {  	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; @@ -355,6 +359,13 @@ __rb_erase_color(struct rb_node *parent, struct rb_root *root,  		}  	}  } + +/* Non-inline version for rb_erase_augmented() use */ +void __rb_erase_color(struct rb_node *parent, struct rb_root *root, +	void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) +{ +	____rb_erase_color(parent, root, augment_rotate); +}  EXPORT_SYMBOL(__rb_erase_color);  /* @@ -380,7 +391,10 @@ EXPORT_SYMBOL(rb_insert_color);  void rb_erase(struct rb_node *node, struct rb_root *root)  { -	rb_erase_augmented(node, root, &dummy_callbacks); +	struct rb_node *rebalance; +	rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); +	if (rebalance) +		____rb_erase_color(rebalance, root, dummy_rotate);  }  EXPORT_SYMBOL(rb_erase);  |