From: "Tantilov, Emil S" <emil.s.tantilov@intel.com>
To: <netdev-bot+sashiko@kernel.org>, <anthony.l.nguyen@intel.com>
Cc: <davem@davemloft.net>, <kuba@kernel.org>, <pabeni@redhat.com>,
<edumazet@kernel.org>, <andrew+netdev@lunn.ch>,
<netdev@vger.kernel.org>, <david.butler@appgate.com>,
<luoxuanqiang@kylinos.cn>, <bryan.fraschetti@canonical.com>,
<tristan@talencesecurity.com>, <tomasz.lichwala@linux.intel.com>,
<horms@kernel.org>, <aleksander.lobakin@intel.com>,
<stable@vger.kernel.org>, <jacob.e.keller@intel.com>,
<aleksandr.loktionov@intel.com>
Subject: Re: [PATCH net 1/6] idpf: fix possible race on remove during a reset
Date: Thu, 1 Oct 2026 16:40:46 -0700 [thread overview]
Message-ID: <e4f1eadf-2bcd-4a1c-b321-b4004ba0645d@intel.com> (raw)
In-Reply-To: <179072991189.434549.5989394906343796155@kernel.org>
On 9/29/2026 5:58 PM, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider.
>
> Critical: 0 · High: 1 (2) · Medium: 0 · Low: 0
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [High] The patch removes the IDPF_REMOVE_IN_PROG early return from
> idpf_stop(), which opens a double-teardown race between a userspace…
>
> Pre-existing issues:
> - [High] This problem wasn't introduced by this patch, but the patch
> relies on the loop that contains it.
> - [High] This problem wasn't introduced by this patch, but the patch now
> sends the remove-racing-reset case through it.
>
> --
>
> idpf: fix possible race on remove during a reset
>
> This patch drops the IDPF_REMOVE_IN_PROG early return from idpf_stop(),
> so idpf_vport_stop() always runs on close. The goal is to let a reset
> that races with remove tear down NAPI in idpf_detach_and_close(), which
> runs under RTNL.
>
>> diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c
>> index 827c795afcb62..2c148377540cd 100644
>> --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
>> +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
>> @@ -1033,12 +1033,8 @@ static void idpf_vport_stop(struct idpf_vport *vport, bool rtnl)
>> */
>> static int idpf_stop(struct net_device *netdev)
>> {
>> - struct idpf_netdev_priv *np = netdev_priv(netdev);
>> struct idpf_vport *vport;
>>
>> - if (test_bit(IDPF_REMOVE_IN_PROG, np->adapter->flags))
>> - return 0;
>> -
>
> [Severity: High]
> Without this check, can a userspace close that runs during idpf_remove()
> tear down the vport a second time?
>
> The remove path is idpf_remove() -> idpf_vc_core_deinit() ->
> idpf_deinit_task() -> idpf_vport_dealloc() -> idpf_vport_stop(vport, true).
> It holds neither vport_ctrl_lock nor RTNL on entry. idpf_vport_stop() tests
> the UP bit before it takes RTNL and does not test it again afterwards:
>
> idpf_vport_stop() {
> if (!test_bit(IDPF_VPORT_UP, np->state))
> return;
>
> if (rtnl)
> rtnl_lock();
> ...
> }
>
> This is the interleaving in question:
>
> CPU1 (rmmod) CPU2 (ip link set dev down)
> __dev_close_many() holds RTNL
> idpf_vport_stop(vport, true)
> IDPF_VPORT_UP is set
> rtnl_lock() blocks
> idpf_stop()
> idpf_vport_stop(vport, false)
> queues/vectors released
> IDPF_VPORT_UP cleared
> rtnl_unlock()
> teardown continues on released state
>
> idpf_vport_intr_rel() sets q_vectors to NULL but does not change
> num_q_vectors:
>
> kfree(rsrc->q_vectors);
> rsrc->q_vectors = NULL;
>
> On the second pass, idpf_vport_intr_dis_irq_all() does:
>
> struct idpf_q_vector *q_vector = rsrc->q_vectors;
> ...
> for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++)
> writel(0, q_vector[q_idx].intr_reg.dyn_ctl);
>
> Won't that dereference a NULL q_vector? The virtchnl message builders
> that walk the NULLed rsrc->txq_grps/rxq_grps may also crash before that
> point.
>
> Before this patch, a close that reached idpf_stop() after remove had set
> IDPF_REMOVE_IN_PROG returned 0, so only one teardown ran.
>
> Would it help to re-check IDPF_VPORT_UP in idpf_vport_stop() after
> rtnl_lock() is taken, or to hold vport_ctrl_lock around the stop in the
> remove path?
>
>> idpf_vport_ctrl_lock(netdev);
>> vport = idpf_netdev_to_vport(netdev);
>>
This is a valid hit. I will post v2 to address it. For the pre-existing
below, I will review and post fixes as needed.
Thanks,
Emil
>
> [Severity: High]
> This is a pre-existing issue and was not introduced by this patch. It
> matters here because this fix now depends on the loop in
> idpf_detach_and_close():
>
> for (int i = 0; i < max_vports; i++) {
> struct net_device *netdev = adapter->netdevs[i];
> ...
> if (!netif_device_present(netdev))
> continue;
>
> idpf_vc_core_init() sizes adapter->netdevs by caps.max_vports. However,
> idpf_init_task() only creates netdevs up to default_num_vports. If the
> device reports max_vports > default_num_vports, can the first hard reset
> pass a NULL netdev to netif_device_present()?
>
> idpf_vc_event_task() -> idpf_init_hard_reset() -> idpf_detach_and_close()
> -> netif_device_present(NULL)
>
> The other max_vports-bounded loops in the driver check for empty slots.
> idpf_remove() does "if (!adapter->netdevs[i]) continue;", idpf_init_task()
> checks !netdev, and idpf_decfg_netdev() stores NULL into the slot on
> purpose.
>
> It is not clear which shipping firmware reports max_vports larger than
> default_num_vports. virtchnl2 defines them as separate fields, though.
> This has been present since 2e281e1155fc, the commit named in Fixes:.
>
> [Severity: High]
> This is also a pre-existing issue and was not introduced by this patch.
> However, the remove-racing-reset case now goes through it as well.
>
> On a software-initiated function reset, the transaction manager is shut
> down before the close path runs:
>
> idpf_vc_event_task() {
> ...
> func_reset:
> if (adapter->xnm)
> libie_ctlq_xn_shutdown(adapter->xnm);
> drv_load:
> set_bit(IDPF_HR_RESET_IN_PROG, adapter->flags);
> idpf_init_hard_reset(adapter);
> ...
> }
>
> After that, libie_ctlq_xn_pop_free() refuses new transactions:
>
> if (unlikely(xnm->shutdown))
> return NULL;
>
> The call chain is idpf_init_hard_reset() -> idpf_detach_and_close() ->
> dev_close() -> idpf_stop() -> idpf_vport_stop(). The DISABLE_VPORT and
> DISABLE_QUEUES messages fail silently because their return values are
> ignored. Then the rings and buffers are freed:
>
> idpf_vport_intr_deinit(vport, rsrc);
> idpf_xdp_rxq_info_deinit_all(rsrc);
> idpf_vport_queues_rel(vport, rsrc);
> idpf_vport_intr_rel(rsrc);
>
> reg_ops->trigger_reset() is only called later, after
> idpf_vc_core_deinit(). Can the still-enabled Rx queues DMA into the freed
> descriptor rings or buffers during that window?
>
> On a VF, idpf_vf_trigger_reset() skips the reset entirely during remove:
>
> if (trig_cause == IDPF_HR_FUNC_RESET &&
> !test_bit(IDPF_REMOVE_IN_PROG, adapter->flags))
> idpf_send_vf_reset_msg(adapter);
>
> In that case, no device reset follows the free at all.
>
> Before this patch, the remove-racing-reset case skipped idpf_vport_stop()
> in idpf_stop(). The rings leaked, but they were not freed while still in
> use.
>
> Would it help to shut down the transaction manager only after
> idpf_detach_and_close() has disabled the queues? Another option is to
> keep the DMA memory until the device has been reset.
>
next prev parent reply other threads:[~2026-10-01 23:40 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 23:04 [PATCH net 0/6][pull request] Intel Wired LAN Driver Updates 2026-09-28 (idpf, ice, iavf) Tony Nguyen
2026-09-28 23:04 ` [PATCH net 1/6] idpf: fix possible race on remove during a reset Tony Nguyen
2026-09-30 0:58 ` netdev-bot+sashiko
2026-10-01 23:40 ` Tantilov, Emil S [this message]
2026-09-28 23:04 ` [PATCH net 2/6] ice: fix use-after-free in dynamic port cleanup Tony Nguyen
2026-09-28 23:04 ` [PATCH net 3/6] ice: Restore Ordered MMIO Writes for Tx Doorbells Tony Nguyen
2026-09-30 0:58 ` netdev-bot+sashiko
2026-10-01 16:35 ` Tony Nguyen
2026-09-28 23:04 ` [PATCH net 4/6] ice: fix metadata_dst refcount handling on representor teardown Tony Nguyen
2026-09-28 23:04 ` [PATCH net 5/6] iavf: fix VF stats not updating due to PTP command preemption Tony Nguyen
2026-09-30 0:58 ` netdev-bot+sashiko
2026-09-30 15:07 ` Tomasz Lichwala
2026-09-28 23:04 ` [PATCH net 6/6] iavf: cap advertised max_pkt_size at the single-buffer HW limit Tony Nguyen
2026-09-29 16:18 ` Alexander Lobakin
2026-09-29 20:32 ` Dave Butler
2026-09-30 11:32 ` Alexander Lobakin
2026-09-30 0:58 ` netdev-bot+sashiko
2026-09-30 6:02 ` Dave Butler
[not found] ` <IA3PR05MB22078430E404FAD12912A706298B892@IA3PR05MB220784.namprd05.prod.outlook.com>
[not found] ` <CANm61jc37jivo=XmRwN8ic8PNJFXZK+6Gsw5VRy=b-oZKpMsMA@mail.gmail.com>
2026-10-02 21:09 ` Fw: " David Butler
2026-09-28 23:10 ` [PATCH net 0/6][pull request] Intel Wired LAN Driver Updates 2026-09-28 (idpf, ice, iavf) netdev-bot+sinfo
2026-09-29 1:41 ` Dave Butler
[not found] ` <IA3PR05MB22078467309FA5DFF33EF712488B892@IA3PR05MB220784.namprd05.prod.outlook.com>
2026-10-02 21:21 ` Fw: " David Butler
2026-09-29 17:16 ` Tantilov, Emil S
2026-09-30 15:06 ` Tomasz Lichwala
2026-10-01 23:47 ` Tony Nguyen
2026-10-02 20:39 ` Jakub Kicinski
[not found] ` <IA3PR05MB220784D3846E12367B0CA1D3738B892@IA3PR05MB220784.namprd05.prod.outlook.com>
[not found] ` <CANm61jco98RoBmBAtbnjRZCPwqS0Vt6SqXjYAEUwSD4-bWLuZA@mail.gmail.com>
2026-10-02 21:06 ` Fw: " David Butler
2026-10-02 20:50 ` patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e4f1eadf-2bcd-4a1c-b321-b4004ba0645d@intel.com \
--to=emil.s.tantilov@intel.com \
--cc=aleksander.lobakin@intel.com \
--cc=aleksandr.loktionov@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=bryan.fraschetti@canonical.com \
--cc=davem@davemloft.net \
--cc=david.butler@appgate.com \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=jacob.e.keller@intel.com \
--cc=kuba@kernel.org \
--cc=luoxuanqiang@kylinos.cn \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.kernel.org \
--cc=tomasz.lichwala@linux.intel.com \
--cc=tristan@talencesecurity.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox