From: Parav Pandit <pa...@mellanox.com>

[ Upstream commit 0f6ef65d1c6ec8deb5d0f11f86631ec4cfe8f22e ]

If the provider driver (such as rdma_rxe) doesn't support pma counters,
avoid exposing its directory similar to optional hw_counters directory.
If core fails to read the PMA counter, return an error so that user can
retry later if needed.

Fixes: 35c4cbb17811 ("IB/core: Create get_perf_mad function in sysfs.c")
Reported-by: Holger Hoffstätte <hol...@applied-asynchrony.com>
Tested-by: Holger Hoffstätte <hol...@applied-asynchrony.com>
Signed-off-by: Parav Pandit <pa...@mellanox.com>
Signed-off-by: Leon Romanovsky <leo...@mellanox.com>
Signed-off-by: Doug Ledford <dledf...@redhat.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/infiniband/core/sysfs.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 42de5f22da93..a1240ddca026 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -485,7 +485,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct 
port_attribute *attr,
        ret = get_perf_mad(p->ibdev, p->port_num, tab_attr->attr_id, &data,
                        40 + offset / 8, sizeof(data));
        if (ret < 0)
-               return sprintf(buf, "N/A (no PMA)\n");
+               return ret;
 
        switch (width) {
        case 4:
@@ -1008,10 +1008,12 @@ static int add_port(struct ib_device *device, int 
port_num,
                goto err_put;
        }
 
-       p->pma_table = get_counter_table(device, port_num);
-       ret = sysfs_create_group(&p->kobj, p->pma_table);
-       if (ret)
-               goto err_put_gid_attrs;
+       if (device->process_mad) {
+               p->pma_table = get_counter_table(device, port_num);
+               ret = sysfs_create_group(&p->kobj, p->pma_table);
+               if (ret)
+                       goto err_put_gid_attrs;
+       }
 
        p->gid_group.name  = "gids";
        p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
@@ -1124,7 +1126,8 @@ static int add_port(struct ib_device *device, int 
port_num,
        p->gid_group.attrs = NULL;
 
 err_remove_pma:
-       sysfs_remove_group(&p->kobj, p->pma_table);
+       if (p->pma_table)
+               sysfs_remove_group(&p->kobj, p->pma_table);
 
 err_put_gid_attrs:
        kobject_put(&p->gid_attr_group->kobj);
@@ -1236,7 +1239,9 @@ static void free_port_list_attributes(struct ib_device 
*device)
                        kfree(port->hw_stats);
                        free_hsag(&port->kobj, port->hw_stats_ag);
                }
-               sysfs_remove_group(p, port->pma_table);
+
+               if (port->pma_table)
+                       sysfs_remove_group(p, port->pma_table);
                sysfs_remove_group(p, &port->pkey_group);
                sysfs_remove_group(p, &port->gid_group);
                sysfs_remove_group(&port->gid_attr_group->kobj,
-- 
2.17.1

Reply via email to