diff options
author | Steve French <stfrench@microsoft.com> | 2019-03-26 14:53:21 -0400 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-05-08 00:24:54 -0400 |
commit | 433b8dd7672be1140ffbb17eacba776298bf4733 (patch) | |
tree | 101f08af23bd07fd74e55000ba1f0ce5e5a8261c /fs/cifs | |
parent | d3511f53bb2475f2a4e8460bee5a1ae6dea2a433 (diff) |
SMB3: Track total time spent on roundtrips for each SMB3 command
Also track minimum and maximum time by command in /proc/fs/cifs/Stats
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifs_debug.c | 19 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 4 | ||||
-rw-r--r-- | fs/cifs/transport.c | 27 |
3 files changed, 44 insertions, 6 deletions
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 13c1288b04a7..19ed9abe00de 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -462,8 +462,13 @@ static ssize_t cifs_stats_proc_write(struct file *file, | |||
462 | server = list_entry(tmp1, struct TCP_Server_Info, | 462 | server = list_entry(tmp1, struct TCP_Server_Info, |
463 | tcp_ses_list); | 463 | tcp_ses_list); |
464 | #ifdef CONFIG_CIFS_STATS2 | 464 | #ifdef CONFIG_CIFS_STATS2 |
465 | for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) | 465 | for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { |
466 | atomic_set(&server->num_cmds[i], 0); | ||
466 | atomic_set(&server->smb2slowcmd[i], 0); | 467 | atomic_set(&server->smb2slowcmd[i], 0); |
468 | server->time_per_cmd[i] = 0; | ||
469 | server->slowest_cmd[i] = 0; | ||
470 | server->fastest_cmd[0] = 0; | ||
471 | } | ||
467 | #endif /* CONFIG_CIFS_STATS2 */ | 472 | #endif /* CONFIG_CIFS_STATS2 */ |
468 | list_for_each(tmp2, &server->smb_ses_list) { | 473 | list_for_each(tmp2, &server->smb_ses_list) { |
469 | ses = list_entry(tmp2, struct cifs_ses, | 474 | ses = list_entry(tmp2, struct cifs_ses, |
@@ -531,9 +536,19 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) | |||
531 | server = list_entry(tmp1, struct TCP_Server_Info, | 536 | server = list_entry(tmp1, struct TCP_Server_Info, |
532 | tcp_ses_list); | 537 | tcp_ses_list); |
533 | #ifdef CONFIG_CIFS_STATS2 | 538 | #ifdef CONFIG_CIFS_STATS2 |
539 | seq_puts(m, "\nTotal time spent processing by command. Time "); | ||
540 | seq_printf(m, "units are jiffies (%d per second)\n", HZ); | ||
541 | seq_puts(m, " SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n"); | ||
542 | seq_puts(m, " --------\t------\t----------\t-------\t-------\n"); | ||
543 | for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) | ||
544 | seq_printf(m, " %d\t\t%d\t%llu\t\t%u\t%u\n", j, | ||
545 | atomic_read(&server->num_cmds[j]), | ||
546 | server->time_per_cmd[j], | ||
547 | server->fastest_cmd[j], | ||
548 | server->slowest_cmd[j]); | ||
534 | for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) | 549 | for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) |
535 | if (atomic_read(&server->smb2slowcmd[j])) | 550 | if (atomic_read(&server->smb2slowcmd[j])) |
536 | seq_printf(m, "%d slow responses from %s for command %d\n", | 551 | seq_printf(m, " %d slow responses from %s for command %d\n", |
537 | atomic_read(&server->smb2slowcmd[j]), | 552 | atomic_read(&server->smb2slowcmd[j]), |
538 | server->hostname, j); | 553 | server->hostname, j); |
539 | #endif /* STATS2 */ | 554 | #endif /* STATS2 */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 585ad3207cb1..779ceb1f0412 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -714,7 +714,11 @@ struct TCP_Server_Info { | |||
714 | #ifdef CONFIG_CIFS_STATS2 | 714 | #ifdef CONFIG_CIFS_STATS2 |
715 | atomic_t in_send; /* requests trying to send */ | 715 | atomic_t in_send; /* requests trying to send */ |
716 | atomic_t num_waiters; /* blocked waiting to get in sendrecv */ | 716 | atomic_t num_waiters; /* blocked waiting to get in sendrecv */ |
717 | atomic_t num_cmds[NUMBER_OF_SMB2_COMMANDS]; /* total requests by cmd */ | ||
717 | atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ | 718 | atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ |
719 | __u64 time_per_cmd[NUMBER_OF_SMB2_COMMANDS]; /* total time per cmd */ | ||
720 | __u32 slowest_cmd[NUMBER_OF_SMB2_COMMANDS]; | ||
721 | __u32 fastest_cmd[NUMBER_OF_SMB2_COMMANDS]; | ||
718 | #endif /* STATS2 */ | 722 | #endif /* STATS2 */ |
719 | unsigned int max_read; | 723 | unsigned int max_read; |
720 | unsigned int max_write; | 724 | unsigned int max_write; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 1de8e996e566..65d9f3e2eb88 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -104,7 +104,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) | |||
104 | { | 104 | { |
105 | #ifdef CONFIG_CIFS_STATS2 | 105 | #ifdef CONFIG_CIFS_STATS2 |
106 | __le16 command = midEntry->server->vals->lock_cmd; | 106 | __le16 command = midEntry->server->vals->lock_cmd; |
107 | __u16 smb_cmd = le16_to_cpu(midEntry->command); | ||
107 | unsigned long now; | 108 | unsigned long now; |
109 | unsigned long roundtrip_time; | ||
110 | struct TCP_Server_Info *server = midEntry->server; | ||
108 | #endif | 111 | #endif |
109 | midEntry->mid_state = MID_FREE; | 112 | midEntry->mid_state = MID_FREE; |
110 | atomic_dec(&midCount); | 113 | atomic_dec(&midCount); |
@@ -114,6 +117,23 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) | |||
114 | cifs_small_buf_release(midEntry->resp_buf); | 117 | cifs_small_buf_release(midEntry->resp_buf); |
115 | #ifdef CONFIG_CIFS_STATS2 | 118 | #ifdef CONFIG_CIFS_STATS2 |
116 | now = jiffies; | 119 | now = jiffies; |
120 | if (now < midEntry->when_alloc) | ||
121 | cifs_dbg(VFS, "invalid mid allocation time\n"); | ||
122 | roundtrip_time = now - midEntry->when_alloc; | ||
123 | |||
124 | if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) { | ||
125 | if (atomic_read(&server->num_cmds[smb_cmd]) == 0) { | ||
126 | server->slowest_cmd[smb_cmd] = roundtrip_time; | ||
127 | server->fastest_cmd[smb_cmd] = roundtrip_time; | ||
128 | } else { | ||
129 | if (server->slowest_cmd[smb_cmd] < roundtrip_time) | ||
130 | server->slowest_cmd[smb_cmd] = roundtrip_time; | ||
131 | else if (server->fastest_cmd[smb_cmd] > roundtrip_time) | ||
132 | server->fastest_cmd[smb_cmd] = roundtrip_time; | ||
133 | } | ||
134 | cifs_stats_inc(&server->num_cmds[smb_cmd]); | ||
135 | server->time_per_cmd[smb_cmd] += roundtrip_time; | ||
136 | } | ||
117 | /* | 137 | /* |
118 | * commands taking longer than one second (default) can be indications | 138 | * commands taking longer than one second (default) can be indications |
119 | * that something is wrong, unless it is quite a slow link or a very | 139 | * that something is wrong, unless it is quite a slow link or a very |
@@ -131,11 +151,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) | |||
131 | * smb2slowcmd[NUMBER_OF_SMB2_COMMANDS] counts by command | 151 | * smb2slowcmd[NUMBER_OF_SMB2_COMMANDS] counts by command |
132 | * NB: le16_to_cpu returns unsigned so can not be negative below | 152 | * NB: le16_to_cpu returns unsigned so can not be negative below |
133 | */ | 153 | */ |
134 | if (le16_to_cpu(midEntry->command) < NUMBER_OF_SMB2_COMMANDS) | 154 | if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) |
135 | cifs_stats_inc(&midEntry->server->smb2slowcmd[le16_to_cpu(midEntry->command)]); | 155 | cifs_stats_inc(&server->smb2slowcmd[smb_cmd]); |
136 | 156 | ||
137 | trace_smb3_slow_rsp(le16_to_cpu(midEntry->command), | 157 | trace_smb3_slow_rsp(smb_cmd, midEntry->mid, midEntry->pid, |
138 | midEntry->mid, midEntry->pid, | ||
139 | midEntry->when_sent, midEntry->when_received); | 158 | midEntry->when_sent, midEntry->when_received); |
140 | if (cifsFYI & CIFS_TIMER) { | 159 | if (cifsFYI & CIFS_TIMER) { |
141 | pr_debug(" CIFS slow rsp: cmd %d mid %llu", | 160 | pr_debug(" CIFS slow rsp: cmd %d mid %llu", |