Support RDMA events monitoring through
Subsystems (4)
v3 cover Support RDMA events monitoring through
This series consists of multiple parts that collectively offer a method to monitor RDMA events from userspace.
Using netlink, users will be able to monitor their IB device events and changes such as device register, device unregister and netdev attachment.
The first 2 patches contain fixes in mlx5 lag code that are required for accurate event reporting in case of a lag bond.
Patch #3 initializes phys_port_cnt early in device probe to allow the IB-to-netdev mapping API to work properly.
Patches #4,#5 modify and export IB-to-netdev mapping API, making it accessible to all vendors who wish to rely on it for associating their IB device with a netdevice.
Patches #6,#7 add the netlink support for reporting IB device events to userspace.
Changes in v3:
- Fix lockdep warning in ib_device_get_netdev by dropping optimization part from it
- Extend event info to include device names
- Instead of disregarding unknown events, report them to userspace
- Remove fill_mon_register and replace with fill_nldev_handle to fill netlink messages for register events
Changes in v2:
- Fix compilation issues with forward declaration of ib_device
- Add missing setting of return code in error flow
Chiara Meiohas (5):
RDMA/mlx5: Initialize phys_port_cnt earlier in RDMA device creation RDMA/device: Remove optimization in ib_device_get_netdev() RDMA/mlx5: Use IB set_netdev and get_netdev functions RDMA/nldev: Add support for RDMA monitoring
RDMA/nldev: Expose whether RDMA monitoring is supported
Mark Bloch (2):
RDMA/mlx5: Check RoCE LAG status before getting netdev RDMA/mlx5: Obtain upper net device only when needed
drivers/infiniband/core/device.c | 51 ++++- drivers/infiniband/core/netlink.c | 1 + drivers/infiniband/core/nldev.c | 130 ++++++++++++ drivers/infiniband/hw/mlx5/ib_rep.c | 22 +- drivers/infiniband/hw/mlx5/main.c | 197 +++++++++++++----- drivers/infiniband/hw/mlx5/mlx5_ib.h | 3 +- .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 76 +++---- include/linux/mlx5/device.h | 1 + include/linux/mlx5/driver.h | 2 +- include/rdma/ib_verbs.h | 2 + include/rdma/rdma_netlink.h | 12 ++ include/uapi/rdma/rdma_netlink.h | 16 ++ 12 files changed, 399 insertions(+), 114 deletions(-)
Signature · 1 line
2.17.2
PATCH v3 1/7 RDMA/mlx5: Check RoCE LAG status before getting netdev
From: Mark Bloch <[email protected]>
Check if RoCE LAG is active before calling the LAG layer for netdev. This clarifies if LAG is active. No behavior changes with this patch.
--- drivers/infiniband/hw/mlx5/main.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
drivers/infiniband/hw/mlx5/main.c +13 -6
@@ -198,12 +198,18 @@ static int mlx5_netdev_event(struct notifier_block *this,case NETDEV_CHANGE :case NETDEV_UP :case NETDEV_DOWN : { -struct net_device *lag_ndev =mlx5_lag_get_roce_netdev (mdev);struct net_device *upper =NULL ; -if (lag_ndev) { - upper =netdev_master_upper_dev_get (lag_ndev); -dev_put (lag_ndev); +if (mlx5_lag_is_roce (mdev)) { +struct net_device *lag_ndev; + + lag_ndev =mlx5_lag_get_roce_netdev (mdev); +if (lag_ndev) { + upper =netdev_master_upper_dev_get (lag_ndev); +dev_put (lag_ndev); + }else { + goto done; + } }if (ibdev->is_rep)
@@ -257,9 +263,10 @@ static struct net_device *mlx5_ib_get_netdev(struct ib_device *device,if (!mdev)return NULL ; - ndev =mlx5_lag_get_roce_netdev (mdev); -if (ndev) +if (mlx5_lag_is_roce (mdev)) { + ndev =mlx5_lag_get_roce_netdev (mdev); goto out; + }/* Ensure ndev does not disappear before we invoke dev_hold() */
Signature · 1 line
2.17.2
Re: [PATCH v3 rdma-next 1/7] RDMA/mlx5: Check RoCE LAG status before getting netdev
Quoted 9 lines · Michael Guralnik
From: Mark Bloch <[email protected]>
Check if RoCE LAG is active before calling the LAG layer for netdev. This clarifies if LAG is active. No behavior changes with this patch.
Signed-off-by Mark Bloch <[email protected]>Signed-off-by Michael Guralnik <[email protected]>Reviewed-by Leon Romanovsky <[email protected]>
Looks good to me
Quoted 48 lines
--- drivers/infiniband/hw/mlx5/main.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)drivers/infiniband/hw/mlx5/main.c +13
-7@@ -198,12 +198,18 @@ static int mlx5_netdev_event(struct notifier_block *this,case NETDEV_CHANGE :case NETDEV_UP :case NETDEV_DOWN : { -struct net_device *lag_ndev =mlx5_lag_get_roce_netdev (mdev);struct net_device *upper =NULL ; -if (lag_ndev) { - upper =netdev_master_upper_dev_get (lag_ndev); -dev_put (lag_ndev); +if (mlx5_lag_is_roce (mdev)) { +struct net_device *lag_ndev; + + lag_ndev =mlx5_lag_get_roce_netdev (mdev); +if (lag_ndev) { + upper =netdev_master_upper_dev_get (lag_ndev); +dev_put (lag_ndev); + }else { + goto done; + } }if (ibdev->is_rep)@@ -257,9 +263,10 @@ static struct net_device *mlx5_ib_get_netdev(struct ib_device *device,if (!mdev)return NULL ; - ndev =mlx5_lag_get_roce_netdev (mdev); -if (ndev) +if (mlx5_lag_is_roce (mdev)) { + ndev =mlx5_lag_get_roce_netdev (mdev); goto out; + }/* Ensure ndev does not disappear before we invoke dev_hold() */ --2.17.2
Signature · 2 lines
Regards, Kalesh A P
PATCH v3 2/7 RDMA/mlx5: Obtain upper net device only when needed
In reply to Michael GuralnikFrom: Mark Bloch <[email protected]>
Report the upper device's state as the RDMA port state only in RoCE LAG or switchdev LAG.
--- drivers/infiniband/hw/mlx5/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/main.c +1 -1
@@ -558,7 +558,7 @@ static int mlx5_query_port_roce(struct ib_device *device, u32 port_num,if (!ndev) goto out; -if (dev->lag_active) { +if (mlx5_lag_is_roce (mdev) ||mlx5_lag_is_sriov (mdev)) {rcu_read_lock (); upper =netdev_master_upper_dev_get_rcu (ndev);if (upper) {
Signature · 1 line
2.17.2
Re: [PATCH v3 rdma-next 2/7] RDMA/mlx5: Obtain upper net device only when needed
Quoted 10 lines · Michael Guralnik
From: Mark Bloch <[email protected]>
Report the upper device's state as the RDMA port state only in RoCE LAG or switchdev LAG.
Fixes 27f9e0ccb6da ("net/mlx5: Lag, Add single RDMA device in multiport mode")Signed-off-by Mark Bloch <[email protected]>Signed-off-by Michael Guralnik <[email protected]>Reviewed-by Leon Romanovsky <[email protected]>
Looks good to me
Quoted 21 lines
--- drivers/infiniband/hw/mlx5/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/infiniband/hw/mlx5/main.c +1
-2@@ -558,7 +558,7 @@ static int mlx5_query_port_roce(struct ib_device *device, u32 port_num,if (!ndev) goto out; -if (dev->lag_active) { +if (mlx5_lag_is_roce (mdev) ||mlx5_lag_is_sriov (mdev)) {rcu_read_lock (); upper =netdev_master_upper_dev_get_rcu (ndev);if (upper) { --2.17.2
Signature · 2 lines
Regards, Kalesh A P
PATCH v3 3/7 RDMA/mlx5: Initialize phys_port_cnt earlier in RDMA device creation
In reply to Michael GuralnikFrom: Chiara Meiohas <[email protected]>
phys_port_cnt of the IB device must be initialized before calling ib_device_set_netdev().
Previously, phys_port_cnt was initialized in the mlx5_ib init function. Remove this initialization to allow setting it separately, providing the flexibility to call ib_device_set_netdev before registering the IB device.
--- drivers/infiniband/hw/mlx5/ib_rep.c | 1 + drivers/infiniband/hw/mlx5/main.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/ib_rep.c +1 -0
@@ -104,6 +104,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ibdev->is_rep = true; vport_index = rep->vport_index; ibdev->port[vport_index].rep = rep; + ibdev->ib_dev.phys_port_cnt = num_ports; ibdev->port[vport_index].roce.netdev =mlx5_ib_get_rep_netdev (lag_master->priv.eswitch, rep->vport); ibdev->mdev = lag_master;
drivers/infiniband/hw/mlx5/main.c +2 -1
@@ -3932,7 +3932,6 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev) dev->ib_dev.node_type =RDMA_NODE_IB_CA ; dev->ib_dev.local_dma_lkey =0 /* not supported for now */ ; - dev->ib_dev.phys_port_cnt = dev->num_ports; dev->ib_dev.dev.parent = mdev->device; dev->ib_dev.lag_flags =RDMA_LAG_FLAGS_HASH_ALL_SLAVES ;
@@ -4647,6 +4646,7 @@ static struct ib_device *mlx5_ib_add_sub_dev(struct ib_device *parent, mplane->mdev = mparent->mdev; mplane->num_ports = mparent->num_plane; mplane->sub_dev_name = name; + mplane->ib_dev.phys_port_cnt = mplane->num_ports; ret =__mlx5_ib_add (mplane, &plane_profile);if (ret)
@@ -4763,6 +4763,7 @@ static int mlx5r_probe(struct auxiliary_device *adev, dev->mdev = mdev; dev->num_ports = num_ports; + dev->ib_dev.phys_port_cnt = num_ports;if (ll ==IB_LINK_LAYER_ETHERNET && !mlx5_get_roce_state (mdev)) profile = &raw_eth_profile;
Signature · 1 line
2.17.2
PATCH v3 4/7 RDMA/device: Remove optimization in ib_device_get_netdev()
In reply to Michael GuralnikFrom: Chiara Meiohas <[email protected]>
The caller of ib_device_get_netdev() relies on its result to accurately match a given netdev with the ib device associated netdev.
ib_device_get_netdev returns NULL when the IB device associated netdev is unregistering, preventing the caller of matching netdevs properly.
Thus, remove this optimization and return the netdev even if it is undergoing unregistration, allowing matching by the caller.
This change ensures proper netdev matching and reference count handling by the caller of ib_device_get_netdev/ib_device_set_netdev API.
--- drivers/infiniband/core/device.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/infiniband/core/device.c +0 -9
@@ -2252,15 +2252,6 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,spin_unlock (&pdata->netdev_lock); } -/* -* If we are starting to unregister expedite things by preventing -* propagation of an unregistering netdev. -*/ -if (res && res->reg_state !=NETREG_REGISTERED ) { -dev_put (res); -return NULL ; - } -return res; }
Signature · 1 line
2.17.2
Re: [PATCH v3 rdma-next 4/7] RDMA/device: Remove optimization in ib_device_get_netdev()
Quoted 12 lines · Michael Guralnik
From: Chiara Meiohas <[email protected]>
The caller of
ib_device_get_netdev()relies on its result to accurately match a given netdev with the ib device associated netdev.
ib_device_get_netdevreturns NULL when the IB device associated netdev is unregistering, preventing the caller of matching netdevs properly.Thus, remove this optimization and return the netdev even if it is undergoing unregistration, allowing matching by the caller.
Quoted 7 lines
This change ensures proper netdev matching and reference count handling by the caller of ib_device_get_netdev/ib_device_set_netdev API.
Signed-off-by Maher Sanalla <[email protected]>Signed-off-by Chiara Meiohas <[email protected]>Signed-off-by Michael Guralnik <[email protected]>Reviewed-by Leon Romanovsky <[email protected]>
Looks good to me
Quoted 28 lines
--- drivers/infiniband/core/device.c | 9 --------- 1 file changed, 9 deletions(-)drivers/infiniband/core/device.c +0
-10@@ -2252,15 +2252,6 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,spin_unlock (&pdata->netdev_lock); } -/* -* If we are starting to unregister expedite things by preventing -* propagation of an unregistering netdev. -*/ -if (res && res->reg_state !=NETREG_REGISTERED ) { -dev_put (res); -return NULL ; - } -return res; } --2.17.2
Signature · 2 lines
Regards, Kalesh A P
PATCH v3 5/7 RDMA/mlx5: Use IB set_netdev and get_netdev functions
In reply to Michael GuralnikFrom: Chiara Meiohas <[email protected]>
The IB layer provides a common interface to store and get net devices associated to an IB device port (ib_device_set_netdev() and ib_device_get_netdev()).
Previously, mlx5_ib stored and managed the associated net devices internally.
Replace internal net device management in mlx5_ib with ib_device_set_netdev() when attaching/detaching a net device and ib_device_get_netdev() when retrieving the net device.
Export ib_device_get_netdev().
For mlx5 representors/PFs/VFs and lag creation we replace the netdev assignments with the IB set/get netdev functions.
In active-backup mode lag the active slave net device is stored in the lag itself. To assure the net device stored in a lag bond IB device is the active slave we implement the following:
- mlx5_core: when modifying the slave of a bond we send the internal driver event MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE.
- mlx5_ib: when catching the event call ib_device_set_netdev()
This patch also ensures the correct IB events are sent in switchdev lag.
While at it, when in multiport eswitch mode, only a single IB device is created for all ports. The said IB device will receive all netdev events of its VFs once loaded, thus to avoid overwriting the mapping of PF IB device to PF netdev, ignore NETDEV_REGISTER events if the ib device has already been mapped to a netdev.
--- drivers/infiniband/core/device.c | 4 + drivers/infiniband/hw/mlx5/ib_rep.c | 23 +-- drivers/infiniband/hw/mlx5/main.c | 183 ++++++++++++------ drivers/infiniband/hw/mlx5/mlx5_ib.h | 3 +- .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 76 ++++---- include/linux/mlx5/device.h | 1 + include/linux/mlx5/driver.h | 2 +- include/rdma/ib_verbs.h | 2 + 8 files changed, 191 insertions(+), 103 deletions(-)
drivers/infiniband/core/device.c +4 -0
@@ -2236,6 +2236,9 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,if (!rdma_is_port_valid (ib_dev, port))return NULL ; +if (!ib_dev->port_data) +return NULL ; + pdata = &ib_dev->port_data[port];/*
@@ -2254,6 +2257,7 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,return res; } +EXPORT_SYMBOL (ib_device_get_netdev);/** * ib_device_get_by_netdev - Find an IB device associated with a netdev
drivers/infiniband/hw/mlx5/ib_rep.c +12 -11
@@ -13,6 +13,7 @@ mlx5_ib_set_vport_rep(struct mlx5_core_dev *dev, int vport_index) {struct mlx5_ib_dev *ibdev; +struct net_device *ndev; ibdev =mlx5_eswitch_uplink_get_proto_dev (dev->priv.eswitch,REP_IB );if (!ibdev)
@@ -20,12 +21,9 @@ mlx5_ib_set_vport_rep(struct mlx5_core_dev *dev, ibdev->port[vport_index].rep = rep; rep->rep_data[REP_IB ].priv = ibdev; -write_lock (&ibdev->port[vport_index].roce.netdev_lock); - ibdev->port[vport_index].roce.netdev = -mlx5_ib_get_rep_netdev (rep->esw, rep->vport); -write_unlock (&ibdev->port[vport_index].roce.netdev_lock); + ndev =mlx5_ib_get_rep_netdev (rep->esw, rep->vport); -return 0 ; +return ib_device_set_netdev (&ibdev->ib_dev, ndev, vport_index +1 ); }static void mlx5_ib_register_peer_vport_reps (struct mlx5_core_dev *mdev);
@@ -104,11 +102,15 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ibdev->is_rep = true; vport_index = rep->vport_index; ibdev->port[vport_index].rep = rep; - ibdev->ib_dev.phys_port_cnt = num_ports; - ibdev->port[vport_index].roce.netdev = -mlx5_ib_get_rep_netdev (lag_master->priv.eswitch, rep->vport); ibdev->mdev = lag_master; ibdev->num_ports = num_ports; + ibdev->ib_dev.phys_port_cnt = num_ports; + ret =ib_device_set_netdev (&ibdev->ib_dev, +mlx5_ib_get_rep_netdev (lag_master->priv.eswitch, + rep->vport), + vport_index +1 ); +if (ret) + goto fail_add; ret =__mlx5_ib_add (ibdev, profile);if (ret)
@@ -161,9 +163,8 @@ mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep *rep) } port = &dev->port[vport_index]; -write_lock (&port->roce.netdev_lock); - port->roce.netdev =NULL ; -write_unlock (&port->roce.netdev_lock); + +ib_device_set_netdev (&dev->ib_dev,NULL , vport_index +1 ); rep->rep_data[REP_IB ].priv =NULL ; port->rep =NULL ;
drivers/infiniband/hw/mlx5/main.c +129 -54
283 lines not on this page · raw message
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -2
@@ -896,8 +896,6 @@ struct mlx5_roce {/* Protect mlx5_ib_get_netdev from invoking dev_hold() with a NULL * netdev pointer */ -rwlock_t netdev_lock; -struct net_device *netdev;struct notifier_block nb;struct netdev_net_notifier nn;struct notifier_block mdev_nb;
@@ -1146,6 +1144,7 @@ struct mlx5_ib_dev {/* protect accessing data_direct_dev */ struct mutex data_direct_lock;struct notifier_block mdev_events; +struct notifier_block lag_events;int num_ports;/* serialize update of capability mask */
drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +41 -35
100 lines not on this page · raw message
include/linux/mlx5/device.h +1 -0
@@ -370,6 +370,7 @@ enum mlx5_driver_event {MLX5_DRIVER_EVENT_SF_PEER_DEVLINK ,MLX5_DRIVER_EVENT_AFFILIATION_DONE ,MLX5_DRIVER_EVENT_AFFILIATION_REMOVED , + MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE, }; enum {
include/linux/mlx5/driver.h +1 -1
@@ -643,6 +643,7 @@ struct mlx5_priv {struct mlx5_sf_hw_table *sf_hw_table;struct mlx5_sf_table *sf_table;#endif +struct blocking_notifier_head lag_nh; };enum mlx5_device_state {
@@ -1181,7 +1182,6 @@ bool mlx5_lag_mode_is_hash(struct mlx5_core_dev *dev);bool mlx5_lag_is_master (struct mlx5_core_dev *dev);bool mlx5_lag_is_shared_fdb (struct mlx5_core_dev *dev);bool mlx5_lag_is_mpesw (struct mlx5_core_dev *dev); -struct net_device *mlx5_lag_get_roce_netdev (struct mlx5_core_dev *dev);u8 mlx5_lag_get_slave_port (struct mlx5_core_dev *dev,struct net_device *slave); int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
include/rdma/ib_verbs.h +2 -0
@@ -4453,6 +4453,8 @@ struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u32 port, const struct sockaddr *addr);int ib_device_set_netdev (struct ib_device *ib_dev,struct net_device *ndev,unsigned int port); +struct net_device *ib_device_get_netdev (struct ib_device *ib_dev, +u32 port);struct ib_wq *ib_create_wq (struct ib_pd *pd,struct ib_wq_init_attr *init_attr);int ib_destroy_wq_user (struct ib_wq *wq,struct ib_udata *udata);
Signature · 1 line
2.17.2
PATCH v3 6/7 RDMA/nldev: Add support for RDMA monitoring
In reply to Michael GuralnikFrom: Chiara Meiohas <[email protected]>
Introduce a new netlink command to allow rdma event monitoring. The rdma events supported now are IB device registration/unregistration and net device attachment/detachment.
Example output of rdma monitor and the commands which trigger the events:
$ rdma monitor $ rmmod mlx5_ib [UNREGISTER] ibdev_idx 1 ibdev rocep8s0f1 [UNREGISTER] ibdev_idx 0 ibdev rocep8s0f0
$ modprobe mlx5_ib [REGISTER] ibdev_idx 2 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 2 ibdev mlx5_0 port 1 netdev_idx 4 netdev eth2 [REGISTER] ibdev_idx 3 ibdev mlx5_1 [NETDEV_ATTACH] ibdev_idx 3 ibdev mlx5_1 port 1 netdev_idx 5 netdev eth3
$ devlink dev eswitch set pci/0000:08:00.0 mode switchdev [UNREGISTER] ibdev_idx 2 ibdev rocep8s0f0 [REGISTER] ibdev_idx 4 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 4 ibdev mlx5_0 port 30 netdev_idx 4 netdev eth2
$ echo 4 > /sys/class/net/eth2/device/sriov_numvfs [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 2 netdev_idx 7 netdev eth4 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 3 netdev_idx 8 netdev eth5 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 4 netdev_idx 9 netdev eth6 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 5 netdev_idx 10 netdev eth7 [REGISTER] ibdev_idx 5 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 5 ibdev mlx5_0 port 1 netdev_idx 11 netdev eth8 [REGISTER] ibdev_idx 6 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 6 ibdev mlx5_0 port 1 netdev_idx 12 netdev eth9 [REGISTER] ibdev_idx 7 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 7 ibdev mlx5_0 port 1 netdev_idx 13 netdev eth10 [REGISTER] ibdev_idx 8 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 8 ibdev mlx5_0 port 1 netdev_idx 14 netdev eth11
$ echo 0 > /sys/class/net/eth2/device/sriov_numvfs [UNREGISTER] ibdev_idx 5 ibdev rocep8s0f0v0 [UNREGISTER] ibdev_idx 6 ibdev rocep8s0f0v1 [UNREGISTER] ibdev_idx 7 ibdev rocep8s0f0v2 [UNREGISTER] ibdev_idx 8 ibdev rocep8s0f0v3 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 2 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 3 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 4 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 5
--- drivers/infiniband/core/device.c | 38 +++++++++ drivers/infiniband/core/netlink.c | 1 + drivers/infiniband/core/nldev.c | 124 ++++++++++++++++++++++++++++++ include/rdma/rdma_netlink.h | 12 +++ include/uapi/rdma/rdma_netlink.h | 15 ++++ 5 files changed, 190 insertions(+)
drivers/infiniband/core/device.c +38 -0
@@ -1351,6 +1351,30 @@ static void prevent_dealloc_device(struct ib_device *ib_dev) { } +static void ib_device_notify_register (struct ib_device *device) +{ +struct net_device *netdev; +u32 port; +int ret; + + ret =rdma_nl_notify_event (device,0 ,RDMA_REGISTER_EVENT ); +if (ret) +return ; + +rdma_for_each_port (device, port) { + netdev =ib_device_get_netdev (device, port); +if (!netdev) +continue ; + + ret =rdma_nl_notify_event (device, port, +RDMA_NETDEV_ATTACH_EVENT ); +dev_put (netdev); +if (ret) +return ; + } +return ; +} +/** * ib_register_device - Register an IB device with IB core * @device: Device to register
@@ -1449,6 +1473,8 @@ int ib_register_device(struct ib_device *device, const char *name,dev_set_uevent_suppress (&device->dev, false);/* Mark for userspace that device is ready */ kobject_uevent (&device->dev.kobj,KOBJ_ADD ); + +ib_device_notify_register (device);ib_device_put (device);return 0 ;
@@ -1491,6 +1517,7 @@ static void __ib_unregister_device(struct ib_device *ib_dev) goto out;disable_device (ib_dev); +rdma_nl_notify_event (ib_dev,0 ,RDMA_UNREGISTER_EVENT );/* Expedite removing unregistered pointers from the hash table */ free_netdevs (ib_dev);
@@ -2159,6 +2186,7 @@ static void add_ndev_hash(struct ib_port_data *pdata)int ib_device_set_netdev (struct ib_device *ib_dev,struct net_device *ndev,u32 port) { +enum rdma_nl_notify_event_type etype;struct net_device *old_ndev;struct ib_port_data *pdata;unsigned long flags;
@@ -2190,6 +2218,16 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev,spin_unlock_irqrestore (&pdata->netdev_lock, flags);add_ndev_hash (pdata); + +down_read (&devices_rwsem); +if (xa_get_mark (&devices, ib_dev->index,DEVICE_REGISTERED ) && +xa_load (&devices, ib_dev->index) == ib_dev) { + etype = ndev ? +RDMA_NETDEV_ATTACH_EVENT :RDMA_NETDEV_DETACH_EVENT ; +rdma_nl_notify_event (ib_dev, port, etype); + } +up_read (&devices_rwsem); +return 0 ; }EXPORT_SYMBOL (ib_device_set_netdev);
drivers/infiniband/core/netlink.c +1 -0
@@ -311,6 +311,7 @@ int rdma_nl_net_init(struct rdma_dev_net *rnet)struct net *net =read_pnet (&rnet->net);struct netlink_kernel_cfg cfg = { .input = rdma_nl_rcv, + .flags =NL_CFG_F_NONROOT_RECV , };struct sock *nls;
drivers/infiniband/core/nldev.c +124 -0
136 lines not on this page · raw message
include/rdma/rdma_netlink.h +12 -0
@@ -6,6 +6,8 @@#include <linux/netlink.h> #include <uapi/rdma/rdma_netlink.h> +struct ib_device ; +enum {RDMA_NLDEV_ATTR_EMPTY_STRING =1 ,RDMA_NLDEV_ATTR_ENTRY_STRLEN =16 ,
@@ -110,6 +112,16 @@ int rdma_nl_multicast(struct net *net, struct sk_buff *skb,*/ bool rdma_nl_chk_listeners (unsigned int group); +/** +* Prepare and send an event message +* @ib: the IB device which triggered the event +* @port_num: the port number which triggered the event - 0 if unused +* @type: the event type +* Returns 0 on success or a negative error code +*/ +int rdma_nl_notify_event (struct ib_device *ib,u32 port_num, +enum rdma_nl_notify_event_type type); +struct rdma_link_ops {struct list_head list;const char *type;
include/uapi/rdma/rdma_netlink.h +15 -0
@@ -15,6 +15,7 @@ enum {enum {RDMA_NL_GROUP_IWPM =2 ,RDMA_NL_GROUP_LS , +RDMA_NL_GROUP_NOTIFY ,RDMA_NL_NUM_GROUPS };
@@ -305,6 +306,8 @@ enum rdma_nldev_command {RDMA_NLDEV_CMD_DELDEV , +RDMA_NLDEV_CMD_MONITOR , + RDMA_NLDEV_NUM_OPS };
@@ -574,6 +577,8 @@ enum rdma_nldev_attr {RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE ,/* u8 */ + RDMA_NLDEV_ATTR_EVENT_TYPE, /* u8 */ +/* * Always the end */
@@ -624,4 +629,14 @@ enum rdma_nl_name_assign_type { RDMA_NAME_ASSIGN_TYPE_USER = 1, /* Provided by user-space */ }; +/* +* Supported rdma monitoring event types. +*/ +enum rdma_nl_notify_event_type { +RDMA_REGISTER_EVENT , +RDMA_UNREGISTER_EVENT , +RDMA_NETDEV_ATTACH_EVENT , +RDMA_NETDEV_DETACH_EVENT , +}; +#endif /* _UAPI_RDMA_NETLINK_H */
Signature · 1 line
2.17.2
Leon Romanovsky
maintainerRe: [PATCH v3 rdma-next 6/7] RDMA/nldev: Add support for RDMA monitoring
Quoted 14 lines · Michael Guralnik
From: Chiara Meiohas <[email protected]>
Introduce a new netlink command to allow rdma event monitoring. The rdma events supported now are IB device registration/unregistration and net device attachment/detachment.
Example output of rdma monitor and the commands which trigger the events:
$ rdma monitor $ rmmod mlx5_ib [UNREGISTER] ibdev_idx 1 ibdev rocep8s0f1 [UNREGISTER] ibdev_idx 0 ibdev rocep8s0f0
Quoted 5 lines
$ modprobe mlx5_ib [REGISTER] ibdev_idx 2 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 2 ibdev mlx5_0 port 1 netdev_idx 4 netdev eth2 [REGISTER] ibdev_idx 3 ibdev mlx5_1 [NETDEV_ATTACH] ibdev_idx 3 ibdev mlx5_1 port 1 netdev_idx 5 netdev eth3
No need to resend the series, I will fix when applying, but the right format will be:
[NETDEV_ATTACH] dev 3 mlx5_1 port 1 netdev 5 eth3
Thanks
Leon Romanovsky
maintainerRe: [PATCH v3 rdma-next 6/7] RDMA/nldev: Add support for RDMA monitoring
In reply to Michael GuralnikQuoted 59 lines · Michael Guralnik
From: Chiara Meiohas <[email protected]>
Introduce a new netlink command to allow rdma event monitoring. The rdma events supported now are IB device registration/unregistration and net device attachment/detachment.
Example output of rdma monitor and the commands which trigger the events:
$ rdma monitor $ rmmod mlx5_ib [UNREGISTER] ibdev_idx 1 ibdev rocep8s0f1 [UNREGISTER] ibdev_idx 0 ibdev rocep8s0f0$ modprobe mlx5_ib [REGISTER] ibdev_idx 2 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 2 ibdev mlx5_0 port 1 netdev_idx 4 netdev eth2 [REGISTER] ibdev_idx 3 ibdev mlx5_1 [NETDEV_ATTACH] ibdev_idx 3 ibdev mlx5_1 port 1 netdev_idx 5 netdev eth3$ devlink dev eswitch set pci/0000:08:00.0 mode switchdev [UNREGISTER] ibdev_idx 2 ibdev rocep8s0f0 [REGISTER] ibdev_idx 4 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 4 ibdev mlx5_0 port 30 netdev_idx 4 netdev eth2$ echo 4 > /sys/class/net/eth2/device/sriov_numvfs [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 2 netdev_idx 7 netdev eth4 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 3 netdev_idx 8 netdev eth5 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 4 netdev_idx 9 netdev eth6 [NETDEV_ATTACH] ibdev_idx 4 ibdev rdmap8s0f0 port 5 netdev_idx 10 netdev eth7 [REGISTER] ibdev_idx 5 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 5 ibdev mlx5_0 port 1 netdev_idx 11 netdev eth8 [REGISTER] ibdev_idx 6 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 6 ibdev mlx5_0 port 1 netdev_idx 12 netdev eth9 [REGISTER] ibdev_idx 7 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 7 ibdev mlx5_0 port 1 netdev_idx 13 netdev eth10 [REGISTER] ibdev_idx 8 ibdev mlx5_0 [NETDEV_ATTACH] ibdev_idx 8 ibdev mlx5_0 port 1 netdev_idx 14 netdev eth11$ echo 0 > /sys/class/net/eth2/device/sriov_numvfs [UNREGISTER] ibdev_idx 5 ibdev rocep8s0f0v0 [UNREGISTER] ibdev_idx 6 ibdev rocep8s0f0v1 [UNREGISTER] ibdev_idx 7 ibdev rocep8s0f0v2 [UNREGISTER] ibdev_idx 8 ibdev rocep8s0f0v3 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 2 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 3 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 4 [NETDEV_DETACH] ibdev_idx 4 ibdev rdmap8s0f0 port 5Signed-off-by Chiara Meiohas <[email protected]>Signed-off-by Michael Guralnik <[email protected]>Reviewed-by Leon Romanovsky <[email protected]>--- drivers/infiniband/core/device.c | 38 +++++++++ drivers/infiniband/core/netlink.c | 1 + drivers/infiniband/core/nldev.c | 124 ++++++++++++++++++++++++++++++ include/rdma/rdma_netlink.h | 12 +++ include/uapi/rdma/rdma_netlink.h | 15 ++++ 5 files changed, 190 insertions(+)
<...>
Quoted 13 lines
(quoted diff) +1
-0/* Expedite removing unregistered pointers from the hash table */ free_netdevs(ib_dev);@@ -2159,6 +2186,7 @@ static void add_ndev_hash(struct ib_port_data *pdata) int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, u32 port) { + enum rdma_nl_notify_event_type etype; struct net_device *old_ndev; struct ib_port_data *pdata; unsigned long flags;@@ -2190,6 +2218,16 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, spin_unlock_irqrestore(&pdata->netdev_lock, flags);
Review int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, · line 2229
Quoted 10 lines
(quoted diff) +9
-0add_ndev_hash(pdata); + + down_read(&devices_rwsem); + if (xa_get_mark(&devices, ib_dev->index, DEVICE_REGISTERED) && + xa_load(&devices, ib_dev->index) == ib_dev) { + etype = ndev ? + RDMA_NETDEV_ATTACH_EVENT : RDMA_NETDEV_DETACH_EVENT; + rdma_nl_notify_event(ib_dev, port, etype); + } + up_read(&devices_rwsem);
There is no need in this locking, let's rewrite the following code without it. We are in -rc7, I'll add this hunk when applying.
Thanks
drivers/infiniband/core/device.c +6 -8
@@ -2219,14 +2219,12 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev,add_ndev_hash (pdata); -down_read (&devices_rwsem); -if (xa_get_mark (&devices, ib_dev->index,DEVICE_REGISTERED ) && -xa_load (&devices, ib_dev->index) == ib_dev) { - etype = ndev ? -RDMA_NETDEV_ATTACH_EVENT :RDMA_NETDEV_DETACH_EVENT ; -rdma_nl_notify_event (ib_dev, port, etype); - } -up_read (&devices_rwsem); +/* Make sure that the device is registered before we send events */ +if (xa_load (&devices, ib_dev->index) != ib_dev) +return 0 ; + + etype = ndev ?RDMA_NETDEV_ATTACH_EVENT :RDMA_NETDEV_DETACH_EVENT ; +rdma_nl_notify_event (ib_dev, port, etype);return 0 ; }
PATCH v3 7/7 RDMA/nldev: Expose whether RDMA monitoring is supported
In reply to Michael GuralnikFrom: Chiara Meiohas <[email protected]>
Extend the "rdma sys" command to display whether RDMA monitoring is supported.
RDMA monitoring is not supported in mlx4 because it does not use the ib_device_set_netdev() API, which sends the RDMA events.
Example output for kernel where monitoring is supported:
$ rdma sys show netns shared privileged-qkey off monitor on copy-on-fork on
Example output for kernel where monitoring is not supported:
$ rdma sys show netns shared privileged-qkey off monitor off copy-on-fork on
--- drivers/infiniband/core/nldev.c | 6 ++++++ include/uapi/rdma/rdma_netlink.h | 1 + 2 files changed, 7 insertions(+)
drivers/infiniband/core/nldev.c +6 -0
@@ -1952,6 +1952,12 @@ static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,nlmsg_free (msg);return err; } + + err =nla_put_u8 (msg,RDMA_NLDEV_SYS_ATTR_MONITOR_MODE ,1 ); +if (err) { +nlmsg_free (msg); +return err; + }/* * Copy-on-fork is supported. * See commits:
include/uapi/rdma/rdma_netlink.h +1 -0
@@ -579,6 +579,7 @@ enum rdma_nldev_attr {RDMA_NLDEV_ATTR_EVENT_TYPE ,/* u8 */ + RDMA_NLDEV_SYS_ATTR_MONITOR_MODE, /* u8 *//* * Always the end */
Signature · 1 line
2.17.2
Leon Romanovsky
AppliedQuoted 10 lines · Michael Guralnik
This series consists of multiple parts that collectively offer a method to monitor RDMA events from userspace.
Using netlink, users will be able to monitor their IB device events and changes such as device register, device unregister and netdev attachment.The first 2 patches contain fixes in mlx5 lag code that are required for accurate event reporting in case of a lag bond.
[...]
Applied, thanks!
[1/7] RDMA/mlx5: Check RoCE LAG status before getting netdev
https://git.kernel.org/rdma/rdma/c/e67266dc429670 [2/7] RDMA/mlx5: Obtain upper net device only when needed https://git.kernel.org/rdma/rdma/c/eb66fcc43fde8f [3/7] RDMA/mlx5: Initialize phys_port_cnt earlier in RDMA device creation https://git.kernel.org/rdma/rdma/c/41068c95b0bf6e [4/7] RDMA/device: Remove optimization in ib_device_get_netdev() https://git.kernel.org/rdma/rdma/c/95ae29d023a4ba [5/7] RDMA/mlx5: Use IB set_netdev and get_netdev functions https://git.kernel.org/rdma/rdma/c/425b36d3b2cb81 [6/7] RDMA/nldev: Add support for RDMA monitoring https://git.kernel.org/rdma/rdma/c/9a13c8cffcf6e8 [7/7] RDMA/nldev: Expose whether RDMA monitoring is supported https://git.kernel.org/rdma/rdma/c/61eb1e03c16f38
Best regards,
Signature · 1 line
Leon Romanovsky <[email protected]>