diff options
-rw-r--r-- | arch/x86/kernel/head_32.S | 2 | ||||
-rw-r--r-- | drivers/leds/led-class.c | 8 | ||||
-rw-r--r-- | drivers/leds/led-core.c | 4 | ||||
-rw-r--r-- | drivers/leds/led-triggers.c | 8 | ||||
-rw-r--r-- | drivers/leds/leds-locomo.c | 2 | ||||
-rw-r--r-- | drivers/leds/leds.h | 3 | ||||
-rw-r--r-- | include/asm-x86/byteorder.h | 4 | ||||
-rw-r--r-- | include/asm-x86/msr.h | 74 | ||||
-rw-r--r-- | include/linux/slub_def.h | 2 | ||||
-rw-r--r-- | mm/slub.c | 105 |
10 files changed, 149 insertions, 63 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index ac0637a6d71..fbad51fce67 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -196,7 +196,7 @@ default_entry: /* Do an early initialization of the fixmap area */ movl $(swapper_pg_dir - __PAGE_OFFSET), %edx movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax - addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ + addl $0x67, %eax /* 0x67 == _PAGE_TABLE */ movl %eax, 4092(%edx) xorl %ebx,%ebx /* This is the boot CPU (BSP) */ diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index ba8b04b03b9..64c66b3769c 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) goto err_out; /* add to the list of leds */ - write_lock(&leds_list_lock); + down_write(&leds_list_lock); list_add_tail(&led_cdev->node, &leds_list); - write_unlock(&leds_list_lock); + up_write(&leds_list_lock); #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); @@ -155,9 +155,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev) device_unregister(led_cdev->dev); - write_lock(&leds_list_lock); + down_write(&leds_list_lock); list_del(&led_cdev->node); - write_unlock(&leds_list_lock); + up_write(&leds_list_lock); } EXPORT_SYMBOL_GPL(led_classdev_unregister); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 9b015f9af35..5d1ca10524b 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -14,11 +14,11 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/spinlock.h> +#include <linux/rwsem.h> #include <linux/leds.h> #include "leds.h" -DEFINE_RWLOCK(leds_list_lock); +DECLARE_RWSEM(leds_list_lock); LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 0bdb786210b..13c9026d68a 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) up_write(&triggers_list_lock); /* Register with any LEDs that have this as a default trigger */ - read_lock(&leds_list_lock); + down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (!led_cdev->trigger && led_cdev->default_trigger && @@ -177,7 +177,7 @@ int led_trigger_register(struct led_trigger *trigger) led_trigger_set(led_cdev, trigger); up_write(&led_cdev->trigger_lock); } - read_unlock(&leds_list_lock); + up_read(&leds_list_lock); return 0; } @@ -212,14 +212,14 @@ void led_trigger_unregister(struct led_trigger *trigger) up_write(&triggers_list_lock); /* Remove anyone actively using this trigger */ - read_lock(&leds_list_lock); + down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (led_cdev->trigger == trigger) led_trigger_set(led_cdev, NULL); up_write(&led_cdev->trigger_lock); } - read_unlock(&leds_list_lock); + up_read(&leds_list_lock); } void led_trigger_unregister_simple(struct led_trigger *trigger) diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c index bfac499f325..2207335e921 100644 --- a/drivers/leds/leds-locomo.c +++ b/drivers/leds/leds-locomo.c @@ -19,7 +19,7 @@ static void locomoled_brightness_set(struct led_classdev *led_cdev, enum led_brightness value, int offset) { - struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev); + struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent); unsigned long flags; local_irq_save(flags); diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index f2f3884fe06..12b6fe93b13 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -14,6 +14,7 @@ #define __LEDS_H_INCLUDED #include <linux/device.h> +#include <linux/rwsem.h> #include <linux/leds.h> static 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, led_cdev->brightness_set(led_cdev, value); } -extern rwlock_t leds_list_lock; +extern struct rw_semaphore leds_list_lock; extern struct list_head leds_list; #ifdef CONFIG_LEDS_TRIGGERS diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h index 1f2d6d5bf20..fe2f2e5d51b 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) } v; v.u = val; #ifdef CONFIG_X86_BSWAP - asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); #else v.s.a = ___arch__swab32(v.s.a); v.s.b = ___arch__swab32(v.s.b); - asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); + __asm__("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b)); #endif return v.u; } diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index ba4b3143212..664a2fa7adc 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) #define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32) -/* wrmsr with exception handling */ -#define wrmsr_safe(msr,a,b) ({ int ret__; \ - asm volatile("2: wrmsr ; xorl %0,%0\n" \ - "1:\n\t" \ - ".section .fixup,\"ax\"\n\t" \ - "3: movl %4,%0 ; jmp 1b\n\t" \ - ".previous\n\t" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n\t" \ - " .quad 2b,3b\n\t" \ - ".previous" \ - : "=a" (ret__) \ - : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ - ret__; }) - -#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) - -#define rdmsr_safe(msr,a,b) \ - ({ int ret__; \ - asm volatile ("1: rdmsr\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl %4,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 8\n" \ - " .quad 1b,3b\n" \ - ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ - :"c"(msr), "i"(-EIO), "0"(0)); \ - ret__; }) - #define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) @@ -230,17 +198,17 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") #define rdtscp(low,high,aux) \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) + __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) #define rdtscll(val) do { \ unsigned int __a,__d; \ - asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ + __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d)); \ (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) #define rdtscpll(val, aux) do { \ unsigned long __a, __d; \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ + __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ (val) = (__d << 32) | __a; \ } while (0) @@ -253,6 +221,7 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) : "=a" (low), "=d" (high) \ : "c" (counter)) + static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -320,6 +289,40 @@ static inline unsigned int cpuid_edx(unsigned int op) return edx; } +#ifdef __KERNEL__ + +/* wrmsr with exception handling */ +#define wrmsr_safe(msr,a,b) ({ int ret__; \ + asm volatile("2: wrmsr ; xorl %0,%0\n" \ + "1:\n\t" \ + ".section .fixup,\"ax\"\n\t" \ + "3: movl %4,%0 ; jmp 1b\n\t" \ + ".previous\n\t" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n\t" \ + " .quad 2b,3b\n\t" \ + ".previous" \ + : "=a" (ret__) \ + : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT)); \ + ret__; }) + +#define checking_wrmsrl(msr,val) wrmsr_safe(msr,(u32)(val),(u32)((val)>>32)) + +#define rdmsr_safe(msr,a,b) \ + ({ int ret__; \ + asm volatile ("1: rdmsr\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %4,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 8\n" \ + " .quad 1b,3b\n" \ + ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b)) \ + :"c"(msr), "i"(-EIO), "0"(0)); \ + ret__; }) + #ifdef CONFIG_SMP void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); void 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) return wrmsr_safe(msr_no, l, h); } #endif /* CONFIG_SMP */ +#endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* !__i386__ */ diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 40801e754af..b7d9408a00f 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) } #endif +extern const struct seq_operations slabinfo_op; + #endif /* _LINUX_SLUB_DEF_H */ diff --git a/mm/slub.c b/mm/slub.c index 3655ad359f0..903dabd92da 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3076,6 +3076,19 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, return slab_alloc(s, gfpflags, node, caller); } +static unsigned long count_partial(struct kmem_cache_node *n) +{ + unsigned long flags; + unsigned long x = 0; + struct page *page; + + spin_lock_irqsave(&n->list_lock, flags); + list_for_each_entry(page, &n->partial, lru) + x += page->inuse; + spin_unlock_irqrestore(&n->list_lock, flags); + return x; +} + #if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) static int validate_slab(struct kmem_cache *s, struct page *page, unsigned long *map) @@ -3458,19 +3471,6 @@ static int list_locations(struct kmem_cache *s, char *buf, return n; } -static unsigned long count_partial(struct kmem_cache_node *n) -{ - unsigned long flags; - unsigned long x = 0; - struct page *page; - - spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - x += page->inuse; - spin_unlock_irqrestore(&n->list_lock, flags); - return x; -} - enum slab_stat_type { SL_FULL, SL_PARTIAL, @@ -4123,3 +4123,82 @@ static int __init slab_sysfs_init(void) __initcall(slab_sysfs_init); #endif + +/* + * The /proc/slabinfo ABI + */ +#ifdef CONFIG_PROC_FS + +static void print_slabinfo_header(struct seq_file *m) +{ + seq_puts(m, "slabinfo - version: 2.1\n"); + seq_puts(m, "# name <active_objs> <num_objs> <objsize> " + "<objperslab> <pagesperslab>"); + seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>"); + seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); + seq_putc(m, '\n'); +} + +static void *s_start(struct seq_file *m, loff_t *pos) +{ + loff_t n = *pos; + + down_read(&slub_lock); + if (!n) + print_slabinfo_header(m); + + return seq_list_start(&slab_caches, *pos); +} + +static void *s_next(struct seq_file *m, void *p, loff_t *pos) +{ + return seq_list_next(p, &slab_caches, pos); +} + +static void s_stop(struct seq_file *m, void *p) +{ + up_read(&slub_lock); +} + +static int s_show(struct seq_file *m, void *p) +{ + unsigned long nr_partials = 0; + unsigned long nr_slabs = 0; + unsigned long nr_inuse = 0; + unsigned long nr_objs; + struct kmem_cache *s; + int node; + + s = list_entry(p, struct kmem_cache, list); + + for_each_online_node(node) { + struct kmem_cache_node *n = get_node(s, node); + + if (!n) + continue; + + nr_partials += n->nr_partial; + nr_slabs += atomic_long_read(&n->nr_slabs); + nr_inuse += count_partial(n); + } + + nr_objs = nr_slabs * s->objects; + nr_inuse += (nr_slabs - nr_partials) * s->objects; + + seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, nr_inuse, + nr_objs, s->size, s->objects, (1 << s->order)); + seq_printf(m, " : tunables %4u %4u %4u", 0, 0, 0); + seq_printf(m, " : slabdata %6lu %6lu %6lu", nr_slabs, nr_slabs, + 0UL); + seq_putc(m, '\n'); + return 0; +} + +const struct seq_operations slabinfo_op = { + .start = s_start, + .next = s_next, + .stop = s_stop, + .show = s_show, +}; + +#endif /* CONFIG_PROC_FS */ |