aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/head_32.S2
-rw-r--r--drivers/leds/led-class.c8
-rw-r--r--drivers/leds/led-core.c4
-rw-r--r--drivers/leds/led-triggers.c8
-rw-r--r--drivers/leds/leds-locomo.c2
-rw-r--r--drivers/leds/leds.h3
-rw-r--r--include/asm-x86/byteorder.h4
-rw-r--r--include/asm-x86/msr.h74
-rw-r--r--include/linux/slub_def.h2
-rw-r--r--mm/slub.c105
10 files changed, 149 insertions, 63 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index ac0637a6d71c..fbad51fce672 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -196,7 +196,7 @@ default_entry:
196 /* Do an early initialization of the fixmap area */ 196 /* Do an early initialization of the fixmap area */
197 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx 197 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
198 movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax 198 movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
199 addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ 199 addl $0x67, %eax /* 0x67 == _PAGE_TABLE */
200 movl %eax, 4092(%edx) 200 movl %eax, 4092(%edx)
201 201
202 xorl %ebx,%ebx /* This is the boot CPU (BSP) */ 202 xorl %ebx,%ebx /* This is the boot CPU (BSP) */
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index ba8b04b03b9f..64c66b3769c9 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -106,9 +106,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
106 goto err_out; 106 goto err_out;
107 107
108 /* add to the list of leds */ 108 /* add to the list of leds */
109 write_lock(&leds_list_lock); 109 down_write(&leds_list_lock);
110 list_add_tail(&led_cdev->node, &leds_list); 110 list_add_tail(&led_cdev->node, &leds_list);
111 write_unlock(&leds_list_lock); 111 up_write(&leds_list_lock);
112 112
113#ifdef CONFIG_LEDS_TRIGGERS 113#ifdef CONFIG_LEDS_TRIGGERS
114 init_rwsem(&led_cdev->trigger_lock); 114 init_rwsem(&led_cdev->trigger_lock);
@@ -155,9 +155,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
155 155
156 device_unregister(led_cdev->dev); 156 device_unregister(led_cdev->dev);
157 157
158 write_lock(&leds_list_lock); 158 down_write(&leds_list_lock);
159 list_del(&led_cdev->node); 159 list_del(&led_cdev->node);
160 write_unlock(&leds_list_lock); 160 up_write(&leds_list_lock);
161} 161}
162EXPORT_SYMBOL_GPL(led_classdev_unregister); 162EXPORT_SYMBOL_GPL(led_classdev_unregister);
163 163
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 9b015f9af351..5d1ca10524b6 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -14,11 +14,11 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/spinlock.h> 17#include <linux/rwsem.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include "leds.h" 19#include "leds.h"
20 20
21DEFINE_RWLOCK(leds_list_lock); 21DECLARE_RWSEM(leds_list_lock);
22LIST_HEAD(leds_list); 22LIST_HEAD(leds_list);
23 23
24EXPORT_SYMBOL_GPL(leds_list); 24EXPORT_SYMBOL_GPL(leds_list);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 0bdb786210b1..13c9026d68af 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -169,7 +169,7 @@ int led_trigger_register(struct led_trigger *trigger)
169 up_write(&triggers_list_lock); 169 up_write(&triggers_list_lock);
170 170
171 /* Register with any LEDs that have this as a default trigger */ 171 /* Register with any LEDs that have this as a default trigger */
172 read_lock(&leds_list_lock); 172 down_read(&leds_list_lock);
173 list_for_each_entry(led_cdev, &leds_list, node) { 173 list_for_each_entry(led_cdev, &leds_list, node) {
174 down_write(&led_cdev->trigger_lock); 174 down_write(&led_cdev->trigger_lock);
175 if (!led_cdev->trigger && led_cdev->default_trigger && 175 if (!led_cdev->trigger && led_cdev->default_trigger &&
@@ -177,7 +177,7 @@ int led_trigger_register(struct led_trigger *trigger)
177 led_trigger_set(led_cdev, trigger); 177 led_trigger_set(led_cdev, trigger);
178 up_write(&led_cdev->trigger_lock); 178 up_write(&led_cdev->trigger_lock);
179 } 179 }
180 read_unlock(&leds_list_lock); 180 up_read(&leds_list_lock);
181 181
182 return 0; 182 return 0;
183} 183}
@@ -212,14 +212,14 @@ void led_trigger_unregister(struct led_trigger *trigger)
212 up_write(&triggers_list_lock); 212 up_write(&triggers_list_lock);
213 213
214 /* Remove anyone actively using this trigger */ 214 /* Remove anyone actively using this trigger */
215 read_lock(&leds_list_lock); 215 down_read(&leds_list_lock);
216 list_for_each_entry(led_cdev, &leds_list, node) { 216 list_for_each_entry(led_cdev, &leds_list, node) {
217 down_write(&led_cdev->trigger_lock); 217 down_write(&led_cdev->trigger_lock);
218 if (led_cdev->trigger == trigger) 218 if (led_cdev->trigger == trigger)
219 led_trigger_set(led_cdev, NULL); 219 led_trigger_set(led_cdev, NULL);
220 up_write(&led_cdev->trigger_lock); 220 up_write(&led_cdev->trigger_lock);
221 } 221 }
222 read_unlock(&leds_list_lock); 222 up_read(&leds_list_lock);
223} 223}
224 224
225void led_trigger_unregister_simple(struct led_trigger *trigger) 225void led_trigger_unregister_simple(struct led_trigger *trigger)
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index bfac499f3258..2207335e9212 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -19,7 +19,7 @@
19static void locomoled_brightness_set(struct led_classdev *led_cdev, 19static void locomoled_brightness_set(struct led_classdev *led_cdev,
20 enum led_brightness value, int offset) 20 enum led_brightness value, int offset)
21{ 21{
22 struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev); 22 struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
23 unsigned long flags; 23 unsigned long flags;
24 24
25 local_irq_save(flags); 25 local_irq_save(flags);
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index f2f3884fe063..12b6fe93b135 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -14,6 +14,7 @@
14#define __LEDS_H_INCLUDED 14#define __LEDS_H_INCLUDED
15 15
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/rwsem.h>
17#include <linux/leds.h> 18#include <linux/leds.h>
18 19
19static inline void led_set_brightness(struct led_classdev *led_cdev, 20static inline void led_set_brightness(struct led_classdev *led_cdev,
@@ -26,7 +27,7 @@ static inline void led_set_brightness(struct led_classdev *led_cdev,
26 led_cdev->brightness_set(led_cdev, value); 27 led_cdev->brightness_set(led_cdev, value);
27} 28}
28 29
29extern rwlock_t leds_list_lock; 30extern struct rw_semaphore leds_list_lock;
30extern struct list_head leds_list; 31extern struct list_head leds_list;
31 32
32#ifdef CONFIG_LEDS_TRIGGERS 33#ifdef CONFIG_LEDS_TRIGGERS
diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h
index 1f2d6d5bf20d..fe2f2e5d51ba 100644
--- a/include/asm-x86/byteorder.h
+++ b/include/asm-x86/byteorder.h
@@ -30,13 +30,13 @@ static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
30 } v; 30 } v;
31 v.u = val; 31 v.u = val;
32#ifdef CONFIG_X86_BSWAP 32#ifdef CONFIG_X86_BSWAP
33 asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" 33 __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
34 : "=r" (v.s.a), "=r" (v.s.b) 34 : "=r" (v.s.a), "=r" (v.s.b)
35 : "0" (v.s.a), "1" (v.s.b)); 35 : "0" (v.s.a), "1" (v.s.b));
36#else 36#else
37 v.s.a = ___arch__swab32(v.s.a); 37 v.s.a = ___arch__swab32(v.s.a);
38 v.s.b = ___arch__swab32(v.s.b); 38 v.s.b = ___arch__swab32(v.s.b);
39 asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); 39 __asm__("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b));
40#endif 40#endif
41 return v.u; 41 return v.u;
42} 42}
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
index ba4b31432120..664a2fa7adc9 100644
--- a/include/asm-x86/msr.h
+++ b/include/asm-x86/msr.h
@@ -191,38 +191,6 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
191 191
192#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) 192#define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32)
193 193
194/* wrmsr with exception handling */
195#define wrmsr_safe(msr,a,b) ({ int ret__; \
196 asm volatile("2: wrmsr ; xorl %0,%0\n" \
197 "1:\n\t" \
198 ".section .fixup,\"ax\"\n\t" \
199 "3: movl %4,%0 ; jmp 1b\n\t" \
200 ".previous\n\t" \
201 ".section __ex_table,\"a\"\n" \
202 " .align 8\n\t" \
203 " .quad 2b,3b\n\t" \
204 ".previous" \
205 : "=a" (ret__) \
206 : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
207 ret__; })
208
209#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
210
211#define rdmsr_safe(msr,a,b) \
212 ({ int ret__; \
213 asm volatile ("1: rdmsr\n" \
214 "2:\n" \
215 ".section .fixup,\"ax\"\n" \
216 "3: movl %4,%0\n" \
217 " jmp 2b\n" \
218 ".previous\n" \
219 ".section __ex_table,\"a\"\n" \
220 " .align 8\n" \
221 " .quad 1b,3b\n" \
222 ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \
223 :"c"(msr), "i"(-EIO), "0"(0)); \
224 ret__; })
225
226#define rdtsc(low,high) \ 194#define rdtsc(low,high) \
227 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) 195 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
228 196
@@ -230,17 +198,17 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
230 __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") 198 __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
231 199
232#define rdtscp(low,high,aux) \ 200#define rdtscp(low,high,aux) \
233 asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) 201 __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux))
234 202
235#define rdtscll(val) do { \ 203#define rdtscll(val) do { \
236 unsigned int __a,__d; \ 204 unsigned int __a,__d; \
237 asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ 205 __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d)); \
238 (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ 206 (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
239} while(0) 207} while(0)
240 208
241#define rdtscpll(val, aux) do { \ 209#define rdtscpll(val, aux) do { \
242 unsigned long __a, __d; \ 210 unsigned long __a, __d; \
243 asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ 211 __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \
244 (val) = (__d << 32) | __a; \ 212 (val) = (__d << 32) | __a; \
245} while (0) 213} while (0)
246 214
@@ -253,6 +221,7 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
253 : "=a" (low), "=d" (high) \ 221 : "=a" (low), "=d" (high) \
254 : "c" (counter)) 222 : "c" (counter))
255 223
224
256static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, 225static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
257 unsigned int *ecx, unsigned int *edx) 226 unsigned int *ecx, unsigned int *edx)
258{ 227{
@@ -320,6 +289,40 @@ static inline unsigned int cpuid_edx(unsigned int op)
320 return edx; 289 return edx;
321} 290}
322 291
292#ifdef __KERNEL__
293
294/* wrmsr with exception handling */
295#define wrmsr_safe(msr,a,b) ({ int ret__; \
296 asm volatile("2: wrmsr ; xorl %0,%0\n" \
297 "1:\n\t" \
298 ".section .fixup,\"ax\"\n\t" \
299 "3: movl %4,%0 ; jmp 1b\n\t" \
300 ".previous\n\t" \
301 ".section __ex_table,\"a\"\n" \
302 " .align 8\n\t" \
303 " .quad 2b,3b\n\t" \
304 ".previous" \
305 : "=a" (ret__) \
306 : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \
307 ret__; })
308
309#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32))
310
311#define rdmsr_safe(msr,a,b) \
312 ({ int ret__; \
313 asm volatile ("1: rdmsr\n" \
314 "2:\n" \
315 ".section .fixup,\"ax\"\n" \
316 "3: movl %4,%0\n" \
317 " jmp 2b\n" \
318 ".previous\n" \
319 ".section __ex_table,\"a\"\n" \
320 " .align 8\n" \
321 " .quad 1b,3b\n" \
322 ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \
323 :"c"(msr), "i"(-EIO), "0"(0)); \
324 ret__; })
325
323#ifdef CONFIG_SMP 326#ifdef CONFIG_SMP
324void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); 327void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
325void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); 328void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
@@ -343,6 +346,7 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
343 return wrmsr_safe(msr_no, l, h); 346 return wrmsr_safe(msr_no, l, h);
344} 347}
345#endif /* CONFIG_SMP */ 348#endif /* CONFIG_SMP */
349#endif /* __KERNEL__ */
346#endif /* __ASSEMBLY__ */ 350#endif /* __ASSEMBLY__ */
347 351
348#endif /* !__i386__ */ 352#endif /* !__i386__ */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 40801e754afb..b7d9408a00ff 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -200,4 +200,6 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
200} 200}
201#endif 201#endif
202 202
203extern const struct seq_operations slabinfo_op;
204
203#endif /* _LINUX_SLUB_DEF_H */ 205#endif /* _LINUX_SLUB_DEF_H */
diff --git a/mm/slub.c b/mm/slub.c
index 3655ad359f03..903dabd92daf 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3076,6 +3076,19 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
3076 return slab_alloc(s, gfpflags, node, caller); 3076 return slab_alloc(s, gfpflags, node, caller);
3077} 3077}
3078 3078
3079static unsigned long count_partial(struct kmem_cache_node *n)
3080{
3081 unsigned long flags;
3082 unsigned long x = 0;
3083 struct page *page;
3084
3085 spin_lock_irqsave(&n->list_lock, flags);
3086 list_for_each_entry(page, &n->partial, lru)
3087 x += page->inuse;
3088 spin_unlock_irqrestore(&n->list_lock, flags);
3089 return x;
3090}
3091
3079#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) 3092#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)
3080static int validate_slab(struct kmem_cache *s, struct page *page, 3093static int validate_slab(struct kmem_cache *s, struct page *page,
3081 unsigned long *map) 3094 unsigned long *map)
@@ -3458,19 +3471,6 @@ static int list_locations(struct kmem_cache *s, char *buf,
3458 return n; 3471 return n;
3459} 3472}
3460 3473
3461static unsigned long count_partial(struct kmem_cache_node *n)
3462{
3463 unsigned long flags;
3464 unsigned long x = 0;
3465 struct page *page;
3466
3467 spin_lock_irqsave(&n->list_lock, flags);
3468 list_for_each_entry(page, &n->partial, lru)
3469 x += page->inuse;
3470 spin_unlock_irqrestore(&n->list_lock, flags);
3471 return x;
3472}
3473
3474enum slab_stat_type { 3474enum slab_stat_type {
3475 SL_FULL, 3475 SL_FULL,
3476 SL_PARTIAL, 3476 SL_PARTIAL,
@@ -4123,3 +4123,82 @@ static int __init slab_sysfs_init(void)
4123 4123
4124__initcall(slab_sysfs_init); 4124__initcall(slab_sysfs_init);
4125#endif 4125#endif
4126
4127/*
4128 * The /proc/slabinfo ABI
4129 */
4130#ifdef CONFIG_PROC_FS
4131
4132static void print_slabinfo_header(struct seq_file *m)
4133{
4134 seq_puts(m, "slabinfo - version: 2.1\n");
4135 seq_puts(m, "# name <active_objs> <num_objs> <objsize> "
4136 "<objperslab> <pagesperslab>");
4137 seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
4138 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
4139 seq_putc(m, '\n');
4140}
4141
4142static void *s_start(struct seq_file *m, loff_t *pos)
4143{
4144 loff_t n = *pos;
4145
4146 down_read(&slub_lock);
4147 if (!n)
4148 print_slabinfo_header(m);
4149
4150 return seq_list_start(&slab_caches, *pos);
4151}
4152
4153static void *s_next(struct seq_file *m, void *p, loff_t *pos)
4154{
4155 return seq_list_next(p, &slab_caches, pos);
4156}
4157
4158static void s_stop(struct seq_file *m, void *p)
4159{
4160 up_read(&slub_lock);
4161}
4162
4163static int s_show(struct seq_file *m, void *p)
4164{
4165 unsigned long nr_partials = 0;
4166 unsigned long nr_slabs = 0;
4167 unsigned long nr_inuse = 0;
4168 unsigned long nr_objs;
4169 struct kmem_cache *s;
4170 int node;
4171
4172 s = list_entry(p, struct kmem_cache, list);
4173
4174 for_each_online_node(node) {
4175 struct kmem_cache_node *n = get_node(s, node);
4176
4177 if (!n)
4178 continue;
4179
4180 nr_partials += n->nr_partial;
4181 nr_slabs += atomic_long_read(&n->nr_slabs);
4182 nr_inuse += count_partial(n);
4183 }
4184
4185 nr_objs = nr_slabs * s->objects;
4186 nr_inuse += (nr_slabs - nr_partials) * s->objects;
4187
4188 seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse,
4189 nr_objs, s->size, s->objects, (1 << s->order));
4190 seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0);
4191 seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs,
4192 0UL);
4193 seq_putc(m, '\n');
4194 return 0;
4195}
4196
4197const struct seq_operations slabinfo_op = {
4198 .start = s_start,
4199 .next = s_next,
4200 .stop = s_stop,
4201 .show = s_show,
4202};
4203
4204#endif /* CONFIG_PROC_FS */