X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fproc%2Fproc_misc.c;h=16271a10a549236a036e42540d1f82ce8d2a01a3;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=d94d5960b8aa84b82f679f8ce80350fc9c789f68;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index d94d5960b..16271a10a 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -44,14 +45,15 @@ #include #include #include -#include -#include - +#include #include #include #include #include #include +#include "internal.h" + +#include #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -63,8 +65,6 @@ */ extern int get_hardware_list(char *); extern int get_stram_list(char *); -extern int get_chrdev_list(char *); -extern int get_blkdev_list(char *); extern int get_filesystem_list(char *); extern int get_exec_domain_list(char *); extern int get_dma_list(char *); @@ -84,53 +84,33 @@ static int proc_calc_metrics(char *page, char **start, off_t off, static int loadavg_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + unsigned int running, threads; int a, b, c; int len; - a = avenrun[0] + (FIXED_1/200); - b = avenrun[1] + (FIXED_1/200); - c = avenrun[2] + (FIXED_1/200); - len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", - LOAD_INT(a), LOAD_FRAC(a), - LOAD_INT(b), LOAD_FRAC(b), - LOAD_INT(c), LOAD_FRAC(c), - nr_running(), nr_threads, last_pid); - return proc_calc_metrics(page, start, off, count, eof, len); -} - -struct vmalloc_info { - unsigned long used; - unsigned long largest_chunk; -}; - -static struct vmalloc_info get_vmalloc_info(void) -{ - unsigned long prev_end = VMALLOC_START; - struct vm_struct* vma; - struct vmalloc_info vmi; - vmi.used = 0; + if (vx_flags(VXF_VIRT_LOAD, 0)) { + struct vx_info *vxi = current->vx_info; - read_lock(&vmlist_lock); + a = vxi->cvirt.load[0] + (FIXED_1/200); + b = vxi->cvirt.load[1] + (FIXED_1/200); + c = vxi->cvirt.load[2] + (FIXED_1/200); - if(!vmlist) - vmi.largest_chunk = (VMALLOC_END-VMALLOC_START); - else - vmi.largest_chunk = 0; + running = atomic_read(&vxi->cvirt.nr_running); + threads = atomic_read(&vxi->cvirt.nr_threads); + } else { + a = avenrun[0] + (FIXED_1/200); + b = avenrun[1] + (FIXED_1/200); + c = avenrun[2] + (FIXED_1/200); - for (vma = vmlist; vma; vma = vma->next) { - unsigned long free_area_size = - (unsigned long)vma->addr - prev_end; - vmi.used += vma->size; - if (vmi.largest_chunk < free_area_size ) - - vmi.largest_chunk = free_area_size; - prev_end = vma->size + (unsigned long)vma->addr; + running = nr_running(); + threads = nr_threads; } - if(VMALLOC_END-prev_end > vmi.largest_chunk) - vmi.largest_chunk = VMALLOC_END-prev_end; - - read_unlock(&vmlist_lock); - return vmi; + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n", + LOAD_INT(a), LOAD_FRAC(a), + LOAD_INT(b), LOAD_FRAC(b), + LOAD_INT(c), LOAD_FRAC(c), + running, threads, last_pid); + return proc_calc_metrics(page, start, off, count, eof, len); } static int uptime_read_proc(char *page, char **start, off_t off, @@ -139,10 +119,10 @@ static int uptime_read_proc(char *page, char **start, off_t off, struct timespec uptime; struct timespec idle; int len; - u64 idle_jiffies = init_task.utime + init_task.stime; + cputime_t idletime = cputime_add(init_task.utime, init_task.stime); do_posix_clock_monotonic_gettime(&uptime); - jiffies_to_timespec(idle_jiffies, &idle); + cputime_to_timespec(idletime, &idle); if (vx_flags(VXF_VIRT_UPTIME, 0)) vx_vsi_uptime(&uptime, &idle); @@ -159,13 +139,15 @@ static int meminfo_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct sysinfo i; - int len, committed; + int len; struct page_state ps; unsigned long inactive; unsigned long active; unsigned long free; - unsigned long vmtot; + unsigned long committed; + unsigned long allowed; struct vmalloc_info vmi; + long cached; get_page_state(&ps); get_zone_counts(&active, &inactive, &free); @@ -177,11 +159,14 @@ static int meminfo_read_proc(char *page, char **start, off_t off, si_meminfo(&i); si_swapinfo(&i); committed = atomic_read(&vm_committed_space); + allowed = ((totalram_pages - hugetlb_total_pages()) + * sysctl_overcommit_ratio / 100) + total_swap_pages; - vmtot = (VMALLOC_END-VMALLOC_START)>>10; - vmi = get_vmalloc_info(); - vmi.used >>= 10; - vmi.largest_chunk >>= 10; + cached = get_page_cache_size() - total_swapcache_pages - i.bufferram; + if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0)) + cached = 0; + + get_vmalloc_info(&vmi); /* * Tagged format, for easy grepping and expansion. @@ -204,7 +189,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off, "Writeback: %8lu kB\n" "Mapped: %8lu kB\n" "Slab: %8lu kB\n" - "Committed_AS: %8u kB\n" + "CommitLimit: %8lu kB\n" + "Committed_AS: %8lu kB\n" "PageTables: %8lu kB\n" "VmallocTotal: %8lu kB\n" "VmallocUsed: %8lu kB\n" @@ -212,7 +198,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off, K(i.totalram), K(i.freeram), K(i.bufferram), - K(get_page_cache_size()-total_swapcache_pages-i.bufferram), + K(cached), K(total_swapcache_pages), K(active), K(inactive), @@ -226,11 +212,12 @@ static int meminfo_read_proc(char *page, char **start, off_t off, K(ps.nr_writeback), K(ps.nr_mapped), K(ps.nr_slab), + K(allowed), K(committed), K(ps.nr_page_table_pages), - vmtot, - vmi.used, - vmi.largest_chunk + (unsigned long)VMALLOC_TOTAL >> 10, + vmi.used >> 10, + vmi.largest_chunk >> 10 ); len += hugetlb_report_meminfo(page + len); @@ -253,14 +240,27 @@ static struct file_operations fragmentation_file_operations = { .release = seq_release, }; +extern struct seq_operations zoneinfo_op; +static int zoneinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &zoneinfo_op); +} + +static struct file_operations proc_zoneinfo_file_operations = { + .open = zoneinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static int version_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - extern char *linux_banner; int len; - strcpy(page, linux_banner); - len = strlen(page); + len = sprintf(page, vx_linux_banner, + vx_new_uts(release), + vx_new_uts(version)); return proc_calc_metrics(page, start, off, count, eof, len); } @@ -269,6 +269,7 @@ static int cpuinfo_open(struct inode *inode, struct file *file) { return seq_open(file, &cpuinfo_op); } + static struct file_operations proc_cpuinfo_operations = { .open = cpuinfo_open, .read = seq_read, @@ -276,6 +277,62 @@ static struct file_operations proc_cpuinfo_operations = { .release = seq_release, }; +static int devinfo_show(struct seq_file *f, void *v) +{ + int i = *(loff_t *) v; + + if (i < CHRDEV_MAJOR_HASH_SIZE) { + if (i == 0) + seq_printf(f, "Character devices:\n"); + chrdev_show(f, i); + } else { + i -= CHRDEV_MAJOR_HASH_SIZE; + if (i == 0) + seq_printf(f, "\nBlock devices:\n"); + blkdev_show(f, i); + } + return 0; +} + +static void *devinfo_start(struct seq_file *f, loff_t *pos) +{ + if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + return pos; + return NULL; +} + +static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) +{ + (*pos)++; + if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) + return NULL; + return pos; +} + +static void devinfo_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + +static struct seq_operations devinfo_ops = { + .start = devinfo_start, + .next = devinfo_next, + .stop = devinfo_stop, + .show = devinfo_show +}; + +static int devinfo_open(struct inode *inode, struct file *filp) +{ + return seq_open(filp, &devinfo_ops); +} + +static struct file_operations proc_devinfo_operations = { + .open = devinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + extern struct seq_operations vmstat_op; static int vmstat_open(struct inode *inode, struct file *file) { @@ -344,6 +401,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) @@ -358,40 +416,78 @@ static struct file_operations proc_slabinfo_operations = { .release = seq_release, }; -int show_stat(struct seq_file *p, void *v) +#ifdef CONFIG_DEBUG_SLAB_LEAK +extern struct seq_operations slabstats_op; +static int slabstats_open(struct inode *inode, struct file *file) +{ + unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL); + int ret = -ENOMEM; + if (n) { + ret = seq_open(file, &slabstats_op); + if (!ret) { + struct seq_file *m = file->private_data; + *n = PAGE_SIZE / (2 * sizeof(unsigned long)); + m->private = n; + n = NULL; + } + kfree(n); + } + return ret; +} + +static int slabstats_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + kfree(m->private); + return seq_release(inode, file); +} + +static struct file_operations proc_slabstats_operations = { + .open = slabstats_open, + .read = seq_read, + .llseek = seq_lseek, + .release = slabstats_release, +}; +#endif +#endif + +static int show_stat(struct seq_file *p, void *v) { int i; - extern unsigned long total_forks; unsigned long jif; - u64 sum = 0, user = 0, nice = 0, system = 0, - idle = 0, iowait = 0, irq = 0, softirq = 0; + cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; + u64 sum = 0; + user = nice = system = idle = iowait = + irq = softirq = steal = cputime64_zero; jif = - wall_to_monotonic.tv_sec; if (wall_to_monotonic.tv_nsec) --jif; - for_each_cpu(i) { + for_each_possible_cpu(i) { int j; - user += kstat_cpu(i).cpustat.user; - nice += kstat_cpu(i).cpustat.nice; - system += kstat_cpu(i).cpustat.system; - idle += kstat_cpu(i).cpustat.idle; - iowait += kstat_cpu(i).cpustat.iowait; - irq += kstat_cpu(i).cpustat.irq; - softirq += kstat_cpu(i).cpustat.softirq; + user = cputime64_add(user, kstat_cpu(i).cpustat.user); + nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice); + system = cputime64_add(system, kstat_cpu(i).cpustat.system); + idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle); + iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait); + irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq); + softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); + steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); for (j = 0 ; j < NR_IRQS ; j++) sum += kstat_cpu(i).irqs[j]; } - seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu\n", - (unsigned long long)jiffies_64_to_clock_t(user), - (unsigned long long)jiffies_64_to_clock_t(nice), - (unsigned long long)jiffies_64_to_clock_t(system), - (unsigned long long)jiffies_64_to_clock_t(idle), - (unsigned long long)jiffies_64_to_clock_t(iowait), - (unsigned long long)jiffies_64_to_clock_t(irq), - (unsigned long long)jiffies_64_to_clock_t(softirq)); + seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu\n", + (unsigned long long)cputime64_to_clock_t(user), + (unsigned long long)cputime64_to_clock_t(nice), + (unsigned long long)cputime64_to_clock_t(system), + (unsigned long long)cputime64_to_clock_t(idle), + (unsigned long long)cputime64_to_clock_t(iowait), + (unsigned long long)cputime64_to_clock_t(irq), + (unsigned long long)cputime64_to_clock_t(softirq), + (unsigned long long)cputime64_to_clock_t(steal)); for_each_online_cpu(i) { /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ @@ -402,19 +498,21 @@ int show_stat(struct seq_file *p, void *v) iowait = kstat_cpu(i).cpustat.iowait; irq = kstat_cpu(i).cpustat.irq; softirq = kstat_cpu(i).cpustat.softirq; - seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu\n", + steal = kstat_cpu(i).cpustat.steal; + seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n", i, - (unsigned long long)jiffies_64_to_clock_t(user), - (unsigned long long)jiffies_64_to_clock_t(nice), - (unsigned long long)jiffies_64_to_clock_t(system), - (unsigned long long)jiffies_64_to_clock_t(idle), - (unsigned long long)jiffies_64_to_clock_t(iowait), - (unsigned long long)jiffies_64_to_clock_t(irq), - (unsigned long long)jiffies_64_to_clock_t(softirq)); + (unsigned long long)cputime64_to_clock_t(user), + (unsigned long long)cputime64_to_clock_t(nice), + (unsigned long long)cputime64_to_clock_t(system), + (unsigned long long)cputime64_to_clock_t(idle), + (unsigned long long)cputime64_to_clock_t(iowait), + (unsigned long long)cputime64_to_clock_t(irq), + (unsigned long long)cputime64_to_clock_t(softirq), + (unsigned long long)cputime64_to_clock_t(steal)); } seq_printf(p, "intr %llu", (unsigned long long)sum); -#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) +#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) for (i = 0; i < NR_IRQS; i++) seq_printf(p, " %u", kstat_irqs(i)); #endif @@ -464,14 +562,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); - return proc_calc_metrics(page, start, off, count, eof, len); -} - /* * /proc/interrupts */ @@ -502,7 +592,7 @@ static struct seq_operations int_seq_ops = { .show = show_interrupts }; -int interrupts_open(struct inode *inode, struct file *filp) +static int interrupts_open(struct inode *inode, struct file *filp) { return seq_open(filp, &int_seq_ops); } @@ -547,70 +637,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off, return proc_calc_metrics(page, start, off, count, eof, len); } -/* - * This function accesses profiling information. The returned data is - * binary: the sampling step and the actual contents of the profile - * buffer. Use of the program readprofile is recommended in order to - * get meaningful info out of these data. - */ -static ssize_t -read_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - unsigned long p = *ppos; - ssize_t read; - char * pnt; - unsigned int sample_step = 1 << prof_shift; - - if (p >= (prof_len+1)*sizeof(unsigned int)) - return 0; - if (count > (prof_len+1)*sizeof(unsigned int) - p) - count = (prof_len+1)*sizeof(unsigned int) - p; - read = 0; - - while (p < sizeof(unsigned int) && count > 0) { - put_user(*((char *)(&sample_step)+p),buf); - buf++; p++; count--; read++; - } - pnt = (char *)prof_buffer + p - sizeof(unsigned int); - if (copy_to_user(buf,(void *)pnt,count)) - return -EFAULT; - read += count; - *ppos += read; - return read; -} - -/* - * Writing to /proc/profile resets the counters - * - * Writing a 'profiling multiplier' value into it also re-sets the profiling - * interrupt frequency, on architectures that support this. - */ -static ssize_t write_profile(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ -#ifdef CONFIG_SMP - extern int setup_profiling_timer (unsigned int multiplier); - - if (count == sizeof(int)) { - unsigned int multiplier; - - if (copy_from_user(&multiplier, buf, sizeof(int))) - return -EFAULT; - - if (setup_profiling_timer(multiplier)) - return -EINVAL; - } -#endif - - memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer)); - return count; -} - -static struct file_operations proc_profile_operations = { - .read = read_profile, - .write = write_profile, -}; - #ifdef CONFIG_MAGIC_SYSRQ /* * writing 'C' to /proc/sysrq-trigger is like sysrq-C @@ -623,7 +649,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, if (get_user(c, buf)) return -EFAULT; - __handle_sysrq(c, NULL, NULL); + __handle_sysrq(c, NULL, NULL, 0); } return count; } @@ -635,7 +661,7 @@ static struct file_operations proc_sysrq_trigger_operations = { struct proc_dir_entry *proc_root_kcore; -static void create_seq_entry(char *name, mode_t mode, struct file_operations *f) +void create_seq_entry(char *name, mode_t mode, const struct file_operations *f) { struct proc_dir_entry *entry; entry = create_proc_entry(name, mode, NULL); @@ -660,7 +686,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}, @@ -676,17 +701,27 @@ 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); create_seq_entry("interrupts", 0, &proc_interrupts_operations); +#ifdef CONFIG_SLAB create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); +#ifdef CONFIG_DEBUG_SLAB_LEAK + create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); +#endif +#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); create_seq_entry("diskstats", 0, &proc_diskstats_operations); #ifdef CONFIG_MODULES create_seq_entry("modules", 0, &proc_modules_operations); #endif +#ifdef CONFIG_SCHEDSTATS + create_seq_entry("schedstat", 0, &proc_schedstat_operations); +#endif #ifdef CONFIG_PROC_KCORE proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); if (proc_root_kcore) { @@ -695,24 +730,14 @@ void __init proc_misc_init(void) (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; } #endif - if (prof_on) { - entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL); - if (entry) { - entry->proc_fops = &proc_profile_operations; - entry->size = (1+prof_len) * sizeof(unsigned int); - } - } +#ifdef CONFIG_PROC_VMCORE + proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL); + if (proc_vmcore) + proc_vmcore->proc_fops = &proc_vmcore_operations; +#endif #ifdef CONFIG_MAGIC_SYSRQ entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); if (entry) entry->proc_fops = &proc_sysrq_trigger_operations; #endif -#ifdef CONFIG_PPC32 - { - extern struct file_operations ppc_htab_operations; - entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL); - if (entry) - entry->proc_fops = &ppc_htab_operations; - } -#endif }