From 10cef6029502915bdb3cf0821d425cf9dc30c817 Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Sun, 8 Jan 2006 01:01:45 -0800 Subject: [PATCH] slob: introduce the SLOB allocator configurable replacement for slab allocator This adds a CONFIG_SLAB option under CONFIG_EMBEDDED. When CONFIG_SLAB is disabled, the kernel falls back to using the 'SLOB' allocator. SLOB is a traditional K&R/UNIX allocator with a SLAB emulation layer, similar to the original Linux kmalloc allocator that SLAB replaced. It's signicantly smaller code and is more memory efficient. But like all similar allocators, it scales poorly and suffers from fragmentation more than SLAB, so it's only appropriate for small systems. It's been tested extensively in the Linux-tiny tree. I've also stress-tested it with make -j 8 compiles on a 3G SMP+PREEMPT box (not recommended). Here's a comparison for otherwise identical builds, showing SLOB saving nearly half a megabyte of RAM: $ size vmlinux* text data bss dec hex filename 3336372 529360 190812 4056544 3de5e0 vmlinux-slab 3323208 527948 190684 4041840 3dac70 vmlinux-slob $ size mm/{slab,slob}.o text data bss dec hex filename 13221 752 48 14021 36c5 mm/slab.o 1896 52 8 1956 7a4 mm/slob.o /proc/meminfo: SLAB SLOB delta MemTotal: 27964 kB 27980 kB +16 kB MemFree: 24596 kB 25092 kB +496 kB Buffers: 36 kB 36 kB 0 kB Cached: 1188 kB 1188 kB 0 kB SwapCached: 0 kB 0 kB 0 kB Active: 608 kB 600 kB -8 kB Inactive: 808 kB 812 kB +4 kB HighTotal: 0 kB 0 kB 0 kB HighFree: 0 kB 0 kB 0 kB LowTotal: 27964 kB 27980 kB +16 kB LowFree: 24596 kB 25092 kB +496 kB SwapTotal: 0 kB 0 kB 0 kB SwapFree: 0 kB 0 kB 0 kB Dirty: 4 kB 12 kB +8 kB Writeback: 0 kB 0 kB 0 kB Mapped: 560 kB 556 kB -4 kB Slab: 1756 kB 0 kB -1756 kB CommitLimit: 13980 kB 13988 kB +8 kB Committed_AS: 4208 kB 4208 kB 0 kB PageTables: 28 kB 28 kB 0 kB VmallocTotal: 1007312 kB 1007312 kB 0 kB VmallocUsed: 48 kB 48 kB 0 kB VmallocChunk: 1007264 kB 1007264 kB 0 kB (this work has been sponsored in part by CELF) From: Ingo Molnar Fix 32-bitness bugs in mm/slob.c. Signed-off-by: Matt Mackall Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/proc_misc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/proc/proc_misc.c') diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 5b6b0b6038a7..63bf6c00fa0c 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -323,6 +323,7 @@ static struct file_operations proc_modules_operations = { }; #endif +#ifdef CONFIG_SLAB extern struct seq_operations slabinfo_op; extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); static int slabinfo_open(struct inode *inode, struct file *file) @@ -336,6 +337,7 @@ static struct file_operations proc_slabinfo_operations = { .llseek = seq_lseek, .release = seq_release, }; +#endif static int show_stat(struct seq_file *p, void *v) { @@ -600,7 +602,9 @@ void __init proc_misc_init(void) create_seq_entry("partitions", 0, &proc_partitions_operations); create_seq_entry("stat", 0, &proc_stat_operations); create_seq_entry("interrupts", 0, &proc_interrupts_operations); +#ifdef CONFIG_SLAB create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); +#endif create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); -- cgit From 7170be5f586b59bdcdab082778a5d9203ba7b667 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Sat, 14 Jan 2006 13:20:38 -0800 Subject: [PATCH] convert /proc/devices to use seq_file interface A Christoph suggested that the /proc/devices file be converted to use the seq_file interface. This patch does that. I've obxerved one or two installation that had sufficiently large sans that they overran the 4k limit on /proc/devices. Signed-off-by: Neil Horman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/proc_misc.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 150 insertions(+), 10 deletions(-) (limited to 'fs/proc/proc_misc.c') diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 63bf6c00fa0c..8f8014285a34 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,6 @@ */ extern int get_hardware_list(char *); extern int get_stram_list(char *); -extern int get_chrdev_list(char *); extern int get_filesystem_list(char *); extern int get_exec_domain_list(char *); extern int get_dma_list(char *); @@ -248,6 +248,154 @@ static int cpuinfo_open(struct inode *inode, struct file *file) { return seq_open(file, &cpuinfo_op); } + +enum devinfo_states { + CHR_HDR, + CHR_LIST, + BLK_HDR, + BLK_LIST, + DEVINFO_DONE +}; + +struct devinfo_state { + void *chrdev; + void *blkdev; + unsigned int num_records; + unsigned int cur_record; + enum devinfo_states state; +}; + +static void *devinfo_start(struct seq_file *f, loff_t *pos) +{ + struct devinfo_state *info = f->private; + + if (*pos) { + if ((info) && (*pos <= info->num_records)) + return info; + return NULL; + } + info = kmalloc(sizeof(*info), GFP_KERNEL); + f->private = info; + info->chrdev = acquire_chrdev_list(); + info->blkdev = acquire_blkdev_list(); + info->state = CHR_HDR; + info->num_records = count_chrdev_list(); + info->num_records += count_blkdev_list(); + info->num_records += 2; /* Character and Block headers */ + *pos = 1; + info->cur_record = *pos; + return info; +} + +static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) +{ + int idummy; + char *ndummy; + struct devinfo_state *info = f->private; + + switch (info->state) { + case CHR_HDR: + info->state = CHR_LIST; + (*pos)++; + /*fallthrough*/ + case CHR_LIST: + if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) { + /* + * The character dev list is complete + */ + info->state = BLK_HDR; + } else { + info->chrdev = get_next_chrdev(info->chrdev); + } + (*pos)++; + break; + case BLK_HDR: + info->state = BLK_LIST; + (*pos)++; + break; + case BLK_LIST: + if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) { + /* + * The block dev list is complete + */ + info->state = DEVINFO_DONE; + } else { + info->blkdev = get_next_blkdev(info->blkdev); + } + (*pos)++; + break; + case DEVINFO_DONE: + (*pos)++; + info->cur_record = *pos; + info = NULL; + break; + default: + break; + } + if (info) + info->cur_record = *pos; + return info; +} + +static void devinfo_stop(struct seq_file *f, void *v) +{ + struct devinfo_state *info = f->private; + + if (info) { + release_chrdev_list(info->chrdev); + release_blkdev_list(info->blkdev); + f->private = NULL; + kfree(info); + } +} + +static int devinfo_show(struct seq_file *f, void *arg) +{ + int major; + char *name; + struct devinfo_state *info = f->private; + + switch(info->state) { + case CHR_HDR: + seq_printf(f,"Character devices:\n"); + /* fallthrough */ + case CHR_LIST: + if (!get_chrdev_info(info->chrdev,&major,&name)) + seq_printf(f,"%3d %s\n",major,name); + break; + case BLK_HDR: + seq_printf(f,"\nBlock devices:\n"); + /* fallthrough */ + case BLK_LIST: + if (!get_blkdev_info(info->blkdev,&major,&name)) + seq_printf(f,"%3d %s\n",major,name); + break; + default: + break; + } + + return 0; +} + +static struct seq_operations devinfo_op = { + .start = devinfo_start, + .next = devinfo_next, + .stop = devinfo_stop, + .show = devinfo_show, +}; + +static int devinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &devinfo_op); +} + +static struct file_operations proc_devinfo_operations = { + .open = devinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static struct file_operations proc_cpuinfo_operations = { .open = cpuinfo_open, .read = seq_read, @@ -450,14 +598,6 @@ static struct file_operations proc_stat_operations = { .release = single_release, }; -static int devices_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = get_chrdev_list(page); - len += get_blkdev_list(page+len, len); - return proc_calc_metrics(page, start, off, count, eof, len); -} - /* * /proc/interrupts */ @@ -582,7 +722,6 @@ void __init proc_misc_init(void) #ifdef CONFIG_STRAM_PROC {"stram", stram_read_proc}, #endif - {"devices", devices_read_proc}, {"filesystems", filesystems_read_proc}, {"cmdline", cmdline_read_proc}, {"locks", locks_read_proc}, @@ -598,6 +737,7 @@ void __init proc_misc_init(void) entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); if (entry) entry->proc_fops = &proc_kmsg_operations; + create_seq_entry("devices", 0, &proc_devinfo_operations); create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); create_seq_entry("partitions", 0, &proc_partitions_operations); create_seq_entry("stat", 0, &proc_stat_operations); -- cgit