From: sashiko-bot@kernel.org
To: "Ratheesh Kannoth" <rkannoth@marvell.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH v15 net-next 1/2] octeontx2: use atomic bitops for PF/VF and rep flags
Date: Sat, 12 Sep 2026 10:56:28 +0000 [thread overview]
Message-ID: <20260912105628.B3E251F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260911105521.689565-2-rkannoth@marvell.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] TC offload setup on representors corrupts the shared physical function (PF) device state by locklessly overwriting its netdev and clobbering its flags via a non-atomic bitwise sync loop.
- [High] Inverted logic in `otx2_tc_del_flow()` prematurely disables TC MARK hardware offload when any single mark rule is deleted.
- [High] Missing cancellation of `stats_wrk` leads to a Use-After-Free during representor teardown.
- [High] `rvu_rep_mcam_flow_init()` interacts with the mailbox without acquiring its lock and executes an unbalanced `mutex_unlock()`.
--
commit 5dc6aa35da96ae18ff3fd015c81c420c4cead463
Author: Ratheesh Kannoth <rkannoth@marvell.com>
octeontx2: use atomic bitops for PF/VF and rep flags
This commit replaces non-atomic u64 flag read-modify-write operations
with unsigned long bitmaps across the octeontx2 driver. It introduces
helpers for atomic bitwise flag updates and representor state sync.
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> index eecee612b7b2c..7e09c1444a6d5 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
> @@ -594,6 +595,34 @@ struct otx2_nic {
> unsigned long *af_xdp_zc_qidx;
> };
>
> +static inline void otx2_set_flag(struct otx2_nic *nic, unsigned int flag)
> +{
> + set_bit(flag, &nic->flags);
> +}
> +
> +static inline void otx2_clear_flag(struct otx2_nic *nic, unsigned int flag)
> +{
> + clear_bit(flag, &nic->flags);
> +}
> +
> +static inline bool otx2_test_flag(struct otx2_nic *nic, unsigned int flag)
> +{
> + return test_bit(flag, &nic->flags);
> +}
> +
> +static inline void otx2_sync_flags_from_rep(struct otx2_nic *dst,
> + unsigned long *src_flags)
> +{
> + unsigned int flag;
> +
> + for (flag = 0; flag <= OTX2_REP_VF_INITIALIZED; flag++) {
> + if (test_bit(flag, src_flags))
> + set_bit(flag, &dst->flags);
> + else
> + clear_bit(flag, &dst->flags);
> + }
> +}
[Severity: High]
This isn't a bug introduced by this patch, but does this loop corrupt
the physical function (PF) state by blindly overwriting its flags?
If a TC rule is configured on a representor, rvu_rep_setup_tc_cb() calls
this sync loop. It iteratively clears all global PF-specific flags (like
OTX2_FLAG_REP_MODE_ENABLED and OTX2_FLAG_INTF_DOWN) that aren't set
on the local representor, breaking datapath routing.
Additionally, is this 22-step bitwise copy susceptible to race conditions
with concurrent interrupt state changes since the updates are not atomic as
a single block?
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
> index 039fd47ebf522..ddb46b580c3b6 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
> @@ -1195,12 +1195,12 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
> /* Disable TC MARK flag if they are no rules with skbedit mark action */
> if (flow_node->req.match_id)
> if (!refcount_dec_and_test(&flow_cfg->mark_flows))
> - nic->flags &= ~OTX2_FLAG_TC_MARK_ENABLED;
> + otx2_clear_flag(nic, OTX2_FLAG_TC_MARK_ENABLED);
[Severity: High]
This is a pre-existing issue, but does this inverted logic prematurely
disable TC MARK hardware offload when any single mark rule is deleted?
Because the base refcount is 1, deleting a rule drops the count to > 0,
causing refcount_dec_and_test() to return false. The logical NOT operator
inverts this to true, triggering the clear flag while other flows are
still active.
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> index 0f5d5642d3f7a..8a8c0088fd204 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> @@ -93,9 +93,9 @@ static int rvu_rep_mcam_flow_init(struct rep_dev *rep)
> rep->flow_cfg->max_flows = allocated;
>
> if (allocated) {
> - rep->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
> - rep->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
> - rep->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
> + set_bit(OTX2_FLAG_MCAM_ENTRIES_ALLOC, &rep->flags);
> + set_bit(OTX2_FLAG_NTUPLE_SUPPORT, &rep->flags);
> + set_bit(OTX2_FLAG_TC_FLOWER_SUPPORT, &rep->flags);
> }
[Severity: High]
This isn't a bug introduced by this patch, but does this function interact
with the mailbox without acquiring its lock and execute an unbalanced
mutex_unlock?
When called by rvu_rep_setup_tc_cb(), the function enters without acquiring
priv->mbox.lock, issues mailbox allocation commands directly, and
unconditionally unlocks the mutex right before this block on the exit path.
This could trigger a lockdep splat or panic, and risks ring corruption.
> @@ -109,14 +109,14 @@ static int rvu_rep_setup_tc_cb(enum tc_setup_type type,
> struct rep_dev *rep = cb_priv;
> struct otx2_nic *priv = rep->mdev;
>
> - if (!(rep->flags & RVU_REP_VF_INITIALIZED))
> + if (!test_bit(OTX2_REP_VF_INITIALIZED, &rep->flags))
> return -EINVAL;
>
> - if (!(rep->flags & OTX2_FLAG_TC_FLOWER_SUPPORT))
> + if (!test_bit(OTX2_FLAG_TC_FLOWER_SUPPORT, &rep->flags))
> rvu_rep_mcam_flow_init(rep);
>
> priv->netdev = rep->netdev;
> - priv->flags = rep->flags;
> + otx2_sync_flags_from_rep(priv, &rep->flags);
> priv->pcifunc = rep->pcifunc;
> priv->flow_cfg = rep->flow_cfg;
[Severity: High]
This is a pre-existing issue, but does this locklessly overwrite the shared
PF's netdev with the representor's netdev?
By reassigning priv->netdev to rep->netdev, subsequent TX completions in
otx2_tx_napi_handler() will incorrectly route packets to this single
representor's netdev.
> @@ -382,7 +382,7 @@ static void rvu_rep_get_stats64(struct net_device *dev,
> {
> struct rep_dev *rep = netdev_priv(dev);
>
> - if (!(rep->flags & RVU_REP_VF_INITIALIZED))
> + if (!test_bit(OTX2_REP_VF_INITIALIZED, &rep->flags))
> return;
>
> stats->rx_packets = rep->stats.rx_frames;
[ ... ]
> @@ -632,7 +632,7 @@ void rvu_rep_destroy(struct otx2_nic *priv)
> int rep_id;
>
> rvu_eswitch_config(priv, false);
> - priv->flags |= OTX2_FLAG_INTF_DOWN;
> + otx2_set_flag(priv, OTX2_FLAG_INTF_DOWN);
> rvu_rep_free_cq_rsrc(priv);
> for (rep_id = 0; rep_id < priv->rep_cnt; rep_id++) {
> rep = priv->reps[rep_id];
[Severity: High]
This is a pre-existing issue, but can this lead to a Use-After-Free during
representor teardown?
If a user queries interface statistics (e.g., via ip -s link),
rvu_rep_get_stats64() schedules the delayed work stats_wrk. If the
representor is destroyed via rvu_rep_destroy() before the timer expires,
the struct is unregistered and freed without canceling the pending work.
When the timer fires, the workqueue executes and accesses the freed memory.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260911105521.689565-1-rkannoth@marvell.com?part=1
next prev parent reply other threads:[~2026-09-12 10:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 10:55 [PATCH v15 net-next 0/2] octeontx2-pf: mqprio bandwidth offload for NIX TX schedulers Ratheesh Kannoth
2026-09-11 10:55 ` [PATCH v15 net-next 1/2] octeontx2: use atomic bitops for PF/VF and rep flags Ratheesh Kannoth
2026-09-12 10:56 ` sashiko-bot [this message]
2026-09-11 10:55 ` [PATCH v15 net-next 2/2] octeontx2-pf: add mqprio bandwidth offload for NIX TX schedulers Ratheesh Kannoth
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=20260912105628.B3E251F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=rkannoth@marvell.com \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.