Commit a8650a5e authored by Karan Tilak Kumar's avatar Karan Tilak Kumar Committed by Martin K. Petersen
Browse files

scsi: fnic: Add stats and related functionality



Add statistics and related functionality for FDLS.

Add supporting functions to display stats.

Reviewed-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Reviewed-by: default avatarArulprabhu Ponnusamy <arulponn@cisco.com>
Reviewed-by: default avatarGian Carlo Boffa <gcboffa@cisco.com>
Signed-off-by: default avatarKaran Tilak Kumar <kartilak@cisco.com>
Link: https://lore.kernel.org/r/20241212020312.4786-13-kartilak@cisco.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9243626c
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -877,6 +877,7 @@ static void fdls_send_fabric_flogi(struct fnic_iport_s *iport)
		 oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);
	atomic64_inc(&iport->iport_stats.fabric_flogi_sent);
err_out:
	/* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */
	fdls_start_fabric_timer(iport, 2 * iport->e_d_tov);
@@ -919,6 +920,7 @@ static void fdls_send_fabric_plogi(struct fnic_iport_s *iport)
		 oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);
	atomic64_inc(&iport->iport_stats.fabric_plogi_sent);

err_out:
	/* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */
@@ -1080,6 +1082,7 @@ static void fdls_send_scr(struct fnic_iport_s *iport)
		 oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);
	atomic64_inc(&iport->iport_stats.fabric_scr_sent);

err_out:
	/* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */
@@ -1201,6 +1204,8 @@ fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
				 "0x%x: FDLS send ADISC to tgt fcid: 0x%x",
				 iport->fcid, tport->fcid);

	atomic64_inc(&iport->iport_stats.tport_adisc_sent);

	fnic_send_fcoe_frame(iport, frame, frame_size);

err_out:
@@ -1310,6 +1315,7 @@ fdls_send_tgt_plogi(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
				 iport->fcid, tport->fcid, oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);
	atomic64_inc(&iport->iport_stats.tport_plogi_sent);

err_out:
	timeout = max(2 * iport->e_d_tov, iport->plogi_timeout);
@@ -1515,6 +1521,7 @@ fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
			iport->fcid, tport->fcid, oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);
	atomic64_inc(&iport->iport_stats.tport_prli_sent);

err_out:
	timeout = max(2 * iport->e_d_tov, iport->plogi_timeout);
@@ -1626,6 +1633,8 @@ void fdls_tgt_logout(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
		 iport->fcid, oxid);

	fnic_send_fcoe_frame(iport, frame, frame_size);

	atomic64_inc(&iport->iport_stats.tport_logo_sent);
}

static void fdls_tgt_discovery_start(struct fnic_iport_s *iport)
@@ -2515,6 +2524,7 @@ fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport,

	switch (adisc_rsp->els.adisc_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.tport_adisc_ls_accepts);
		if (tport->timer_pending) {
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
						 "tport 0x%p Canceling fabric disc timer\n",
@@ -2537,6 +2547,7 @@ fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport,
		break;

	case ELS_LS_RJT:
		atomic64_inc(&iport->iport_stats.tport_adisc_ls_rejects);
		if (((els_rjt->rej.er_reason == ELS_RJT_BUSY)
		     || (els_rjt->rej.er_reason == ELS_RJT_UNAB))
			&& (tport->retry_counter < FDLS_RETRY_COUNT)) {
@@ -2608,11 +2619,13 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport,

	switch (plogi_rsp->els.fl_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.tport_plogi_ls_accepts);
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "PLOGI accepted by target: 0x%x", tgt_fcid);
		break;

	case ELS_LS_RJT:
		atomic64_inc(&iport->iport_stats.tport_plogi_ls_rejects);
		if (((els_rjt->rej.er_reason == ELS_RJT_BUSY)
		     || (els_rjt->rej.er_reason == ELS_RJT_UNAB))
			&& (tport->retry_counter < iport->max_plogi_retries)) {
@@ -2630,6 +2643,7 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport,
		return;

	default:
		atomic64_inc(&iport->iport_stats.tport_plogi_misc_rejects);
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "PLOGI not accepted from target fcid: 0x%x",
					 tgt_fcid);
@@ -2733,6 +2747,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,

	switch (prli_rsp->els_prli.prli_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.tport_prli_ls_accepts);
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "PRLI accepted from target: 0x%x", tgt_fcid);

@@ -2749,6 +2764,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,
		}
		break;
	case ELS_LS_RJT:
		atomic64_inc(&iport->iport_stats.tport_prli_ls_rejects);
		if (((els_rjt->rej.er_reason == ELS_RJT_BUSY)
		     || (els_rjt->rej.er_reason == ELS_RJT_UNAB))
			&& (tport->retry_counter < FDLS_RETRY_COUNT)) {
@@ -2772,6 +2788,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,
		break;

	default:
		atomic64_inc(&iport->iport_stats.tport_prli_misc_rejects);
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "PRLI not accepted from target: 0x%x", tgt_fcid);
		return;
@@ -3075,6 +3092,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport,

	switch (scr_rsp->scr.scr_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.fabric_scr_ls_accepts);
		if (iport->fabric.timer_pending) {
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
						 "Canceling fabric disc timer %p\n", iport);
@@ -3086,7 +3104,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport,
		break;

	case ELS_LS_RJT:

		atomic64_inc(&iport->iport_stats.fabric_scr_ls_rejects);
		if (((els_rjt->rej.er_reason == ELS_RJT_BUSY)
	     || (els_rjt->rej.er_reason == ELS_RJT_UNAB))
			&& (fdls->retry_counter < FDLS_RETRY_COUNT)) {
@@ -3111,6 +3129,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport,
		break;

	default:
		atomic64_inc(&iport->iport_stats.fabric_scr_misc_rejects);
		break;
	}
}
@@ -3434,6 +3453,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport,

	switch (flogi_rsp->els.fl_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.fabric_flogi_ls_accepts);
		if (iport->fabric.timer_pending) {
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
						 "iport fcid: 0x%x Canceling fabric disc timer\n",
@@ -3507,6 +3527,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport,
		break;

	case ELS_LS_RJT:
		atomic64_inc(&iport->iport_stats.fabric_flogi_ls_rejects);
		if (fabric->retry_counter < iport->max_flogi_retries) {
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
				 "FLOGI returned ELS_LS_RJT BUSY. Retry from timer routine %p",
@@ -3534,6 +3555,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport,
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "FLOGI response not accepted: 0x%x",
		     flogi_rsp->els.fl_cmd);
		atomic64_inc(&iport->iport_stats.fabric_flogi_misc_rejects);
		break;
	}
}
@@ -3564,6 +3586,7 @@ fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport,

	switch (plogi_rsp->els.fl_cmd) {
	case ELS_LS_ACC:
		atomic64_inc(&iport->iport_stats.fabric_plogi_ls_accepts);
		if (iport->fabric.timer_pending) {
			FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
				 "iport fcid: 0x%x fabric PLOGI response: Accepted\n",
@@ -3576,7 +3599,7 @@ fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport,
		fdls_send_rpn_id(iport);
		break;
	case ELS_LS_RJT:

		atomic64_inc(&iport->iport_stats.fabric_plogi_ls_rejects);
		if (((els_rjt->rej.er_reason == ELS_RJT_BUSY)
	     || (els_rjt->rej.er_reason == ELS_RJT_UNAB))
			&& (iport->fabric.retry_counter < iport->max_plogi_retries)) {
@@ -3602,6 +3625,7 @@ fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport,
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					 "PLOGI response not accepted: 0x%x",
		     plogi_rsp->els.fl_cmd);
		atomic64_inc(&iport->iport_stats.fabric_plogi_misc_rejects);
		break;
	}
}
@@ -3945,6 +3969,7 @@ fdls_process_unsupported_els_req(struct fnic_iport_s *iport,
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
			 "Dropping unsupported ELS with illegal frame bits 0x%x\n",
			 d_id);
		atomic64_inc(&iport->iport_stats.unsupported_frames_dropped);
		return;
	}

@@ -3953,6 +3978,7 @@ fdls_process_unsupported_els_req(struct fnic_iport_s *iport,
		FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
			 "Dropping unsupported ELS request in iport state: %d",
			 iport->state);
		atomic64_inc(&iport->iport_stats.unsupported_frames_dropped);
		return;
	}

@@ -4381,6 +4407,8 @@ fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
	struct fnic *fnic = iport->fnic;
	uint16_t rscn_payload_len;

	atomic64_inc(&iport->iport_stats.num_rscns);

	FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
				 "FDLS process RSCN %p", iport);

+4 −2
Original line number Diff line number Diff line
@@ -305,9 +305,11 @@ struct fnic_iport_s {
	uint16_t max_payload_size;
	spinlock_t deleted_tport_lst_lock;
	struct completion *flogi_reg_done;
	struct fnic_iport_stats iport_stats;
	char str_wwpn[20];
	char str_wwnn[20];
};

struct rport_dd_data_s {
	struct fnic_tport_s *tport;
	struct fnic_iport_s *iport;
+33 −1
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ static struct fc_function_template fnic_fc_functions = {
	.show_rport_dev_loss_tmo = 1,
	.set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo,
	.issue_fc_host_lip = fnic_issue_fc_host_lip,
	.get_fc_host_stats = NULL,
	.get_fc_host_stats = fnic_get_stats,
	.reset_fc_host_stats = fnic_reset_host_stats,
	.dd_fcrport_size = sizeof(struct rport_dd_data_s),
	.terminate_rport_io = fnic_terminate_rport_io,
@@ -174,9 +174,11 @@ static void fnic_get_host_speed(struct Scsi_Host *shost)
{
	struct fnic *fnic = *((struct fnic **) shost_priv(shost));
	u32 port_speed = vnic_dev_port_speed(fnic->vdev);
	struct fnic_stats *fnic_stats = &fnic->fnic_stats;

	FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
				  "port_speed: %d Mbps", port_speed);
	atomic64_set(&fnic_stats->misc_stats.port_speed_in_mbps, port_speed);

	/* Add in other values as they get defined in fw */
	switch (port_speed) {
@@ -234,8 +236,38 @@ static void fnic_get_host_speed(struct Scsi_Host *shost)
/* Placeholder function */
static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host)
{
	int ret;
	struct fnic *fnic = *((struct fnic **) shost_priv(host));
	struct fc_host_statistics *stats = &fnic->fnic_stats.host_stats;
	struct vnic_stats *vs;
	unsigned long flags;

	if (time_before
		(jiffies, fnic->stats_time + HZ / FNIC_STATS_RATE_LIMIT))
		return stats;
	fnic->stats_time = jiffies;

	spin_lock_irqsave(&fnic->fnic_lock, flags);
	ret = vnic_dev_stats_dump(fnic->vdev, &fnic->stats);
	spin_unlock_irqrestore(&fnic->fnic_lock, flags);

	if (ret) {
		FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
					  "fnic: Get vnic stats failed: 0x%x", ret);
		return stats;
	}
	vs = fnic->stats;
	stats->tx_frames = vs->tx.tx_unicast_frames_ok;
	stats->tx_words = vs->tx.tx_unicast_bytes_ok / 4;
	stats->rx_frames = vs->rx.rx_unicast_frames_ok;
	stats->rx_words = vs->rx.rx_unicast_bytes_ok / 4;
	stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors;
	stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop;
	stats->invalid_crc_count = vs->rx.rx_crc_errors;
	stats->seconds_since_last_reset =
		(jiffies - fnic->stats_reset_time) / HZ;
	stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000);
	stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000);
	return stats;
}

+17 −2
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
	if (ret) {
		FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
				"rport is not ready\n");
		atomic64_inc(&fnic_stats->misc_stats.tport_not_ready);
		sc->result = ret;
		done(sc);
		return 0;
@@ -1128,6 +1129,15 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, unsigned int cq_ind
		  jiffies_to_msecs(jiffies - start_time)),
		  desc, cmd_trace, fnic_flags_and_state(sc));

	if (sc->sc_data_direction == DMA_FROM_DEVICE) {
		fnic_stats->host_stats.fcp_input_requests++;
		fnic->fcp_input_bytes += xfer_len;
	} else if (sc->sc_data_direction == DMA_TO_DEVICE) {
		fnic_stats->host_stats.fcp_output_requests++;
		fnic->fcp_output_bytes += xfer_len;
	} else
		fnic_stats->host_stats.fcp_control_requests++;

	/* Call SCSI completion function to complete the IO */
	scsi_done(sc);

@@ -1977,8 +1987,8 @@ void fnic_scsi_unload_cleanup(struct fnic *fnic)
{
	int hwq = 0;

	fc_remove_host(fnic->host);
	scsi_remove_host(fnic->host);
	fc_remove_host(fnic->lport->host);
	scsi_remove_host(fnic->lport->host);
	for (hwq = 0; hwq < fnic->wq_copy_count; hwq++)
		kfree(fnic->sw_copy_wq[hwq].io_req_table);
}
@@ -2057,6 +2067,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
				  fnic_priv(sc)->flags);

	if (iport->state != FNIC_IPORT_STATE_READY) {
		atomic64_inc(&fnic_stats->misc_stats.iport_not_ready);
		FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					  "iport NOT in READY state");
		ret = FAILED;
@@ -2140,6 +2151,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
	if (fc_remote_port_chkready(rport) == 0)
		task_req = FCPIO_ITMF_ABT_TASK;
	else {
		atomic64_inc(&fnic_stats->misc_stats.tport_not_ready);
		task_req = FCPIO_ITMF_ABT_TASK_TERM;
	}

@@ -2577,6 +2589,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
	}

	if (iport->state != FNIC_IPORT_STATE_READY) {
		atomic64_inc(&fnic_stats->misc_stats.iport_not_ready);
		FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
					  "iport NOT in READY state");
		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
@@ -2594,6 +2607,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)

	/* Check if remote port up */
	if (fc_remote_port_chkready(rport)) {
		atomic64_inc(&fnic_stats->misc_stats.tport_not_ready);
		goto fnic_device_reset_end;
	}

@@ -3071,6 +3085,7 @@ void fnic_scsi_fcpio_reset(struct fnic *fnic)
				  "FW reset completion timed out after %d ms)\n",
				  FNIC_FW_RESET_TIMEOUT);
		}
		atomic64_inc(&fnic->fnic_stats.reset_stats.fw_reset_timeouts);
	}
	fnic->fw_reset_done = NULL;
}
+44 −1
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct reset_stats {
	atomic64_t fw_resets;
	atomic64_t fw_reset_completions;
	atomic64_t fw_reset_failures;
	atomic64_t fw_reset_timeouts;
	atomic64_t fnic_resets;
	atomic64_t fnic_reset_completions;
	atomic64_t fnic_reset_failures;
@@ -103,10 +104,51 @@ struct misc_stats {
	atomic64_t no_icmnd_itmf_cmpls;
	atomic64_t check_condition;
	atomic64_t queue_fulls;
	atomic64_t rport_not_ready;
	atomic64_t tport_not_ready;
	atomic64_t iport_not_ready;
	atomic64_t frame_errors;
	atomic64_t current_port_speed;
	atomic64_t intx_dummy;
	atomic64_t port_speed_in_mbps;
};

struct fnic_iport_stats {
	atomic64_t num_linkdn;
	atomic64_t num_linkup;
	atomic64_t link_failure_count;
	atomic64_t num_rscns;
	atomic64_t rscn_redisc;
	atomic64_t rscn_not_redisc;
	atomic64_t frame_err;
	atomic64_t num_rnid;
	atomic64_t fabric_flogi_sent;
	atomic64_t fabric_flogi_ls_accepts;
	atomic64_t fabric_flogi_ls_rejects;
	atomic64_t fabric_flogi_misc_rejects;
	atomic64_t fabric_plogi_sent;
	atomic64_t fabric_plogi_ls_accepts;
	atomic64_t fabric_plogi_ls_rejects;
	atomic64_t fabric_plogi_misc_rejects;
	atomic64_t fabric_scr_sent;
	atomic64_t fabric_scr_ls_accepts;
	atomic64_t fabric_scr_ls_rejects;
	atomic64_t fabric_scr_misc_rejects;
	atomic64_t fabric_logo_sent;
	atomic64_t tport_alive;
	atomic64_t tport_plogi_sent;
	atomic64_t tport_plogi_ls_accepts;
	atomic64_t tport_plogi_ls_rejects;
	atomic64_t tport_plogi_misc_rejects;
	atomic64_t tport_prli_sent;
	atomic64_t tport_prli_ls_accepts;
	atomic64_t tport_prli_ls_rejects;
	atomic64_t tport_prli_misc_rejects;
	atomic64_t tport_adisc_sent;
	atomic64_t tport_adisc_ls_accepts;
	atomic64_t tport_adisc_ls_rejects;
	atomic64_t tport_logo_sent;
	atomic64_t unsupported_frames_ls_rejects;
	atomic64_t unsupported_frames_dropped;
};

struct fnic_stats {
@@ -129,4 +171,5 @@ struct stats_debug_info {
};

int fnic_get_stats_data(struct stats_debug_info *, struct fnic_stats *);
const char *fnic_role_to_str(unsigned int role);
#endif /* _FNIC_STATS_H_ */
Loading