aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-08-03 04:40:51 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-30 23:33:39 -0400
commitc1e7e466120b80ce49e91af0c9da1ce6dee4844a (patch)
treefc67dbaf01fff7e0f411315ee3b5a6923cf22354
parent2a4fae148cf4b60e73faf0a427302697917409d9 (diff)
IB/mlx4: Add iov directory in sysfs under the ib device
This directory is added only for the master -- slaves do not have it. The sysfs iov directory is used to manage and examine the port P_Key and guid paravirtualization. Under iov/ports, the administrator may examine the gid and P_Key tables as they are present in the device (and as are seen in the "network view" presented to the SM). Under the iov/<pci slot number> directories, the admin may map the index numbers in the physical tables (as under iov/ports) to the paravirtualized index numbers that guests see. For example, if the administrator, for port 1 on guest 2 maps physical pkey index 10 to virtual index 1, then that guest, whenever it uses its pkey index 1, will actually be using the real pkey index 10. Based on patch from Erez Shitrit <erezsh@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/mlx4/Makefile2
-rw-r--r--drivers/infiniband/hw/mlx4/alias_GUID.c6
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c9
-rw-r--r--drivers/infiniband/hw/mlx4/mcg.c67
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h43
-rw-r--r--drivers/infiniband/hw/mlx4/sysfs.c794
6 files changed, 917 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/mlx4/Makefile b/drivers/infiniband/hw/mlx4/Makefile
index 31d4c8aac679..f4213b3a8fe1 100644
--- a/drivers/infiniband/hw/mlx4/Makefile
+++ b/drivers/infiniband/hw/mlx4/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_MLX4_INFINIBAND) += mlx4_ib.o 1obj-$(CONFIG_MLX4_INFINIBAND) += mlx4_ib.o
2 2
3mlx4_ib-y := ah.o cq.o doorbell.o mad.o main.o mr.o qp.o srq.o mcg.o cm.o alias_GUID.o 3mlx4_ib-y := ah.o cq.o doorbell.o mad.o main.o mr.o qp.o srq.o mcg.o cm.o alias_GUID.o sysfs.o
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index ef6d356927c3..0fcd5cd6f3ee 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -113,7 +113,7 @@ static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index
113} 113}
114 114
115 115
116static ib_sa_comp_mask get_aguid_comp_mask_from_ix(int index) 116ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index)
117{ 117{
118 return IB_SA_COMP_MASK(4 + index); 118 return IB_SA_COMP_MASK(4 + index);
119} 119}
@@ -259,7 +259,7 @@ static void aliasguid_query_handler(int status,
259 /* Mark the record as not assigned, and let it 259 /* Mark the record as not assigned, and let it
260 * be sent again in the next work sched.*/ 260 * be sent again in the next work sched.*/
261 rec->status = MLX4_GUID_INFO_STATUS_IDLE; 261 rec->status = MLX4_GUID_INFO_STATUS_IDLE;
262 rec->guid_indexes |= get_aguid_comp_mask_from_ix(i); 262 rec->guid_indexes |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
263 } 263 }
264 } else { 264 } else {
265 /* properly assigned record. */ 265 /* properly assigned record. */
@@ -337,7 +337,7 @@ static void invalidate_guid_record(struct mlx4_ib_dev *dev, u8 port, int index)
337 MLX4_GUID_NONE_ASSIGN == dev->sriov.alias_guid. 337 MLX4_GUID_NONE_ASSIGN == dev->sriov.alias_guid.
338 ports_guid[port - 1].all_rec_per_port[index].ownership) 338 ports_guid[port - 1].all_rec_per_port[index].ownership)
339 continue; 339 continue;
340 comp_mask |= get_aguid_comp_mask_from_ix(i); 340 comp_mask |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
341 } 341 }
342 dev->sriov.alias_guid.ports_guid[port - 1]. 342 dev->sriov.alias_guid.ports_guid[port - 1].
343 all_rec_per_port[index].guid_indexes = comp_mask; 343 all_rec_per_port[index].guid_indexes = comp_mask;
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 591c2891159b..b689dbd6d8f6 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -1963,6 +1963,11 @@ int mlx4_ib_init_sriov(struct mlx4_ib_dev *dev)
1963 mlx4_ib_warn(&dev->ib_dev, "Failed init alias guid process.\n"); 1963 mlx4_ib_warn(&dev->ib_dev, "Failed init alias guid process.\n");
1964 goto paravirt_err; 1964 goto paravirt_err;
1965 } 1965 }
1966 err = mlx4_ib_device_register_sysfs(dev);
1967 if (err) {
1968 mlx4_ib_warn(&dev->ib_dev, "Failed to register sysfs\n");
1969 goto sysfs_err;
1970 }
1966 1971
1967 mlx4_ib_warn(&dev->ib_dev, "initializing demux service for %d qp1 clients\n", 1972 mlx4_ib_warn(&dev->ib_dev, "initializing demux service for %d qp1 clients\n",
1968 dev->dev->caps.sqp_demux); 1973 dev->dev->caps.sqp_demux);
@@ -1989,6 +1994,9 @@ demux_err:
1989 mlx4_ib_free_demux_ctx(&dev->sriov.demux[i]); 1994 mlx4_ib_free_demux_ctx(&dev->sriov.demux[i]);
1990 --i; 1995 --i;
1991 } 1996 }
1997 mlx4_ib_device_unregister_sysfs(dev);
1998
1999sysfs_err:
1992 mlx4_ib_destroy_alias_guid_service(dev); 2000 mlx4_ib_destroy_alias_guid_service(dev);
1993 2001
1994paravirt_err: 2002paravirt_err:
@@ -2019,5 +2027,6 @@ void mlx4_ib_close_sriov(struct mlx4_ib_dev *dev)
2019 2027
2020 mlx4_ib_cm_paravirt_clean(dev, -1); 2028 mlx4_ib_cm_paravirt_clean(dev, -1);
2021 mlx4_ib_destroy_alias_guid_service(dev); 2029 mlx4_ib_destroy_alias_guid_service(dev);
2030 mlx4_ib_device_unregister_sysfs(dev);
2022 } 2031 }
2023} 2032}
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
index 1ee2e3a3347a..3c3b54c3fdd9 100644
--- a/drivers/infiniband/hw/mlx4/mcg.c
+++ b/drivers/infiniband/hw/mlx4/mcg.c
@@ -110,6 +110,7 @@ struct mcast_group {
110 __be64 last_req_tid; 110 __be64 last_req_tid;
111 111
112 char name[33]; /* MGID string */ 112 char name[33]; /* MGID string */
113 struct device_attribute dentry;
113 114
114 /* refcount is the reference count for the following: 115 /* refcount is the reference count for the following:
115 1. Each queued request 116 1. Each queued request
@@ -445,6 +446,8 @@ static int release_group(struct mcast_group *group, int from_timeout_handler)
445 } 446 }
446 447
447 nzgroup = memcmp(&group->rec.mgid, &mgid0, sizeof mgid0); 448 nzgroup = memcmp(&group->rec.mgid, &mgid0, sizeof mgid0);
449 if (nzgroup)
450 del_sysfs_port_mcg_attr(ctx->dev, ctx->port, &group->dentry.attr);
448 if (!list_empty(&group->pending_list)) 451 if (!list_empty(&group->pending_list))
449 mcg_warn_group(group, "releasing a group with non empty pending list\n"); 452 mcg_warn_group(group, "releasing a group with non empty pending list\n");
450 if (nzgroup) 453 if (nzgroup)
@@ -769,6 +772,7 @@ static struct mcast_group *search_relocate_mgid0_group(struct mlx4_ib_demux_ctx
769 } 772 }
770 773
771 atomic_inc(&group->refcount); 774 atomic_inc(&group->refcount);
775 add_sysfs_port_mcg_attr(ctx->dev, ctx->port, &group->dentry.attr);
772 mutex_unlock(&group->lock); 776 mutex_unlock(&group->lock);
773 mutex_unlock(&ctx->mcg_table_lock); 777 mutex_unlock(&ctx->mcg_table_lock);
774 return group; 778 return group;
@@ -796,6 +800,9 @@ static struct mcast_group *search_relocate_mgid0_group(struct mlx4_ib_demux_ctx
796 return NULL; 800 return NULL;
797} 801}
798 802
803static ssize_t sysfs_show_group(struct device *dev,
804 struct device_attribute *attr, char *buf);
805
799static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx, 806static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx,
800 union ib_gid *mgid, int create, 807 union ib_gid *mgid, int create,
801 gfp_t gfp_mask) 808 gfp_t gfp_mask)
@@ -830,6 +837,11 @@ static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx,
830 sprintf(group->name, "%016llx%016llx", 837 sprintf(group->name, "%016llx%016llx",
831 be64_to_cpu(group->rec.mgid.global.subnet_prefix), 838 be64_to_cpu(group->rec.mgid.global.subnet_prefix),
832 be64_to_cpu(group->rec.mgid.global.interface_id)); 839 be64_to_cpu(group->rec.mgid.global.interface_id));
840 sysfs_attr_init(&group->dentry.attr);
841 group->dentry.show = sysfs_show_group;
842 group->dentry.store = NULL;
843 group->dentry.attr.name = group->name;
844 group->dentry.attr.mode = 0400;
833 group->state = MCAST_IDLE; 845 group->state = MCAST_IDLE;
834 846
835 if (is_mgid0) { 847 if (is_mgid0) {
@@ -844,6 +856,8 @@ static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx,
844 return ERR_PTR(-EINVAL); 856 return ERR_PTR(-EINVAL);
845 } 857 }
846 858
859 add_sysfs_port_mcg_attr(ctx->dev, ctx->port, &group->dentry.attr);
860
847found: 861found:
848 atomic_inc(&group->refcount); 862 atomic_inc(&group->refcount);
849 return group; 863 return group;
@@ -969,6 +983,58 @@ int mlx4_ib_mcg_multiplex_handler(struct ib_device *ibdev, int port,
969 } 983 }
970} 984}
971 985
986static ssize_t sysfs_show_group(struct device *dev,
987 struct device_attribute *attr, char *buf)
988{
989 struct mcast_group *group =
990 container_of(attr, struct mcast_group, dentry);
991 struct mcast_req *req = NULL;
992 char pending_str[40];
993 char state_str[40];
994 ssize_t len = 0;
995 int f;
996
997 if (group->state == MCAST_IDLE)
998 sprintf(state_str, "%s", get_state_string(group->state));