RDMA/core: Add iWARP protocol statistics attributes in sysfs
authorSteve Wise <swise@opengridcomputing.com>
Tue, 15 Jul 2008 06:48:48 +0000 (23:48 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 15 Jul 2008 06:48:48 +0000 (23:48 -0700)
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@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/core/sysfs.c
include/rdma/ib_verbs.h

index 36a0ef9..4d10421 100644 (file)
@@ -663,6 +663,120 @@ 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;
+
+       ret = dev->get_protocol_stats(dev, &stats);
+       if (ret)
+               return ret;
+
+       return sprintf(buf, "%llu\n",
+                      (unsigned long long) ((u64 *) &stats)[offset]);
+}
+
+/* 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) / \
+                                 sizeof (u64));                        \
+}                                                                      \
+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;
@@ -705,6 +819,12 @@ 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:
index 74c24b9..10ebaaa 100644 (file)
@@ -226,6 +226,57 @@ static inline int ib_width_enum_to_int(enum ib_port_width width)
        }
 }
 
+struct ib_protocol_stats {
+       /* TBD... */
+};
+
+struct iw_protocol_stats {
+       u64     ipInReceives;
+       u64     ipInHdrErrors;
+       u64     ipInTooBigErrors;
+       u64     ipInNoRoutes;
+       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;
+};
+
 struct ib_port_attr {
        enum ib_port_state      state;
        enum ib_mtu             max_mtu;
@@ -943,6 +994,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,