aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2015-03-03 10:28:49 -0500
committerDoug Ledford <dledford@redhat.com>2015-04-15 15:51:50 -0400
commitee59fa0d7e9af130bfc1b75524e04c101670bd5e (patch)
treef5686baddd5dc88e658064aa40205d650c3af7f0 /drivers/infiniband/hw
parentf54796012837687532d0a87a0504de22da7c2503 (diff)
IB/mlx4: Request alias GUID on demand
Request GIDs from the SM on demand, i.e., when a VF actually needs them, and release them when the GIDs are no longer in use. In cloud environments, this is useful for GID migrations, in which a GID is assigned to a VF on the destination HCA, while the VF on the source HCA is shutdown (but the GID was not administratively released). Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/mlx4/alias_GUID.c51
-rw-r--r--drivers/infiniband/hw/mlx4/main.c22
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h2
3 files changed, 75 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c
index 5b4080740321..0f00204d2ece 100644
--- a/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ b/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -123,6 +123,57 @@ ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index)
123 return IB_SA_COMP_MASK(4 + index); 123 return IB_SA_COMP_MASK(4 + index);
124} 124}
125 125
126void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave,
127 int port, int slave_init)
128{
129 __be64 curr_guid, required_guid;
130 int record_num = slave / 8;
131 int index = slave % 8;
132 int port_index = port - 1;
133 unsigned long flags;
134 int do_work = 0;
135
136 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
137 if (dev->sriov.alias_guid.ports_guid[port_index].state_flags &
138 GUID_STATE_NEED_PORT_INIT)
139 goto unlock;
140 if (!slave_init) {
141 curr_guid = *(__be64 *)&dev->sriov.
142 alias_guid.ports_guid[port_index].
143 all_rec_per_port[record_num].
144 all_recs[GUID_REC_SIZE * index];
145 if (curr_guid == cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL) ||
146 !curr_guid)
147 goto unlock;
148 required_guid = cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL);
149 } else {
150 required_guid = mlx4_get_admin_guid(dev->dev, slave, port);
151 if (required_guid == cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL))
152 goto unlock;
153 }
154 *(__be64 *)&dev->sriov.alias_guid.ports_guid[port_index].
155 all_rec_per_port[record_num].
156 all_recs[GUID_REC_SIZE * index] = required_guid;
157 dev->sriov.alias_guid.ports_guid[port_index].
158 all_rec_per_port[record_num].guid_indexes
159 |= mlx4_ib_get_aguid_comp_mask_from_ix(index);
160 dev->sriov.alias_guid.ports_guid[port_index].
161 all_rec_per_port[record_num].status
162 = MLX4_GUID_INFO_STATUS_IDLE;
163 /* set to run immediately */
164 dev->sriov.alias_guid.ports_guid[port_index].
165 all_rec_per_port[record_num].time_to_run = 0;
166 dev->sriov.alias_guid.ports_guid[port_index].
167 all_rec_per_port[record_num].
168 guids_retry_schedule[index] = 0;
169 do_work = 1;
170unlock:
171 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
172
173 if (do_work)
174 mlx4_ib_init_alias_guid_work(dev, port_index);
175}
176
126/* 177/*
127 * Whenever new GUID is set/unset (guid table change) create event and 178 * Whenever new GUID is set/unset (guid table change) create event and
128 * notify the relevant slave (master also should be notified). 179 * notify the relevant slave (master also should be notified).
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 976bea794b5f..e92dc9aa075e 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -2791,9 +2791,31 @@ static void mlx4_ib_event(struct mlx4_dev *dev, void *ibdev_ptr,
2791 case MLX4_DEV_EVENT_SLAVE_INIT: 2791 case MLX4_DEV_EVENT_SLAVE_INIT:
2792 /* here, p is the slave id */ 2792 /* here, p is the slave id */
2793 do_slave_init(ibdev, p, 1); 2793 do_slave_init(ibdev, p, 1);
2794 if (mlx4_is_master(dev)) {
2795 int i;
2796
2797 for (i = 1; i <= ibdev->num_ports; i++) {
2798 if (rdma_port_get_link_layer(&ibdev->ib_dev, i)
2799 == IB_LINK_LAYER_INFINIBAND)
2800 mlx4_ib_slave_alias_guid_event(ibdev,
2801 p, i,
2802 1);
2803 }
2804 }
2794 return; 2805 return;
2795 2806
2796 case MLX4_DEV_EVENT_SLAVE_SHUTDOWN: 2807 case MLX4_DEV_EVENT_SLAVE_SHUTDOWN:
2808 if (mlx4_is_master(dev)) {
2809 int i;
2810
2811 for (i = 1; i <= ibdev->num_ports; i++) {
2812 if (rdma_port_get_link_layer(&ibdev->ib_dev, i)
2813 == IB_LINK_LAYER_INFINIBAND)
2814 mlx4_ib_slave_alias_guid_event(ibdev,
2815 p, i,
2816 0);
2817 }
2818 }
2797 /* here, p is the slave id */ 2819 /* here, p is the slave id */
2798 do_slave_init(ibdev, p, 0); 2820 do_slave_init(ibdev, p, 0);
2799 return; 2821 return;
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 532a8772b63f..fce3934372a1 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -798,6 +798,8 @@ int add_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
798void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, 798void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num,
799 struct attribute *attr); 799 struct attribute *attr);
800ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index); 800ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index);
801void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave,
802 int port, int slave_init);
801 803
802int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *device) ; 804int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *device) ;
803 805