diff options
author | Yishai Hadas <yishaih@mellanox.com> | 2015-03-03 10:28:49 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-04-15 15:51:50 -0400 |
commit | ee59fa0d7e9af130bfc1b75524e04c101670bd5e (patch) | |
tree | f5686baddd5dc88e658064aa40205d650c3af7f0 /drivers/infiniband/hw | |
parent | f54796012837687532d0a87a0504de22da7c2503 (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.c | 51 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 22 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 2 |
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 | ||
126 | void 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; | ||
170 | unlock: | ||
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, | |||
798 | void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, | 798 | void del_sysfs_port_mcg_attr(struct mlx4_ib_dev *device, int port_num, |
799 | struct attribute *attr); | 799 | struct attribute *attr); |
800 | ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index); | 800 | ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index); |
801 | void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave, | ||
802 | int port, int slave_init); | ||
801 | 803 | ||
802 | int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *device) ; | 804 | int mlx4_ib_device_register_sysfs(struct mlx4_ib_dev *device) ; |
803 | 805 | ||