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