Hello,

     we need a possibility to reset the port counters in 
/sys/class/infiniband/mthca0/ports/1/counters/.

     The attached patch implements the ability to reset the counters by writing 
to the sysfs  counter files.
     The patch uses the same process_mad() mechanism as in the counter reading, 
but with IB_MGMT_METHOD_SET.

     The patch was checked on IBED-1.0-rc3 code, with MTHCA adaptor.

     I  checked also possibility to set specific counter values, but always got 
the counter reset instead.

     The questions are:
          Is it a protocol or a firmware limitation, that I couldn't set 
specific values?
          If there is a way to set specific values, should we implement it?
          Should we implement an ability to reset (or set) specific counters,
          just like like I did in this patch?
               (this can cause inconsistency between  counter values,
                for example between  port_xmit_data and port_xmit_packets)
          Should we create an additional sysfs entry for the counter reset 
purpose
          (like /sys/class/infiniband/mthca0/ports/1/reset_counters) instead?


    Regards,
       Leonid
            



Signed-off-by: Leonid Arsh <[EMAIL PROTECTED]>

--- linux-kernel/infiniband/core/sysfs.c.orig   2006-05-07 23:07:10.000000000 
+0300
+++ linux-kernel/infiniband/core/sysfs.c        2006-05-09 17:55:55.000000000 
+0300
@@ -88,8 +88,24 @@
        return port_attr->show(p, port_attr, buf);
 }
 
+static ssize_t port_attr_store(struct kobject *kobj,
+                              struct attribute *attr, const char *buf, size_t 
len)
+{
+       struct port_attribute *port_attr =
+               container_of(attr, struct port_attribute, attr);
+       struct ib_port *p = container_of(kobj, struct ib_port, kobj);
+
+       if (!port_attr->store)
+               return -EIO;
+       if (!ibdev_is_alive(p->ibdev))
+               return -ENODEV;
+
+       return port_attr->store(p, port_attr, buf, len);
+}
+
 static struct sysfs_ops port_sysfs_ops = {
-       .show = port_attr_show
+       .show = port_attr_show,
+       .store = port_attr_store
 };
 
 static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
@@ -292,10 +308,65 @@
 
 #define PORT_PMA_ATTR(_name, _counter, _width, _offset)                        
\
 struct port_table_attribute port_pma_attr_##_name = {                  \
-       .attr  = __ATTR(_name, S_IRUGO, show_pma_counter, NULL),        \
+       .attr  = __ATTR(_name, S_IRUGO | S_IWUSR,                       \
+        show_pma_counter, store_pma_counter),                          \
        .index = (_offset) | ((_width) << 16) | ((_counter) << 24)      \
 }
 
+static ssize_t store_pma_counter(struct ib_port *p, struct port_attribute 
*attr,
+                                const char *buf, size_t count)
+{
+       struct port_table_attribute *tab_attr =
+               container_of(attr, struct port_table_attribute, attr);
+       int counter = (tab_attr->index >> 24) & 0xff;
+       struct ib_mad *in_mad  = NULL;
+       struct ib_mad *out_mad = NULL;
+       ssize_t ret;
+
+       if (!p->ibdev->process_mad)
+       {
+               printk("store_pma_counter() process_mad() == NULL");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
+       out_mad = kmalloc(sizeof *in_mad, GFP_KERNEL);
+       if (!in_mad || !out_mad) {
+               printk("store_pma_counter() NOMEM");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memset( in_mad, 0, sizeof *in_mad );
+
+       in_mad->mad_hdr.base_version  = 1;
+       in_mad->mad_hdr.mgmt_class    = IB_MGMT_CLASS_PERF_MGMT;
+       in_mad->mad_hdr.class_version = 1;
+       in_mad->mad_hdr.method        = IB_MGMT_METHOD_SET;
+       in_mad->mad_hdr.attr_id       = cpu_to_be16(0x12); /* PortCounters */
+
+       *(__be16 *)(in_mad->data+42) = cpu_to_be16( ((__u16)1) << counter ); /* 
CounterSelect field */
+
+       in_mad->data[41] = p->port_num; /* PortSelect field */
+
+       if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
+                p->port_num, NULL, NULL, in_mad, out_mad) &
+            (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
+           (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
+               printk("store_pma_counter() EINVAL");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = count;
+out:
+       kfree(in_mad);
+       kfree(out_mad);
+
+       return ret;
+}
+
 static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
                                char *buf)
 {
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to