]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - fs/proc/proc_misc.c
mm: show quicklist usage in /proc/meminfo
[linux-2.6.git] / fs / proc / proc_misc.c
index 51288db37a0cf2e25ed2037b3e5161f6bc52a49e..00f10a2dcf1239d0b72b48a62d8265a0a59b3d78 100644 (file)
 #include <linux/tty.h>
 #include <linux/string.h>
 #include <linux/mman.h>
+#include <linux/quicklist.h>
 #include <linux/proc_fs.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/pagemap.h>
+#include <linux/interrupt.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
+#include <linux/genhd.h>
 #include <linux/smp.h>
 #include <linux/signal.h>
 #include <linux/module.h>
@@ -64,7 +67,6 @@
  */
 extern int get_hardware_list(char *);
 extern int get_stram_list(char *);
-extern int get_filesystem_list(char *);
 extern int get_exec_domain_list(char *);
 extern int get_dma_list(char *);
 
@@ -84,10 +86,15 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
 {
        int a, b, c;
        int len;
+       unsigned long seq;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               a = avenrun[0] + (FIXED_1/200);
+               b = avenrun[1] + (FIXED_1/200);
+               c = avenrun[2] + (FIXED_1/200);
+       } while (read_seqretry(&xtime_lock, seq));
 
-       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),
@@ -117,6 +124,11 @@ static int uptime_read_proc(char *page, char **start, off_t off,
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
+int __attribute__((weak)) arch_report_meminfo(char *page)
+{
+       return 0;
+}
+
 static int meminfo_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
 {
@@ -133,7 +145,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
 #define K(x) ((x) << (PAGE_SHIFT - 10))
        si_meminfo(&i);
        si_swapinfo(&i);
-       committed = atomic_read(&vm_committed_space);
+       committed = atomic_long_read(&vm_committed_space);
        allowed = ((totalram_pages - hugetlb_total_pages())
                * sysctl_overcommit_ratio / 100) + total_swap_pages;
 
@@ -173,11 +185,13 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                "PageTables:   %8lu kB\n"
                "NFS_Unstable: %8lu kB\n"
                "Bounce:       %8lu kB\n"
+               "WritebackTmp: %8lu kB\n"
                "CommitLimit:  %8lu kB\n"
                "Committed_AS: %8lu kB\n"
                "VmallocTotal: %8lu kB\n"
                "VmallocUsed:  %8lu kB\n"
-               "VmallocChunk: %8lu kB\n",
+               "VmallocChunk: %8lu kB\n"
+               "Quicklists:   %8lu kB\n",
                K(i.totalram),
                K(i.freeram),
                K(i.bufferram),
@@ -204,20 +218,23 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                K(global_page_state(NR_PAGETABLE)),
                K(global_page_state(NR_UNSTABLE_NFS)),
                K(global_page_state(NR_BOUNCE)),
+               K(global_page_state(NR_WRITEBACK_TEMP)),
                K(allowed),
                K(committed),
                (unsigned long)VMALLOC_TOTAL >> 10,
                vmi.used >> 10,
-               vmi.largest_chunk >> 10
+               vmi.largest_chunk >> 10,
+               K(quicklist_total_size())
                );
 
                len += hugetlb_report_meminfo(page + len);
 
+       len += arch_report_meminfo(page + len);
+
        return proc_calc_metrics(page, start, off, count, eof, len);
 #undef K
 }
 
-extern struct seq_operations fragmentation_op;
 static int fragmentation_open(struct inode *inode, struct file *file)
 {
        (void)inode;
@@ -231,7 +248,6 @@ static const struct file_operations fragmentation_file_operations = {
        .release        = seq_release,
 };
 
-extern struct seq_operations pagetypeinfo_op;
 static int pagetypeinfo_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &pagetypeinfo_op);
@@ -244,7 +260,6 @@ static const struct file_operations pagetypeinfo_file_ops = {
        .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);
@@ -269,7 +284,7 @@ static int version_read_proc(char *page, char **start, off_t off,
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-extern struct seq_operations cpuinfo_op;
+extern const struct seq_operations cpuinfo_op;
 static int cpuinfo_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &cpuinfo_op);
@@ -322,7 +337,7 @@ static void devinfo_stop(struct seq_file *f, void *v)
        /* Nothing to do */
 }
 
-static struct seq_operations devinfo_ops = {
+static const struct seq_operations devinfo_ops = {
        .start = devinfo_start,
        .next  = devinfo_next,
        .stop  = devinfo_stop,
@@ -341,7 +356,6 @@ static const struct file_operations proc_devinfo_operations = {
        .release        = seq_release,
 };
 
-extern struct seq_operations vmstat_op;
 static int vmstat_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &vmstat_op);
@@ -372,7 +386,6 @@ static int stram_read_proc(char *page, char **start, off_t off,
 #endif
 
 #ifdef CONFIG_BLOCK
-extern struct seq_operations partitions_op;
 static int partitions_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &partitions_op);
@@ -384,7 +397,6 @@ static const struct file_operations proc_partitions_operations = {
        .release        = seq_release,
 };
 
-extern struct seq_operations diskstats_op;
 static int diskstats_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &diskstats_op);
@@ -398,7 +410,7 @@ static const struct file_operations proc_diskstats_operations = {
 #endif
 
 #ifdef CONFIG_MODULES
-extern struct seq_operations modules_op;
+extern const struct seq_operations modules_op;
 static int modules_open(struct inode *inode, struct file *file)
 {
        return seq_open(file, &modules_op);
@@ -425,7 +437,7 @@ static const struct file_operations proc_slabinfo_operations = {
 };
 
 #ifdef CONFIG_DEBUG_SLAB_LEAK
-extern struct seq_operations slabstats_op;
+extern const struct seq_operations slabstats_op;
 static int slabstats_open(struct inode *inode, struct file *file)
 {
        unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
@@ -452,6 +464,38 @@ static const struct file_operations proc_slabstats_operations = {
 #endif
 #endif
 
+#ifdef CONFIG_MMU
+static int vmalloc_open(struct inode *inode, struct file *file)
+{
+       unsigned int *ptr = NULL;
+       int ret;
+
+       if (NUMA_BUILD)
+               ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
+       ret = seq_open(file, &vmalloc_op);
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               m->private = ptr;
+       } else
+               kfree(ptr);
+       return ret;
+}
+
+static const struct file_operations proc_vmalloc_operations = {
+       .open           = vmalloc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release_private,
+};
+#endif
+
+#ifndef arch_irq_stat_cpu
+#define arch_irq_stat_cpu(cpu) 0
+#endif
+#ifndef arch_irq_stat
+#define arch_irq_stat() 0
+#endif
+
 static int show_stat(struct seq_file *p, void *v)
 {
        int i;
@@ -489,7 +533,9 @@ static int show_stat(struct seq_file *p, void *v)
                        sum += temp;
                        per_irq_sum[j] += temp;
                }
+               sum += arch_irq_stat_cpu(i);
        }
+       sum += arch_irq_stat();
 
        seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
                (unsigned long long)cputime64_to_clock_t(user),
@@ -599,8 +645,7 @@ static void int_seq_stop(struct seq_file *f, void *v)
 }
 
 
-extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */
-static struct seq_operations int_seq_ops = {
+static const struct seq_operations int_seq_ops = {
        .start = int_seq_start,
        .next  = int_seq_next,
        .stop  = int_seq_stop,
@@ -697,7 +742,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
        pfn = src / KPMSIZE;
        count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
        if (src & KPMMASK || count & KPMMASK)
-               return -EIO;
+               return -EINVAL;
 
        while (count > 0) {
                ppage = NULL;
@@ -707,7 +752,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
                if (!ppage)
                        pcount = 0;
                else
-                       pcount = atomic_read(&ppage->_count);
+                       pcount = page_mapcount(ppage);
 
                if (put_user(pcount, out++)) {
                        ret = -EFAULT;
@@ -763,7 +808,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
        pfn = src / KPMSIZE;
        count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
        if (src & KPMMASK || count & KPMMASK)
-               return -EIO;
+               return -EINVAL;
 
        while (count > 0) {
                ppage = NULL;
@@ -809,14 +854,6 @@ static struct file_operations proc_kpageflags_operations = {
 
 struct proc_dir_entry *proc_root_kcore;
 
-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);
-       if (entry)
-               entry->proc_fops = f;
-}
-
 void __init proc_misc_init(void)
 {
        static struct {
@@ -845,63 +882,52 @@ void __init proc_misc_init(void)
 
        /* And now for trickier ones */
 #ifdef CONFIG_PRINTK
-       {
-               struct proc_dir_entry *entry;
-               entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
-               if (entry)
-                       entry->proc_fops = &proc_kmsg_operations;
-       }
+       proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
 #endif
-       create_seq_entry("locks", 0, &proc_locks_operations);
-       create_seq_entry("devices", 0, &proc_devinfo_operations);
-       create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
+       proc_create("locks", 0, NULL, &proc_locks_operations);
+       proc_create("devices", 0, NULL, &proc_devinfo_operations);
+       proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
 #ifdef CONFIG_BLOCK
-       create_seq_entry("partitions", 0, &proc_partitions_operations);
+       proc_create("partitions", 0, NULL, &proc_partitions_operations);
 #endif
-       create_seq_entry("stat", 0, &proc_stat_operations);
-       create_seq_entry("interrupts", 0, &proc_interrupts_operations);
+       proc_create("stat", 0, NULL, &proc_stat_operations);
+       proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
 #ifdef CONFIG_SLABINFO
-       create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
+       proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
 #ifdef CONFIG_DEBUG_SLAB_LEAK
-       create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
+       proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
 #endif
 #endif
-       create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
-       create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops);
-       create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
-       create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
+#ifdef CONFIG_MMU
+       proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
+#endif
+       proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
+       proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
+       proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
+       proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
 #ifdef CONFIG_BLOCK
-       create_seq_entry("diskstats", 0, &proc_diskstats_operations);
+       proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
 #endif
 #ifdef CONFIG_MODULES
-       create_seq_entry("modules", 0, &proc_modules_operations);
+       proc_create("modules", 0, NULL, &proc_modules_operations);
 #endif
 #ifdef CONFIG_SCHEDSTATS
-       create_seq_entry("schedstat", 0, &proc_schedstat_operations);
+       proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
 #endif
 #ifdef CONFIG_PROC_KCORE
-       proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
-       if (proc_root_kcore) {
-               proc_root_kcore->proc_fops = &proc_kcore_operations;
+       proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
+       if (proc_root_kcore)
                proc_root_kcore->size =
                                (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
-       }
 #endif
 #ifdef CONFIG_PROC_PAGE_MONITOR
-       create_seq_entry("kpagecount", S_IRUSR, &proc_kpagecount_operations);
-       create_seq_entry("kpageflags", S_IRUSR, &proc_kpageflags_operations);
+       proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
+       proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
 #endif
 #ifdef CONFIG_PROC_VMCORE
-       proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL);
-       if (proc_vmcore)
-               proc_vmcore->proc_fops = &proc_vmcore_operations;
+       proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
-       {
-               struct proc_dir_entry *entry;
-               entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
-               if (entry)
-                       entry->proc_fops = &proc_sysrq_trigger_operations;
-       }
+       proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
 #endif
 }