RE: [PATCH iwl-net 1/3] ice: avoid RTNL deadlock when notifying the RDMA auxiliary driver
From: Loktionov, Aleksandr
Date: Wed Oct 21 2026 - 07:21:55 EST
> -----Original Message-----
> From: Petr Oros <poros@xxxxxxxxxx>
> Sent: Monday, October 19, 2026 8:53 AM
> To: netdev@xxxxxxxxxxxxxxx
> Cc: Oros, Petr <poros@xxxxxxxxxx>; Nguyen, Anthony L
> <anthony.l.nguyen@xxxxxxxxx>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@xxxxxxxxx>; Andrew Lunn <andrew+netdev@xxxxxxx>;
> David S . Miller <davem@xxxxxxxxxxxxx>; Eric Dumazet
> <edumazet@xxxxxxxxxx>; Jakub Kicinski <kuba@xxxxxxxxxx>; Paolo Abeni
> <pabeni@xxxxxxxxxx>; Ertman, David M <david.m.ertman@xxxxxxxxx>; Shiraz
> Saleem <shiraz.saleem@xxxxxxxxx>; Leon Romanovsky <leon@xxxxxxxxxx>;
> Maziarz, Kamil <kamil.maziarz@xxxxxxxxx>; Rafal Rogalski
> <rafalx.rogalski@xxxxxxxxx>; Loktionov, Aleksandr
> <aleksandr.loktionov@xxxxxxxxx>; Schmidt, Michal <mschmidt@xxxxxxxxxx>;
> linux-rdma@xxxxxxxxxxxxxxx; intel-wired-lan@xxxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx; stable@xxxxxxxxxxxxxxx; Sebastian Andrzej
> Siewior <bigeasy@xxxxxxxxxxxxx>; Clark Williams <clrkwllms@xxxxxxxxxx>;
> Steven Rostedt <rostedt@xxxxxxxxxxx>; Mateusz Palczewski
> <mateusz.palczewski@xxxxxxxxx>; linux-rt-devel@xxxxxxxxxxxxxxx
> Subject: [PATCH iwl-net 1/3] ice: avoid RTNL deadlock when notifying the
> RDMA auxiliary driver
>
> ice_send_event_to_aux() blocks on the auxiliary device lock, and the
> dcbnl callers reach it with the RTNL lock held. The RDMA auxiliary probe
> takes the two in the opposite order, because __driver_attach() holds the
> auxiliary device lock across ib_register_device(), which needs the RTNL
> lock:
>
> systemd-udevd state:D
> really_probe <- holds device_lock(&adev->dev)
> icrdma_probe
> irdma_ib_register_device
> ib_register_device
> setup_device
> irdma_roce_port_immutable
> ib_query_port
> irdma_query_port
> ib_get_eth_speed <- blocks on rtnl_lock()
>
> lldpad state:D
> rtnetlink_rcv_msg <- holds rtnl_lock()
> dcb_doit
> dcbnl_ieee_set
> ice_dcbnl_setets
> ice_pf_dcb_cfg
> ice_send_event_to_aux <- blocks on device_lock(&adev->dev)
>
> Everything else that needs the RTNL lock piles up behind lldpad and the
> boot never completes. The probe side cannot be changed, so use
> device_trylock() and report whether the event reached the driver.
>
> IIDC_RDMA_EVENT_BEFORE_TC_CHANGE has to arrive before the traffic
> classes change, so ice_pf_dcb_cfg() refuses the request with -EBUSY
> rather than run it behind the RDMA driver's back. The critical error and
> MTU change events are sent from the service task, which consumes their
> pending bits before sending, so those are re-armed instead.
> AFTER_TC_CHANGE keeps its fire and forget behaviour, it can be neither
> refused, the hardware has already changed, nor deferred, every lock that
> would serialise a deferred delivery against the dcbnl callers forms
> another cycle.
>
> Fixes: 348048e724a0 ("ice: Implement iidc operations")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Petr Oros <poros@xxxxxxxxxx>
> ---
> drivers/net/ethernet/intel/ice/ice_dcb_lib.c | 9 ++++++++-
> drivers/net/ethernet/intel/ice/ice_idc.c | 20 ++++++++++++++++----
> drivers/net/ethernet/intel/ice/ice_idc_int.h | 2 +-
> drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++++++++----
> 4 files changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
> b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
> index 0bc6dd37568792..2022b46c990cb2 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
> @@ -355,8 +355,10 @@ int ice_pf_dcb_cfg(struct ice_pf *pf, struct
> ice_dcbx_cfg *new_cfg, bool locked)
> struct iidc_rdma_event *event;
> int ret = ICE_DCB_NO_HW_CHG;
> struct ice_vsi *pf_vsi;
> + bool dcb_ena;
>
> curr_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
> + dcb_ena = test_bit(ICE_FLAG_DCB_ENA, pf->flags);
>
> /* FW does not care if change happened */
> if (!pf->hw.port_info->qos_cfg.is_sw_lldp)
> @@ -406,7 +408,12 @@ int ice_pf_dcb_cfg(struct ice_pf *pf, struct
> ice_dcbx_cfg *new_cfg, bool locked)
> }
>
> set_bit(IIDC_RDMA_EVENT_BEFORE_TC_CHANGE, event->type);
> - ice_send_event_to_aux(pf, event);
> + if (!ice_send_event_to_aux(pf, event)) {
> + assign_bit(ICE_FLAG_DCB_ENA, pf->flags, dcb_ena);
> + kfree(event);
> + ret = -EBUSY;
-EBUSY doesn't match to any ICE_DCB_* constant, are you sure you tested this case?
It looks like it will be processed like ICE_DCB_NO_HW_CHG i.e. no change needed, isn't it?
> + goto free_cfg;
> + }
> kfree(event);
>
> /* avoid race conditions by holding the lock while disabling and
> diff --git a/drivers/net/ethernet/intel/ice/ice_idc.c
> b/drivers/net/ethernet/intel/ice/ice_idc.c
> index 102d63c3018b1f..7fd35ce966ea65 100644
> --- a/drivers/net/ethernet/intel/ice/ice_idc.c
> +++ b/drivers/net/ethernet/intel/ice/ice_idc.c
> @@ -34,30 +34,42 @@ ice_get_auxiliary_drv(struct iidc_rdma_core_dev_info
> *cdev)
> * ice_send_event_to_aux - send event to RDMA AUX driver
> * @pf: pointer to PF struct
> * @event: event struct
...
> kfree(event);
> }
> }
> --
> 2.56.0