1d9ef5a8cSChuck Lever /* 2d9ef5a8cSChuck Lever * linux/fs/nfs/iostat.h 3d9ef5a8cSChuck Lever * 4d9ef5a8cSChuck Lever * Declarations for NFS client per-mount statistics 5d9ef5a8cSChuck Lever * 6d9ef5a8cSChuck Lever * Copyright (C) 2005, 2006 Chuck Lever <cel@netapp.com> 7d9ef5a8cSChuck Lever * 8d9ef5a8cSChuck Lever * NFS client per-mount statistics provide information about the health of 9d9ef5a8cSChuck Lever * the NFS client and the health of each NFS mount point. Generally these 10d9ef5a8cSChuck Lever * are not for detailed problem diagnosis, but simply to indicate that there 11d9ef5a8cSChuck Lever * is a problem. 12d9ef5a8cSChuck Lever * 13d9ef5a8cSChuck Lever * These counters are not meant to be human-readable, but are meant to be 14d9ef5a8cSChuck Lever * integrated into system monitoring tools such as "sar" and "iostat". As 15d9ef5a8cSChuck Lever * such, the counters are sampled by the tools over time, and are never 16d9ef5a8cSChuck Lever * zeroed after a file system is mounted. Moving averages can be computed 17d9ef5a8cSChuck Lever * by the tools by taking the difference between two instantaneous samples 18d9ef5a8cSChuck Lever * and dividing that by the time between the samples. 19d9ef5a8cSChuck Lever */ 20d9ef5a8cSChuck Lever 21d9ef5a8cSChuck Lever #ifndef _NFS_IOSTAT 22d9ef5a8cSChuck Lever #define _NFS_IOSTAT 23d9ef5a8cSChuck Lever 24d9ef5a8cSChuck Lever #define NFS_IOSTAT_VERS "1.0" 25d9ef5a8cSChuck Lever 26d9ef5a8cSChuck Lever /* 27d9ef5a8cSChuck Lever * NFS byte counters 28d9ef5a8cSChuck Lever * 29d9ef5a8cSChuck Lever * 1. SERVER - the number of payload bytes read from or written to the 30d9ef5a8cSChuck Lever * server by the NFS client via an NFS READ or WRITE request. 31d9ef5a8cSChuck Lever * 32d9ef5a8cSChuck Lever * 2. NORMAL - the number of bytes read or written by applications via 33d9ef5a8cSChuck Lever * the read(2) and write(2) system call interfaces. 34d9ef5a8cSChuck Lever * 35d9ef5a8cSChuck Lever * 3. DIRECT - the number of bytes read or written from files opened 36d9ef5a8cSChuck Lever * with the O_DIRECT flag. 37d9ef5a8cSChuck Lever * 38d9ef5a8cSChuck Lever * These counters give a view of the data throughput into and out of the NFS 39d9ef5a8cSChuck Lever * client. Comparing the number of bytes requested by an application with the 40d9ef5a8cSChuck Lever * number of bytes the client requests from the server can provide an 41d9ef5a8cSChuck Lever * indication of client efficiency (per-op, cache hits, etc). 42d9ef5a8cSChuck Lever * 43d9ef5a8cSChuck Lever * These counters can also help characterize which access methods are in 44d9ef5a8cSChuck Lever * use. DIRECT by itself shows whether there is any O_DIRECT traffic. 45d9ef5a8cSChuck Lever * NORMAL + DIRECT shows how much data is going through the system call 46d9ef5a8cSChuck Lever * interface. A large amount of SERVER traffic without much NORMAL or 47d9ef5a8cSChuck Lever * DIRECT traffic shows that applications are using mapped files. 48d9ef5a8cSChuck Lever * 49d9ef5a8cSChuck Lever * NFS page counters 50d9ef5a8cSChuck Lever * 51d9ef5a8cSChuck Lever * These count the number of pages read or written via nfs_readpage(), 52d9ef5a8cSChuck Lever * nfs_readpages(), or their write equivalents. 53d9ef5a8cSChuck Lever */ 54d9ef5a8cSChuck Lever enum nfs_stat_bytecounters { 55d9ef5a8cSChuck Lever NFSIOS_NORMALREADBYTES = 0, 56d9ef5a8cSChuck Lever NFSIOS_NORMALWRITTENBYTES, 57d9ef5a8cSChuck Lever NFSIOS_DIRECTREADBYTES, 58d9ef5a8cSChuck Lever NFSIOS_DIRECTWRITTENBYTES, 59d9ef5a8cSChuck Lever NFSIOS_SERVERREADBYTES, 60d9ef5a8cSChuck Lever NFSIOS_SERVERWRITTENBYTES, 61d9ef5a8cSChuck Lever NFSIOS_READPAGES, 62d9ef5a8cSChuck Lever NFSIOS_WRITEPAGES, 63d9ef5a8cSChuck Lever __NFSIOS_BYTESMAX, 64d9ef5a8cSChuck Lever }; 65d9ef5a8cSChuck Lever 66d9ef5a8cSChuck Lever /* 67d9ef5a8cSChuck Lever * NFS event counters 68d9ef5a8cSChuck Lever * 69d9ef5a8cSChuck Lever * These counters provide a low-overhead way of monitoring client activity 70d9ef5a8cSChuck Lever * without enabling NFS trace debugging. The counters show the rate at 71d9ef5a8cSChuck Lever * which VFS requests are made, and how often the client invalidates its 72d9ef5a8cSChuck Lever * data and attribute caches. This allows system administrators to monitor 73d9ef5a8cSChuck Lever * such things as how close-to-open is working, and answer questions such 74d9ef5a8cSChuck Lever * as "why are there so many GETATTR requests on the wire?" 75d9ef5a8cSChuck Lever * 76d9ef5a8cSChuck Lever * They also count anamolous events such as short reads and writes, silly 77d9ef5a8cSChuck Lever * renames due to close-after-delete, and operations that change the size 78d9ef5a8cSChuck Lever * of a file (such operations can often be the source of data corruption 79d9ef5a8cSChuck Lever * if applications aren't using file locking properly). 80d9ef5a8cSChuck Lever */ 81d9ef5a8cSChuck Lever enum nfs_stat_eventcounters { 82d9ef5a8cSChuck Lever NFSIOS_INODEREVALIDATE = 0, 83d9ef5a8cSChuck Lever NFSIOS_DENTRYREVALIDATE, 84d9ef5a8cSChuck Lever NFSIOS_DATAINVALIDATE, 85d9ef5a8cSChuck Lever NFSIOS_ATTRINVALIDATE, 86d9ef5a8cSChuck Lever NFSIOS_VFSOPEN, 87d9ef5a8cSChuck Lever NFSIOS_VFSLOOKUP, 88d9ef5a8cSChuck Lever NFSIOS_VFSACCESS, 89d9ef5a8cSChuck Lever NFSIOS_VFSUPDATEPAGE, 90d9ef5a8cSChuck Lever NFSIOS_VFSREADPAGE, 91d9ef5a8cSChuck Lever NFSIOS_VFSREADPAGES, 92d9ef5a8cSChuck Lever NFSIOS_VFSWRITEPAGE, 93d9ef5a8cSChuck Lever NFSIOS_VFSWRITEPAGES, 94d9ef5a8cSChuck Lever NFSIOS_VFSGETDENTS, 95d9ef5a8cSChuck Lever NFSIOS_VFSSETATTR, 96d9ef5a8cSChuck Lever NFSIOS_VFSFLUSH, 97d9ef5a8cSChuck Lever NFSIOS_VFSFSYNC, 98d9ef5a8cSChuck Lever NFSIOS_VFSLOCK, 99d9ef5a8cSChuck Lever NFSIOS_VFSRELEASE, 100d9ef5a8cSChuck Lever NFSIOS_CONGESTIONWAIT, 101d9ef5a8cSChuck Lever NFSIOS_SETATTRTRUNC, 102d9ef5a8cSChuck Lever NFSIOS_EXTENDWRITE, 103d9ef5a8cSChuck Lever NFSIOS_SILLYRENAME, 104d9ef5a8cSChuck Lever NFSIOS_SHORTREAD, 105d9ef5a8cSChuck Lever NFSIOS_SHORTWRITE, 106*006ea73eSChuck Lever NFSIOS_DELAY, 107d9ef5a8cSChuck Lever __NFSIOS_COUNTSMAX, 108d9ef5a8cSChuck Lever }; 109d9ef5a8cSChuck Lever 110d9ef5a8cSChuck Lever #ifdef __KERNEL__ 111d9ef5a8cSChuck Lever 112d9ef5a8cSChuck Lever #include <linux/percpu.h> 113d9ef5a8cSChuck Lever #include <linux/cache.h> 114d9ef5a8cSChuck Lever 115d9ef5a8cSChuck Lever struct nfs_iostats { 116d9ef5a8cSChuck Lever unsigned long long bytes[__NFSIOS_BYTESMAX]; 117d9ef5a8cSChuck Lever unsigned long events[__NFSIOS_COUNTSMAX]; 118d9ef5a8cSChuck Lever } ____cacheline_aligned; 119d9ef5a8cSChuck Lever 120*006ea73eSChuck Lever static inline void nfs_inc_server_stats(struct nfs_server *server, enum nfs_stat_eventcounters stat) 121d9ef5a8cSChuck Lever { 122d9ef5a8cSChuck Lever struct nfs_iostats *iostats; 123d9ef5a8cSChuck Lever int cpu; 124d9ef5a8cSChuck Lever 125d9ef5a8cSChuck Lever cpu = get_cpu(); 126*006ea73eSChuck Lever iostats = per_cpu_ptr(server->io_stats, cpu); 127d9ef5a8cSChuck Lever iostats->events[stat] ++; 128d9ef5a8cSChuck Lever put_cpu_no_resched(); 129d9ef5a8cSChuck Lever } 130d9ef5a8cSChuck Lever 131*006ea73eSChuck Lever static inline void nfs_inc_stats(struct inode *inode, enum nfs_stat_eventcounters stat) 132*006ea73eSChuck Lever { 133*006ea73eSChuck Lever nfs_inc_server_stats(NFS_SERVER(inode), stat); 134*006ea73eSChuck Lever } 135*006ea73eSChuck Lever 136*006ea73eSChuck Lever static inline void nfs_add_server_stats(struct nfs_server *server, enum nfs_stat_bytecounters stat, unsigned long addend) 137*006ea73eSChuck Lever { 138*006ea73eSChuck Lever struct nfs_iostats *iostats; 139*006ea73eSChuck Lever int cpu; 140*006ea73eSChuck Lever 141*006ea73eSChuck Lever cpu = get_cpu(); 142*006ea73eSChuck Lever iostats = per_cpu_ptr(server->io_stats, cpu); 143*006ea73eSChuck Lever iostats->bytes[stat] += addend; 144*006ea73eSChuck Lever put_cpu_no_resched(); 145*006ea73eSChuck Lever } 146*006ea73eSChuck Lever 147d9ef5a8cSChuck Lever static inline void nfs_add_stats(struct inode *inode, enum nfs_stat_bytecounters stat, unsigned long addend) 148d9ef5a8cSChuck Lever { 149*006ea73eSChuck Lever nfs_add_server_stats(NFS_SERVER(inode), stat, addend); 150d9ef5a8cSChuck Lever } 151d9ef5a8cSChuck Lever 152d9ef5a8cSChuck Lever static inline struct nfs_iostats *nfs_alloc_iostats(void) 153d9ef5a8cSChuck Lever { 154d9ef5a8cSChuck Lever return alloc_percpu(struct nfs_iostats); 155d9ef5a8cSChuck Lever } 156d9ef5a8cSChuck Lever 157d9ef5a8cSChuck Lever static inline void nfs_free_iostats(struct nfs_iostats *stats) 158d9ef5a8cSChuck Lever { 159d9ef5a8cSChuck Lever free_percpu(stats); 160d9ef5a8cSChuck Lever } 161d9ef5a8cSChuck Lever 162d9ef5a8cSChuck Lever #endif 163d9ef5a8cSChuck Lever #endif 164