Skip to content

Commit a45af9a

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5: SD, Implement devcom communication and primary election
Use devcom to communicate between the different devices. Add a new devcom component type for this. Each device registers itself to the devcom component <SD, group ID>. Once all devices of a component are registered, the component becomes ready, and a primary device is elected. In principle, any of the devices can act as a primary, they are all capable, and a random election would've worked. However, we aim to achieve predictability and consistency, hence each group always choses the same device, with the lowest PCI BUS number, as primary. Signed-off-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 63b9ce9 commit a45af9a

File tree

2 files changed

+121
-2
lines changed

2 files changed

+121
-2
lines changed

drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum mlx5_devcom_component {
1010
MLX5_DEVCOM_ESW_OFFLOADS,
1111
MLX5_DEVCOM_MPV,
1212
MLX5_DEVCOM_HCA_PORTS,
13+
MLX5_DEVCOM_SD_GROUP,
1314
MLX5_DEVCOM_NUM_COMPONENTS,
1415
};
1516

drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
struct mlx5_sd {
1515
u32 group_id;
1616
u8 host_buses;
17+
struct mlx5_devcom_comp_dev *devcom;
18+
bool primary;
19+
union {
20+
struct { /* primary */
21+
struct mlx5_core_dev *secondaries[MLX5_SD_MAX_GROUP_SZ - 1];
22+
};
23+
struct { /* secondary */
24+
struct mlx5_core_dev *primary_dev;
25+
};
26+
};
1727
};
1828

1929
static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
@@ -26,13 +36,29 @@ static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
2636
return sd->host_buses;
2737
}
2838

39+
static struct mlx5_core_dev *mlx5_sd_get_primary(struct mlx5_core_dev *dev)
40+
{
41+
struct mlx5_sd *sd = mlx5_get_sd(dev);
42+
43+
if (!sd)
44+
return dev;
45+
46+
return sd->primary ? dev : sd->primary_dev;
47+
}
48+
2949
struct mlx5_core_dev *
3050
mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx)
3151
{
52+
struct mlx5_sd *sd;
53+
3254
if (idx == 0)
3355
return primary;
3456

35-
return NULL;
57+
if (idx >= mlx5_sd_get_host_buses(primary))
58+
return NULL;
59+
60+
sd = mlx5_get_sd(primary);
61+
return sd->secondaries[idx - 1];
3662
}
3763

3864
int mlx5_sd_ch_ix_get_dev_ix(struct mlx5_core_dev *dev, int ch_ix)
@@ -136,15 +162,93 @@ static void sd_cleanup(struct mlx5_core_dev *dev)
136162
kfree(sd);
137163
}
138164

165+
static int sd_register(struct mlx5_core_dev *dev)
166+
{
167+
struct mlx5_devcom_comp_dev *devcom, *pos;
168+
struct mlx5_core_dev *peer, *primary;
169+
struct mlx5_sd *sd, *primary_sd;
170+
int err, i;
171+
172+
sd = mlx5_get_sd(dev);
173+
devcom = mlx5_devcom_register_component(dev->priv.devc, MLX5_DEVCOM_SD_GROUP,
174+
sd->group_id, NULL, dev);
175+
if (!devcom)
176+
return -ENOMEM;
177+
178+
sd->devcom = devcom;
179+
180+
if (mlx5_devcom_comp_get_size(devcom) != sd->host_buses)
181+
return 0;
182+
183+
mlx5_devcom_comp_lock(devcom);
184+
mlx5_devcom_comp_set_ready(devcom, true);
185+
mlx5_devcom_comp_unlock(devcom);
186+
187+
if (!mlx5_devcom_for_each_peer_begin(devcom)) {
188+
err = -ENODEV;
189+
goto err_devcom_unreg;
190+
}
191+
192+
primary = dev;
193+
mlx5_devcom_for_each_peer_entry(devcom, peer, pos)
194+
if (peer->pdev->bus->number < primary->pdev->bus->number)
195+
primary = peer;
196+
197+
primary_sd = mlx5_get_sd(primary);
198+
primary_sd->primary = true;
199+
i = 0;
200+
/* loop the secondaries */
201+
mlx5_devcom_for_each_peer_entry(primary_sd->devcom, peer, pos) {
202+
struct mlx5_sd *peer_sd = mlx5_get_sd(peer);
203+
204+
primary_sd->secondaries[i++] = peer;
205+
peer_sd->primary = false;
206+
peer_sd->primary_dev = primary;
207+
}
208+
209+
mlx5_devcom_for_each_peer_end(devcom);
210+
return 0;
211+
212+
err_devcom_unreg:
213+
mlx5_devcom_comp_lock(sd->devcom);
214+
mlx5_devcom_comp_set_ready(sd->devcom, false);
215+
mlx5_devcom_comp_unlock(sd->devcom);
216+
mlx5_devcom_unregister_component(sd->devcom);
217+
return err;
218+
}
219+
220+
static void sd_unregister(struct mlx5_core_dev *dev)
221+
{
222+
struct mlx5_sd *sd = mlx5_get_sd(dev);
223+
224+
mlx5_devcom_comp_lock(sd->devcom);
225+
mlx5_devcom_comp_set_ready(sd->devcom, false);
226+
mlx5_devcom_comp_unlock(sd->devcom);
227+
mlx5_devcom_unregister_component(sd->devcom);
228+
}
229+
139230
int mlx5_sd_init(struct mlx5_core_dev *dev)
140231
{
232+
struct mlx5_sd *sd = mlx5_get_sd(dev);
141233
int err;
142234

143235
err = sd_init(dev);
144236
if (err)
145237
return err;
146238

239+
sd = mlx5_get_sd(dev);
240+
if (!sd)
241+
return 0;
242+
243+
err = sd_register(dev);
244+
if (err)
245+
goto err_sd_cleanup;
246+
147247
return 0;
248+
249+
err_sd_cleanup:
250+
sd_cleanup(dev);
251+
return err;
148252
}
149253

150254
void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
@@ -154,12 +258,26 @@ void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
154258
if (!sd)
155259
return;
156260

261+
sd_unregister(dev);
157262
sd_cleanup(dev);
158263
}
159264

160265
struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
161266
struct auxiliary_device *adev,
162267
int idx)
163268
{
164-
return adev;
269+
struct mlx5_sd *sd = mlx5_get_sd(dev);
270+
struct mlx5_core_dev *primary;
271+
272+
if (!sd)
273+
return adev;
274+
275+
if (!mlx5_devcom_comp_is_ready(sd->devcom))
276+
return NULL;
277+
278+
primary = mlx5_sd_get_primary(dev);
279+
if (dev == primary)
280+
return adev;
281+
282+
return &primary->priv.adev[idx]->adev;
165283
}

0 commit comments

Comments
 (0)