at v5.2-rc1 2.8 kB view raw
1/* CacheFiles statistics 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12#include <linux/module.h> 13#include <linux/proc_fs.h> 14#include <linux/seq_file.h> 15#include "internal.h" 16 17atomic_t cachefiles_lookup_histogram[HZ]; 18atomic_t cachefiles_mkdir_histogram[HZ]; 19atomic_t cachefiles_create_histogram[HZ]; 20 21/* 22 * display the latency histogram 23 */ 24static int cachefiles_histogram_show(struct seq_file *m, void *v) 25{ 26 unsigned long index; 27 unsigned x, y, z, t; 28 29 switch ((unsigned long) v) { 30 case 1: 31 seq_puts(m, "JIFS SECS LOOKUPS MKDIRS CREATES\n"); 32 return 0; 33 case 2: 34 seq_puts(m, "===== ===== ========= ========= =========\n"); 35 return 0; 36 default: 37 index = (unsigned long) v - 3; 38 x = atomic_read(&cachefiles_lookup_histogram[index]); 39 y = atomic_read(&cachefiles_mkdir_histogram[index]); 40 z = atomic_read(&cachefiles_create_histogram[index]); 41 if (x == 0 && y == 0 && z == 0) 42 return 0; 43 44 t = (index * 1000) / HZ; 45 46 seq_printf(m, "%4lu 0.%03u %9u %9u %9u\n", index, t, x, y, z); 47 return 0; 48 } 49} 50 51/* 52 * set up the iterator to start reading from the first line 53 */ 54static void *cachefiles_histogram_start(struct seq_file *m, loff_t *_pos) 55{ 56 if ((unsigned long long)*_pos >= HZ + 2) 57 return NULL; 58 if (*_pos == 0) 59 *_pos = 1; 60 return (void *)(unsigned long) *_pos; 61} 62 63/* 64 * move to the next line 65 */ 66static void *cachefiles_histogram_next(struct seq_file *m, void *v, loff_t *pos) 67{ 68 (*pos)++; 69 return (unsigned long long)*pos > HZ + 2 ? 70 NULL : (void *)(unsigned long) *pos; 71} 72 73/* 74 * clean up after reading 75 */ 76static void cachefiles_histogram_stop(struct seq_file *m, void *v) 77{ 78} 79 80static const struct seq_operations cachefiles_histogram_ops = { 81 .start = cachefiles_histogram_start, 82 .stop = cachefiles_histogram_stop, 83 .next = cachefiles_histogram_next, 84 .show = cachefiles_histogram_show, 85}; 86 87/* 88 * initialise the /proc/fs/cachefiles/ directory 89 */ 90int __init cachefiles_proc_init(void) 91{ 92 _enter(""); 93 94 if (!proc_mkdir("fs/cachefiles", NULL)) 95 goto error_dir; 96 97 if (!proc_create_seq("fs/cachefiles/histogram", S_IFREG | 0444, NULL, 98 &cachefiles_histogram_ops)) 99 goto error_histogram; 100 101 _leave(" = 0"); 102 return 0; 103 104error_histogram: 105 remove_proc_entry("fs/cachefiles", NULL); 106error_dir: 107 _leave(" = -ENOMEM"); 108 return -ENOMEM; 109} 110 111/* 112 * clean up the /proc/fs/cachefiles/ directory 113 */ 114void cachefiles_proc_cleanup(void) 115{ 116 remove_proc_entry("fs/cachefiles/histogram", NULL); 117 remove_proc_entry("fs/cachefiles", NULL); 118}