4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright 2022 Hewlett Packard Enterprise Development LP
26 * This file is part of Lustre, http://www.lustre.org/
29 * kfilnd device implementation.
32 #include "kfilnd_dev.h"
34 #define TIME_MAX 0xFFFFFFFFFFFF
35 static s64 get_ave_duration(struct kfilnd_tn_duration_stat *stat)
39 if (!atomic_read(&stat->accumulated_count))
42 duration = atomic64_read(&stat->accumulated_duration) /
43 atomic_read(&stat->accumulated_count);
45 return min_t(s64, duration, TIME_MAX);
48 static s64 get_min_duration(struct kfilnd_tn_duration_stat *stat)
52 min = atomic64_read(&stat->min_duration);
53 if (min == MIN_DURATION_RESET)
58 static void seq_print_tn_state_stats(struct seq_file *s, struct kfilnd_dev *dev,
61 struct kfilnd_tn_state_data_size_duration_stats *state_stats;
62 unsigned int data_size;
65 state_stats = &dev->initiator_state_stats;
67 state_stats = &dev->target_state_stats;
69 seq_printf(s, "%-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s %-20s\n",
70 "MSG_SIZE", "IDLE", "WAIT_TAG_COMP", "IMM_SEND",
71 "TAGGED_RECV_POSTED", "SEND_FAILED", "WAIT_COMP",
72 "WAIT_TOUT_COMP", "SEND_COMP", "WAIT_TOUT_TAG_COMP", "FAIL",
73 "IMM_RECV", "WAIT_TAG_RMA_COMP");
75 for (data_size = 0; data_size < KFILND_DATA_SIZE_BUCKETS; data_size++) {
76 seq_printf(s, "%-20lu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu %-20llu\n",
77 data_size == 0 ? 0 : BIT(data_size - 1),
78 get_ave_duration(&state_stats->state[TN_STATE_IDLE].data_size[data_size]),
79 get_ave_duration(&state_stats->state[TN_STATE_WAIT_TAG_COMP].data_size[data_size]),
80 get_ave_duration(&state_stats->state[TN_STATE_IMM_SEND].data_size[data_size]),
81 get_ave_duration(&state_stats->state[TN_STATE_TAGGED_RECV_POSTED].data_size[data_size]),
82 get_ave_duration(&state_stats->state[TN_STATE_SEND_FAILED].data_size[data_size]),
83 get_ave_duration(&state_stats->state[TN_STATE_WAIT_COMP].data_size[data_size]),
84 get_ave_duration(&state_stats->state[TN_STATE_WAIT_TIMEOUT_COMP].data_size[data_size]),
85 get_ave_duration(&state_stats->state[TN_STATE_WAIT_SEND_COMP].data_size[data_size]),
86 get_ave_duration(&state_stats->state[TN_STATE_WAIT_TIMEOUT_TAG_COMP].data_size[data_size]),
87 get_ave_duration(&state_stats->state[TN_STATE_FAIL].data_size[data_size]),
88 get_ave_duration(&state_stats->state[TN_STATE_IMM_RECV].data_size[data_size]),
89 get_ave_duration(&state_stats->state[TN_STATE_WAIT_TAG_RMA_COMP].data_size[data_size]));
93 static int kfilnd_initiator_state_stats_file_show(struct seq_file *s,
96 seq_print_tn_state_stats(s, s->private, true);
101 static int kfilnd_initiator_state_stats_file_open(struct inode *inode,
104 return single_open(file, kfilnd_initiator_state_stats_file_show,
108 const struct file_operations kfilnd_initiator_state_stats_file_ops = {
109 .owner = THIS_MODULE,
110 .open = kfilnd_initiator_state_stats_file_open,
113 .release = seq_release,
116 static int kfilnd_target_state_stats_file_show(struct seq_file *s,
119 seq_print_tn_state_stats(s, s->private, false);
124 static int kfilnd_target_state_stats_file_open(struct inode *inode,
127 return single_open(file, kfilnd_target_state_stats_file_show,
131 const struct file_operations kfilnd_target_state_stats_file_ops = {
132 .owner = THIS_MODULE,
133 .open = kfilnd_target_state_stats_file_open,
136 .release = seq_release,
139 static void seq_print_tn_stats(struct seq_file *s, struct kfilnd_dev *dev,
142 struct kfilnd_tn_data_size_duration_stats *stats;
143 unsigned int data_size;
146 stats = &dev->initiator_stats;
148 stats = &dev->target_stats;
150 seq_printf(s, "%16s %16s %16s %16s %16s\n", "MSG_SIZE", "MIN", "MAX",
153 for (data_size = 0; data_size < KFILND_DATA_SIZE_BUCKETS; data_size++) {
154 seq_printf(s, "%16lu %16llu %16llu %16llu %16d\n",
155 data_size == 0 ? 0 : BIT(data_size - 1),
156 get_min_duration(&stats->data_size[data_size]),
157 atomic64_read(&stats->data_size[data_size].max_duration),
158 get_ave_duration(&stats->data_size[data_size]),
159 atomic_read(&stats->data_size[data_size].accumulated_count));
163 static int kfilnd_initiator_stats_file_show(struct seq_file *s, void *unused)
165 seq_print_tn_stats(s, s->private, true);
170 static int kfilnd_initiator_stats_file_open(struct inode *inode,
173 return single_open(file, kfilnd_initiator_stats_file_show,
177 const struct file_operations kfilnd_initiator_stats_file_ops = {
178 .owner = THIS_MODULE,
179 .open = kfilnd_initiator_stats_file_open,
182 .release = seq_release,
185 static int kfilnd_target_stats_file_show(struct seq_file *s, void *unused)
187 seq_print_tn_stats(s, s->private, false);
192 static int kfilnd_target_stats_file_open(struct inode *inode, struct file *file)
194 return single_open(file, kfilnd_target_stats_file_show,
198 const struct file_operations kfilnd_target_stats_file_ops = {
199 .owner = THIS_MODULE,
200 .open = kfilnd_target_stats_file_open,
203 .release = seq_release,
206 static ssize_t kfilnd_reset_stats_file_write(struct file *filp,
207 const char __user *buf,
208 size_t count, loff_t *loff)
210 kfilnd_dev_reset_stats(filp->f_inode->i_private);
215 const struct file_operations kfilnd_reset_stats_file_ops = {
216 .owner = THIS_MODULE,
217 .write = kfilnd_reset_stats_file_write,