Whamcloud - gitweb
LU-16993 kfilnd: Add count value to debugfs stats
[fs/lustre-release.git] / lnet / klnds / kfilnd / kfilnd_debugfs.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright 2022 Hewlett Packard Enterprise Development LP
24  */
25 /*
26  * This file is part of Lustre, http://www.lustre.org/
27  */
28 /*
29  * kfilnd device implementation.
30  */
31 #include "kfilnd.h"
32 #include "kfilnd_dev.h"
33
34 #define TIME_MAX 0xFFFFFFFFFFFF
35 static s64 get_ave_duration(struct kfilnd_tn_duration_stat *stat)
36 {
37         s64 duration;
38
39         if (!atomic_read(&stat->accumulated_count))
40                 return 0;
41
42         duration = atomic64_read(&stat->accumulated_duration) /
43                 atomic_read(&stat->accumulated_count);
44
45         return min_t(s64, duration, TIME_MAX);
46 }
47
48 static s64 get_min_duration(struct kfilnd_tn_duration_stat *stat)
49 {
50         s64 min;
51
52         min = atomic64_read(&stat->min_duration);
53         if (min == MIN_DURATION_RESET)
54                 return 0;
55         return min;
56 }
57
58 static void seq_print_tn_state_stats(struct seq_file *s, struct kfilnd_dev *dev,
59                                      bool initiator)
60 {
61         struct kfilnd_tn_state_data_size_duration_stats *state_stats;
62         unsigned int data_size;
63
64         if (initiator)
65                 state_stats = &dev->initiator_state_stats;
66         else
67                 state_stats = &dev->target_state_stats;
68
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");
74
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]));
90         }
91 }
92
93 static int kfilnd_initiator_state_stats_file_show(struct seq_file *s,
94                                                   void *unused)
95 {
96         seq_print_tn_state_stats(s, s->private, true);
97
98         return 0;
99 }
100
101 static int kfilnd_initiator_state_stats_file_open(struct inode *inode,
102                                                   struct file *file)
103 {
104         return single_open(file, kfilnd_initiator_state_stats_file_show,
105                            inode->i_private);
106 }
107
108 const struct file_operations kfilnd_initiator_state_stats_file_ops = {
109         .owner = THIS_MODULE,
110         .open = kfilnd_initiator_state_stats_file_open,
111         .read = seq_read,
112         .llseek  = seq_lseek,
113         .release = seq_release,
114 };
115
116 static int kfilnd_target_state_stats_file_show(struct seq_file *s,
117                                                void *unused)
118 {
119         seq_print_tn_state_stats(s, s->private, false);
120
121         return 0;
122 }
123
124 static int kfilnd_target_state_stats_file_open(struct inode *inode,
125                                                struct file *file)
126 {
127         return single_open(file, kfilnd_target_state_stats_file_show,
128                            inode->i_private);
129 }
130
131 const struct file_operations kfilnd_target_state_stats_file_ops = {
132         .owner = THIS_MODULE,
133         .open = kfilnd_target_state_stats_file_open,
134         .read = seq_read,
135         .llseek  = seq_lseek,
136         .release = seq_release,
137 };
138
139 static void seq_print_tn_stats(struct seq_file *s, struct kfilnd_dev *dev,
140                                bool initiator)
141 {
142         struct kfilnd_tn_data_size_duration_stats *stats;
143         unsigned int data_size;
144
145         if (initiator)
146                 stats = &dev->initiator_stats;
147         else
148                 stats = &dev->target_stats;
149
150         seq_printf(s, "%16s %16s %16s %16s %16s\n", "MSG_SIZE", "MIN", "MAX",
151                    "AVE", "COUNT");
152
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));
160         }
161 }
162
163 static int kfilnd_initiator_stats_file_show(struct seq_file *s, void *unused)
164 {
165         seq_print_tn_stats(s, s->private, true);
166
167         return 0;
168 }
169
170 static int kfilnd_initiator_stats_file_open(struct inode *inode,
171                                             struct file *file)
172 {
173         return single_open(file, kfilnd_initiator_stats_file_show,
174                            inode->i_private);
175 }
176
177 const struct file_operations kfilnd_initiator_stats_file_ops = {
178         .owner = THIS_MODULE,
179         .open = kfilnd_initiator_stats_file_open,
180         .read = seq_read,
181         .llseek  = seq_lseek,
182         .release = seq_release,
183 };
184
185 static int kfilnd_target_stats_file_show(struct seq_file *s, void *unused)
186 {
187         seq_print_tn_stats(s, s->private, false);
188
189         return 0;
190 }
191
192 static int kfilnd_target_stats_file_open(struct inode *inode, struct file *file)
193 {
194         return single_open(file, kfilnd_target_stats_file_show,
195                            inode->i_private);
196 }
197
198 const struct file_operations kfilnd_target_stats_file_ops = {
199         .owner = THIS_MODULE,
200         .open = kfilnd_target_stats_file_open,
201         .read = seq_read,
202         .llseek  = seq_lseek,
203         .release = seq_release,
204 };
205
206 static ssize_t kfilnd_reset_stats_file_write(struct file *filp,
207                                              const char __user *buf,
208                                              size_t count, loff_t *loff)
209 {
210         kfilnd_dev_reset_stats(filp->f_inode->i_private);
211
212         return count;
213 }
214
215 const struct file_operations kfilnd_reset_stats_file_ops = {
216         .owner = THIS_MODULE,
217         .write = kfilnd_reset_stats_file_write,
218 };