From: Nilesh Javali <njavali@marvell.com>
To: <martin.petersen@oracle.com>
Cc: <linux-scsi@vger.kernel.org>, <GR-QLogic-Storage-Upstream@marvell.com>
Subject: [PATCH 1/2] scsi: fc: Update statistics for host and rport on FPIN reception.
Date: Wed, 29 Jul 2020 23:11:15 -0700 [thread overview]
Message-ID: <20200730061116.20111-2-njavali@marvell.com> (raw)
In-Reply-To: <20200730061116.20111-1-njavali@marvell.com>
From: Shyam Sundar <ssundar@marvell.com>
Add Fabric Performance Impact Notification (FPIN) stats structure to
fc_host_attr and the fc_rport structures to maintain FPIN statistics
for the respective entities when the LLD notifies the transport of an
FPIN ELS.
Add sysfs nodes to display FPIN statistics
Specifically, this patch:
- Adds the formal definition of FPIN descriptors
* Delivery Notification Descriptor
* Peer Congestion Notification Descriptor
* Congestion Notification Descriptor
- Adds the formal definition of the event types associated with them
- Adds a structure for holding fpin stats for host & rport
- Adds functions to parse the FPIN ELS and update the stats
- Adds sysfs nodes to maintain FPIN stats:
/sys/class/fc_host/hostXX/statistics/
/sys/class/fc_remote_ports/rport-XX\:Y-Z/statistics/
- Add stats for Congestion Signals, that are delivered to the host as
interrupt signals, under fc_host_statistics.
Signed-off-by: Shyam Sundar <ssundar@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
---
drivers/scsi/lpfc/lpfc_attr.c | 2 +
drivers/scsi/qla2xxx/qla_attr.c | 2 +
drivers/scsi/scsi_transport_fc.c | 410 ++++++++++++++++++++++++++++++-
include/scsi/scsi_transport_fc.h | 34 ++-
include/uapi/scsi/fc/fc_els.h | 114 +++++++++
5 files changed, 559 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index a62c60ca6477..9fd35b90cb53 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -7158,6 +7158,8 @@ struct fc_function_template lpfc_transport_functions = {
.set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
.show_rport_dev_loss_tmo = 1,
+ .show_rport_statistics = 1,
+
.get_starget_port_id = lpfc_get_starget_port_id,
.show_starget_port_id = 1,
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 5d93ccc73153..e34623b7cb6f 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -3143,6 +3143,8 @@ struct fc_function_template qla2xxx_transport_functions = {
.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
.show_rport_dev_loss_tmo = 1,
+ .show_rport_statistics = 1,
+
.issue_fc_host_lip = qla2x00_issue_lip,
.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
.terminate_rport_io = qla2x00_terminate_rport_io,
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 2732fa65119c..587b610e13a2 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -22,6 +22,7 @@
#include <net/netlink.h>
#include <scsi/scsi_netlink_fc.h>
#include <scsi/scsi_bsg_fc.h>
+#include <uapi/scsi/fc/fc_els.h>
#include "scsi_priv.h"
static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
@@ -33,6 +34,10 @@ static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *);
static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *);
static void fc_bsg_remove(struct request_queue *);
static void fc_bsg_goose_queue(struct fc_rport *);
+static void fc_li_stats_update(struct fc_fn_li_desc *li_desc,
+ struct fpin_stats *stats);
+static void fc_deli_stats_update(u32 reason_code, struct fpin_stats *stats);
+static void fc_cn_stats_update(u16 event_type, struct fpin_stats *stats);
/*
* Module Parameters
@@ -418,6 +423,7 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
fc_host->fabric_name = -1;
memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
+ memset(&fc_host->stats, 0, sizeof(struct fpin_stats));
fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
@@ -627,6 +633,266 @@ fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
}
EXPORT_SYMBOL(fc_host_post_vendor_event);
+/**
+ * fc_find_rport_by_wwpn - find the fc_rport pointer for a given wwpn
+ * @shost: host the fc_rport is associated with
+ * @wwpn: wwpn of the fc_rport device
+ *
+ * Notes:
+ * This routine assumes no locks are held on entry.
+ */
+struct fc_rport *
+fc_find_rport_by_wwpn(struct Scsi_Host *shost, u64 wwpn)
+{
+ struct fc_rport *rport, *found = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+
+ list_for_each_entry(rport, &fc_host_rports(shost), peers) {
+ if (rport->scsi_target_id == -1)
+ continue;
+
+ if (rport->port_state != FC_PORTSTATE_ONLINE)
+ continue;
+
+ if (rport->port_name == wwpn)
+ found = rport;
+ }
+
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ return found;
+}
+EXPORT_SYMBOL(fc_find_rport_by_wwpn);
+
+static void
+fc_li_stats_update(struct fc_fn_li_desc *li_desc,
+ struct fpin_stats *stats)
+{
+ switch (be16_to_cpu(li_desc->event_type)) {
+ case FPIN_LI_UNKNOWN:
+ stats->li_failure_unknown +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_LINK_FAILURE:
+ stats->li_link_failure_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_LOSS_OF_SYNC:
+ stats->li_loss_of_sync_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_LOSS_OF_SIG:
+ stats->li_loss_of_signals_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_PRIM_SEQ_ERR:
+ stats->li_prim_seq_err_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_INVALID_TX_WD:
+ stats->li_invalid_tx_word_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_INVALID_CRC:
+ stats->li_invalid_crc_count +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ case FPIN_LI_DEVICE_SPEC:
+ stats->li_device_specific +=
+ be32_to_cpu(li_desc->event_count);
+ break;
+ }
+}
+
+static void
+fc_deli_stats_update(u32 deli_reason_code, struct fpin_stats *stats)
+{
+ switch (deli_reason_code) {
+ case FPIN_DELI_UNKNOWN:
+ stats->dn_unknown++;
+ break;
+ case FPIN_DELI_TIMEOUT:
+ stats->dn_timeout++;
+ break;
+ case FPIN_DELI_UNABLE_TO_ROUTE:
+ stats->dn_unable_to_route++;
+ break;
+ case FPIN_DELI_DEVICE_SPEC:
+ stats->dn_device_specific++;
+ break;
+ }
+}
+
+static void
+fc_cn_stats_update(u16 event_type, struct fpin_stats *stats)
+{
+ switch (event_type) {
+ case FPIN_CONGN_CLEAR:
+ stats->cn_clear++;
+ break;
+ case FPIN_CONGN_LOST_CREDIT:
+ stats->cn_lost_credit++;
+ break;
+ case FPIN_CONGN_CREDIT_STALL:
+ stats->cn_credit_stall++;
+ break;
+ case FPIN_CONGN_OVERSUBSCRIPTION:
+ stats->cn_oversubscription++;
+ break;
+ case FPIN_CONGN_DEVICE_SPEC:
+ stats->cn_device_specific++;
+ }
+}
+
+/*
+ * fc_fpin_li_stats_update - routine to update Link Integrity
+ * event statistics.
+ * @shost: host the FPIN was received on
+ * @tlv: pointer to link integrity descriptor
+ *
+ */
+static void
+fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv)
+{
+ u8 i;
+ struct fc_rport *rport = NULL;
+ struct fc_rport *det_rport = NULL, *attach_rport = NULL;
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+ struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;
+ u64 wwpn;
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(li_desc->detecting_wwpn));
+ if (rport) {
+ det_rport = rport;
+ fc_li_stats_update(li_desc, &det_rport->stats);
+ }
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(li_desc->attached_wwpn));
+ if (rport) {
+ attach_rport = rport;
+ fc_li_stats_update(li_desc, &attach_rport->stats);
+ }
+
+ if (be32_to_cpu(li_desc->pname_count) > 0) {
+ for (i = 0;
+ i < be32_to_cpu(li_desc->pname_count);
+ i++) {
+ wwpn = be64_to_cpu(li_desc->pname_list[i]);
+ rport = fc_find_rport_by_wwpn(shost, wwpn);
+ if (rport && rport != det_rport &&
+ rport != attach_rport) {
+ fc_li_stats_update(li_desc, &rport->stats);
+ }
+ }
+ }
+
+ if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn))
+ fc_li_stats_update(li_desc, &fc_host->stats);
+}
+
+/*
+ * fc_fpin_deli_stats_update - routine to update Delivery Notification
+ * event statistics.
+ * @shost: host the FPIN was received on
+ * @tlv: pointer to delivery descriptor
+ *
+ */
+static void
+fc_fpin_deli_stats_update(struct Scsi_Host *shost,
+ struct fc_tlv_desc *tlv)
+{
+ struct fc_rport *rport = NULL;
+ struct fc_rport *det_rport = NULL, *attach_rport = NULL;
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+ struct fc_fn_deli_desc *deli_desc = (struct fc_fn_deli_desc *)tlv;
+ u32 reason_code = be32_to_cpu(deli_desc->deli_reason_code);
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(deli_desc->detecting_wwpn));
+ if (rport) {
+ det_rport = rport;
+ fc_deli_stats_update(reason_code, &det_rport->stats);
+ }
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(deli_desc->attached_wwpn));
+ if (rport) {
+ attach_rport = rport;
+ fc_deli_stats_update(reason_code, &attach_rport->stats);
+ }
+
+ if (fc_host->port_name == be64_to_cpu(deli_desc->attached_wwpn))
+ fc_deli_stats_update(reason_code, &fc_host->stats);
+}
+
+/*
+ * fc_fpin_peer_congn_stats_update - routine to update Peer Congestion
+ * event statistics.
+ * @shost: host the FPIN was received on
+ * @tlv: pointer to peer congestion descriptor
+ *
+ */
+static void
+fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost,
+ struct fc_tlv_desc *tlv)
+{
+ u8 i;
+ struct fc_rport *rport = NULL;
+ struct fc_rport *det_rport = NULL, *attach_rport = NULL;
+ struct fc_fn_peer_congn_desc *pc_desc =
+ (struct fc_fn_peer_congn_desc *)tlv;
+ u16 event_type = be16_to_cpu(pc_desc->event_type);
+ u64 wwpn;
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(pc_desc->detecting_wwpn));
+ if (rport) {
+ det_rport = rport;
+ fc_cn_stats_update(event_type, &det_rport->stats);
+ }
+
+ rport = fc_find_rport_by_wwpn(shost,
+ be64_to_cpu(pc_desc->attached_wwpn));
+ if (rport) {
+ attach_rport = rport;
+ fc_cn_stats_update(event_type, &attach_rport->stats);
+ }
+
+ if (be32_to_cpu(pc_desc->pname_count) > 0) {
+ for (i = 0;
+ i < be32_to_cpu(pc_desc->pname_count);
+ i++) {
+ wwpn = be64_to_cpu(pc_desc->pname_list[i]);
+ rport = fc_find_rport_by_wwpn(shost, wwpn);
+ if (rport && rport != det_rport &&
+ rport != attach_rport) {
+ fc_cn_stats_update(event_type,
+ &rport->stats);
+ }
+ }
+ }
+}
+
+/*
+ * fc_fpin_congn_stats_update - routine to update Congestion
+ * event statistics.
+ * @shost: host the FPIN was received on
+ * @tlv: pointer to congestion descriptor
+ *
+ */
+static void
+fc_fpin_congn_stats_update(struct Scsi_Host *shost,
+ struct fc_tlv_desc *tlv)
+{
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
+ struct fc_fn_congn_desc *congn = (struct fc_fn_congn_desc *)tlv;
+
+ fc_cn_stats_update(be16_to_cpu(congn->event_type), &fc_host->stats);
+}
+
/**
* fc_host_rcv_fpin - routine to process a received FPIN.
* @shost: host the FPIN was received on
@@ -639,8 +905,41 @@ EXPORT_SYMBOL(fc_host_post_vendor_event);
void
fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf)
{
+ struct fc_els_fpin *fpin = (struct fc_els_fpin *)fpin_buf;
+ struct fc_tlv_desc *tlv;
+ u32 desc_cnt = 0, bytes_remain;
+ u32 dtag;
+
+ /* Update Statistics */
+ tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0];
+ bytes_remain = fpin_len - offsetof(struct fc_els_fpin, fpin_desc);
+ bytes_remain = min_t(u32, bytes_remain, be32_to_cpu(fpin->desc_len));
+
+ while (bytes_remain >= FC_TLV_DESC_HDR_SZ &&
+ bytes_remain >= FC_TLV_DESC_SZ_FROM_LENGTH(tlv)) {
+ dtag = be32_to_cpu(tlv->desc_tag);
+ switch (dtag) {
+ case ELS_DTAG_LNK_INTEGRITY:
+ fc_fpin_li_stats_update(shost, tlv);
+ break;
+ case ELS_DTAG_DELIVERY:
+ fc_fpin_deli_stats_update(shost, tlv);
+ break;
+ case ELS_DTAG_PEER_CONGEST:
+ fc_fpin_peer_congn_stats_update(shost, tlv);
+ break;
+ case ELS_DTAG_CONGESTION:
+ fc_fpin_congn_stats_update(shost, tlv);
+ }
+
+ desc_cnt++;
+ bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv);
+ tlv = fc_tlv_next_desc(tlv);
+ }
+
fc_host_post_fc_event(shost, fc_get_event_number(),
- FCH_EVT_LINK_FPIN, fpin_len, fpin_buf, 0);
+ FCH_EVT_LINK_FPIN, fpin_len, fpin_buf, 0);
+
}
EXPORT_SYMBOL(fc_host_fpin_rcv);
@@ -990,6 +1289,61 @@ store_fc_rport_fast_io_fail_tmo(struct device *dev,
static FC_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo);
+#define fc_rport_fpin_statistic(name) \
+static ssize_t fc_rport_fpinstat_##name(struct device *cd, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct fc_rport *rport = transport_class_to_rport(cd); \
+ \
+ return snprintf(buf, 20, "0x%llx\n", rport->stats.name); \
+} \
+static FC_DEVICE_ATTR(rport, fpin_##name, 0444, fc_rport_fpinstat_##name, NULL)
+
+fc_rport_fpin_statistic(dn_unknown);
+fc_rport_fpin_statistic(dn_timeout);
+fc_rport_fpin_statistic(dn_unable_to_route);
+fc_rport_fpin_statistic(dn_device_specific);
+fc_rport_fpin_statistic(cn_clear);
+fc_rport_fpin_statistic(cn_lost_credit);
+fc_rport_fpin_statistic(cn_credit_stall);
+fc_rport_fpin_statistic(cn_oversubscription);
+fc_rport_fpin_statistic(cn_device_specific);
+fc_rport_fpin_statistic(li_failure_unknown);
+fc_rport_fpin_statistic(li_link_failure_count);
+fc_rport_fpin_statistic(li_loss_of_sync_count);
+fc_rport_fpin_statistic(li_loss_of_signals_count);
+fc_rport_fpin_statistic(li_prim_seq_err_count);
+fc_rport_fpin_statistic(li_invalid_tx_word_count);
+fc_rport_fpin_statistic(li_invalid_crc_count);
+fc_rport_fpin_statistic(li_device_specific);
+
+static struct attribute *fc_rport_statistics_attrs[] = {
+ &device_attr_rport_fpin_dn_unknown.attr,
+ &device_attr_rport_fpin_dn_timeout.attr,
+ &device_attr_rport_fpin_dn_unable_to_route.attr,
+ &device_attr_rport_fpin_dn_device_specific.attr,
+ &device_attr_rport_fpin_li_failure_unknown.attr,
+ &device_attr_rport_fpin_li_link_failure_count.attr,
+ &device_attr_rport_fpin_li_loss_of_sync_count.attr,
+ &device_attr_rport_fpin_li_loss_of_signals_count.attr,
+ &device_attr_rport_fpin_li_prim_seq_err_count.attr,
+ &device_attr_rport_fpin_li_invalid_tx_word_count.attr,
+ &device_attr_rport_fpin_li_invalid_crc_count.attr,
+ &device_attr_rport_fpin_li_device_specific.attr,
+ &device_attr_rport_fpin_cn_clear.attr,
+ &device_attr_rport_fpin_cn_lost_credit.attr,
+ &device_attr_rport_fpin_cn_credit_stall.attr,
+ &device_attr_rport_fpin_cn_oversubscription.attr,
+ &device_attr_rport_fpin_cn_device_specific.attr,
+ NULL
+};
+
+static struct attribute_group fc_rport_statistics_group = {
+ .name = "statistics",
+ .attrs = fc_rport_statistics_attrs,
+};
+
/*
* FC SCSI Target Attribute Management
@@ -1743,6 +2097,38 @@ fc_host_statistic(fc_xid_not_found);
fc_host_statistic(fc_xid_busy);
fc_host_statistic(fc_seq_not_found);
fc_host_statistic(fc_non_bls_resp);
+fc_host_statistic(cn_sig_warn);
+fc_host_statistic(cn_sig_alarm);
+
+#define fc_host_fpin_statistic(name) \
+static ssize_t fc_host_fpinstat_##name(struct device *cd, \
+ struct device_attribute *attr, \
+ char *buf) \
+{ \
+ struct Scsi_Host *shost = transport_class_to_shost(cd); \
+ struct fc_host_attrs *fc_host = shost_to_fc_host(shost); \
+ \
+ return snprintf(buf, 20, "0x%llx\n", fc_host->stats.name); \
+} \
+static FC_DEVICE_ATTR(host, fpin_##name, 0444, fc_host_fpinstat_##name, NULL)
+
+fc_host_fpin_statistic(dn_unknown);
+fc_host_fpin_statistic(dn_timeout);
+fc_host_fpin_statistic(dn_unable_to_route);
+fc_host_fpin_statistic(dn_device_specific);
+fc_host_fpin_statistic(cn_clear);
+fc_host_fpin_statistic(cn_lost_credit);
+fc_host_fpin_statistic(cn_credit_stall);
+fc_host_fpin_statistic(cn_oversubscription);
+fc_host_fpin_statistic(cn_device_specific);
+fc_host_fpin_statistic(li_failure_unknown);
+fc_host_fpin_statistic(li_link_failure_count);
+fc_host_fpin_statistic(li_loss_of_sync_count);
+fc_host_fpin_statistic(li_loss_of_signals_count);
+fc_host_fpin_statistic(li_prim_seq_err_count);
+fc_host_fpin_statistic(li_invalid_tx_word_count);
+fc_host_fpin_statistic(li_invalid_crc_count);
+fc_host_fpin_statistic(li_device_specific);
static ssize_t
fc_reset_statistics(struct device *dev, struct device_attribute *attr,
@@ -1792,7 +2178,26 @@ static struct attribute *fc_statistics_attrs[] = {
&device_attr_host_fc_xid_busy.attr,
&device_attr_host_fc_seq_not_found.attr,
&device_attr_host_fc_non_bls_resp.attr,
+ &device_attr_host_cn_sig_warn.attr,
+ &device_attr_host_cn_sig_alarm.attr,
&device_attr_host_reset_statistics.attr,
+ &device_attr_host_fpin_dn_unknown.attr,
+ &device_attr_host_fpin_dn_timeout.attr,
+ &device_attr_host_fpin_dn_unable_to_route.attr,
+ &device_attr_host_fpin_dn_device_specific.attr,
+ &device_attr_host_fpin_li_failure_unknown.attr,
+ &device_attr_host_fpin_li_link_failure_count.attr,
+ &device_attr_host_fpin_li_loss_of_sync_count.attr,
+ &device_attr_host_fpin_li_loss_of_signals_count.attr,
+ &device_attr_host_fpin_li_prim_seq_err_count.attr,
+ &device_attr_host_fpin_li_invalid_tx_word_count.attr,
+ &device_attr_host_fpin_li_invalid_crc_count.attr,
+ &device_attr_host_fpin_li_device_specific.attr,
+ &device_attr_host_fpin_cn_clear.attr,
+ &device_attr_host_fpin_cn_lost_credit.attr,
+ &device_attr_host_fpin_cn_credit_stall.attr,
+ &device_attr_host_fpin_cn_oversubscription.attr,
+ &device_attr_host_fpin_cn_device_specific.attr,
NULL
};
@@ -1801,7 +2206,6 @@ static struct attribute_group fc_statistics_group = {
.attrs = fc_statistics_attrs,
};
-
/* Host Vport Attributes */
static int
@@ -2176,6 +2580,8 @@ fc_attach_transport(struct fc_function_template *ft)
i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
i->rport_attr_cont.ac.class = &fc_rport_class.class;
i->rport_attr_cont.ac.match = fc_rport_match;
+ if (ft->show_rport_statistics)
+ i->rport_attr_cont.statistics = &fc_rport_statistics_group;
transport_container_register(&i->rport_attr_cont);
i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 7db2dd783834..be7392ea9f91 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -284,6 +284,33 @@ struct fc_rport_identifiers {
u32 roles;
};
+/*
+ * Fabric Performance Impact Notification Statistics
+ */
+struct fpin_stats {
+ /* Delivery */
+ u64 dn_unknown;
+ u64 dn_timeout;
+ u64 dn_unable_to_route;
+ u64 dn_device_specific;
+
+ /* Link Integrity */
+ u64 li_failure_unknown;
+ u64 li_link_failure_count;
+ u64 li_loss_of_sync_count;
+ u64 li_loss_of_signals_count;
+ u64 li_prim_seq_err_count;
+ u64 li_invalid_tx_word_count;
+ u64 li_invalid_crc_count;
+ u64 li_device_specific;
+
+ /* Congestion/Peer Congestion */
+ u64 cn_clear;
+ u64 cn_lost_credit;
+ u64 cn_credit_stall;
+ u64 cn_oversubscription;
+ u64 cn_device_specific;
+};
/* Macro for use in defining Remote Port attributes */
#define FC_RPORT_ATTR(_name,_mode,_show,_store) \
@@ -325,6 +352,7 @@ struct fc_rport { /* aka fc_starget_attrs */
/* Dynamic Attributes */
u32 dev_loss_tmo; /* Remote Port loss timeout in seconds. */
+ struct fpin_stats stats;
/* Private (Transport-managed) Attributes */
u64 node_name;
@@ -394,7 +422,6 @@ struct fc_starget_attrs { /* aka fc_target_attrs */
#define starget_to_rport(s) \
scsi_is_fc_rport(s->dev.parent) ? dev_to_rport(s->dev.parent) : NULL
-
/*
* FC Local Port (Host) Statistics
*/
@@ -436,6 +463,9 @@ struct fc_host_statistics {
u64 fc_seq_not_found; /* seq is not found for exchange */
u64 fc_non_bls_resp; /* a non BLS response frame with
a sequence responder in new exch */
+ /* Host Congestion Signals */
+ u64 cn_sig_warn;
+ u64 cn_sig_alarm;
};
@@ -515,6 +545,7 @@ struct fc_host_attrs {
char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
char system_hostname[FC_SYMBOLIC_NAME_SIZE];
u32 dev_loss_tmo;
+ struct fpin_stats stats;
/* Private (Transport-managed) Attributes */
enum fc_tgtid_binding_type tgtid_bind_type;
@@ -667,6 +698,7 @@ struct fc_function_template {
unsigned long show_rport_maxframe_size:1;
unsigned long show_rport_supported_classes:1;
unsigned long show_rport_dev_loss_tmo:1;
+ unsigned long show_rport_statistics:1;
/*
* target dynamic attributes
diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
index 8c704e510e39..d630692a6346 100644
--- a/include/uapi/scsi/fc/fc_els.h
+++ b/include/uapi/scsi/fc/fc_els.h
@@ -917,6 +917,9 @@ enum fc_els_clid_ic {
};
+/*
+ * Link Integrity event types
+ */
enum fc_fpin_li_event_types {
FPIN_LI_UNKNOWN = 0x0,
FPIN_LI_LINK_FAILURE = 0x1,
@@ -943,6 +946,55 @@ enum fc_fpin_li_event_types {
{ FPIN_LI_DEVICE_SPEC, "Device Specific" }, \
}
+/*
+ * Delivery event types
+ */
+enum fc_fpin_deli_event_types {
+ FPIN_DELI_UNKNOWN = 0x0,
+ FPIN_DELI_TIMEOUT = 0x1,
+ FPIN_DELI_UNABLE_TO_ROUTE = 0x2,
+ FPIN_DELI_DEVICE_SPEC = 0xF,
+};
+
+/*
+ * Initializer useful for decoding table.
+ * Please keep this in sync with the above definitions.
+ */
+#define FC_FPIN_DELI_EVT_TYPES_INIT { \
+ { FPIN_DELI_UNKNOWN, "Unknown" }, \
+ { FPIN_DELI_TIMEOUT, "Timeout" }, \
+ { FPIN_DELI_UNABLE_TO_ROUTE, "Unable to Route" }, \
+ { FPIN_DELI_DEVICE_SPEC, "Device Specific" }, \
+}
+
+/*
+ * Congestion event types
+ */
+enum fc_fpin_congn_event_types {
+ FPIN_CONGN_CLEAR = 0x0,
+ FPIN_CONGN_LOST_CREDIT = 0x1,
+ FPIN_CONGN_CREDIT_STALL = 0x2,
+ FPIN_CONGN_OVERSUBSCRIPTION = 0x3,
+ FPIN_CONGN_DEVICE_SPEC = 0xF,
+};
+
+/*
+ * Initializer useful for decoding table.
+ * Please keep this in sync with the above definitions.
+ */
+#define FC_FPIN_CONGN_EVT_TYPES_INIT { \
+ { FPIN_CONGN_CLEAR, "Clear" }, \
+ { FPIN_CONGN_LOST_CREDIT, "Lost Credit" }, \
+ { FPIN_CONGN_CREDIT_STALL, "Credit Stall" }, \
+ { FPIN_CONGN_OVERSUBSCRIPTION, "Oversubscription" }, \
+ { FPIN_CONGN_DEVICE_SPEC, "Device Specific" }, \
+}
+
+enum fc_fpin_congn_severity_types {
+ FPIN_CONGN_SEVERITY_WARNING = 0xF1,
+ FPIN_CONGN_SEVERITY_ERROR = 0xF7,
+};
+
/*
* Link Integrity Notification Descriptor
@@ -974,6 +1026,68 @@ struct fc_fn_li_desc {
*/
};
+/*
+ * Delivery Notification Descriptor
+ */
+struct fc_fn_deli_desc {
+ __be32 desc_tag; /* Descriptor Tag (0x00020002) */
+ __be32 desc_len; /* Length of Descriptor (in bytes).
+ * Size of descriptor excluding
+ * desc_tag and desc_len fields.
+ */
+ __be64 detecting_wwpn; /* Port Name that detected event */
+ __be64 attached_wwpn; /* Port Name of device attached to
+ * detecting Port Name
+ */
+ __be32 deli_reason_code;/* see enum fc_fpin_deli_event_types */
+};
+
+/*
+ * Peer Congestion Notification Descriptor
+ */
+struct fc_fn_peer_congn_desc {
+ __be32 desc_tag; /* Descriptor Tag (0x00020003) */
+ __be32 desc_len; /* Length of Descriptor (in bytes).
+ * Size of descriptor excluding
+ * desc_tag and desc_len fields.
+ */
+ __be64 detecting_wwpn; /* Port Name that detected event */
+ __be64 attached_wwpn; /* Port Name of device attached to
+ * detecting Port Name
+ */
+ __be16 event_type; /* see enum fc_fpin_congn_event_types */
+ __be16 event_modifier; /* Implementation specific value
+ * describing the event type
+ */
+ __be32 event_period; /* duration (ms) of the detected
+ * congestion event
+ */
+ __be32 pname_count; /* number of portname_list elements */
+ __be64 pname_list[0]; /* list of N_Port_Names accessible
+ * through the attached port
+ */
+};
+
+/*
+ * Congestion Notification Descriptor
+ */
+struct fc_fn_congn_desc {
+ __be32 desc_tag; /* Descriptor Tag (0x00020004) */
+ __be32 desc_len; /* Length of Descriptor (in bytes).
+ * Size of descriptor excluding
+ * desc_tag and desc_len fields.
+ */
+ __be16 event_type; /* see enum fc_fpin_congn_event_types */
+ __be16 event_modifier; /* Implementation specific value
+ * describing the event type
+ */
+ __be32 event_period; /* duration (ms) of the detected
+ * congestion event
+ */
+ __u8 severity; /* command */
+ __u8 resv[3]; /* reserved - must be zero */
+};
+
/*
* ELS_FPIN - Fabric Performance Impact Notification
*/
--
2.19.0.rc0
next prev parent reply other threads:[~2020-07-30 6:12 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-30 6:11 [PATCH 0/2] SAN Congestion Management (SCM) statistics Nilesh Javali
2020-07-30 6:11 ` Nilesh Javali [this message]
2020-09-09 13:51 ` [PATCH 1/2] scsi: fc: Update statistics for host and rport on FPIN reception Himanshu Madhani
2020-09-23 0:01 ` James Smart
2020-09-28 20:07 ` Shyam Sundar
2020-09-29 21:33 ` James Smart
2020-09-30 20:55 ` [EXT] " Shyam Sundar
2021-10-01 1:37 ` kernel test robot
2020-07-30 6:11 ` [PATCH 2/2] scsi: fc: Update documentation of sysfs nodes for FPIN stats Nilesh Javali
2020-09-09 13:51 ` Himanshu Madhani
2020-09-23 0:15 ` James Smart
2020-09-07 10:44 ` [PATCH 0/2] SAN Congestion Management (SCM) statistics Nilesh Javali
2020-09-09 2:57 ` Martin K. Petersen
2020-09-17 16:53 ` [EXT] " Nilesh Javali
2020-09-23 8:38 ` Hannes Reinecke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200730061116.20111-2-njavali@marvell.com \
--to=njavali@marvell.com \
--cc=GR-QLogic-Storage-Upstream@marvell.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).