| From: Jason Xing <kernelxing@tencent.com> |
| Subject: relayfs: introduce getting relayfs statistics function |
| Date: Thu, 12 Jun 2025 14:11:59 +0800 |
| |
| In this version, only support getting the counter for buffer full and |
| implement the framework of how it works. |
| |
| Users can pass certain flag to fetch what field/statistics they expect to |
| know. Each time it only returns one result. So do not pass multiple |
| flags. |
| |
| Link: https://lkml.kernel.org/r/20250612061201.34272-4-kerneljasonxing@gmail.com |
| Signed-off-by: Jason Xing <kernelxing@tencent.com> |
| Reviewed-by: Yushan Zhou <katrinzhou@tencent.com> |
| Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> |
| Cc: Jens Axboe <axboe@kernel.dk> |
| Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| include/linux/relay.h | 7 +++++++ |
| kernel/relay.c | 30 ++++++++++++++++++++++++++++++ |
| 2 files changed, 37 insertions(+) |
| |
| --- a/include/linux/relay.h~relayfs-introduce-getting-relayfs-statistics-function |
| +++ a/include/linux/relay.h |
| @@ -31,6 +31,12 @@ |
| /* |
| * Relay buffer statistics |
| */ |
| +enum { |
| + RELAY_STATS_BUF_FULL = (1 << 0), |
| + |
| + RELAY_STATS_LAST = RELAY_STATS_BUF_FULL, |
| +}; |
| + |
| struct rchan_buf_stats |
| { |
| unsigned int full_count; /* counter for buffer full */ |
| @@ -167,6 +173,7 @@ struct rchan *relay_open(const char *bas |
| void *private_data); |
| extern void relay_close(struct rchan *chan); |
| extern void relay_flush(struct rchan *chan); |
| +size_t relay_stats(struct rchan *chan, int flags); |
| extern void relay_subbufs_consumed(struct rchan *chan, |
| unsigned int cpu, |
| size_t consumed); |
| --- a/kernel/relay.c~relayfs-introduce-getting-relayfs-statistics-function |
| +++ a/kernel/relay.c |
| @@ -701,6 +701,36 @@ void relay_flush(struct rchan *chan) |
| EXPORT_SYMBOL_GPL(relay_flush); |
| |
| /** |
| + * relay_stats - get channel buffer statistics |
| + * @chan: the channel |
| + * @flags: select particular information to get |
| + * |
| + * Returns the count of certain field that caller specifies. |
| + */ |
| +size_t relay_stats(struct rchan *chan, int flags) |
| +{ |
| + unsigned int i, count = 0; |
| + struct rchan_buf *rbuf; |
| + |
| + if (!chan || flags > RELAY_STATS_LAST) |
| + return 0; |
| + |
| + if (chan->is_global) { |
| + rbuf = *per_cpu_ptr(chan->buf, 0); |
| + if (flags & RELAY_STATS_BUF_FULL) |
| + count = rbuf->stats.full_count; |
| + } else { |
| + for_each_online_cpu(i) { |
| + rbuf = *per_cpu_ptr(chan->buf, i); |
| + if (rbuf && flags & RELAY_STATS_BUF_FULL) |
| + count += rbuf->stats.full_count; |
| + } |
| + } |
| + |
| + return count; |
| +} |
| + |
| +/** |
| * relay_file_open - open file op for relay files |
| * @inode: the inode |
| * @filp: the file |
| _ |