diff options
author | Narsimhulu Musini <nmusini@cisco.com> | 2013-09-09 16:31:45 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-09-11 15:47:44 -0400 |
commit | 1adee040114461787c031a792a9392a8b4866fc3 (patch) | |
tree | d1906072190719e2fe7994fb2e5bf6839b53075a /drivers/scsi/fnic | |
parent | 984f1733fcee3fbc78d47e26c5096921c5d9946a (diff) |
[SCSI] fnic: FC stat param seconds_since_last_reset not getting updated
Code to reset fc_host statistics.
echo 1 > /sys/class/fc_host/hostX/statistics/reset_statistics clears fc_host stats,
the code also issues command to fnic firmware to clear vnic stats.
Signed-off-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Hiral Patel <hiralpat@cisco.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fnic')
-rw-r--r-- | drivers/scsi/fnic/fnic.h | 5 | ||||
-rw-r--r-- | drivers/scsi/fnic/fnic_main.c | 108 |
2 files changed, 112 insertions, 1 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index c18c68150e9f..d276aaf84f18 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h | |||
@@ -154,6 +154,9 @@ do { \ | |||
154 | FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING, \ | 154 | FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING, \ |
155 | shost_printk(kern_level, host, fmt, ##args);) | 155 | shost_printk(kern_level, host, fmt, ##args);) |
156 | 156 | ||
157 | #define FNIC_MAIN_NOTE(kern_level, host, fmt, args...) \ | ||
158 | shost_printk(kern_level, host, fmt, ##args) | ||
159 | |||
157 | extern const char *fnic_state_str[]; | 160 | extern const char *fnic_state_str[]; |
158 | 161 | ||
159 | enum fnic_intx_intr_index { | 162 | enum fnic_intx_intr_index { |
@@ -215,6 +218,7 @@ struct fnic { | |||
215 | 218 | ||
216 | struct vnic_stats *stats; | 219 | struct vnic_stats *stats; |
217 | unsigned long stats_time; /* time of stats update */ | 220 | unsigned long stats_time; /* time of stats update */ |
221 | unsigned long stats_reset_time; /* time of stats reset */ | ||
218 | struct vnic_nic_cfg *nic_cfg; | 222 | struct vnic_nic_cfg *nic_cfg; |
219 | char name[IFNAMSIZ]; | 223 | char name[IFNAMSIZ]; |
220 | struct timer_list notify_timer; /* used for MSI interrupts */ | 224 | struct timer_list notify_timer; /* used for MSI interrupts */ |
@@ -359,4 +363,5 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) | |||
359 | return ((fnic->state_flags & st_flags) == st_flags); | 363 | return ((fnic->state_flags & st_flags) == st_flags); |
360 | } | 364 | } |
361 | void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); | 365 | void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); |
366 | void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *); | ||
362 | #endif /* _FNIC_H_ */ | 367 | #endif /* _FNIC_H_ */ |
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 42e15ee6e1bb..b619dabaec31 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c | |||
@@ -126,6 +126,7 @@ fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
126 | static void fnic_get_host_speed(struct Scsi_Host *shost); | 126 | static void fnic_get_host_speed(struct Scsi_Host *shost); |
127 | static struct scsi_transport_template *fnic_fc_transport; | 127 | static struct scsi_transport_template *fnic_fc_transport; |
128 | static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *); | 128 | static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *); |
129 | static void fnic_reset_host_stats(struct Scsi_Host *); | ||
129 | 130 | ||
130 | static struct fc_function_template fnic_fc_functions = { | 131 | static struct fc_function_template fnic_fc_functions = { |
131 | 132 | ||
@@ -153,6 +154,7 @@ static struct fc_function_template fnic_fc_functions = { | |||
153 | .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo, | 154 | .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo, |
154 | .issue_fc_host_lip = fnic_reset, | 155 | .issue_fc_host_lip = fnic_reset, |
155 | .get_fc_host_stats = fnic_get_stats, | 156 | .get_fc_host_stats = fnic_get_stats, |
157 | .reset_fc_host_stats = fnic_reset_host_stats, | ||
156 | .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), | 158 | .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), |
157 | .terminate_rport_io = fnic_terminate_rport_io, | 159 | .terminate_rport_io = fnic_terminate_rport_io, |
158 | .bsg_request = fc_lport_bsg_request, | 160 | .bsg_request = fc_lport_bsg_request, |
@@ -206,13 +208,116 @@ static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host) | |||
206 | stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors; | 208 | stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors; |
207 | stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop; | 209 | stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop; |
208 | stats->invalid_crc_count = vs->rx.rx_crc_errors; | 210 | stats->invalid_crc_count = vs->rx.rx_crc_errors; |
209 | stats->seconds_since_last_reset = (jiffies - lp->boot_time) / HZ; | 211 | stats->seconds_since_last_reset = |
212 | (jiffies - fnic->stats_reset_time) / HZ; | ||
210 | stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000); | 213 | stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000); |
211 | stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000); | 214 | stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000); |
212 | 215 | ||
213 | return stats; | 216 | return stats; |
214 | } | 217 | } |
215 | 218 | ||
219 | /* | ||
220 | * fnic_dump_fchost_stats | ||
221 | * note : dumps fc_statistics into system logs | ||
222 | */ | ||
223 | void fnic_dump_fchost_stats(struct Scsi_Host *host, | ||
224 | struct fc_host_statistics *stats) | ||
225 | { | ||
226 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
227 | "fnic: seconds since last reset = %llu\n", | ||
228 | stats->seconds_since_last_reset); | ||
229 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
230 | "fnic: tx frames = %llu\n", | ||
231 | stats->tx_frames); | ||
232 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
233 | "fnic: tx words = %llu\n", | ||
234 | stats->tx_words); | ||
235 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
236 | "fnic: rx frames = %llu\n", | ||
237 | stats->rx_frames); | ||
238 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
239 | "fnic: rx words = %llu\n", | ||
240 | stats->rx_words); | ||
241 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
242 | "fnic: lip count = %llu\n", | ||
243 | stats->lip_count); | ||
244 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
245 | "fnic: nos count = %llu\n", | ||
246 | stats->nos_count); | ||
247 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
248 | "fnic: error frames = %llu\n", | ||
249 | stats->error_frames); | ||
250 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
251 | "fnic: dumped frames = %llu\n", | ||
252 | stats->dumped_frames); | ||
253 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
254 | "fnic: link failure count = %llu\n", | ||
255 | stats->link_failure_count); | ||
256 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
257 | "fnic: loss of sync count = %llu\n", | ||
258 | stats->loss_of_sync_count); | ||
259 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
260 | "fnic: loss of signal count = %llu\n", | ||
261 | stats->loss_of_signal_count); | ||
262 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
263 | "fnic: prim seq protocol err count = %llu\n", | ||
264 | stats->prim_seq_protocol_err_count); | ||
265 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
266 | "fnic: invalid tx word count= %llu\n", | ||
267 | stats->invalid_tx_word_count); | ||
268 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
269 | "fnic: invalid crc count = %llu\n", | ||
270 | stats->invalid_crc_count); | ||
271 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
272 | "fnic: fcp input requests = %llu\n", | ||
273 | stats->fcp_input_requests); | ||
274 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
275 | "fnic: fcp output requests = %llu\n", | ||
276 | stats->fcp_output_requests); | ||
277 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
278 | "fnic: fcp control requests = %llu\n", | ||
279 | stats->fcp_control_requests); | ||
280 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
281 | "fnic: fcp input megabytes = %llu\n", | ||
282 | stats->fcp_input_megabytes); | ||
283 | FNIC_MAIN_NOTE(KERN_NOTICE, host, | ||
284 | "fnic: fcp output megabytes = %llu\n", | ||
285 | stats->fcp_output_megabytes); | ||
286 | return; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * fnic_reset_host_stats : clears host stats | ||
291 | * note : called when reset_statistics set under sysfs dir | ||
292 | */ | ||
293 | static void fnic_reset_host_stats(struct Scsi_Host *host) | ||
294 | { | ||
295 | int ret; | ||
296 | struct fc_lport *lp = shost_priv(host); | ||
297 | struct fnic *fnic = lport_priv(lp); | ||
298 | struct fc_host_statistics *stats; | ||
299 | unsigned long flags; | ||
300 | |||
301 | /* dump current stats, before clearing them */ | ||
302 | stats = fnic_get_stats(host); | ||
303 | fnic_dump_fchost_stats(host, stats); | ||
304 | |||
305 | spin_lock_irqsave(&fnic->fnic_lock, flags); | ||
306 | ret = vnic_dev_stats_clear(fnic->vdev); | ||
307 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | ||
308 | |||
309 | if (ret) { | ||
310 | FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host, | ||
311 | "fnic: Reset vnic stats failed" | ||
312 | " 0x%x", ret); | ||
313 | return; | ||
314 | } | ||
315 | fnic->stats_reset_time = jiffies; | ||
316 | memset(stats, 0, sizeof(*stats)); | ||
317 | |||
318 | return; | ||
319 | } | ||
320 | |||
216 | void fnic_log_q_error(struct fnic *fnic) | 321 | void fnic_log_q_error(struct fnic *fnic) |
217 | { | 322 | { |
218 | unsigned int i; | 323 | unsigned int i; |
@@ -719,6 +824,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
719 | } | 824 | } |
720 | 825 | ||
721 | fc_lport_init_stats(lp); | 826 | fc_lport_init_stats(lp); |
827 | fnic->stats_reset_time = jiffies; | ||
722 | 828 | ||
723 | fc_lport_config(lp); | 829 | fc_lport_config(lp); |
724 | 830 | ||