Skip to content

Commit 5ec8c83

Browse files
Aviv Hellerdledford
authored andcommitted
IB/mlx5: Port events in RoCE now rely on netdev events
Since ib_query_port() in RoCE returns the state of its netdev as the port state, it makes sense to propagate the port up/down events to ib_core when the netdev port state changes, instead of relying on traditional core events. This also keeps both the event and ib_query_port() synchronized. Signed-off-by: Aviv Heller <avivh@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
1 parent 350d0e4 commit 5ec8c83

File tree

1 file changed

+51
-15
lines changed
  • drivers/infiniband/hw/mlx5

1 file changed

+51
-15
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,32 @@ static int mlx5_netdev_event(struct notifier_block *this,
107107
struct mlx5_ib_dev *ibdev = container_of(this, struct mlx5_ib_dev,
108108
roce.nb);
109109

110-
if ((event != NETDEV_UNREGISTER) && (event != NETDEV_REGISTER))
111-
return NOTIFY_DONE;
110+
switch (event) {
111+
case NETDEV_REGISTER:
112+
case NETDEV_UNREGISTER:
113+
write_lock(&ibdev->roce.netdev_lock);
114+
if (ndev->dev.parent == &ibdev->mdev->pdev->dev)
115+
ibdev->roce.netdev = (event == NETDEV_UNREGISTER) ?
116+
NULL : ndev;
117+
write_unlock(&ibdev->roce.netdev_lock);
118+
break;
112119

113-
write_lock(&ibdev->roce.netdev_lock);
114-
if (ndev->dev.parent == &ibdev->mdev->pdev->dev)
115-
ibdev->roce.netdev = (event == NETDEV_UNREGISTER) ? NULL : ndev;
116-
write_unlock(&ibdev->roce.netdev_lock);
120+
case NETDEV_UP:
121+
case NETDEV_DOWN:
122+
if (ndev == ibdev->roce.netdev && ibdev->ib_active) {
123+
struct ib_event ibev = {0};
124+
125+
ibev.device = &ibdev->ib_dev;
126+
ibev.event = (event == NETDEV_UP) ?
127+
IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
128+
ibev.element.port_num = 1;
129+
ib_dispatch_event(&ibev);
130+
}
131+
break;
132+
133+
default:
134+
break;
135+
}
117136

118137
return NOTIFY_DONE;
119138
}
@@ -2267,14 +2286,19 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
22672286
break;
22682287

22692288
case MLX5_DEV_EVENT_PORT_UP:
2270-
ibev.event = IB_EVENT_PORT_ACTIVE;
2271-
port = (u8)param;
2272-
break;
2273-
22742289
case MLX5_DEV_EVENT_PORT_DOWN:
22752290
case MLX5_DEV_EVENT_PORT_INITIALIZED:
2276-
ibev.event = IB_EVENT_PORT_ERR;
22772291
port = (u8)param;
2292+
2293+
/* In RoCE, port up/down events are handled in
2294+
* mlx5_netdev_event().
2295+
*/
2296+
if (mlx5_ib_port_link_layer(&ibdev->ib_dev, port) ==
2297+
IB_LINK_LAYER_ETHERNET)
2298+
return;
2299+
2300+
ibev.event = (event == MLX5_DEV_EVENT_PORT_UP) ?
2301+
IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
22782302
break;
22792303

22802304
case MLX5_DEV_EVENT_LID_CHANGE:
@@ -2679,14 +2703,24 @@ static void get_dev_fw_str(struct ib_device *ibdev, char *str,
26792703
fw_rev_min(dev->mdev), fw_rev_sub(dev->mdev));
26802704
}
26812705

2706+
static void mlx5_remove_roce_notifier(struct mlx5_ib_dev *dev)
2707+
{
2708+
if (dev->roce.nb.notifier_call) {
2709+
unregister_netdevice_notifier(&dev->roce.nb);
2710+
dev->roce.nb.notifier_call = NULL;
2711+
}
2712+
}
2713+
26822714
static int mlx5_enable_roce(struct mlx5_ib_dev *dev)
26832715
{
26842716
int err;
26852717

26862718
dev->roce.nb.notifier_call = mlx5_netdev_event;
26872719
err = register_netdevice_notifier(&dev->roce.nb);
2688-
if (err)
2720+
if (err) {
2721+
dev->roce.nb.notifier_call = NULL;
26892722
return err;
2723+
}
26902724

26912725
err = mlx5_nic_vport_enable_roce(dev->mdev);
26922726
if (err)
@@ -2695,14 +2729,13 @@ static int mlx5_enable_roce(struct mlx5_ib_dev *dev)
26952729
return 0;
26962730

26972731
err_unregister_netdevice_notifier:
2698-
unregister_netdevice_notifier(&dev->roce.nb);
2732+
mlx5_remove_roce_notifier(dev);
26992733
return err;
27002734
}
27012735

27022736
static void mlx5_disable_roce(struct mlx5_ib_dev *dev)
27032737
{
27042738
mlx5_nic_vport_disable_roce(dev->mdev);
2705-
unregister_netdevice_notifier(&dev->roce.nb);
27062739
}
27072740

27082741
static void mlx5_ib_dealloc_q_counters(struct mlx5_ib_dev *dev)
@@ -3051,8 +3084,10 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
30513084
destroy_dev_resources(&dev->devr);
30523085

30533086
err_disable_roce:
3054-
if (ll == IB_LINK_LAYER_ETHERNET)
3087+
if (ll == IB_LINK_LAYER_ETHERNET) {
30553088
mlx5_disable_roce(dev);
3089+
mlx5_remove_roce_notifier(dev);
3090+
}
30563091

30573092
err_free_port:
30583093
kfree(dev->port);
@@ -3068,6 +3103,7 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
30683103
struct mlx5_ib_dev *dev = context;
30693104
enum rdma_link_layer ll = mlx5_ib_port_link_layer(&dev->ib_dev, 1);
30703105

3106+
mlx5_remove_roce_notifier(dev);
30713107
ib_unregister_device(&dev->ib_dev);
30723108
mlx5_ib_dealloc_q_counters(dev);
30733109
destroy_umrc_res(dev);

0 commit comments

Comments
 (0)