1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
211c556b3SChuck Lever /*
311c556b3SChuck Lever * linux/include/linux/sunrpc/metrics.h
411c556b3SChuck Lever *
511c556b3SChuck Lever * Declarations for RPC client per-operation metrics
611c556b3SChuck Lever *
711c556b3SChuck Lever * Copyright (C) 2005 Chuck Lever <cel@netapp.com>
811c556b3SChuck Lever *
911c556b3SChuck Lever * RPC client per-operation statistics provide latency and retry
1011c556b3SChuck Lever * information about each type of RPC procedure in a given RPC program.
1111c556b3SChuck Lever * These statistics are not for detailed problem diagnosis, but simply
1211c556b3SChuck Lever * to indicate whether the problem is local or remote.
1311c556b3SChuck Lever *
1411c556b3SChuck Lever * These counters are not meant to be human-readable, but are meant to be
1511c556b3SChuck Lever * integrated into system monitoring tools such as "sar" and "iostat". As
1611c556b3SChuck Lever * such, the counters are sampled by the tools over time, and are never
1711c556b3SChuck Lever * zeroed after a file system is mounted. Moving averages can be computed
1811c556b3SChuck Lever * by the tools by taking the difference between two instantaneous samples
1911c556b3SChuck Lever * and dividing that by the time between the samples.
2011c556b3SChuck Lever *
2111c556b3SChuck Lever * The counters are maintained in a single array per RPC client, indexed
2211c556b3SChuck Lever * by procedure number. There is no need to maintain separate counter
2311c556b3SChuck Lever * arrays per-CPU because these counters are always modified behind locks.
2411c556b3SChuck Lever */
2511c556b3SChuck Lever
2611c556b3SChuck Lever #ifndef _LINUX_SUNRPC_METRICS_H
2711c556b3SChuck Lever #define _LINUX_SUNRPC_METRICS_H
2811c556b3SChuck Lever
2911c556b3SChuck Lever #include <linux/seq_file.h>
30ff839970SChuck Lever #include <linux/ktime.h>
31edef1297SChuck Lever #include <linux/spinlock.h>
3211c556b3SChuck Lever
33a332518fSDave Wysochanski #define RPC_IOSTATS_VERS "1.1"
3411c556b3SChuck Lever
3511c556b3SChuck Lever struct rpc_iostats {
36edef1297SChuck Lever spinlock_t om_lock;
37edef1297SChuck Lever
3811c556b3SChuck Lever /*
3911c556b3SChuck Lever * These counters give an idea about how many request
4011c556b3SChuck Lever * transmissions are required, on average, to complete that
4111c556b3SChuck Lever * particular procedure. Some procedures may require more
4211c556b3SChuck Lever * than one transmission because the server is unresponsive,
4311c556b3SChuck Lever * the client is retransmitting too aggressively, or the
4411c556b3SChuck Lever * requests are large and the network is congested.
4511c556b3SChuck Lever */
4611c556b3SChuck Lever unsigned long om_ops, /* count of operations */
4711c556b3SChuck Lever om_ntrans, /* count of RPC transmissions */
4811c556b3SChuck Lever om_timeouts; /* count of major timeouts */
4911c556b3SChuck Lever
5011c556b3SChuck Lever /*
5111c556b3SChuck Lever * These count how many bytes are sent and received for a
5211c556b3SChuck Lever * given RPC procedure type. This indicates how much load a
5311c556b3SChuck Lever * particular procedure is putting on the network. These
5411c556b3SChuck Lever * counts include the RPC and ULP headers, and the request
5511c556b3SChuck Lever * payload.
5611c556b3SChuck Lever */
5711c556b3SChuck Lever unsigned long long om_bytes_sent, /* count of bytes out */
5811c556b3SChuck Lever om_bytes_recv; /* count of bytes in */
5911c556b3SChuck Lever
6011c556b3SChuck Lever /*
6111c556b3SChuck Lever * The length of time an RPC request waits in queue before
6211c556b3SChuck Lever * transmission, the network + server latency of the request,
6311c556b3SChuck Lever * and the total time the request spent from init to release
6411c556b3SChuck Lever * are measured.
6511c556b3SChuck Lever */
66ff839970SChuck Lever ktime_t om_queue, /* queued for xmit */
67ff839970SChuck Lever om_rtt, /* RPC RTT */
68ff839970SChuck Lever om_execute; /* RPC execution */
69a332518fSDave Wysochanski /*
70a332518fSDave Wysochanski * The count of operations that complete with tk_status < 0.
71a332518fSDave Wysochanski * These statuses usually indicate error conditions.
72a332518fSDave Wysochanski */
73a332518fSDave Wysochanski unsigned long om_error_status;
7411c556b3SChuck Lever } ____cacheline_aligned;
7511c556b3SChuck Lever
7611c556b3SChuck Lever struct rpc_task;
7711c556b3SChuck Lever struct rpc_clnt;
7811c556b3SChuck Lever
7911c556b3SChuck Lever /*
8011c556b3SChuck Lever * EXPORTed functions for managing rpc_iostats structures
8111c556b3SChuck Lever */
827866babaSAdrian Bunk
837866babaSAdrian Bunk #ifdef CONFIG_PROC_FS
847866babaSAdrian Bunk
8511c556b3SChuck Lever struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *);
860a702195SWeston Andros Adamson void rpc_count_iostats(const struct rpc_task *,
870a702195SWeston Andros Adamson struct rpc_iostats *);
88840210fcSWeston Andros Adamson void rpc_count_iostats_metrics(const struct rpc_task *,
89840210fcSWeston Andros Adamson struct rpc_iostats *);
90016583d7SDave Wysochanski void rpc_clnt_show_stats(struct seq_file *, struct rpc_clnt *);
9111c556b3SChuck Lever void rpc_free_iostats(struct rpc_iostats *);
9211c556b3SChuck Lever
937866babaSAdrian Bunk #else /* CONFIG_PROC_FS */
947866babaSAdrian Bunk
rpc_alloc_iostats(struct rpc_clnt * clnt)957866babaSAdrian Bunk static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
rpc_count_iostats(const struct rpc_task * task,struct rpc_iostats * stats)960a702195SWeston Andros Adamson static inline void rpc_count_iostats(const struct rpc_task *task,
970a702195SWeston Andros Adamson struct rpc_iostats *stats) {}
rpc_count_iostats_metrics(const struct rpc_task * task,struct rpc_iostats * stats)9854d7e72aSTrond Myklebust static inline void rpc_count_iostats_metrics(const struct rpc_task *task,
9954d7e72aSTrond Myklebust struct rpc_iostats *stats)
10054d7e72aSTrond Myklebust {
10154d7e72aSTrond Myklebust }
10254d7e72aSTrond Myklebust
rpc_clnt_show_stats(struct seq_file * seq,struct rpc_clnt * clnt)103016583d7SDave Wysochanski static inline void rpc_clnt_show_stats(struct seq_file *seq, struct rpc_clnt *clnt) {}
rpc_free_iostats(struct rpc_iostats * stats)1047866babaSAdrian Bunk static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
1057866babaSAdrian Bunk
1067866babaSAdrian Bunk #endif /* CONFIG_PROC_FS */
1077866babaSAdrian Bunk
10811c556b3SChuck Lever #endif /* _LINUX_SUNRPC_METRICS_H */
109