2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* linux/fs/proc/proc_misc.c
|
|
|
|
*
|
|
|
|
* linux/fs/proc/array.c
|
|
|
|
* Copyright (C) 1992 by Linus Torvalds
|
|
|
|
* based on ideas by Darren Senn
|
|
|
|
*
|
|
|
|
* This used to be the part of array.c. See the rest of history and credits
|
|
|
|
* there. I took this into a separate file and switched the thing to generic
|
|
|
|
* proc_file_inode_operations, leaving in array.c only per-process stuff.
|
|
|
|
* Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
|
|
|
|
*
|
|
|
|
* Changes:
|
|
|
|
* Fulton Green : Encapsulated position metric calculations.
|
|
|
|
* <kernel@FultonGreen.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/time.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/kernel_stat.h>
|
2006-01-15 05:20:38 +08:00
|
|
|
#include <linux/fs.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/tty.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/mman.h>
|
|
|
|
#include <linux/proc_fs.h>
|
|
|
|
#include <linux/ioport.h>
|
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/mmzone.h>
|
|
|
|
#include <linux/pagemap.h>
|
|
|
|
#include <linux/swap.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/smp.h>
|
|
|
|
#include <linux/signal.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
#include <linux/times.h>
|
|
|
|
#include <linux/profile.h>
|
2006-12-08 18:41:14 +08:00
|
|
|
#include <linux/utsname.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/blkdev.h>
|
|
|
|
#include <linux/hugetlb.h>
|
|
|
|
#include <linux/jiffies.h>
|
|
|
|
#include <linux/sysrq.h>
|
|
|
|
#include <linux/vmalloc.h>
|
2005-06-26 05:58:21 +08:00
|
|
|
#include <linux/crash_dump.h>
|
2006-12-08 18:37:58 +08:00
|
|
|
#include <linux/pid_namespace.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <asm/uaccess.h>
|
|
|
|
#include <asm/pgtable.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
#include <asm/tlb.h>
|
|
|
|
#include <asm/div64.h>
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
#define LOAD_INT(x) ((x) >> FSHIFT)
|
|
|
|
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
|
|
|
|
/*
|
|
|
|
* Warning: stuff below (imported functions) assumes that its output will fit
|
|
|
|
* into one page. For some of those functions it may be wrong. Moreover, we
|
|
|
|
* have a way to deal with that gracefully. Right now I used straightforward
|
|
|
|
* wrappers, but this needs further analysis wrt potential overflows.
|
|
|
|
*/
|
|
|
|
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 *);
|
|
|
|
extern int get_locks_status (char *, char **, off_t, int);
|
|
|
|
|
|
|
|
static int proc_calc_metrics(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, int len)
|
|
|
|
{
|
|
|
|
if (len <= off+count) *eof = 1;
|
|
|
|
*start = page + off;
|
|
|
|
len -= off;
|
|
|
|
if (len>count) len = count;
|
|
|
|
if (len<0) len = 0;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int loadavg_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
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),
|
2006-12-08 18:38:00 +08:00
|
|
|
nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
|
2005-04-17 06:20:36 +08:00
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int uptime_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
struct timespec uptime;
|
|
|
|
struct timespec idle;
|
|
|
|
int len;
|
|
|
|
cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
|
|
|
|
|
|
|
|
do_posix_clock_monotonic_gettime(&uptime);
|
2007-07-16 14:39:42 +08:00
|
|
|
monotonic_to_bootbased(&uptime);
|
2005-04-17 06:20:36 +08:00
|
|
|
cputime_to_timespec(idletime, &idle);
|
|
|
|
len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
|
|
|
|
(unsigned long) uptime.tv_sec,
|
|
|
|
(uptime.tv_nsec / (NSEC_PER_SEC / 100)),
|
|
|
|
(unsigned long) idle.tv_sec,
|
|
|
|
(idle.tv_nsec / (NSEC_PER_SEC / 100)));
|
|
|
|
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int meminfo_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
struct sysinfo i;
|
|
|
|
int len;
|
|
|
|
unsigned long committed;
|
|
|
|
unsigned long allowed;
|
|
|
|
struct vmalloc_info vmi;
|
2005-04-17 06:24:08 +08:00
|
|
|
long cached;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* display in kilobytes.
|
|
|
|
*/
|
|
|
|
#define K(x) ((x) << (PAGE_SHIFT - 10))
|
|
|
|
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;
|
|
|
|
|
2006-06-30 16:55:35 +08:00
|
|
|
cached = global_page_state(NR_FILE_PAGES) -
|
|
|
|
total_swapcache_pages - i.bufferram;
|
2005-04-17 06:24:08 +08:00
|
|
|
if (cached < 0)
|
|
|
|
cached = 0;
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
get_vmalloc_info(&vmi);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Tagged format, for easy grepping and expansion.
|
|
|
|
*/
|
|
|
|
len = sprintf(page,
|
|
|
|
"MemTotal: %8lu kB\n"
|
|
|
|
"MemFree: %8lu kB\n"
|
|
|
|
"Buffers: %8lu kB\n"
|
|
|
|
"Cached: %8lu kB\n"
|
|
|
|
"SwapCached: %8lu kB\n"
|
|
|
|
"Active: %8lu kB\n"
|
|
|
|
"Inactive: %8lu kB\n"
|
2006-09-26 14:31:10 +08:00
|
|
|
#ifdef CONFIG_HIGHMEM
|
2005-04-17 06:20:36 +08:00
|
|
|
"HighTotal: %8lu kB\n"
|
|
|
|
"HighFree: %8lu kB\n"
|
|
|
|
"LowTotal: %8lu kB\n"
|
|
|
|
"LowFree: %8lu kB\n"
|
2006-09-26 14:31:10 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
"SwapTotal: %8lu kB\n"
|
|
|
|
"SwapFree: %8lu kB\n"
|
|
|
|
"Dirty: %8lu kB\n"
|
|
|
|
"Writeback: %8lu kB\n"
|
2006-06-30 16:55:36 +08:00
|
|
|
"AnonPages: %8lu kB\n"
|
2005-04-17 06:20:36 +08:00
|
|
|
"Mapped: %8lu kB\n"
|
|
|
|
"Slab: %8lu kB\n"
|
2006-09-26 14:31:51 +08:00
|
|
|
"SReclaimable: %8lu kB\n"
|
|
|
|
"SUnreclaim: %8lu kB\n"
|
2006-06-30 16:55:38 +08:00
|
|
|
"PageTables: %8lu kB\n"
|
2006-08-27 16:23:58 +08:00
|
|
|
"NFS_Unstable: %8lu kB\n"
|
2006-06-30 16:55:41 +08:00
|
|
|
"Bounce: %8lu kB\n"
|
2005-04-17 06:20:36 +08:00
|
|
|
"CommitLimit: %8lu kB\n"
|
|
|
|
"Committed_AS: %8lu kB\n"
|
|
|
|
"VmallocTotal: %8lu kB\n"
|
|
|
|
"VmallocUsed: %8lu kB\n"
|
|
|
|
"VmallocChunk: %8lu kB\n",
|
|
|
|
K(i.totalram),
|
|
|
|
K(i.freeram),
|
|
|
|
K(i.bufferram),
|
2005-04-17 06:24:08 +08:00
|
|
|
K(cached),
|
2005-04-17 06:20:36 +08:00
|
|
|
K(total_swapcache_pages),
|
2007-02-10 17:43:05 +08:00
|
|
|
K(global_page_state(NR_ACTIVE)),
|
|
|
|
K(global_page_state(NR_INACTIVE)),
|
2006-09-26 14:31:10 +08:00
|
|
|
#ifdef CONFIG_HIGHMEM
|
2005-04-17 06:20:36 +08:00
|
|
|
K(i.totalhigh),
|
|
|
|
K(i.freehigh),
|
|
|
|
K(i.totalram-i.totalhigh),
|
|
|
|
K(i.freeram-i.freehigh),
|
2006-09-26 14:31:10 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
K(i.totalswap),
|
|
|
|
K(i.freeswap),
|
2006-06-30 16:55:39 +08:00
|
|
|
K(global_page_state(NR_FILE_DIRTY)),
|
2006-06-30 16:55:40 +08:00
|
|
|
K(global_page_state(NR_WRITEBACK)),
|
2006-06-30 16:55:36 +08:00
|
|
|
K(global_page_state(NR_ANON_PAGES)),
|
2006-06-30 16:55:34 +08:00
|
|
|
K(global_page_state(NR_FILE_MAPPED)),
|
2006-09-26 14:31:51 +08:00
|
|
|
K(global_page_state(NR_SLAB_RECLAIMABLE) +
|
|
|
|
global_page_state(NR_SLAB_UNRECLAIMABLE)),
|
|
|
|
K(global_page_state(NR_SLAB_RECLAIMABLE)),
|
|
|
|
K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
|
2006-06-30 16:55:38 +08:00
|
|
|
K(global_page_state(NR_PAGETABLE)),
|
2006-06-30 16:55:40 +08:00
|
|
|
K(global_page_state(NR_UNSTABLE_NFS)),
|
2006-06-30 16:55:41 +08:00
|
|
|
K(global_page_state(NR_BOUNCE)),
|
2005-04-17 06:20:36 +08:00
|
|
|
K(allowed),
|
|
|
|
K(committed),
|
|
|
|
(unsigned long)VMALLOC_TOTAL >> 10,
|
|
|
|
vmi.used >> 10,
|
|
|
|
vmi.largest_chunk >> 10
|
|
|
|
);
|
|
|
|
|
|
|
|
len += hugetlb_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;
|
|
|
|
return seq_open(file, &fragmentation_op);
|
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations fragmentation_file_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = fragmentation_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
|
2005-06-22 08:14:38 +08:00
|
|
|
extern struct seq_operations zoneinfo_op;
|
|
|
|
static int zoneinfo_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &zoneinfo_op);
|
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_zoneinfo_file_operations = {
|
2005-06-22 08:14:38 +08:00
|
|
|
.open = zoneinfo_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
static int version_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
2007-01-10 21:45:28 +08:00
|
|
|
len = snprintf(page, PAGE_SIZE, linux_proc_banner,
|
2006-12-12 01:28:46 +08:00
|
|
|
utsname()->sysname,
|
|
|
|
utsname()->release,
|
|
|
|
utsname()->version);
|
2005-04-17 06:20:36 +08:00
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern struct seq_operations cpuinfo_op;
|
|
|
|
static int cpuinfo_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &cpuinfo_op);
|
|
|
|
}
|
2006-01-15 05:20:38 +08:00
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_cpuinfo_operations = {
|
2006-03-31 18:30:32 +08:00
|
|
|
.open = cpuinfo_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
2006-01-15 05:20:38 +08:00
|
|
|
};
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static int devinfo_show(struct seq_file *f, void *v)
|
2006-01-15 05:20:38 +08:00
|
|
|
{
|
2006-03-31 18:30:32 +08:00
|
|
|
int i = *(loff_t *) v;
|
|
|
|
|
|
|
|
if (i < CHRDEV_MAJOR_HASH_SIZE) {
|
|
|
|
if (i == 0)
|
|
|
|
seq_printf(f, "Character devices:\n");
|
|
|
|
chrdev_show(f, i);
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
}
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
|
|
else {
|
2006-03-31 18:30:32 +08:00
|
|
|
i -= CHRDEV_MAJOR_HASH_SIZE;
|
|
|
|
if (i == 0)
|
|
|
|
seq_printf(f, "\nBlock devices:\n");
|
|
|
|
blkdev_show(f, i);
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#endif
|
2006-03-31 18:30:32 +08:00
|
|
|
return 0;
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static void *devinfo_start(struct seq_file *f, loff_t *pos)
|
2006-01-15 05:20:38 +08:00
|
|
|
{
|
2006-03-31 18:30:32 +08:00
|
|
|
if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
|
|
|
|
return pos;
|
|
|
|
return NULL;
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
|
2006-01-15 05:20:38 +08:00
|
|
|
{
|
2006-03-31 18:30:32 +08:00
|
|
|
(*pos)++;
|
|
|
|
if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
|
|
|
|
return NULL;
|
|
|
|
return pos;
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static void devinfo_stop(struct seq_file *f, void *v)
|
2006-01-15 05:20:38 +08:00
|
|
|
{
|
2006-03-31 18:30:32 +08:00
|
|
|
/* Nothing to do */
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static struct seq_operations devinfo_ops = {
|
|
|
|
.start = devinfo_start,
|
|
|
|
.next = devinfo_next,
|
|
|
|
.stop = devinfo_stop,
|
|
|
|
.show = devinfo_show
|
2006-01-15 05:20:38 +08:00
|
|
|
};
|
|
|
|
|
2006-03-31 18:30:32 +08:00
|
|
|
static int devinfo_open(struct inode *inode, struct file *filp)
|
2006-01-15 05:20:38 +08:00
|
|
|
{
|
2006-03-31 18:30:32 +08:00
|
|
|
return seq_open(filp, &devinfo_ops);
|
2006-01-15 05:20:38 +08:00
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_devinfo_operations = {
|
2006-01-15 05:20:38 +08:00
|
|
|
.open = devinfo_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
extern struct seq_operations vmstat_op;
|
|
|
|
static int vmstat_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &vmstat_op);
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_vmstat_file_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = vmstat_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_HARDWARE
|
|
|
|
static int hardware_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len = get_hardware_list(page);
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_STRAM_PROC
|
|
|
|
static int stram_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len = get_stram_list(page);
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#ifdef CONFIG_BLOCK
|
2005-04-17 06:20:36 +08:00
|
|
|
extern struct seq_operations partitions_op;
|
|
|
|
static int partitions_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &partitions_op);
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_partitions_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = partitions_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.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);
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_diskstats_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = diskstats_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_MODULES
|
|
|
|
extern struct seq_operations modules_op;
|
|
|
|
static int modules_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &modules_op);
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_modules_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = modules_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2006-01-08 17:01:45 +08:00
|
|
|
#ifdef CONFIG_SLAB
|
2005-04-17 06:20:36 +08:00
|
|
|
static int slabinfo_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
return seq_open(file, &slabinfo_op);
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_slabinfo_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = slabinfo_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.write = slabinfo_write,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
2006-03-25 19:06:39 +08:00
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_slabstats_operations = {
|
2006-03-25 19:06:39 +08:00
|
|
|
.open = slabstats_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
2007-05-08 15:29:26 +08:00
|
|
|
.release = seq_release_private,
|
2006-03-25 19:06:39 +08:00
|
|
|
};
|
|
|
|
#endif
|
2006-01-08 17:01:45 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
static int show_stat(struct seq_file *p, void *v)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
unsigned long jif;
|
|
|
|
cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
|
|
|
|
u64 sum = 0;
|
2007-07-16 14:39:42 +08:00
|
|
|
struct timespec boottime;
|
2007-07-19 16:47:53 +08:00
|
|
|
unsigned int *per_irq_sum;
|
|
|
|
|
|
|
|
per_irq_sum = kzalloc(sizeof(unsigned int)*NR_IRQS, GFP_KERNEL);
|
|
|
|
if (!per_irq_sum)
|
|
|
|
return -ENOMEM;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
user = nice = system = idle = iowait =
|
|
|
|
irq = softirq = steal = cputime64_zero;
|
2007-07-16 14:39:42 +08:00
|
|
|
getboottime(&boottime);
|
|
|
|
jif = boottime.tv_sec;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-03-28 17:56:37 +08:00
|
|
|
for_each_possible_cpu(i) {
|
2005-04-17 06:20:36 +08:00
|
|
|
int j;
|
|
|
|
|
|
|
|
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);
|
2007-07-19 16:47:53 +08:00
|
|
|
for (j = 0; j < NR_IRQS; j++) {
|
|
|
|
unsigned int temp = kstat_cpu(i).irqs[j];
|
|
|
|
sum += temp;
|
|
|
|
per_irq_sum[j] += temp;
|
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
|
|
|
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;
|
|
|
|
steal = kstat_cpu(i).cpustat.steal;
|
|
|
|
seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
|
|
|
|
i,
|
|
|
|
(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);
|
|
|
|
|
2007-07-21 23:10:19 +08:00
|
|
|
#ifndef CONFIG_SMP
|
|
|
|
/* Touches too many cache lines on SMP setups */
|
2005-04-17 06:20:36 +08:00
|
|
|
for (i = 0; i < NR_IRQS; i++)
|
2007-07-19 16:47:53 +08:00
|
|
|
seq_printf(p, " %u", per_irq_sum[i]);
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
seq_printf(p,
|
|
|
|
"\nctxt %llu\n"
|
|
|
|
"btime %lu\n"
|
|
|
|
"processes %lu\n"
|
|
|
|
"procs_running %lu\n"
|
|
|
|
"procs_blocked %lu\n",
|
|
|
|
nr_context_switches(),
|
|
|
|
(unsigned long)jif,
|
|
|
|
total_forks,
|
|
|
|
nr_running(),
|
|
|
|
nr_iowait());
|
|
|
|
|
2007-07-19 16:47:53 +08:00
|
|
|
kfree(per_irq_sum);
|
2005-04-17 06:20:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int stat_open(struct inode *inode, struct file *file)
|
|
|
|
{
|
|
|
|
unsigned size = 4096 * (1 + num_possible_cpus() / 32);
|
|
|
|
char *buf;
|
|
|
|
struct seq_file *m;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
/* don't ask for more than the kmalloc() max size, currently 128 KB */
|
|
|
|
if (size > 128 * 1024)
|
|
|
|
size = 128 * 1024;
|
|
|
|
buf = kmalloc(size, GFP_KERNEL);
|
|
|
|
if (!buf)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
res = single_open(file, show_stat, NULL);
|
|
|
|
if (!res) {
|
|
|
|
m = file->private_data;
|
|
|
|
m->buf = buf;
|
|
|
|
m->size = size;
|
|
|
|
} else
|
|
|
|
kfree(buf);
|
|
|
|
return res;
|
|
|
|
}
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_stat_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = stat_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = single_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* /proc/interrupts
|
|
|
|
*/
|
|
|
|
static void *int_seq_start(struct seq_file *f, loff_t *pos)
|
|
|
|
{
|
|
|
|
return (*pos <= NR_IRQS) ? pos : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
|
|
|
|
{
|
|
|
|
(*pos)++;
|
|
|
|
if (*pos > NR_IRQS)
|
|
|
|
return NULL;
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void int_seq_stop(struct seq_file *f, void *v)
|
|
|
|
{
|
|
|
|
/* Nothing to do */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */
|
|
|
|
static struct seq_operations int_seq_ops = {
|
|
|
|
.start = int_seq_start,
|
|
|
|
.next = int_seq_next,
|
|
|
|
.stop = int_seq_stop,
|
|
|
|
.show = show_interrupts
|
|
|
|
};
|
|
|
|
|
|
|
|
static int interrupts_open(struct inode *inode, struct file *filp)
|
|
|
|
{
|
|
|
|
return seq_open(filp, &int_seq_ops);
|
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_interrupts_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.open = interrupts_open,
|
|
|
|
.read = seq_read,
|
|
|
|
.llseek = seq_lseek,
|
|
|
|
.release = seq_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int filesystems_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len = get_filesystem_list(page);
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cmdline_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = sprintf(page, "%s\n", saved_command_line);
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int locks_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len = get_locks_status(page, start, off, count);
|
|
|
|
|
|
|
|
if (len < count)
|
|
|
|
*eof = 1;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int execdomains_read_proc(char *page, char **start, off_t off,
|
|
|
|
int count, int *eof, void *data)
|
|
|
|
{
|
|
|
|
int len = get_exec_domain_list(page);
|
|
|
|
return proc_calc_metrics(page, start, off, count, eof, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_MAGIC_SYSRQ
|
|
|
|
/*
|
|
|
|
* writing 'C' to /proc/sysrq-trigger is like sysrq-C
|
|
|
|
*/
|
|
|
|
static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
|
|
|
|
size_t count, loff_t *ppos)
|
|
|
|
{
|
|
|
|
if (count) {
|
|
|
|
char c;
|
|
|
|
|
|
|
|
if (get_user(c, buf))
|
|
|
|
return -EFAULT;
|
IRQ: Maintain regs pointer globally rather than passing to IRQ handlers
Maintain a per-CPU global "struct pt_regs *" variable which can be used instead
of passing regs around manually through all ~1800 interrupt handlers in the
Linux kernel.
The regs pointer is used in few places, but it potentially costs both stack
space and code to pass it around. On the FRV arch, removing the regs parameter
from all the genirq function results in a 20% speed up of the IRQ exit path
(ie: from leaving timer_interrupt() to leaving do_IRQ()).
Where appropriate, an arch may override the generic storage facility and do
something different with the variable. On FRV, for instance, the address is
maintained in GR28 at all times inside the kernel as part of general exception
handling.
Having looked over the code, it appears that the parameter may be handed down
through up to twenty or so layers of functions. Consider a USB character
device attached to a USB hub, attached to a USB controller that posts its
interrupts through a cascaded auxiliary interrupt controller. A character
device driver may want to pass regs to the sysrq handler through the input
layer which adds another few layers of parameter passing.
I've build this code with allyesconfig for x86_64 and i386. I've runtested the
main part of the code on FRV and i386, though I can't test most of the drivers.
I've also done partial conversion for powerpc and MIPS - these at least compile
with minimal configurations.
This will affect all archs. Mostly the changes should be relatively easy.
Take do_IRQ(), store the regs pointer at the beginning, saving the old one:
struct pt_regs *old_regs = set_irq_regs(regs);
And put the old one back at the end:
set_irq_regs(old_regs);
Don't pass regs through to generic_handle_irq() or __do_IRQ().
In timer_interrupt(), this sort of change will be necessary:
- update_process_times(user_mode(regs));
- profile_tick(CPU_PROFILING, regs);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
I'd like to move update_process_times()'s use of get_irq_regs() into itself,
except that i386, alone of the archs, uses something other than user_mode().
Some notes on the interrupt handling in the drivers:
(*) input_dev() is now gone entirely. The regs pointer is no longer stored in
the input_dev struct.
(*) finish_unlinks() in drivers/usb/host/ohci-q.c needs checking. It does
something different depending on whether it's been supplied with a regs
pointer or not.
(*) Various IRQ handler function pointers have been moved to type
irq_handler_t.
Signed-Off-By: David Howells <dhowells@redhat.com>
(cherry picked from 1b16e7ac850969f38b375e511e3fa2f474a33867 commit)
2006-10-05 21:55:46 +08:00
|
|
|
__handle_sysrq(c, NULL, 0);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2007-02-12 16:55:34 +08:00
|
|
|
static const struct file_operations proc_sysrq_trigger_operations = {
|
2005-04-17 06:20:36 +08:00
|
|
|
.write = write_sysrq_trigger,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct proc_dir_entry *proc_root_kcore;
|
|
|
|
|
2006-03-28 17:56:41 +08:00
|
|
|
void create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
|
|
|
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 {
|
|
|
|
char *name;
|
|
|
|
int (*read_proc)(char*,char**,off_t,int,int*,void*);
|
|
|
|
} *p, simple_ones[] = {
|
|
|
|
{"loadavg", loadavg_read_proc},
|
|
|
|
{"uptime", uptime_read_proc},
|
|
|
|
{"meminfo", meminfo_read_proc},
|
|
|
|
{"version", version_read_proc},
|
|
|
|
#ifdef CONFIG_PROC_HARDWARE
|
|
|
|
{"hardware", hardware_read_proc},
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_STRAM_PROC
|
|
|
|
{"stram", stram_read_proc},
|
|
|
|
#endif
|
|
|
|
{"filesystems", filesystems_read_proc},
|
|
|
|
{"cmdline", cmdline_read_proc},
|
|
|
|
{"locks", locks_read_proc},
|
|
|
|
{"execdomains", execdomains_read_proc},
|
|
|
|
{NULL,}
|
|
|
|
};
|
|
|
|
for (p = simple_ones; p->name; p++)
|
|
|
|
create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
|
|
|
|
|
|
|
|
proc_symlink("mounts", NULL, "self/mounts");
|
|
|
|
|
|
|
|
/* And now for trickier ones */
|
2006-12-07 12:37:42 +08:00
|
|
|
#ifdef CONFIG_PRINTK
|
2007-02-10 17:45:51 +08:00
|
|
|
{
|
|
|
|
struct proc_dir_entry *entry;
|
|
|
|
entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
|
|
|
|
if (entry)
|
|
|
|
entry->proc_fops = &proc_kmsg_operations;
|
|
|
|
}
|
2006-12-07 12:37:42 +08:00
|
|
|
#endif
|
2006-01-15 05:20:38 +08:00
|
|
|
create_seq_entry("devices", 0, &proc_devinfo_operations);
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#ifdef CONFIG_BLOCK
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("partitions", 0, &proc_partitions_operations);
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("stat", 0, &proc_stat_operations);
|
|
|
|
create_seq_entry("interrupts", 0, &proc_interrupts_operations);
|
2006-01-08 17:01:45 +08:00
|
|
|
#ifdef CONFIG_SLAB
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
|
2006-03-25 19:06:39 +08:00
|
|
|
#ifdef CONFIG_DEBUG_SLAB_LEAK
|
|
|
|
create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
|
|
|
|
#endif
|
2006-01-08 17:01:45 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
|
|
|
|
create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
|
2005-06-22 08:14:38 +08:00
|
|
|
create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#ifdef CONFIG_BLOCK
|
2005-04-17 06:20:36 +08:00
|
|
|
create_seq_entry("diskstats", 0, &proc_diskstats_operations);
|
[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer. Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
(*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
support.
(*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
an item that uses the block layer. This includes:
(*) Block I/O tracing.
(*) Disk partition code.
(*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
(*) The SCSI layer. As far as I can tell, even SCSI chardevs use the
block layer to do scheduling. Some drivers that use SCSI facilities -
such as USB storage - end up disabled indirectly from this.
(*) Various block-based device drivers, such as IDE and the old CDROM
drivers.
(*) MTD blockdev handling and FTL.
(*) JFFS - which uses set_bdev_super(), something it could avoid doing by
taking a leaf out of JFFS2's book.
(*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is,
however, still used in places, and so is still available.
(*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
parts of linux/fs.h.
(*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
(*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
(*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
is not enabled.
(*) fs/no-block.c is created to hold out-of-line stubs and things that are
required when CONFIG_BLOCK is not set:
(*) Default blockdev file operations (to give error ENODEV on opening).
(*) Makes some /proc changes:
(*) /proc/devices does not list any blockdevs.
(*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
(*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
(*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
given command other than Q_SYNC or if a special device is specified.
(*) In init/do_mounts.c, no reference is made to the blockdev routines if
CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2.
(*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
error ENOSYS by way of cond_syscall if so).
(*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2006-10-01 02:45:40 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
#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) {
|
|
|
|
proc_root_kcore->proc_fops = &proc_kcore_operations;
|
|
|
|
proc_root_kcore->size =
|
|
|
|
(size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
|
|
|
|
}
|
|
|
|
#endif
|
2005-06-26 05:58:21 +08:00
|
|
|
#ifdef CONFIG_PROC_VMCORE
|
|
|
|
proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL);
|
|
|
|
if (proc_vmcore)
|
|
|
|
proc_vmcore->proc_fops = &proc_vmcore_operations;
|
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
#ifdef CONFIG_MAGIC_SYSRQ
|
2007-02-10 17:45:51 +08:00
|
|
|
{
|
|
|
|
struct proc_dir_entry *entry;
|
|
|
|
entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
|
|
|
|
if (entry)
|
|
|
|
entry->proc_fops = &proc_sysrq_trigger_operations;
|
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif
|
|
|
|
}
|