[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>

authored by Narsimhulu Musini and committed by James Bottomley 1adee040 984f1733

+112 -1
+5
drivers/scsi/fnic/fnic.h
··· 154 154 FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING, \ 155 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 160 extern const char *fnic_state_str[]; 158 161 159 162 enum fnic_intx_intr_index { ··· 218 215 219 216 struct vnic_stats *stats; 220 217 unsigned long stats_time; /* time of stats update */ 218 + unsigned long stats_reset_time; /* time of stats reset */ 221 219 struct vnic_nic_cfg *nic_cfg; 222 220 char name[IFNAMSIZ]; 223 221 struct timer_list notify_timer; /* used for MSI interrupts */ ··· 363 359 return ((fnic->state_flags & st_flags) == st_flags); 364 360 } 365 361 void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); 362 + void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *); 366 363 #endif /* _FNIC_H_ */
+107 -1
drivers/scsi/fnic/fnic_main.c
··· 126 126 static void fnic_get_host_speed(struct Scsi_Host *shost); 127 127 static struct scsi_transport_template *fnic_fc_transport; 128 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 131 static struct fc_function_template fnic_fc_functions = { 131 132 ··· 154 153 .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo, 155 154 .issue_fc_host_lip = fnic_reset, 156 155 .get_fc_host_stats = fnic_get_stats, 156 + .reset_fc_host_stats = fnic_reset_host_stats, 157 157 .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), 158 158 .terminate_rport_io = fnic_terminate_rport_io, 159 159 .bsg_request = fc_lport_bsg_request, ··· 208 206 stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors; 209 207 stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop; 210 208 stats->invalid_crc_count = vs->rx.rx_crc_errors; 211 - stats->seconds_since_last_reset = (jiffies - lp->boot_time) / HZ; 209 + stats->seconds_since_last_reset = 210 + (jiffies - fnic->stats_reset_time) / HZ; 212 211 stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000); 213 212 stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000); 214 213 215 214 return stats; 215 + } 216 + 217 + /* 218 + * fnic_dump_fchost_stats 219 + * note : dumps fc_statistics into system logs 220 + */ 221 + void fnic_dump_fchost_stats(struct Scsi_Host *host, 222 + struct fc_host_statistics *stats) 223 + { 224 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 225 + "fnic: seconds since last reset = %llu\n", 226 + stats->seconds_since_last_reset); 227 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 228 + "fnic: tx frames = %llu\n", 229 + stats->tx_frames); 230 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 231 + "fnic: tx words = %llu\n", 232 + stats->tx_words); 233 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 234 + "fnic: rx frames = %llu\n", 235 + stats->rx_frames); 236 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 237 + "fnic: rx words = %llu\n", 238 + stats->rx_words); 239 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 240 + "fnic: lip count = %llu\n", 241 + stats->lip_count); 242 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 243 + "fnic: nos count = %llu\n", 244 + stats->nos_count); 245 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 246 + "fnic: error frames = %llu\n", 247 + stats->error_frames); 248 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 249 + "fnic: dumped frames = %llu\n", 250 + stats->dumped_frames); 251 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 252 + "fnic: link failure count = %llu\n", 253 + stats->link_failure_count); 254 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 255 + "fnic: loss of sync count = %llu\n", 256 + stats->loss_of_sync_count); 257 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 258 + "fnic: loss of signal count = %llu\n", 259 + stats->loss_of_signal_count); 260 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 261 + "fnic: prim seq protocol err count = %llu\n", 262 + stats->prim_seq_protocol_err_count); 263 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 264 + "fnic: invalid tx word count= %llu\n", 265 + stats->invalid_tx_word_count); 266 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 267 + "fnic: invalid crc count = %llu\n", 268 + stats->invalid_crc_count); 269 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 270 + "fnic: fcp input requests = %llu\n", 271 + stats->fcp_input_requests); 272 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 273 + "fnic: fcp output requests = %llu\n", 274 + stats->fcp_output_requests); 275 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 276 + "fnic: fcp control requests = %llu\n", 277 + stats->fcp_control_requests); 278 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 279 + "fnic: fcp input megabytes = %llu\n", 280 + stats->fcp_input_megabytes); 281 + FNIC_MAIN_NOTE(KERN_NOTICE, host, 282 + "fnic: fcp output megabytes = %llu\n", 283 + stats->fcp_output_megabytes); 284 + return; 285 + } 286 + 287 + /* 288 + * fnic_reset_host_stats : clears host stats 289 + * note : called when reset_statistics set under sysfs dir 290 + */ 291 + static void fnic_reset_host_stats(struct Scsi_Host *host) 292 + { 293 + int ret; 294 + struct fc_lport *lp = shost_priv(host); 295 + struct fnic *fnic = lport_priv(lp); 296 + struct fc_host_statistics *stats; 297 + unsigned long flags; 298 + 299 + /* dump current stats, before clearing them */ 300 + stats = fnic_get_stats(host); 301 + fnic_dump_fchost_stats(host, stats); 302 + 303 + spin_lock_irqsave(&fnic->fnic_lock, flags); 304 + ret = vnic_dev_stats_clear(fnic->vdev); 305 + spin_unlock_irqrestore(&fnic->fnic_lock, flags); 306 + 307 + if (ret) { 308 + FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host, 309 + "fnic: Reset vnic stats failed" 310 + " 0x%x", ret); 311 + return; 312 + } 313 + fnic->stats_reset_time = jiffies; 314 + memset(stats, 0, sizeof(*stats)); 315 + 316 + return; 216 317 } 217 318 218 319 void fnic_log_q_error(struct fnic *fnic) ··· 824 719 } 825 720 826 721 fc_lport_init_stats(lp); 722 + fnic->stats_reset_time = jiffies; 827 723 828 724 fc_lport_config(lp); 829 725