Commit df097a27 authored by Saeed Mahameed's avatar Saeed Mahameed

IB/mlx5: Use the new mlx5 core notifier API

Remove the deprecated mlx5_interface->event mlx5_ib callback and use new
mlx5 notifier API to subscribe for mlx5 events.

For native mlx5_ib devices profiles pf_profile/nic_rep_profile register
the notifier callback mlx5_ib_handle_event which treats the notifier
context as mlx5_ib_dev.

For vport repesentors, don't register any notifier, same as before, they
didn't receive any mlx5 events.

For slave port (mlx5_ib_multiport_info) register a different notifier
callback mlx5_ib_event_slave_port, which knows that the event is coming
for mlx5_ib_multiport_info and prepares the event job accordingly.
Before this on the event handler work we had to ask mlx5_core if this is
a slave port mlx5_core_is_mp_slave(work->dev), now it is not needed
anymore.
mlx5_ib_multiport_info notifier registration is done on
mlx5_ib_bind_slave_port and de-registration is done on
mlx5_ib_unbind_slave_port.
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 58d180b3
...@@ -82,10 +82,13 @@ static char mlx5_version[] = ...@@ -82,10 +82,13 @@ static char mlx5_version[] =
struct mlx5_ib_event_work { struct mlx5_ib_event_work {
struct work_struct work; struct work_struct work;
struct mlx5_core_dev *dev; union {
void *context; struct mlx5_ib_dev *dev;
struct mlx5_ib_multiport_info *mpi;
};
bool is_slave;
enum mlx5_dev_event event; enum mlx5_dev_event event;
unsigned long param; void *param;
}; };
enum { enum {
...@@ -4240,14 +4243,14 @@ static void mlx5_ib_handle_event(struct work_struct *_work) ...@@ -4240,14 +4243,14 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
struct mlx5_ib_dev *ibdev; struct mlx5_ib_dev *ibdev;
struct ib_event ibev; struct ib_event ibev;
bool fatal = false; bool fatal = false;
u8 port = (u8)work->param; u8 port = (u8)(unsigned long)work->param;
if (mlx5_core_is_mp_slave(work->dev)) { if (work->is_slave) {
ibdev = mlx5_ib_get_ibdev_from_mpi(work->context); ibdev = mlx5_ib_get_ibdev_from_mpi(work->mpi);
if (!ibdev) if (!ibdev)
goto out; goto out;
} else { } else {
ibdev = work->context; ibdev = work->dev;
} }
switch (work->event) { switch (work->event) {
...@@ -4256,7 +4259,6 @@ static void mlx5_ib_handle_event(struct work_struct *_work) ...@@ -4256,7 +4259,6 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
mlx5_ib_handle_internal_error(ibdev); mlx5_ib_handle_internal_error(ibdev);
fatal = true; fatal = true;
break; break;
case MLX5_DEV_EVENT_PORT_UP: case MLX5_DEV_EVENT_PORT_UP:
case MLX5_DEV_EVENT_PORT_DOWN: case MLX5_DEV_EVENT_PORT_DOWN:
case MLX5_DEV_EVENT_PORT_INITIALIZED: case MLX5_DEV_EVENT_PORT_INITIALIZED:
...@@ -4311,22 +4313,43 @@ static void mlx5_ib_handle_event(struct work_struct *_work) ...@@ -4311,22 +4313,43 @@ static void mlx5_ib_handle_event(struct work_struct *_work)
kfree(work); kfree(work);
} }
static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context, static int mlx5_ib_event(struct notifier_block *nb,
enum mlx5_dev_event event, unsigned long param) unsigned long event, void *param)
{ {
struct mlx5_ib_event_work *work; struct mlx5_ib_event_work *work;
work = kmalloc(sizeof(*work), GFP_ATOMIC); work = kmalloc(sizeof(*work), GFP_ATOMIC);
if (!work) if (!work)
return; return NOTIFY_DONE;
INIT_WORK(&work->work, mlx5_ib_handle_event); INIT_WORK(&work->work, mlx5_ib_handle_event);
work->dev = dev; work->dev = container_of(nb, struct mlx5_ib_dev, mdev_events);
work->is_slave = false;
work->param = param; work->param = param;
work->context = context;
work->event = event; work->event = event;
queue_work(mlx5_ib_event_wq, &work->work); queue_work(mlx5_ib_event_wq, &work->work);
return NOTIFY_OK;
}
static int mlx5_ib_event_slave_port(struct notifier_block *nb,
unsigned long event, void *param)
{
struct mlx5_ib_event_work *work;
work = kmalloc(sizeof(*work), GFP_ATOMIC);
if (!work)
return NOTIFY_DONE;
INIT_WORK(&work->work, mlx5_ib_handle_event);
work->mpi = container_of(nb, struct mlx5_ib_multiport_info, mdev_events);
work->is_slave = true;
work->param = param;
work->event = event;
queue_work(mlx5_ib_event_wq, &work->work);
return NOTIFY_OK;
} }
static int set_has_smi_cap(struct mlx5_ib_dev *dev) static int set_has_smi_cap(struct mlx5_ib_dev *dev)
...@@ -5357,6 +5380,11 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev, ...@@ -5357,6 +5380,11 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
spin_unlock(&port->mp.mpi_lock); spin_unlock(&port->mp.mpi_lock);
return; return;
} }
if (mpi->mdev_events.notifier_call)
mlx5_notifier_unregister(mpi->mdev, &mpi->mdev_events);
mpi->mdev_events.notifier_call = NULL;
mpi->ibdev = NULL; mpi->ibdev = NULL;
spin_unlock(&port->mp.mpi_lock); spin_unlock(&port->mp.mpi_lock);
...@@ -5412,6 +5440,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, ...@@ -5412,6 +5440,7 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
ibdev->port[port_num].mp.mpi = mpi; ibdev->port[port_num].mp.mpi = mpi;
mpi->ibdev = ibdev; mpi->ibdev = ibdev;
mpi->mdev_events.notifier_call = NULL;
spin_unlock(&ibdev->port[port_num].mp.mpi_lock); spin_unlock(&ibdev->port[port_num].mp.mpi_lock);
err = mlx5_nic_vport_affiliate_multiport(ibdev->mdev, mpi->mdev); err = mlx5_nic_vport_affiliate_multiport(ibdev->mdev, mpi->mdev);
...@@ -5429,6 +5458,9 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev, ...@@ -5429,6 +5458,9 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
goto unbind; goto unbind;
} }
mpi->mdev_events.notifier_call = mlx5_ib_event_slave_port;
mlx5_notifier_register(mpi->mdev, &mpi->mdev_events);
err = mlx5_ib_init_cong_debugfs(ibdev, port_num); err = mlx5_ib_init_cong_debugfs(ibdev, port_num);
if (err) if (err)
goto unbind; goto unbind;
...@@ -6163,6 +6195,18 @@ static void mlx5_ib_stage_rep_reg_cleanup(struct mlx5_ib_dev *dev) ...@@ -6163,6 +6195,18 @@ static void mlx5_ib_stage_rep_reg_cleanup(struct mlx5_ib_dev *dev)
mlx5_ib_unregister_vport_reps(dev); mlx5_ib_unregister_vport_reps(dev);
} }
static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
{
dev->mdev_events.notifier_call = mlx5_ib_event;
mlx5_notifier_register(dev->mdev, &dev->mdev_events);
return 0;
}
static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev)
{
mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
}
void __mlx5_ib_remove(struct mlx5_ib_dev *dev, void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
const struct mlx5_ib_profile *profile, const struct mlx5_ib_profile *profile,
int stage) int stage)
...@@ -6228,6 +6272,9 @@ static const struct mlx5_ib_profile pf_profile = { ...@@ -6228,6 +6272,9 @@ static const struct mlx5_ib_profile pf_profile = {
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES, STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
mlx5_ib_stage_dev_res_init, mlx5_ib_stage_dev_res_init,
mlx5_ib_stage_dev_res_cleanup), mlx5_ib_stage_dev_res_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
mlx5_ib_stage_dev_notifier_init,
mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_ODP, STAGE_CREATE(MLX5_IB_STAGE_ODP,
mlx5_ib_stage_odp_init, mlx5_ib_stage_odp_init,
mlx5_ib_stage_odp_cleanup), mlx5_ib_stage_odp_cleanup),
...@@ -6279,6 +6326,9 @@ static const struct mlx5_ib_profile nic_rep_profile = { ...@@ -6279,6 +6326,9 @@ static const struct mlx5_ib_profile nic_rep_profile = {
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES, STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
mlx5_ib_stage_dev_res_init, mlx5_ib_stage_dev_res_init,
mlx5_ib_stage_dev_res_cleanup), mlx5_ib_stage_dev_res_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
mlx5_ib_stage_dev_notifier_init,
mlx5_ib_stage_dev_notifier_cleanup),
STAGE_CREATE(MLX5_IB_STAGE_COUNTERS, STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
mlx5_ib_stage_counters_init, mlx5_ib_stage_counters_init,
mlx5_ib_stage_counters_cleanup), mlx5_ib_stage_counters_cleanup),
...@@ -6399,7 +6449,6 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) ...@@ -6399,7 +6449,6 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
static struct mlx5_interface mlx5_ib_interface = { static struct mlx5_interface mlx5_ib_interface = {
.add = mlx5_ib_add, .add = mlx5_ib_add,
.remove = mlx5_ib_remove, .remove = mlx5_ib_remove,
.event = mlx5_ib_event,
.protocol = MLX5_INTERFACE_PROTOCOL_IB, .protocol = MLX5_INTERFACE_PROTOCOL_IB,
}; };
......
...@@ -775,6 +775,7 @@ enum mlx5_ib_stages { ...@@ -775,6 +775,7 @@ enum mlx5_ib_stages {
MLX5_IB_STAGE_NON_DEFAULT_CB, MLX5_IB_STAGE_NON_DEFAULT_CB,
MLX5_IB_STAGE_ROCE, MLX5_IB_STAGE_ROCE,
MLX5_IB_STAGE_DEVICE_RESOURCES, MLX5_IB_STAGE_DEVICE_RESOURCES,
MLX5_IB_STAGE_DEVICE_NOTIFIER,
MLX5_IB_STAGE_ODP, MLX5_IB_STAGE_ODP,
MLX5_IB_STAGE_COUNTERS, MLX5_IB_STAGE_COUNTERS,
MLX5_IB_STAGE_CONG_DEBUGFS, MLX5_IB_STAGE_CONG_DEBUGFS,
...@@ -806,6 +807,7 @@ struct mlx5_ib_multiport_info { ...@@ -806,6 +807,7 @@ struct mlx5_ib_multiport_info {
struct list_head list; struct list_head list;
struct mlx5_ib_dev *ibdev; struct mlx5_ib_dev *ibdev;
struct mlx5_core_dev *mdev; struct mlx5_core_dev *mdev;
struct notifier_block mdev_events;
struct completion unref_comp; struct completion unref_comp;
u64 sys_image_guid; u64 sys_image_guid;
u32 mdev_refcnt; u32 mdev_refcnt;
...@@ -893,6 +895,7 @@ struct mlx5_ib_dev { ...@@ -893,6 +895,7 @@ struct mlx5_ib_dev {
struct ib_device ib_dev; struct ib_device ib_dev;
const struct uverbs_object_tree_def *driver_trees[7]; const struct uverbs_object_tree_def *driver_trees[7];
struct mlx5_core_dev *mdev; struct mlx5_core_dev *mdev;
struct notifier_block mdev_events;
struct mlx5_roce roce[MLX5_MAX_PORTS]; struct mlx5_roce roce[MLX5_MAX_PORTS];
int num_ports; int num_ports;
/* serialize update of capability mask /* serialize update of capability mask
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment