From: Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
To: Vladimir Oltean <vladimir.oltean@nxp.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"mickeyr@marvell.com" <mickeyr@marvell.com>,
Serhiy Pshyk <serhiy.pshyk@plvision.eu>,
Taras Chornyi <taras.chornyi@plvision.eu>,
Volodymyr Mytnyk <vmytnyk@marvell.com>,
Taras Chornyi <tchornyi@marvell.com>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Ioana Ciornei <ioana.ciornei@nxp.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH net] net: marvell: prestera: fix brige port operation
Date: Thu, 18 Nov 2021 14:28:12 +0000 [thread overview]
Message-ID: <AM0P190MB07218D91BF57C903690DF4518F9B9@AM0P190MB0721.EURP190.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <20211117171054.cupmcwwi2ruxjxuh@skbuf>
> On Wed, Nov 17, 2021 at 11:43:51AM +0200, Volodymyr Mytnyk wrote:
> > From: Volodymyr Mytnyk <vmytnyk@marvell.com>
> >
> > - handle SWITCHDEV_BRPORT_[UN]OFFLOADED events for
> > switchdev_bridge_port_offload to avoid fail return.
> > - fix error path handling in prestera_bridge_port_join to
> > fix double free issue (see below).
> >
> > Trace:
> > Internal error: Oops: 96000044 [#1] SMP
> > Modules linked in: prestera_pci prestera uio_pdrv_genirq
> > CPU: 1 PID: 881 Comm: ip Not tainted 5.15.0 #1
> > pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : prestera_bridge_destroy+0x2c/0xb0 [prestera]
> > lr : prestera_bridge_port_join+0x2cc/0x350 [prestera]
> > sp : ffff800011a1b0f0
> > ...
> > x2 : ffff000109ca6c80 x1 : dead000000000100 x0 : dead000000000122
> > Call trace:
> > prestera_bridge_destroy+0x2c/0xb0 [prestera]
> > prestera_bridge_port_join+0x2cc/0x350 [prestera]
> > prestera_netdev_port_event.constprop.0+0x3c4/0x450 [prestera]
> > prestera_netdev_event_handler+0xf4/0x110 [prestera]
> > raw_notifier_call_chain+0x54/0x80
> > call_netdevice_notifiers_info+0x54/0xa0
> > __netdev_upper_dev_link+0x19c/0x380
> >
> > Fixes: 2f5dc00f7a3e ("net: bridge: switchdev: let drivers inform which
> > bridge ports are offloaded")
> > Signed-off-by: Volodymyr Mytnyk <vmytnyk@marvell.com>
> > ---
> > drivers/net/ethernet/marvell/prestera/prestera_switchdev.c | 9
> > +++++----
> > 1 file changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git
> > a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> > b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> > index 3ce6ccd0f539..f1bc6699ec8b 100644
> > --- a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> > +++ b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> > @@ -497,8 +497,8 @@ int prestera_bridge_port_join(struct net_device
> > *br_dev,
> >
> > br_port = prestera_bridge_port_add(bridge, port->dev);
> > if (IS_ERR(br_port)) {
> > - err = PTR_ERR(br_port);
> > - goto err_brport_create;
> > + prestera_bridge_put(bridge);
> > + return PTR_ERR(br_port);
> > }
>
> Here is how the function looked _before_ my patch:
>
> int prestera_bridge_port_join(struct net_device *br_dev,
> struct prestera_port *port)
> {
> struct prestera_switchdev *swdev = port->sw->swdev;
> struct prestera_bridge_port *br_port;
> struct prestera_bridge *bridge;
> int err;
>
> bridge = prestera_bridge_by_dev(swdev, br_dev);
> if (!bridge) {
> bridge = prestera_bridge_create(swdev, br_dev);
> if (IS_ERR(bridge))
> return PTR_ERR(bridge);
> }
>
> br_port = prestera_bridge_port_add(bridge, port->dev);
> if (IS_ERR(br_port)) {
> err = PTR_ERR(br_port);
> goto err_brport_create;
> }
>
> if (bridge->vlan_enabled)
> return 0;
>
> err = prestera_bridge_1d_port_join(br_port);
> if (err)
> goto err_port_join;
>
> return 0;
>
> err_port_join:
> prestera_bridge_port_put(br_port);
> err_brport_create:
> prestera_bridge_put(bridge);
> return err;
> }
>
> The double free is due to the fact that prestera_bridge_port_put() calls
> prestera_bridge_put() by itself too.
>
> But the code was already buggy, for example the error path of
> prestera_bridge_1d_port_join() would trigger this double free as well.
> The change itself is ok (but is very poorly explained), if
> prestera_bridge_port_add() fails, you want to undo just prestera_bridge_create(), otherwise, prestera_bridge_port_put() will undo both prestera_bridge_port_add() and prestera_bridge_create().
>
> So the honest Fixes: tag should be:
>
> Fixes: e1189d9a5fbe ("net: marvell: prestera: Add Switchdev driver implementation")
Right, the double free was before. Will change this the commit tag with e1189d9a5fbe. Thx.
>
> because you want this change to be backported even to stable kernels where commit 2f5dc00f7a3e ("net: bridge: switchdev: let drivers inform which bridge ports are offloaded") is not present.
>
> >
> > err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL,
> > @@ -519,8 +519,6 @@ int prestera_bridge_port_join(struct net_device *br_dev,
> > switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
> > err_switchdev_offload:
> > prestera_bridge_port_put(br_port);
> > -err_brport_create:
> > - prestera_bridge_put(bridge);
> > return err;
> > }
> >
> > @@ -1123,6 +1121,9 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused,
> > prestera_netdev_check,
> > prestera_port_obj_attr_set);
> > break;
> > + case SWITCHDEV_BRPORT_OFFLOADED:
> > + case SWITCHDEV_BRPORT_UNOFFLOADED:
> > + return NOTIFY_DONE;
> > default:
> > err = -EOPNOTSUPP;
>
> May I suggest that the root cause of the problem is that you're returning -EOPNOTSUPP here? The switchdev events may just as well not be destined for your prestera switch. You should return NOTIFY_DONE ("don't
> care") for event types you don't know how to handle.
Yes, I think NOTIFY_DONE can be returned by default. It makes sense to split this change into two commits with their fix tag set respectively.
>
> And technically, this part of the patch should have:
> Fixes: 957e2235e526 ("net: make switchdev_bridge_port_{,unoffload} loosely coupled with the bridge")
>
Regards,
Volodymyr
prev parent reply other threads:[~2021-11-18 14:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-17 9:43 [PATCH net] net: marvell: prestera: fix brige port operation Volodymyr Mytnyk
2021-11-17 17:10 ` Vladimir Oltean
2021-11-18 14:28 ` Volodymyr Mytnyk [this message]
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=AM0P190MB07218D91BF57C903690DF4518F9B9@AM0P190MB0721.EURP190.PROD.OUTLOOK.COM \
--to=volodymyr.mytnyk@plvision.eu \
--cc=davem@davemloft.net \
--cc=ioana.ciornei@nxp.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mickeyr@marvell.com \
--cc=netdev@vger.kernel.org \
--cc=serhiy.pshyk@plvision.eu \
--cc=taras.chornyi@plvision.eu \
--cc=tchornyi@marvell.com \
--cc=vladimir.oltean@nxp.com \
--cc=vmytnyk@marvell.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