proc_misc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  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. #include <linux/types.h>
  18. #include <linux/errno.h>
  19. #include <linux/time.h>
  20. #include <linux/kernel.h>
  21. #include <linux/kernel_stat.h>
  22. #include <linux/fs.h>
  23. #include <linux/tty.h>
  24. #include <linux/string.h>
  25. #include <linux/mman.h>
  26. #include <linux/quicklist.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/irq.h>
  33. #include <linux/interrupt.h>
  34. #include <linux/swap.h>
  35. #include <linux/slab.h>
  36. #include <linux/genhd.h>
  37. #include <linux/smp.h>
  38. #include <linux/signal.h>
  39. #include <linux/module.h>
  40. #include <linux/init.h>
  41. #include <linux/seq_file.h>
  42. #include <linux/times.h>
  43. #include <linux/profile.h>
  44. #include <linux/utsname.h>
  45. #include <linux/blkdev.h>
  46. #include <linux/hugetlb.h>
  47. #include <linux/jiffies.h>
  48. #include <linux/vmalloc.h>
  49. #include <linux/crash_dump.h>
  50. #include <linux/pid_namespace.h>
  51. #include <linux/bootmem.h>
  52. #include <asm/uaccess.h>
  53. #include <asm/pgtable.h>
  54. #include <asm/io.h>
  55. #include <asm/tlb.h>
  56. #include <asm/div64.h>
  57. #include "internal.h"
  58. static int fragmentation_open(struct inode *inode, struct file *file)
  59. {
  60. (void)inode;
  61. return seq_open(file, &fragmentation_op);
  62. }
  63. static const struct file_operations fragmentation_file_operations = {
  64. .open = fragmentation_open,
  65. .read = seq_read,
  66. .llseek = seq_lseek,
  67. .release = seq_release,
  68. };
  69. static int pagetypeinfo_open(struct inode *inode, struct file *file)
  70. {
  71. return seq_open(file, &pagetypeinfo_op);
  72. }
  73. static const struct file_operations pagetypeinfo_file_ops = {
  74. .open = pagetypeinfo_open,
  75. .read = seq_read,
  76. .llseek = seq_lseek,
  77. .release = seq_release,
  78. };
  79. static int zoneinfo_open(struct inode *inode, struct file *file)
  80. {
  81. return seq_open(file, &zoneinfo_op);
  82. }
  83. static const struct file_operations proc_zoneinfo_file_operations = {
  84. .open = zoneinfo_open,
  85. .read = seq_read,
  86. .llseek = seq_lseek,
  87. .release = seq_release,
  88. };
  89. extern const struct seq_operations cpuinfo_op;
  90. static int cpuinfo_open(struct inode *inode, struct file *file)
  91. {
  92. return seq_open(file, &cpuinfo_op);
  93. }
  94. static const struct file_operations proc_cpuinfo_operations = {
  95. .open = cpuinfo_open,
  96. .read = seq_read,
  97. .llseek = seq_lseek,
  98. .release = seq_release,
  99. };
  100. static int devinfo_show(struct seq_file *f, void *v)
  101. {
  102. int i = *(loff_t *) v;
  103. if (i < CHRDEV_MAJOR_HASH_SIZE) {
  104. if (i == 0)
  105. seq_printf(f, "Character devices:\n");
  106. chrdev_show(f, i);
  107. }
  108. #ifdef CONFIG_BLOCK
  109. else {
  110. i -= CHRDEV_MAJOR_HASH_SIZE;
  111. if (i == 0)
  112. seq_printf(f, "\nBlock devices:\n");
  113. blkdev_show(f, i);
  114. }
  115. #endif
  116. return 0;
  117. }
  118. static void *devinfo_start(struct seq_file *f, loff_t *pos)
  119. {
  120. if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
  121. return pos;
  122. return NULL;
  123. }
  124. static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
  125. {
  126. (*pos)++;
  127. if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
  128. return NULL;
  129. return pos;
  130. }
  131. static void devinfo_stop(struct seq_file *f, void *v)
  132. {
  133. /* Nothing to do */
  134. }
  135. static const struct seq_operations devinfo_ops = {
  136. .start = devinfo_start,
  137. .next = devinfo_next,
  138. .stop = devinfo_stop,
  139. .show = devinfo_show
  140. };
  141. static int devinfo_open(struct inode *inode, struct file *filp)
  142. {
  143. return seq_open(filp, &devinfo_ops);
  144. }
  145. static const struct file_operations proc_devinfo_operations = {
  146. .open = devinfo_open,
  147. .read = seq_read,
  148. .llseek = seq_lseek,
  149. .release = seq_release,
  150. };
  151. static int vmstat_open(struct inode *inode, struct file *file)
  152. {
  153. return seq_open(file, &vmstat_op);
  154. }
  155. static const struct file_operations proc_vmstat_file_operations = {
  156. .open = vmstat_open,
  157. .read = seq_read,
  158. .llseek = seq_lseek,
  159. .release = seq_release,
  160. };
  161. #ifdef CONFIG_BLOCK
  162. static int partitions_open(struct inode *inode, struct file *file)
  163. {
  164. return seq_open(file, &partitions_op);
  165. }
  166. static const struct file_operations proc_partitions_operations = {
  167. .open = partitions_open,
  168. .read = seq_read,
  169. .llseek = seq_lseek,
  170. .release = seq_release,
  171. };
  172. static int diskstats_open(struct inode *inode, struct file *file)
  173. {
  174. return seq_open(file, &diskstats_op);
  175. }
  176. static const struct file_operations proc_diskstats_operations = {
  177. .open = diskstats_open,
  178. .read = seq_read,
  179. .llseek = seq_lseek,
  180. .release = seq_release,
  181. };
  182. #endif
  183. #ifdef CONFIG_MODULES
  184. extern const struct seq_operations modules_op;
  185. static int modules_open(struct inode *inode, struct file *file)
  186. {
  187. return seq_open(file, &modules_op);
  188. }
  189. static const struct file_operations proc_modules_operations = {
  190. .open = modules_open,
  191. .read = seq_read,
  192. .llseek = seq_lseek,
  193. .release = seq_release,
  194. };
  195. #endif
  196. #ifdef CONFIG_SLABINFO
  197. static int slabinfo_open(struct inode *inode, struct file *file)
  198. {
  199. return seq_open(file, &slabinfo_op);
  200. }
  201. static const struct file_operations proc_slabinfo_operations = {
  202. .open = slabinfo_open,
  203. .read = seq_read,
  204. .write = slabinfo_write,
  205. .llseek = seq_lseek,
  206. .release = seq_release,
  207. };
  208. #ifdef CONFIG_DEBUG_SLAB_LEAK
  209. extern const struct seq_operations slabstats_op;
  210. static int slabstats_open(struct inode *inode, struct file *file)
  211. {
  212. unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
  213. int ret = -ENOMEM;
  214. if (n) {
  215. ret = seq_open(file, &slabstats_op);
  216. if (!ret) {
  217. struct seq_file *m = file->private_data;
  218. *n = PAGE_SIZE / (2 * sizeof(unsigned long));
  219. m->private = n;
  220. n = NULL;
  221. }
  222. kfree(n);
  223. }
  224. return ret;
  225. }
  226. static const struct file_operations proc_slabstats_operations = {
  227. .open = slabstats_open,
  228. .read = seq_read,
  229. .llseek = seq_lseek,
  230. .release = seq_release_private,
  231. };
  232. #endif
  233. #endif
  234. #ifdef CONFIG_MMU
  235. static int vmalloc_open(struct inode *inode, struct file *file)
  236. {
  237. unsigned int *ptr = NULL;
  238. int ret;
  239. if (NUMA_BUILD)
  240. ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
  241. ret = seq_open(file, &vmalloc_op);
  242. if (!ret) {
  243. struct seq_file *m = file->private_data;
  244. m->private = ptr;
  245. } else
  246. kfree(ptr);
  247. return ret;
  248. }
  249. static const struct file_operations proc_vmalloc_operations = {
  250. .open = vmalloc_open,
  251. .read = seq_read,
  252. .llseek = seq_lseek,
  253. .release = seq_release_private,
  254. };
  255. #endif
  256. #ifndef arch_irq_stat_cpu
  257. #define arch_irq_stat_cpu(cpu) 0
  258. #endif
  259. #ifndef arch_irq_stat
  260. #define arch_irq_stat() 0
  261. #endif
  262. static int show_stat(struct seq_file *p, void *v)
  263. {
  264. int i, j;
  265. unsigned long jif;
  266. cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
  267. cputime64_t guest;
  268. u64 sum = 0;
  269. struct timespec boottime;
  270. unsigned int per_irq_sum;
  271. user = nice = system = idle = iowait =
  272. irq = softirq = steal = cputime64_zero;
  273. guest = cputime64_zero;
  274. getboottime(&boottime);
  275. jif = boottime.tv_sec;
  276. for_each_possible_cpu(i) {
  277. user = cputime64_add(user, kstat_cpu(i).cpustat.user);
  278. nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
  279. system = cputime64_add(system, kstat_cpu(i).cpustat.system);
  280. idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
  281. iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
  282. irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
  283. softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
  284. steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
  285. guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
  286. for_each_irq_nr(j)
  287. sum += kstat_irqs_cpu(j, i);
  288. sum += arch_irq_stat_cpu(i);
  289. }
  290. sum += arch_irq_stat();
  291. seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
  292. (unsigned long long)cputime64_to_clock_t(user),
  293. (unsigned long long)cputime64_to_clock_t(nice),
  294. (unsigned long long)cputime64_to_clock_t(system),
  295. (unsigned long long)cputime64_to_clock_t(idle),
  296. (unsigned long long)cputime64_to_clock_t(iowait),
  297. (unsigned long long)cputime64_to_clock_t(irq),
  298. (unsigned long long)cputime64_to_clock_t(softirq),
  299. (unsigned long long)cputime64_to_clock_t(steal),
  300. (unsigned long long)cputime64_to_clock_t(guest));
  301. for_each_online_cpu(i) {
  302. /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
  303. user = kstat_cpu(i).cpustat.user;
  304. nice = kstat_cpu(i).cpustat.nice;
  305. system = kstat_cpu(i).cpustat.system;
  306. idle = kstat_cpu(i).cpustat.idle;
  307. iowait = kstat_cpu(i).cpustat.iowait;
  308. irq = kstat_cpu(i).cpustat.irq;
  309. softirq = kstat_cpu(i).cpustat.softirq;
  310. steal = kstat_cpu(i).cpustat.steal;
  311. guest = kstat_cpu(i).cpustat.guest;
  312. seq_printf(p,
  313. "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
  314. i,
  315. (unsigned long long)cputime64_to_clock_t(user),
  316. (unsigned long long)cputime64_to_clock_t(nice),
  317. (unsigned long long)cputime64_to_clock_t(system),
  318. (unsigned long long)cputime64_to_clock_t(idle),
  319. (unsigned long long)cputime64_to_clock_t(iowait),
  320. (unsigned long long)cputime64_to_clock_t(irq),
  321. (unsigned long long)cputime64_to_clock_t(softirq),
  322. (unsigned long long)cputime64_to_clock_t(steal),
  323. (unsigned long long)cputime64_to_clock_t(guest));
  324. }
  325. seq_printf(p, "intr %llu", (unsigned long long)sum);
  326. /* sum again ? it could be updated? */
  327. for_each_irq_nr(j) {
  328. per_irq_sum = 0;
  329. for_each_possible_cpu(i)
  330. per_irq_sum += kstat_irqs_cpu(j, i);
  331. seq_printf(p, " %u", per_irq_sum);
  332. }
  333. seq_printf(p,
  334. "\nctxt %llu\n"
  335. "btime %lu\n"
  336. "processes %lu\n"
  337. "procs_running %lu\n"
  338. "procs_blocked %lu\n",
  339. nr_context_switches(),
  340. (unsigned long)jif,
  341. total_forks,
  342. nr_running(),
  343. nr_iowait());
  344. return 0;
  345. }
  346. static int stat_open(struct inode *inode, struct file *file)
  347. {
  348. unsigned size = 4096 * (1 + num_possible_cpus() / 32);
  349. char *buf;
  350. struct seq_file *m;
  351. int res;
  352. /* don't ask for more than the kmalloc() max size, currently 128 KB */
  353. if (size > 128 * 1024)
  354. size = 128 * 1024;
  355. buf = kmalloc(size, GFP_KERNEL);
  356. if (!buf)
  357. return -ENOMEM;
  358. res = single_open(file, show_stat, NULL);
  359. if (!res) {
  360. m = file->private_data;
  361. m->buf = buf;
  362. m->size = size;
  363. } else
  364. kfree(buf);
  365. return res;
  366. }
  367. static const struct file_operations proc_stat_operations = {
  368. .open = stat_open,
  369. .read = seq_read,
  370. .llseek = seq_lseek,
  371. .release = single_release,
  372. };
  373. /*
  374. * /proc/interrupts
  375. */
  376. static void *int_seq_start(struct seq_file *f, loff_t *pos)
  377. {
  378. return (*pos <= nr_irqs) ? pos : NULL;
  379. }
  380. static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
  381. {
  382. (*pos)++;
  383. return (*pos <= nr_irqs) ? pos : NULL;
  384. }
  385. static void int_seq_stop(struct seq_file *f, void *v)
  386. {
  387. /* Nothing to do */
  388. }
  389. static const struct seq_operations int_seq_ops = {
  390. .start = int_seq_start,
  391. .next = int_seq_next,
  392. .stop = int_seq_stop,
  393. .show = show_interrupts
  394. };
  395. static int interrupts_open(struct inode *inode, struct file *filp)
  396. {
  397. return seq_open(filp, &int_seq_ops);
  398. }
  399. static const struct file_operations proc_interrupts_operations = {
  400. .open = interrupts_open,
  401. .read = seq_read,
  402. .llseek = seq_lseek,
  403. .release = seq_release,
  404. };
  405. #ifdef CONFIG_FILE_LOCKING
  406. static int locks_open(struct inode *inode, struct file *filp)
  407. {
  408. return seq_open(filp, &locks_seq_operations);
  409. }
  410. static const struct file_operations proc_locks_operations = {
  411. .open = locks_open,
  412. .read = seq_read,
  413. .llseek = seq_lseek,
  414. .release = seq_release,
  415. };
  416. #endif /* CONFIG_FILE_LOCKING */
  417. #ifdef CONFIG_PROC_PAGE_MONITOR
  418. #define KPMSIZE sizeof(u64)
  419. #define KPMMASK (KPMSIZE - 1)
  420. /* /proc/kpagecount - an array exposing page counts
  421. *
  422. * Each entry is a u64 representing the corresponding
  423. * physical page count.
  424. */
  425. static ssize_t kpagecount_read(struct file *file, char __user *buf,
  426. size_t count, loff_t *ppos)
  427. {
  428. u64 __user *out = (u64 __user *)buf;
  429. struct page *ppage;
  430. unsigned long src = *ppos;
  431. unsigned long pfn;
  432. ssize_t ret = 0;
  433. u64 pcount;
  434. pfn = src / KPMSIZE;
  435. count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
  436. if (src & KPMMASK || count & KPMMASK)
  437. return -EINVAL;
  438. while (count > 0) {
  439. ppage = NULL;
  440. if (pfn_valid(pfn))
  441. ppage = pfn_to_page(pfn);
  442. pfn++;
  443. if (!ppage)
  444. pcount = 0;
  445. else
  446. pcount = page_mapcount(ppage);
  447. if (put_user(pcount, out++)) {
  448. ret = -EFAULT;
  449. break;
  450. }
  451. count -= KPMSIZE;
  452. }
  453. *ppos += (char __user *)out - buf;
  454. if (!ret)
  455. ret = (char __user *)out - buf;
  456. return ret;
  457. }
  458. static struct file_operations proc_kpagecount_operations = {
  459. .llseek = mem_lseek,
  460. .read = kpagecount_read,
  461. };
  462. /* /proc/kpageflags - an array exposing page flags
  463. *
  464. * Each entry is a u64 representing the corresponding
  465. * physical page flags.
  466. */
  467. /* These macros are used to decouple internal flags from exported ones */
  468. #define KPF_LOCKED 0
  469. #define KPF_ERROR 1
  470. #define KPF_REFERENCED 2
  471. #define KPF_UPTODATE 3
  472. #define KPF_DIRTY 4
  473. #define KPF_LRU 5
  474. #define KPF_ACTIVE 6
  475. #define KPF_SLAB 7
  476. #define KPF_WRITEBACK 8
  477. #define KPF_RECLAIM 9
  478. #define KPF_BUDDY 10
  479. #define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
  480. static ssize_t kpageflags_read(struct file *file, char __user *buf,
  481. size_t count, loff_t *ppos)
  482. {
  483. u64 __user *out = (u64 __user *)buf;
  484. struct page *ppage;
  485. unsigned long src = *ppos;
  486. unsigned long pfn;
  487. ssize_t ret = 0;
  488. u64 kflags, uflags;
  489. pfn = src / KPMSIZE;
  490. count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
  491. if (src & KPMMASK || count & KPMMASK)
  492. return -EINVAL;
  493. while (count > 0) {
  494. ppage = NULL;
  495. if (pfn_valid(pfn))
  496. ppage = pfn_to_page(pfn);
  497. pfn++;
  498. if (!ppage)
  499. kflags = 0;
  500. else
  501. kflags = ppage->flags;
  502. uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
  503. kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
  504. kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
  505. kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
  506. kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
  507. kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
  508. kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
  509. kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
  510. kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
  511. kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
  512. kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
  513. if (put_user(uflags, out++)) {
  514. ret = -EFAULT;
  515. break;
  516. }
  517. count -= KPMSIZE;
  518. }
  519. *ppos += (char __user *)out - buf;
  520. if (!ret)
  521. ret = (char __user *)out - buf;
  522. return ret;
  523. }
  524. static struct file_operations proc_kpageflags_operations = {
  525. .llseek = mem_lseek,
  526. .read = kpageflags_read,
  527. };
  528. #endif /* CONFIG_PROC_PAGE_MONITOR */
  529. struct proc_dir_entry *proc_root_kcore;
  530. void __init proc_misc_init(void)
  531. {
  532. proc_symlink("mounts", NULL, "self/mounts");
  533. /* And now for trickier ones */
  534. #ifdef CONFIG_FILE_LOCKING
  535. proc_create("locks", 0, NULL, &proc_locks_operations);
  536. #endif
  537. proc_create("devices", 0, NULL, &proc_devinfo_operations);
  538. proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
  539. #ifdef CONFIG_BLOCK
  540. proc_create("partitions", 0, NULL, &proc_partitions_operations);
  541. #endif
  542. proc_create("stat", 0, NULL, &proc_stat_operations);
  543. proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
  544. #ifdef CONFIG_SLABINFO
  545. proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
  546. #ifdef CONFIG_DEBUG_SLAB_LEAK
  547. proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
  548. #endif
  549. #endif
  550. #ifdef CONFIG_MMU
  551. proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
  552. #endif
  553. proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
  554. proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
  555. proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
  556. proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
  557. #ifdef CONFIG_BLOCK
  558. proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
  559. #endif
  560. #ifdef CONFIG_MODULES
  561. proc_create("modules", 0, NULL, &proc_modules_operations);
  562. #endif
  563. #ifdef CONFIG_SCHEDSTATS
  564. proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
  565. #endif
  566. #ifdef CONFIG_PROC_KCORE
  567. proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
  568. if (proc_root_kcore)
  569. proc_root_kcore->size =
  570. (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
  571. #endif
  572. #ifdef CONFIG_PROC_PAGE_MONITOR
  573. proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
  574. proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
  575. #endif
  576. #ifdef CONFIG_PROC_VMCORE
  577. proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
  578. #endif
  579. }