at v2.6.18-rc7 726 lines 19 kB view raw
1/* 2 * linux/fs/proc/proc_misc.c 3 * 4 * linux/fs/proc/array.c 5 * Copyright (C) 1992 by Linus Torvalds 6 * based on ideas by Darren Senn 7 * 8 * This used to be the part of array.c. See the rest of history and credits 9 * there. I took this into a separate file and switched the thing to generic 10 * proc_file_inode_operations, leaving in array.c only per-process stuff. 11 * Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999. 12 * 13 * Changes: 14 * Fulton Green : Encapsulated position metric calculations. 15 * <kernel@FultonGreen.com> 16 */ 17 18#include <linux/types.h> 19#include <linux/errno.h> 20#include <linux/time.h> 21#include <linux/kernel.h> 22#include <linux/kernel_stat.h> 23#include <linux/fs.h> 24#include <linux/tty.h> 25#include <linux/string.h> 26#include <linux/mman.h> 27#include <linux/proc_fs.h> 28#include <linux/ioport.h> 29#include <linux/mm.h> 30#include <linux/mmzone.h> 31#include <linux/pagemap.h> 32#include <linux/swap.h> 33#include <linux/slab.h> 34#include <linux/smp.h> 35#include <linux/signal.h> 36#include <linux/module.h> 37#include <linux/init.h> 38#include <linux/smp_lock.h> 39#include <linux/seq_file.h> 40#include <linux/times.h> 41#include <linux/profile.h> 42#include <linux/blkdev.h> 43#include <linux/hugetlb.h> 44#include <linux/jiffies.h> 45#include <linux/sysrq.h> 46#include <linux/vmalloc.h> 47#include <linux/crash_dump.h> 48#include <asm/uaccess.h> 49#include <asm/pgtable.h> 50#include <asm/io.h> 51#include <asm/tlb.h> 52#include <asm/div64.h> 53#include "internal.h" 54 55#define LOAD_INT(x) ((x) >> FSHIFT) 56#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) 57/* 58 * Warning: stuff below (imported functions) assumes that its output will fit 59 * into one page. For some of those functions it may be wrong. Moreover, we 60 * have a way to deal with that gracefully. Right now I used straightforward 61 * wrappers, but this needs further analysis wrt potential overflows. 62 */ 63extern int get_hardware_list(char *); 64extern int get_stram_list(char *); 65extern int get_filesystem_list(char *); 66extern int get_exec_domain_list(char *); 67extern int get_dma_list(char *); 68extern int get_locks_status (char *, char **, off_t, int); 69 70static int proc_calc_metrics(char *page, char **start, off_t off, 71 int count, int *eof, int len) 72{ 73 if (len <= off+count) *eof = 1; 74 *start = page + off; 75 len -= off; 76 if (len>count) len = count; 77 if (len<0) len = 0; 78 return len; 79} 80 81static int loadavg_read_proc(char *page, char **start, off_t off, 82 int count, int *eof, void *data) 83{ 84 int a, b, c; 85 int len; 86 87 a = avenrun[0] + (FIXED_1/200); 88 b = avenrun[1] + (FIXED_1/200); 89 c = avenrun[2] + (FIXED_1/200); 90 len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", 91 LOAD_INT(a), LOAD_FRAC(a), 92 LOAD_INT(b), LOAD_FRAC(b), 93 LOAD_INT(c), LOAD_FRAC(c), 94 nr_running(), nr_threads, last_pid); 95 return proc_calc_metrics(page, start, off, count, eof, len); 96} 97 98static int uptime_read_proc(char *page, char **start, off_t off, 99 int count, int *eof, void *data) 100{ 101 struct timespec uptime; 102 struct timespec idle; 103 int len; 104 cputime_t idletime = cputime_add(init_task.utime, init_task.stime); 105 106 do_posix_clock_monotonic_gettime(&uptime); 107 cputime_to_timespec(idletime, &idle); 108 len = sprintf(page,"%lu.%02lu %lu.%02lu\n", 109 (unsigned long) uptime.tv_sec, 110 (uptime.tv_nsec / (NSEC_PER_SEC / 100)), 111 (unsigned long) idle.tv_sec, 112 (idle.tv_nsec / (NSEC_PER_SEC / 100))); 113 114 return proc_calc_metrics(page, start, off, count, eof, len); 115} 116 117static int meminfo_read_proc(char *page, char **start, off_t off, 118 int count, int *eof, void *data) 119{ 120 struct sysinfo i; 121 int len; 122 unsigned long inactive; 123 unsigned long active; 124 unsigned long free; 125 unsigned long committed; 126 unsigned long allowed; 127 struct vmalloc_info vmi; 128 long cached; 129 130 get_zone_counts(&active, &inactive, &free); 131 132/* 133 * display in kilobytes. 134 */ 135#define K(x) ((x) << (PAGE_SHIFT - 10)) 136 si_meminfo(&i); 137 si_swapinfo(&i); 138 committed = atomic_read(&vm_committed_space); 139 allowed = ((totalram_pages - hugetlb_total_pages()) 140 * sysctl_overcommit_ratio / 100) + total_swap_pages; 141 142 cached = global_page_state(NR_FILE_PAGES) - 143 total_swapcache_pages - i.bufferram; 144 if (cached < 0) 145 cached = 0; 146 147 get_vmalloc_info(&vmi); 148 149 /* 150 * Tagged format, for easy grepping and expansion. 151 */ 152 len = sprintf(page, 153 "MemTotal: %8lu kB\n" 154 "MemFree: %8lu kB\n" 155 "Buffers: %8lu kB\n" 156 "Cached: %8lu kB\n" 157 "SwapCached: %8lu kB\n" 158 "Active: %8lu kB\n" 159 "Inactive: %8lu kB\n" 160 "HighTotal: %8lu kB\n" 161 "HighFree: %8lu kB\n" 162 "LowTotal: %8lu kB\n" 163 "LowFree: %8lu kB\n" 164 "SwapTotal: %8lu kB\n" 165 "SwapFree: %8lu kB\n" 166 "Dirty: %8lu kB\n" 167 "Writeback: %8lu kB\n" 168 "AnonPages: %8lu kB\n" 169 "Mapped: %8lu kB\n" 170 "Slab: %8lu kB\n" 171 "PageTables: %8lu kB\n" 172 "NFS_Unstable: %8lu kB\n" 173 "Bounce: %8lu kB\n" 174 "CommitLimit: %8lu kB\n" 175 "Committed_AS: %8lu kB\n" 176 "VmallocTotal: %8lu kB\n" 177 "VmallocUsed: %8lu kB\n" 178 "VmallocChunk: %8lu kB\n", 179 K(i.totalram), 180 K(i.freeram), 181 K(i.bufferram), 182 K(cached), 183 K(total_swapcache_pages), 184 K(active), 185 K(inactive), 186 K(i.totalhigh), 187 K(i.freehigh), 188 K(i.totalram-i.totalhigh), 189 K(i.freeram-i.freehigh), 190 K(i.totalswap), 191 K(i.freeswap), 192 K(global_page_state(NR_FILE_DIRTY)), 193 K(global_page_state(NR_WRITEBACK)), 194 K(global_page_state(NR_ANON_PAGES)), 195 K(global_page_state(NR_FILE_MAPPED)), 196 K(global_page_state(NR_SLAB)), 197 K(global_page_state(NR_PAGETABLE)), 198 K(global_page_state(NR_UNSTABLE_NFS)), 199 K(global_page_state(NR_BOUNCE)), 200 K(allowed), 201 K(committed), 202 (unsigned long)VMALLOC_TOTAL >> 10, 203 vmi.used >> 10, 204 vmi.largest_chunk >> 10 205 ); 206 207 len += hugetlb_report_meminfo(page + len); 208 209 return proc_calc_metrics(page, start, off, count, eof, len); 210#undef K 211} 212 213extern struct seq_operations fragmentation_op; 214static int fragmentation_open(struct inode *inode, struct file *file) 215{ 216 (void)inode; 217 return seq_open(file, &fragmentation_op); 218} 219 220static struct file_operations fragmentation_file_operations = { 221 .open = fragmentation_open, 222 .read = seq_read, 223 .llseek = seq_lseek, 224 .release = seq_release, 225}; 226 227extern struct seq_operations zoneinfo_op; 228static int zoneinfo_open(struct inode *inode, struct file *file) 229{ 230 return seq_open(file, &zoneinfo_op); 231} 232 233static struct file_operations proc_zoneinfo_file_operations = { 234 .open = zoneinfo_open, 235 .read = seq_read, 236 .llseek = seq_lseek, 237 .release = seq_release, 238}; 239 240static int version_read_proc(char *page, char **start, off_t off, 241 int count, int *eof, void *data) 242{ 243 int len; 244 245 strcpy(page, linux_banner); 246 len = strlen(page); 247 return proc_calc_metrics(page, start, off, count, eof, len); 248} 249 250extern struct seq_operations cpuinfo_op; 251static int cpuinfo_open(struct inode *inode, struct file *file) 252{ 253 return seq_open(file, &cpuinfo_op); 254} 255 256static struct file_operations proc_cpuinfo_operations = { 257 .open = cpuinfo_open, 258 .read = seq_read, 259 .llseek = seq_lseek, 260 .release = seq_release, 261}; 262 263static int devinfo_show(struct seq_file *f, void *v) 264{ 265 int i = *(loff_t *) v; 266 267 if (i < CHRDEV_MAJOR_HASH_SIZE) { 268 if (i == 0) 269 seq_printf(f, "Character devices:\n"); 270 chrdev_show(f, i); 271 } else { 272 i -= CHRDEV_MAJOR_HASH_SIZE; 273 if (i == 0) 274 seq_printf(f, "\nBlock devices:\n"); 275 blkdev_show(f, i); 276 } 277 return 0; 278} 279 280static void *devinfo_start(struct seq_file *f, loff_t *pos) 281{ 282 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) 283 return pos; 284 return NULL; 285} 286 287static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) 288{ 289 (*pos)++; 290 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) 291 return NULL; 292 return pos; 293} 294 295static void devinfo_stop(struct seq_file *f, void *v) 296{ 297 /* Nothing to do */ 298} 299 300static struct seq_operations devinfo_ops = { 301 .start = devinfo_start, 302 .next = devinfo_next, 303 .stop = devinfo_stop, 304 .show = devinfo_show 305}; 306 307static int devinfo_open(struct inode *inode, struct file *filp) 308{ 309 return seq_open(filp, &devinfo_ops); 310} 311 312static struct file_operations proc_devinfo_operations = { 313 .open = devinfo_open, 314 .read = seq_read, 315 .llseek = seq_lseek, 316 .release = seq_release, 317}; 318 319extern struct seq_operations vmstat_op; 320static int vmstat_open(struct inode *inode, struct file *file) 321{ 322 return seq_open(file, &vmstat_op); 323} 324static struct file_operations proc_vmstat_file_operations = { 325 .open = vmstat_open, 326 .read = seq_read, 327 .llseek = seq_lseek, 328 .release = seq_release, 329}; 330 331#ifdef CONFIG_PROC_HARDWARE 332static int hardware_read_proc(char *page, char **start, off_t off, 333 int count, int *eof, void *data) 334{ 335 int len = get_hardware_list(page); 336 return proc_calc_metrics(page, start, off, count, eof, len); 337} 338#endif 339 340#ifdef CONFIG_STRAM_PROC 341static int stram_read_proc(char *page, char **start, off_t off, 342 int count, int *eof, void *data) 343{ 344 int len = get_stram_list(page); 345 return proc_calc_metrics(page, start, off, count, eof, len); 346} 347#endif 348 349extern struct seq_operations partitions_op; 350static int partitions_open(struct inode *inode, struct file *file) 351{ 352 return seq_open(file, &partitions_op); 353} 354static struct file_operations proc_partitions_operations = { 355 .open = partitions_open, 356 .read = seq_read, 357 .llseek = seq_lseek, 358 .release = seq_release, 359}; 360 361extern struct seq_operations diskstats_op; 362static int diskstats_open(struct inode *inode, struct file *file) 363{ 364 return seq_open(file, &diskstats_op); 365} 366static struct file_operations proc_diskstats_operations = { 367 .open = diskstats_open, 368 .read = seq_read, 369 .llseek = seq_lseek, 370 .release = seq_release, 371}; 372 373#ifdef CONFIG_MODULES 374extern struct seq_operations modules_op; 375static int modules_open(struct inode *inode, struct file *file) 376{ 377 return seq_open(file, &modules_op); 378} 379static struct file_operations proc_modules_operations = { 380 .open = modules_open, 381 .read = seq_read, 382 .llseek = seq_lseek, 383 .release = seq_release, 384}; 385#endif 386 387#ifdef CONFIG_SLAB 388extern struct seq_operations slabinfo_op; 389extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); 390static int slabinfo_open(struct inode *inode, struct file *file) 391{ 392 return seq_open(file, &slabinfo_op); 393} 394static struct file_operations proc_slabinfo_operations = { 395 .open = slabinfo_open, 396 .read = seq_read, 397 .write = slabinfo_write, 398 .llseek = seq_lseek, 399 .release = seq_release, 400}; 401 402#ifdef CONFIG_DEBUG_SLAB_LEAK 403extern struct seq_operations slabstats_op; 404static int slabstats_open(struct inode *inode, struct file *file) 405{ 406 unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL); 407 int ret = -ENOMEM; 408 if (n) { 409 ret = seq_open(file, &slabstats_op); 410 if (!ret) { 411 struct seq_file *m = file->private_data; 412 *n = PAGE_SIZE / (2 * sizeof(unsigned long)); 413 m->private = n; 414 n = NULL; 415 } 416 kfree(n); 417 } 418 return ret; 419} 420 421static int slabstats_release(struct inode *inode, struct file *file) 422{ 423 struct seq_file *m = file->private_data; 424 kfree(m->private); 425 return seq_release(inode, file); 426} 427 428static struct file_operations proc_slabstats_operations = { 429 .open = slabstats_open, 430 .read = seq_read, 431 .llseek = seq_lseek, 432 .release = slabstats_release, 433}; 434#endif 435#endif 436 437static int show_stat(struct seq_file *p, void *v) 438{ 439 int i; 440 unsigned long jif; 441 cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; 442 u64 sum = 0; 443 444 user = nice = system = idle = iowait = 445 irq = softirq = steal = cputime64_zero; 446 jif = - wall_to_monotonic.tv_sec; 447 if (wall_to_monotonic.tv_nsec) 448 --jif; 449 450 for_each_possible_cpu(i) { 451 int j; 452 453 user = cputime64_add(user, kstat_cpu(i).cpustat.user); 454 nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice); 455 system = cputime64_add(system, kstat_cpu(i).cpustat.system); 456 idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle); 457 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait); 458 irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq); 459 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq); 460 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal); 461 for (j = 0 ; j < NR_IRQS ; j++) 462 sum += kstat_cpu(i).irqs[j]; 463 } 464 465 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu\n", 466 (unsigned long long)cputime64_to_clock_t(user), 467 (unsigned long long)cputime64_to_clock_t(nice), 468 (unsigned long long)cputime64_to_clock_t(system), 469 (unsigned long long)cputime64_to_clock_t(idle), 470 (unsigned long long)cputime64_to_clock_t(iowait), 471 (unsigned long long)cputime64_to_clock_t(irq), 472 (unsigned long long)cputime64_to_clock_t(softirq), 473 (unsigned long long)cputime64_to_clock_t(steal)); 474 for_each_online_cpu(i) { 475 476 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ 477 user = kstat_cpu(i).cpustat.user; 478 nice = kstat_cpu(i).cpustat.nice; 479 system = kstat_cpu(i).cpustat.system; 480 idle = kstat_cpu(i).cpustat.idle; 481 iowait = kstat_cpu(i).cpustat.iowait; 482 irq = kstat_cpu(i).cpustat.irq; 483 softirq = kstat_cpu(i).cpustat.softirq; 484 steal = kstat_cpu(i).cpustat.steal; 485 seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n", 486 i, 487 (unsigned long long)cputime64_to_clock_t(user), 488 (unsigned long long)cputime64_to_clock_t(nice), 489 (unsigned long long)cputime64_to_clock_t(system), 490 (unsigned long long)cputime64_to_clock_t(idle), 491 (unsigned long long)cputime64_to_clock_t(iowait), 492 (unsigned long long)cputime64_to_clock_t(irq), 493 (unsigned long long)cputime64_to_clock_t(softirq), 494 (unsigned long long)cputime64_to_clock_t(steal)); 495 } 496 seq_printf(p, "intr %llu", (unsigned long long)sum); 497 498#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) 499 for (i = 0; i < NR_IRQS; i++) 500 seq_printf(p, " %u", kstat_irqs(i)); 501#endif 502 503 seq_printf(p, 504 "\nctxt %llu\n" 505 "btime %lu\n" 506 "processes %lu\n" 507 "procs_running %lu\n" 508 "procs_blocked %lu\n", 509 nr_context_switches(), 510 (unsigned long)jif, 511 total_forks, 512 nr_running(), 513 nr_iowait()); 514 515 return 0; 516} 517 518static int stat_open(struct inode *inode, struct file *file) 519{ 520 unsigned size = 4096 * (1 + num_possible_cpus() / 32); 521 char *buf; 522 struct seq_file *m; 523 int res; 524 525 /* don't ask for more than the kmalloc() max size, currently 128 KB */ 526 if (size > 128 * 1024) 527 size = 128 * 1024; 528 buf = kmalloc(size, GFP_KERNEL); 529 if (!buf) 530 return -ENOMEM; 531 532 res = single_open(file, show_stat, NULL); 533 if (!res) { 534 m = file->private_data; 535 m->buf = buf; 536 m->size = size; 537 } else 538 kfree(buf); 539 return res; 540} 541static struct file_operations proc_stat_operations = { 542 .open = stat_open, 543 .read = seq_read, 544 .llseek = seq_lseek, 545 .release = single_release, 546}; 547 548/* 549 * /proc/interrupts 550 */ 551static void *int_seq_start(struct seq_file *f, loff_t *pos) 552{ 553 return (*pos <= NR_IRQS) ? pos : NULL; 554} 555 556static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos) 557{ 558 (*pos)++; 559 if (*pos > NR_IRQS) 560 return NULL; 561 return pos; 562} 563 564static void int_seq_stop(struct seq_file *f, void *v) 565{ 566 /* Nothing to do */ 567} 568 569 570extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */ 571static struct seq_operations int_seq_ops = { 572 .start = int_seq_start, 573 .next = int_seq_next, 574 .stop = int_seq_stop, 575 .show = show_interrupts 576}; 577 578static int interrupts_open(struct inode *inode, struct file *filp) 579{ 580 return seq_open(filp, &int_seq_ops); 581} 582 583static struct file_operations proc_interrupts_operations = { 584 .open = interrupts_open, 585 .read = seq_read, 586 .llseek = seq_lseek, 587 .release = seq_release, 588}; 589 590static int filesystems_read_proc(char *page, char **start, off_t off, 591 int count, int *eof, void *data) 592{ 593 int len = get_filesystem_list(page); 594 return proc_calc_metrics(page, start, off, count, eof, len); 595} 596 597static int cmdline_read_proc(char *page, char **start, off_t off, 598 int count, int *eof, void *data) 599{ 600 int len; 601 602 len = sprintf(page, "%s\n", saved_command_line); 603 return proc_calc_metrics(page, start, off, count, eof, len); 604} 605 606static int locks_read_proc(char *page, char **start, off_t off, 607 int count, int *eof, void *data) 608{ 609 int len = get_locks_status(page, start, off, count); 610 611 if (len < count) 612 *eof = 1; 613 return len; 614} 615 616static int execdomains_read_proc(char *page, char **start, off_t off, 617 int count, int *eof, void *data) 618{ 619 int len = get_exec_domain_list(page); 620 return proc_calc_metrics(page, start, off, count, eof, len); 621} 622 623#ifdef CONFIG_MAGIC_SYSRQ 624/* 625 * writing 'C' to /proc/sysrq-trigger is like sysrq-C 626 */ 627static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, 628 size_t count, loff_t *ppos) 629{ 630 if (count) { 631 char c; 632 633 if (get_user(c, buf)) 634 return -EFAULT; 635 __handle_sysrq(c, NULL, NULL, 0); 636 } 637 return count; 638} 639 640static struct file_operations proc_sysrq_trigger_operations = { 641 .write = write_sysrq_trigger, 642}; 643#endif 644 645struct proc_dir_entry *proc_root_kcore; 646 647void create_seq_entry(char *name, mode_t mode, const struct file_operations *f) 648{ 649 struct proc_dir_entry *entry; 650 entry = create_proc_entry(name, mode, NULL); 651 if (entry) 652 entry->proc_fops = f; 653} 654 655void __init proc_misc_init(void) 656{ 657 struct proc_dir_entry *entry; 658 static struct { 659 char *name; 660 int (*read_proc)(char*,char**,off_t,int,int*,void*); 661 } *p, simple_ones[] = { 662 {"loadavg", loadavg_read_proc}, 663 {"uptime", uptime_read_proc}, 664 {"meminfo", meminfo_read_proc}, 665 {"version", version_read_proc}, 666#ifdef CONFIG_PROC_HARDWARE 667 {"hardware", hardware_read_proc}, 668#endif 669#ifdef CONFIG_STRAM_PROC 670 {"stram", stram_read_proc}, 671#endif 672 {"filesystems", filesystems_read_proc}, 673 {"cmdline", cmdline_read_proc}, 674 {"locks", locks_read_proc}, 675 {"execdomains", execdomains_read_proc}, 676 {NULL,} 677 }; 678 for (p = simple_ones; p->name; p++) 679 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL); 680 681 proc_symlink("mounts", NULL, "self/mounts"); 682 683 /* And now for trickier ones */ 684 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); 685 if (entry) 686 entry->proc_fops = &proc_kmsg_operations; 687 create_seq_entry("devices", 0, &proc_devinfo_operations); 688 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); 689 create_seq_entry("partitions", 0, &proc_partitions_operations); 690 create_seq_entry("stat", 0, &proc_stat_operations); 691 create_seq_entry("interrupts", 0, &proc_interrupts_operations); 692#ifdef CONFIG_SLAB 693 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); 694#ifdef CONFIG_DEBUG_SLAB_LEAK 695 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); 696#endif 697#endif 698 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 699 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 700 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); 701 create_seq_entry("diskstats", 0, &proc_diskstats_operations); 702#ifdef CONFIG_MODULES 703 create_seq_entry("modules", 0, &proc_modules_operations); 704#endif 705#ifdef CONFIG_SCHEDSTATS 706 create_seq_entry("schedstat", 0, &proc_schedstat_operations); 707#endif 708#ifdef CONFIG_PROC_KCORE 709 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); 710 if (proc_root_kcore) { 711 proc_root_kcore->proc_fops = &proc_kcore_operations; 712 proc_root_kcore->size = 713 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; 714 } 715#endif 716#ifdef CONFIG_PROC_VMCORE 717 proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL); 718 if (proc_vmcore) 719 proc_vmcore->proc_fops = &proc_vmcore_operations; 720#endif 721#ifdef CONFIG_MAGIC_SYSRQ 722 entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); 723 if (entry) 724 entry->proc_fops = &proc_sysrq_trigger_operations; 725#endif 726}