#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
+#include <linux/fs.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/mman.h>
*/
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 *);
{
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)++;
+ /*fallthrough*/
+ 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,
};
#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)
.release = seq_release,
};
+#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;
if (wall_to_monotonic.tv_nsec)
--jif;
- for_each_cpu(i) {
+ for_each_possible_cpu(i) {
int j;
user = cputime64_add(user, kstat_cpu(i).cpustat.user);
}
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
.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
*/
#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},
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);