The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Leon Romanovsky <leon@kernel.org>
To: Long Li <longli@microsoft.com>
Cc: Konstantin Taranov <kotaranov@microsoft.com>,
	Jakub Kicinski <kuba@kernel.org>,
	"David S . Miller" <davem@davemloft.net>,
	Paolo Abeni <pabeni@redhat.com>,
	Eric Dumazet <edumazet@google.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	Jason Gunthorpe <jgg@ziepe.ca>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	"K . Y . Srinivasan" <kys@microsoft.com>,
	Wei Liu <wei.liu@kernel.org>, Dexuan Cui <decui@microsoft.com>,
	shradhagupta@linux.microsoft.com, Simon Horman <horms@kernel.org>,
	ernis@linux.microsoft.com, stephen@networkplumber.org,
	netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
	linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v6 1/7] net: mana: RCU-protect gc->cq_table lookups against concurrent CQ destroy
Date: Tue, 11 Aug 2026 11:18:05 +0300	[thread overview]
Message-ID: <20260811081805.GA30770@unreal> (raw)
In-Reply-To: <20260811023823.2391255-2-longli@microsoft.com>

On Mon, Aug 10, 2026 at 07:38:15PM -0700, Long Li wrote:
> The EQ interrupt handler (mana_gd_process_eqe) looks up the completing CQ
> in gc->cq_table[cq_id] and runs its callback, concurrently with CQ
> teardown on another CPU that clears the slot and frees the CQ.  cq_table
> was a plain pointer array freed with no grace period, so the two race
> into a use-after-free:
> 
>   CPU A (mana_gd_intr, hard IRQ)        CPU B (CQ destroy)
>   ----------------------------------    ------------------------------
>   cq = gc->cq_table[cq_id];  // valid
>                                         gc->cq_table[id] = NULL;
>                                         kfree(cq);          // freed
>   cq->cq.callback(ctx, cq);  // use-after-free
> 
> The handler's existing rcu_read_lock() only guards the per-IRQ EQ list
> traversal; cq_table was never under any RCU contract, and a read-side
> lock is inert unless the freer also defers the free past a grace period.
> 
> Put cq_table under RCU: annotate the base pointer and entries __rcu, read
> with rcu_dereference() in the handler, publish with rcu_assign_pointer(),
> and on teardown clear the slot then synchronize_rcu() before freeing the
> CQ.  The grace period blocks until every in-flight handler has dropped
> the old pointer, so the kfree() can no longer race the callback.
> 
> This fixes only the CQ lifetime (the use-after-free); it does not make
> the cq_id bound trustworthy.  gc->max_num_cqs is still range-checked
> outside the published table, and hardening that field against a spoofed
> device value is a separate change.
> 
> netdev teardown destroys a CQ per TX and per RX queue, so one grace
> period each in mana_gd_destroy_cq() would serialize up to
> 2 * MANA_MAX_NUM_QUEUES synchronize_rcu() calls under RTNL on every
> ifdown, MTU change or ring/channel reconfigure.  Clear all of a port's
> CQ slots first and take a single grace period per teardown instead:
> mana_gd_unpublish_cq() clears a slot without waiting, and
> mana_gd_destroy_cq() -- which still serves the single-CQ callers --
> finds the slot already cleared and skips its own synchronize_rcu().
> 
> Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
> Signed-off-by: Long Li <longli@microsoft.com>
> ---
> Changes in v6:
>  - mana_gd_unpublish_cq() and mana_ib_remove_cq_cb() clear a cq_table
>    slot only when it still points at the CQ being torn down, so the
>    two-pass teardown cannot wipe an entry a concurrent RDMA CQ create
>    recycled during the grace period.
>  - mana_gd_process_eqe() drops an already-unpublished (NULL) slot quietly
>    instead of a WARN_ON_ONCE() splat during a normal ifdown/MTU change,
>    and reads gc->cq_table before gc->max_num_cqs with an smp_rmb()
>    between them so a shrinking re-establish cannot pair a stale bound
>    with a newly published, smaller table.
>  - Documented the cq_table/max_num_cqs contract on the cq_table field
>    instead of rewording the comment above max_num_cqs.
> 
> Changes in v5:
>  - No code changes since v4 (resend as a standalone thread).
> 
> Changes in v4:
>  - Replaced the per-CQ synchronize_rcu() in the netdev teardown paths
>    with a two-pass quiesce/free that takes one grace period per
>    teardown; mana_gd_unpublish_cq() splits the slot-clear from the grace
>    period.
>  - Snapshot cq->id and max_num_cqs with READ_ONCE() in
>    mana_hwc_establish_channel() so one value sizes, bounds and indexes
>    cq_table.
>  - Corrected the gc->cq_table lifetime comment in gdma.h; rescoped the
>    changelog to the use-after-free fix (the bound is patch 7).
> 
>  drivers/infiniband/hw/mana/cq.c               |  51 ++++++-
>  .../net/ethernet/microsoft/mana/gdma_main.c   |  65 +++++++--
>  .../net/ethernet/microsoft/mana/hw_channel.c  |  29 ++--
>  drivers/net/ethernet/microsoft/mana/mana_en.c | 136 ++++++++++++++----
>  include/net/mana/gdma.h                       |  37 ++++-
>  5 files changed, 268 insertions(+), 50 deletions(-)

This patch is so bloated with AI that it is hard to read and difficult to justify
such a large diff for a simple change, which all drivers experience that
flow.

As a bare minimum. you need to reorder mana_ib_gd_destroy_cq(), mana_ib_destroy_queue(),
and mana_ib_remove_cq_cb() so that HW objects are stopped before SW state is torn down.

And probably introduce get/put CQ primitives.

Thanks

  reply	other threads:[~2026-08-11  8:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-11  2:38 [PATCH net v6 0/7] net: mana: HW channel reliability and hardening fixes Long Li
2026-08-11  2:38 ` [PATCH net v6 1/7] net: mana: RCU-protect gc->cq_table lookups against concurrent CQ destroy Long Li
2026-08-11  8:18   ` Leon Romanovsky [this message]
2026-08-11  2:38 ` [PATCH net v6 2/7] net: mana: fix HWC RQ/SQ buffer size swap Long Li
2026-08-11  2:38 ` [PATCH net v6 3/7] net: mana: free HWC comp_buf after destroying the EQ Long Li
2026-08-11  2:38 ` [PATCH net v6 4/7] net: mana: validate hardware-supplied values in the HWC RX path Long Li
2026-08-11  2:38 ` [PATCH net v6 5/7] net: mana: fix HWC teardown safety with setup_active flag and destroy ordering Long Li
2026-08-11  2:38 ` [PATCH net v6 6/7] net: mana: fix stale HWC response after command timeout Long Li
2026-08-11  2:38 ` [PATCH net v6 7/7] net: mana: keep max_num_cqs immutable once cq_table is allocated Long Li

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=20260811081805.GA30770@unreal \
    --to=leon@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=decui@microsoft.com \
    --cc=edumazet@google.com \
    --cc=ernis@linux.microsoft.com \
    --cc=haiyangz@microsoft.com \
    --cc=horms@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=kotaranov@microsoft.com \
    --cc=kuba@kernel.org \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=longli@microsoft.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shradhagupta@linux.microsoft.com \
    --cc=stephen@networkplumber.org \
    --cc=wei.liu@kernel.org \
    /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