All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
@ 2022-02-24 16:01 Vladimir Oltean
  2022-02-25 10:50 ` patchwork-bot+netdevbpf
  2022-03-01 16:23 ` Ido Schimmel
  0 siblings, 2 replies; 6+ messages in thread
From: Vladimir Oltean @ 2022-02-24 16:01 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jakub Kicinski, John Fastabend, Petr Machata

If I'm not mistaken (and I don't think I am), the way in which the
dcbnl_ops work is that drivers call dcb_ieee_setapp() and this populates
the application table with dynamically allocated struct dcb_app_type
entries that are kept in the module-global dcb_app_list.

However, nobody keeps exact track of these entries, and although
dcb_ieee_delapp() is supposed to remove them, nobody does so when the
interface goes away (example: driver unbinds from device). So the
dcb_app_list will contain lingering entries with an ifindex that no
longer matches any device in dcb_app_lookup().

Reclaim the lost memory by listening for the NETDEV_UNREGISTER event and
flushing the app table entries of interfaces that are now gone.

In fact something like this used to be done as part of the initial
commit (blamed below), but it was done in dcbnl_exit() -> dcb_flushapp(),
essentially at module_exit time. That became dead code after commit
7a6b6f515f77 ("DCB: fix kconfig option") which essentially merged
"tristate config DCB" and "bool config DCBNL" into a single "bool config
DCB", so net/dcb/dcbnl.c could not be built as a module anymore.

Commit 36b9ad8084bd ("net/dcb: make dcbnl.c explicitly non-modular")
recognized this and deleted dcbnl_exit() and dcb_flushapp() altogether,
leaving us with the version we have today.

Since flushing application table entries can and should be done as soon
as the netdevice disappears, fundamentally the commit that is to blame
is the one that introduced the design of this API.

Fixes: 9ab933ab2cc8 ("dcbnl: add appliction tlv handlers")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/dcb/dcbnl.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index b441ab330fd3..36c91273daac 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -2073,8 +2073,52 @@ u8 dcb_ieee_getapp_default_prio_mask(const struct net_device *dev)
 }
 EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
 
+static void dcbnl_flush_dev(struct net_device *dev)
+{
+	struct dcb_app_type *itr, *tmp;
+
+	spin_lock(&dcb_lock);
+
+	list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
+		if (itr->ifindex == dev->ifindex) {
+			list_del(&itr->list);
+			kfree(itr);
+		}
+	}
+
+	spin_unlock(&dcb_lock);
+}
+
+static int dcbnl_netdevice_event(struct notifier_block *nb,
+				 unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+
+	switch (event) {
+	case NETDEV_UNREGISTER:
+		if (!dev->dcbnl_ops)
+			return NOTIFY_DONE;
+
+		dcbnl_flush_dev(dev);
+
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
+}
+
+static struct notifier_block dcbnl_nb __read_mostly = {
+	.notifier_call  = dcbnl_netdevice_event,
+};
+
 static int __init dcbnl_init(void)
 {
+	int err;
+
+	err = register_netdevice_notifier(&dcbnl_nb);
+	if (err)
+		return err;
+
 	rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
 	rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
  2022-02-24 16:01 [PATCH net] net: dcb: flush lingering app table entries for unregistered devices Vladimir Oltean
@ 2022-02-25 10:50 ` patchwork-bot+netdevbpf
  2022-03-01 16:23 ` Ido Schimmel
  1 sibling, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-02-25 10:50 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: netdev, davem, kuba, john.fastabend, petrm

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem@davemloft.net>:

On Thu, 24 Feb 2022 18:01:54 +0200 you wrote:
> If I'm not mistaken (and I don't think I am), the way in which the
> dcbnl_ops work is that drivers call dcb_ieee_setapp() and this populates
> the application table with dynamically allocated struct dcb_app_type
> entries that are kept in the module-global dcb_app_list.
> 
> However, nobody keeps exact track of these entries, and although
> dcb_ieee_delapp() is supposed to remove them, nobody does so when the
> interface goes away (example: driver unbinds from device). So the
> dcb_app_list will contain lingering entries with an ifindex that no
> longer matches any device in dcb_app_lookup().
> 
> [...]

Here is the summary with links:
  - [net] net: dcb: flush lingering app table entries for unregistered devices
    https://git.kernel.org/netdev/net/c/91b0383fef06

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
  2022-02-24 16:01 [PATCH net] net: dcb: flush lingering app table entries for unregistered devices Vladimir Oltean
  2022-02-25 10:50 ` patchwork-bot+netdevbpf
@ 2022-03-01 16:23 ` Ido Schimmel
  2022-03-01 16:36   ` Vladimir Oltean
  1 sibling, 1 reply; 6+ messages in thread
From: Ido Schimmel @ 2022-03-01 16:23 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, David S. Miller, Jakub Kicinski, John Fastabend, Petr Machata

On Thu, Feb 24, 2022 at 06:01:54PM +0200, Vladimir Oltean wrote:
> +static void dcbnl_flush_dev(struct net_device *dev)
> +{
> +	struct dcb_app_type *itr, *tmp;
> +
> +	spin_lock(&dcb_lock);

Should this be spin_lock_bh()? According to commit 52cff74eef5d ("dcbnl
: Disable software interrupts before taking dcb_lock") this lock can be
acquired from softIRQ.

> +
> +	list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
> +		if (itr->ifindex == dev->ifindex) {
> +			list_del(&itr->list);
> +			kfree(itr);
> +		}
> +	}
> +
> +	spin_unlock(&dcb_lock);
> +}

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
  2022-03-01 16:23 ` Ido Schimmel
@ 2022-03-01 16:36   ` Vladimir Oltean
  2022-03-02 15:31     ` Ido Schimmel
  0 siblings, 1 reply; 6+ messages in thread
From: Vladimir Oltean @ 2022-03-01 16:36 UTC (permalink / raw)
  To: Ido Schimmel
  Cc: netdev, David S. Miller, Jakub Kicinski, John Fastabend, Petr Machata

On Tue, Mar 01, 2022 at 06:23:16PM +0200, Ido Schimmel wrote:
> On Thu, Feb 24, 2022 at 06:01:54PM +0200, Vladimir Oltean wrote:
> > +static void dcbnl_flush_dev(struct net_device *dev)
> > +{
> > +	struct dcb_app_type *itr, *tmp;
> > +
> > +	spin_lock(&dcb_lock);
> 
> Should this be spin_lock_bh()? According to commit 52cff74eef5d ("dcbnl
> : Disable software interrupts before taking dcb_lock") this lock can be
> acquired from softIRQ.

Could be. I didn't notice the explanation and I was even wondering in
which circumstance would it be needed to disable softirqs...
Now that I see the explanation I think the dcb_rpl -> cxgb4_dcb_handle_fw_update
-> dcb_ieee_setapp call path is problematic, when a different
DCB-enabled interface unregisters concurrently with a firmware event.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
  2022-03-01 16:36   ` Vladimir Oltean
@ 2022-03-02 15:31     ` Ido Schimmel
  2022-03-02 19:16       ` Vladimir Oltean
  0 siblings, 1 reply; 6+ messages in thread
From: Ido Schimmel @ 2022-03-02 15:31 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, David S. Miller, Jakub Kicinski, John Fastabend, Petr Machata

On Tue, Mar 01, 2022 at 04:36:32PM +0000, Vladimir Oltean wrote:
> On Tue, Mar 01, 2022 at 06:23:16PM +0200, Ido Schimmel wrote:
> > On Thu, Feb 24, 2022 at 06:01:54PM +0200, Vladimir Oltean wrote:
> > > +static void dcbnl_flush_dev(struct net_device *dev)
> > > +{
> > > +	struct dcb_app_type *itr, *tmp;
> > > +
> > > +	spin_lock(&dcb_lock);
> > 
> > Should this be spin_lock_bh()? According to commit 52cff74eef5d ("dcbnl
> > : Disable software interrupts before taking dcb_lock") this lock can be
> > acquired from softIRQ.
> 
> Could be. I didn't notice the explanation and I was even wondering in
> which circumstance would it be needed to disable softirqs...
> Now that I see the explanation I think the dcb_rpl -> cxgb4_dcb_handle_fw_update
> -> dcb_ieee_setapp call path is problematic, when a different
> DCB-enabled interface unregisters concurrently with a firmware event.

Yep. Can you please send a fix so that it gets into Jakub's PR tomorrow?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH net] net: dcb: flush lingering app table entries for unregistered devices
  2022-03-02 15:31     ` Ido Schimmel
@ 2022-03-02 19:16       ` Vladimir Oltean
  0 siblings, 0 replies; 6+ messages in thread
From: Vladimir Oltean @ 2022-03-02 19:16 UTC (permalink / raw)
  To: Ido Schimmel
  Cc: netdev, David S. Miller, Jakub Kicinski, John Fastabend, Petr Machata

On Wed, Mar 02, 2022 at 05:31:36PM +0200, Ido Schimmel wrote:
> On Tue, Mar 01, 2022 at 04:36:32PM +0000, Vladimir Oltean wrote:
> > On Tue, Mar 01, 2022 at 06:23:16PM +0200, Ido Schimmel wrote:
> > > On Thu, Feb 24, 2022 at 06:01:54PM +0200, Vladimir Oltean wrote:
> > > > +static void dcbnl_flush_dev(struct net_device *dev)
> > > > +{
> > > > +	struct dcb_app_type *itr, *tmp;
> > > > +
> > > > +	spin_lock(&dcb_lock);
> > > 
> > > Should this be spin_lock_bh()? According to commit 52cff74eef5d ("dcbnl
> > > : Disable software interrupts before taking dcb_lock") this lock can be
> > > acquired from softIRQ.
> > 
> > Could be. I didn't notice the explanation and I was even wondering in
> > which circumstance would it be needed to disable softirqs...
> > Now that I see the explanation I think the dcb_rpl -> cxgb4_dcb_handle_fw_update
> > -> dcb_ieee_setapp call path is problematic, when a different
> > DCB-enabled interface unregisters concurrently with a firmware event.
> 
> Yep. Can you please send a fix so that it gets into Jakub's PR tomorrow?

Sure, let me send a patch right now.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-03-02 19:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-24 16:01 [PATCH net] net: dcb: flush lingering app table entries for unregistered devices Vladimir Oltean
2022-02-25 10:50 ` patchwork-bot+netdevbpf
2022-03-01 16:23 ` Ido Schimmel
2022-03-01 16:36   ` Vladimir Oltean
2022-03-02 15:31     ` Ido Schimmel
2022-03-02 19:16       ` Vladimir Oltean

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.