[ofa-general] [PATCH RFCv3 1/2] RDMA: Add protocol statistics attributes to the RDMA sysfs.

Steve Wise swise at opengridcomputing.com
Thu Jun 19 08:34:24 PDT 2008


This patch adds a sysfs attribute group called "proto_stats" under
/sys/class/infiniband/$device/ and populates this group with protocol
statistics if they exist for a given device.  Currently, only iWARP
stats are defined, but the code is designed to allow Infiniband protocol
stats if they become available.  These stats are per-device and more
importantly -not- per port.

Details:

- Add union rdma_protocol_stats in ib_verbs.h.  This union allows defining
transport-specific stats.  Currently only iwarp stats are defined.

- Add struct iw_protocol_stats to define the current set of iwarp protocol
stats.

- Add new ib_device method called get_proto_stats() to return protocol
statistics.

- Add logic in core/sysfs.c to create iwarp protocol stats attributes
if the device is an RNIC and has a get_proto_stats() method.

Signed-off-by: Steve Wise <swise at opengridcomputing.com>
---

 drivers/infiniband/core/sysfs.c |  123 +++++++++++++++++++++++++++++++++++++++
 include/rdma/ib_verbs.h         |   53 +++++++++++++++++
 2 files changed, 176 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 9575655..28d0ab9 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -665,6 +665,124 @@ static struct class ib_class = {
 	.dev_uevent = ib_device_uevent,
 };
 
+/* Show a given an attribute in the statistics group */
+static ssize_t show_protocol_stat(const struct device *device,
+			    struct device_attribute *attr, char *buf,
+			    unsigned offset)
+{
+	struct ib_device *dev = container_of(device, struct ib_device, dev);
+	union rdma_protocol_stats stats;
+	ssize_t ret = -EINVAL;
+
+	WARN_ON(offset > sizeof(union rdma_protocol_stats) ||
+			offset % sizeof (u64) != 0);
+
+	if (!dev->get_protocol_stats)
+		goto out;
+	ret = (*dev->get_protocol_stats)(dev, &stats);
+	if (ret)
+		goto out;
+	ret = sprintf(buf, "%llu\n", *(u64 *)(((u8 *)&stats) + offset));
+out:
+	return ret;
+}
+
+/* generate a read-only iwarp statistics attribute */
+#define IW_STATS_ENTRY(name)						\
+static ssize_t show_##name(struct device *device,			\
+			   struct device_attribute *attr, char *buf) 	\
+{									\
+	return show_protocol_stat(device, attr, buf,			\
+			    offsetof(struct iw_protocol_stats, name));  \
+}									\
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+IW_STATS_ENTRY(ipInReceives);
+IW_STATS_ENTRY(ipInHdrErrors);
+IW_STATS_ENTRY(ipInTooBigErrors);
+IW_STATS_ENTRY(ipInNoRoutes);
+IW_STATS_ENTRY(ipInAddrErrors);
+IW_STATS_ENTRY(ipInUnknownProtos);
+IW_STATS_ENTRY(ipInTruncatedPkts);
+IW_STATS_ENTRY(ipInDiscards);
+IW_STATS_ENTRY(ipInDelivers);
+IW_STATS_ENTRY(ipOutForwDatagrams);
+IW_STATS_ENTRY(ipOutRequests);
+IW_STATS_ENTRY(ipOutDiscards);
+IW_STATS_ENTRY(ipOutNoRoutes);
+IW_STATS_ENTRY(ipReasmTimeout);
+IW_STATS_ENTRY(ipReasmReqds);
+IW_STATS_ENTRY(ipReasmOKs);
+IW_STATS_ENTRY(ipReasmFails);
+IW_STATS_ENTRY(ipFragOKs);
+IW_STATS_ENTRY(ipFragFails);
+IW_STATS_ENTRY(ipFragCreates);
+IW_STATS_ENTRY(ipInMcastPkts);
+IW_STATS_ENTRY(ipOutMcastPkts);
+IW_STATS_ENTRY(ipInBcastPkts);
+IW_STATS_ENTRY(ipOutBcastPkts);
+IW_STATS_ENTRY(tcpRtoAlgorithm);
+IW_STATS_ENTRY(tcpRtoMin);
+IW_STATS_ENTRY(tcpRtoMax);
+IW_STATS_ENTRY(tcpMaxConn);
+IW_STATS_ENTRY(tcpActiveOpens);
+IW_STATS_ENTRY(tcpPassiveOpens);
+IW_STATS_ENTRY(tcpAttemptFails);
+IW_STATS_ENTRY(tcpEstabResets);
+IW_STATS_ENTRY(tcpCurrEstab);
+IW_STATS_ENTRY(tcpInSegs);
+IW_STATS_ENTRY(tcpOutSegs);
+IW_STATS_ENTRY(tcpRetransSegs);
+IW_STATS_ENTRY(tcpInErrs);
+IW_STATS_ENTRY(tcpOutRsts);
+
+static struct attribute *iw_proto_stats_attrs[] = {
+	&dev_attr_ipInReceives.attr,
+	&dev_attr_ipInHdrErrors.attr,
+	&dev_attr_ipInTooBigErrors.attr,
+	&dev_attr_ipInNoRoutes.attr,
+	&dev_attr_ipInAddrErrors.attr,
+	&dev_attr_ipInUnknownProtos.attr,
+	&dev_attr_ipInTruncatedPkts.attr,
+	&dev_attr_ipInDiscards.attr,
+	&dev_attr_ipInDelivers.attr,
+	&dev_attr_ipOutForwDatagrams.attr,
+	&dev_attr_ipOutRequests.attr,
+	&dev_attr_ipOutDiscards.attr,
+	&dev_attr_ipOutNoRoutes.attr,
+	&dev_attr_ipReasmTimeout.attr,
+	&dev_attr_ipReasmReqds.attr,
+	&dev_attr_ipReasmOKs.attr,
+	&dev_attr_ipReasmFails.attr,
+	&dev_attr_ipFragOKs.attr,
+	&dev_attr_ipFragFails.attr,
+	&dev_attr_ipFragCreates.attr,
+	&dev_attr_ipInMcastPkts.attr,
+	&dev_attr_ipOutMcastPkts.attr,
+	&dev_attr_ipInBcastPkts.attr,
+	&dev_attr_ipOutBcastPkts.attr,
+	&dev_attr_tcpRtoAlgorithm.attr,
+	&dev_attr_tcpRtoMin.attr,
+	&dev_attr_tcpRtoMax.attr,
+	&dev_attr_tcpMaxConn.attr,
+	&dev_attr_tcpActiveOpens.attr,
+	&dev_attr_tcpPassiveOpens.attr,
+	&dev_attr_tcpAttemptFails.attr,
+	&dev_attr_tcpEstabResets.attr,
+	&dev_attr_tcpCurrEstab.attr,
+	&dev_attr_tcpInSegs.attr,
+	&dev_attr_tcpOutSegs.attr,
+	&dev_attr_tcpRetransSegs.attr,
+	&dev_attr_tcpInErrs.attr,
+	&dev_attr_tcpOutRsts.attr,
+	NULL
+};
+
+static struct attribute_group iw_stats_group = {
+	.name  = "proto_stats",
+	.attrs  = iw_proto_stats_attrs,
+};
+
 int ib_device_register_sysfs(struct ib_device *device)
 {
 	struct device *class_dev = &device->dev;
@@ -707,6 +825,11 @@ int ib_device_register_sysfs(struct ib_device *device)
 		}
 	}
 
+	if (device->node_type == RDMA_NODE_RNIC && device->get_protocol_stats) {
+		ret = sysfs_create_group(&class_dev->kobj, &iw_stats_group);
+		if (ret)
+			goto err_put;
+	}
 	return 0;
 
 err_put:
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 62e5bcd..6f2c180 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -53,6 +53,57 @@
 #include <asm/atomic.h>
 #include <asm/uaccess.h>
 
+struct ib_protocol_stats {
+	/* TBD... */
+};
+
+struct iw_protocol_stats {
+	u64 ipInReceives;
+	u64 ipInHdrErrors;
+	u64 ipInTooBigErrors;
+	u64 ipOutNoRoutes;
+	u64 ipInAddrErrors;
+	u64 ipInUnknownProtos;
+	u64 ipInTruncatedPkts;
+	u64 ipInDiscards;
+	u64 ipInDelivers;
+	u64 ipOutForwDatagrams;
+	u64 ipOutRequests;
+	u64 ipOutDiscards;
+	u64 ipOutNoRoutes;
+	u64 ipReasmTimeout;
+	u64 ipReasmReqds;
+	u64 ipReasmOKs;
+	u64 ipReasmFails;
+	u64 ipFragOKs;
+	u64 ipFragFails;
+	u64 ipFragCreates;
+	u64 ipInMcastPkts;
+	u64 ipOutMcastPkts;
+	u64 ipInBcastPkts;
+	u64 ipOutBcastPkts;
+
+	u64 tcpRtoAlgorithm;
+	u64 tcpRtoMin;
+	u64 tcpRtoMax;
+	u64 tcpMaxConn;
+	u64 tcpActiveOpens;
+	u64 tcpPassiveOpens;
+	u64 tcpAttemptFails;
+	u64 tcpEstabResets;
+	u64 tcpCurrEstab;
+	u64 tcpInSegs;
+	u64 tcpOutSegs;
+	u64 tcpRetransSegs;
+	u64 tcpInErrs;
+	u64 tcpOutRsts;
+};
+
+union rdma_protocol_stats {
+	struct ib_protocol_stats ib;
+	struct iw_protocol_stats iw;
+};
+
 union ib_gid {
 	u8	raw[16];
 	struct {
@@ -947,6 +998,8 @@ struct ib_device {
 
 	struct iw_cm_verbs	     *iwcm;
 
+	int		           (*get_protocol_stats)(struct ib_device *device,
+						   union rdma_protocol_stats *stats);
 	int		           (*query_device)(struct ib_device *device,
 						   struct ib_device_attr *device_attr);
 	int		           (*query_port)(struct ib_device *device,



More information about the general mailing list