diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-11 17:55:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-11 17:55:15 -0500 |
commit | c727b4c63c9bf33c65351bbcc738161edb444b24 (patch) | |
tree | 2e9f3d6cfa17f2fc62a64dbb41fff9e6baabfd24 /lib/cpu_rmap.c | |
parent | 93ccb3910ae3dbff6d224aecd22d8eece3d70ce9 (diff) | |
parent | 3cb7a56344ca45ee56d71c5f8fe9f922306bff1f (diff) |
Merge branch 'akpm' (incoming fixes from Andrew)
Merge misc fixes from Andrew Morton:
"The audit fixes have been floating around for a while - Al and Eric
aren't responding to either myself or Kees so I asked Kees to
re-review them and here they are."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (22 commits)
lib/rbtree.c: avoid the use of non-static __always_inline
MAINTAINERS: Omar had moved
mm: compaction: partially revert capture of suitable high-order page
linux/audit.h: move ptrace.h include to kernel header
kernel/audit.c: avoid negative sleep durations
audit: catch possible NULL audit buffers
audit: create explicit AUDIT_SECCOMP event type
MAINTAINERS: fix a status pattern
MAINTAINERS: fix arch/arm/plat-omap/include/plat/omap_hwmod.h
mm: thp: acquire the anon_vma rwsem for write during split
mm: mmap: annotate vm_lock_anon_vma locking properly for lockdep
lockdep, rwsem: provide down_write_nest_lock()
arch/mn10300/Kconfig: select CONFIG_GENERIC_ATOMIC64
mm: bootmem: fix free_all_bootmem_core() with odd bitmap alignment
mm: use aligned zone start for pfn_to_bitidx calculation
fs/exec.c: work around icc miscompilation
mm: compaction: fix echo 1 > compact_memory return error issue
mm: memblock: fix wrong memmove size in memblock_merge_regions()
drivers/video/ssd1307fb.c: fix bit order bug in the byte translation function
mm: migrate: check page_count of THP before migrating
...
Diffstat (limited to 'lib/cpu_rmap.c')
-rw-r--r-- | lib/cpu_rmap.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index 145dec5267c9..5fbed5caba6e 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) | |||
45 | if (!rmap) | 45 | if (!rmap) |
46 | return NULL; | 46 | return NULL; |
47 | 47 | ||
48 | kref_init(&rmap->refcount); | ||
48 | rmap->obj = (void **)((char *)rmap + obj_offset); | 49 | rmap->obj = (void **)((char *)rmap + obj_offset); |
49 | 50 | ||
50 | /* Initially assign CPUs to objects on a rota, since we have | 51 | /* 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) | |||
63 | } | 64 | } |
64 | EXPORT_SYMBOL(alloc_cpu_rmap); | 65 | EXPORT_SYMBOL(alloc_cpu_rmap); |
65 | 66 | ||
67 | /** | ||
68 | * cpu_rmap_release - internal reclaiming helper called from kref_put | ||
69 | * @ref: kref to struct cpu_rmap | ||
70 | */ | ||
71 | static void cpu_rmap_release(struct kref *ref) | ||
72 | { | ||
73 | struct cpu_rmap *rmap = container_of(ref, struct cpu_rmap, refcount); | ||
74 | kfree(rmap); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * cpu_rmap_get - internal helper to get new ref on a cpu_rmap | ||
79 | * @rmap: reverse-map allocated with alloc_cpu_rmap() | ||
80 | */ | ||
81 | static inline void cpu_rmap_get(struct cpu_rmap *rmap) | ||
82 | { | ||
83 | kref_get(&rmap->refcount); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * cpu_rmap_put - release ref on a cpu_rmap | ||
88 | * @rmap: reverse-map allocated with alloc_cpu_rmap() | ||
89 | */ | ||
90 | int cpu_rmap_put(struct cpu_rmap *rmap) | ||
91 | { | ||
92 | return kref_put(&rmap->refcount, cpu_rmap_release); | ||
93 | } | ||
94 | EXPORT_SYMBOL(cpu_rmap_put); | ||
95 | |||
66 | /* Reevaluate nearest object for given CPU, comparing with the given | 96 | /* Reevaluate nearest object for given CPU, comparing with the given |
67 | * neighbours at the given distance. | 97 | * neighbours at the given distance. |
68 | */ | 98 | */ |
@@ -197,8 +227,7 @@ struct irq_glue { | |||
197 | * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs | 227 | * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs |
198 | * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL | 228 | * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL |
199 | * | 229 | * |
200 | * Must be called in process context, before freeing the IRQs, and | 230 | * Must be called in process context, before freeing the IRQs. |
201 | * without holding any locks required by global workqueue items. | ||
202 | */ | 231 | */ |
203 | void free_irq_cpu_rmap(struct cpu_rmap *rmap) | 232 | void free_irq_cpu_rmap(struct cpu_rmap *rmap) |
204 | { | 233 | { |
@@ -212,12 +241,18 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap) | |||
212 | glue = rmap->obj[index]; | 241 | glue = rmap->obj[index]; |
213 | irq_set_affinity_notifier(glue->notify.irq, NULL); | 242 | irq_set_affinity_notifier(glue->notify.irq, NULL); |
214 | } | 243 | } |
215 | irq_run_affinity_notifiers(); | ||
216 | 244 | ||
217 | kfree(rmap); | 245 | cpu_rmap_put(rmap); |
218 | } | 246 | } |
219 | EXPORT_SYMBOL(free_irq_cpu_rmap); | 247 | EXPORT_SYMBOL(free_irq_cpu_rmap); |
220 | 248 | ||
249 | /** | ||
250 | * irq_cpu_rmap_notify - callback for IRQ subsystem when IRQ affinity updated | ||
251 | * @notify: struct irq_affinity_notify passed by irq/manage.c | ||
252 | * @mask: cpu mask for new SMP affinity | ||
253 | * | ||
254 | * This is executed in workqueue context. | ||
255 | */ | ||
221 | static void | 256 | static void |
222 | irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) | 257 | irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) |
223 | { | 258 | { |
@@ -230,10 +265,16 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) | |||
230 | pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); | 265 | pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); |
231 | } | 266 | } |
232 | 267 | ||
268 | /** | ||
269 | * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem | ||
270 | * @ref: kref to struct irq_affinity_notify passed by irq/manage.c | ||
271 | */ | ||
233 | static void irq_cpu_rmap_release(struct kref *ref) | 272 | static void irq_cpu_rmap_release(struct kref *ref) |
234 | { | 273 | { |
235 | struct irq_glue *glue = | 274 | struct irq_glue *glue = |
236 | container_of(ref, struct irq_glue, notify.kref); | 275 | container_of(ref, struct irq_glue, notify.kref); |
276 | |||
277 | cpu_rmap_put(glue->rmap); | ||
237 | kfree(glue); | 278 | kfree(glue); |
238 | } | 279 | } |
239 | 280 | ||
@@ -258,10 +299,13 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) | |||
258 | glue->notify.notify = irq_cpu_rmap_notify; | 299 | glue->notify.notify = irq_cpu_rmap_notify; |
259 | glue->notify.release = irq_cpu_rmap_release; | 300 | glue->notify.release = irq_cpu_rmap_release; |
260 | glue->rmap = rmap; | 301 | glue->rmap = rmap; |
302 | cpu_rmap_get(rmap); | ||
261 | glue->index = cpu_rmap_add(rmap, glue); | 303 | glue->index = cpu_rmap_add(rmap, glue); |
262 | rc = irq_set_affinity_notifier(irq, &glue->notify); | 304 | rc = irq_set_affinity_notifier(irq, &glue->notify); |
263 | if (rc) | 305 | if (rc) { |
306 | cpu_rmap_put(glue->rmap); | ||
264 | kfree(glue); | 307 | kfree(glue); |
308 | } | ||
265 | return rc; | 309 | return rc; |
266 | } | 310 | } |
267 | EXPORT_SYMBOL(irq_cpu_rmap_add); | 311 | EXPORT_SYMBOL(irq_cpu_rmap_add); |