linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] net: dsa: Keep a reference count on ethernet_dev
@ 2017-01-21 17:40 Florian Fainelli
  2017-01-24 17:39 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Fainelli @ 2017-01-21 17:40 UTC (permalink / raw)
  To: netdev
  Cc: Florian Fainelli, Andrew Lunn, Vivien Didelot, David S. Miller,
	open list

of_find_net_device_by_node() just returns a reference to a net_device but does
not increment its reference count, which means that the master network device
can just vanish under our feet.

Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 net/dsa/dsa2.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index da3862124545..4adb9b11c22c 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -440,6 +440,8 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
 
 	pr_info("DSA: tree %d unapplied\n", dst->tree);
 	dst->applied = false;
+
+	dev_put(dst->master_netdev);
 }
 
 static int dsa_cpu_parse(struct device_node *port, u32 index,
@@ -458,6 +460,8 @@ static int dsa_cpu_parse(struct device_node *port, u32 index,
 	if (!ethernet_dev)
 		return -EPROBE_DEFER;
 
+	dev_hold(ethernet_dev);
+
 	if (!ds->master_netdev)
 		ds->master_netdev = ethernet_dev;
 
@@ -473,6 +477,7 @@ static int dsa_cpu_parse(struct device_node *port, u32 index,
 	dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol);
 	if (IS_ERR(dst->tag_ops)) {
 		dev_warn(ds->dev, "No tagger for this switch\n");
+		dev_put(ethernet_dev);
 		return PTR_ERR(dst->tag_ops);
 	}
 
-- 
2.9.3

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

* Re: [PATCH net] net: dsa: Keep a reference count on ethernet_dev
  2017-01-21 17:40 [PATCH net] net: dsa: Keep a reference count on ethernet_dev Florian Fainelli
@ 2017-01-24 17:39 ` David Miller
  2017-01-24 17:56   ` Florian Fainelli
  2017-01-24 22:29   ` Florian Fainelli
  0 siblings, 2 replies; 4+ messages in thread
From: David Miller @ 2017-01-24 17:39 UTC (permalink / raw)
  To: f.fainelli; +Cc: netdev, andrew, vivien.didelot, linux-kernel

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Sat, 21 Jan 2017 09:40:54 -0800

> of_find_net_device_by_node() just returns a reference to a net_device but does
> not increment its reference count, which means that the master network device
> can just vanish under our feet.
> 
> Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation")
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

This is fine, except now this netdev is completely locked into place with
no way to dynamically unload it.

If someone tries to modunload the driver for this ethernet device,
their screen will fill up with warning messages indicating that the
reference taken here in the DSA code is not going away.

You need to implement a netdev notifier that tears down this DSA
instance during an unregister event and releases the ethernet_dev.
Similar to how we handle protocol addresses bound to a netdev, etc.

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

* Re: [PATCH net] net: dsa: Keep a reference count on ethernet_dev
  2017-01-24 17:39 ` David Miller
@ 2017-01-24 17:56   ` Florian Fainelli
  2017-01-24 22:29   ` Florian Fainelli
  1 sibling, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2017-01-24 17:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, andrew, vivien.didelot, linux-kernel

On 01/24/2017 09:39 AM, David Miller wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
> Date: Sat, 21 Jan 2017 09:40:54 -0800
> 
>> of_find_net_device_by_node() just returns a reference to a net_device but does
>> not increment its reference count, which means that the master network device
>> can just vanish under our feet.
>>
>> Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation")
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> 
> This is fine, except now this netdev is completely locked into place with
> no way to dynamically unload it.
> 
> If someone tries to modunload the driver for this ethernet device,
> their screen will fill up with warning messages indicating that the
> reference taken here in the DSA code is not going away.
> 
> You need to implement a netdev notifier that tears down this DSA
> instance during an unregister event and releases the ethernet_dev.
> Similar to how we handle protocol addresses bound to a netdev, etc.

OK, that was actually my original approach, and then while detaching the
switch from the network device seemed easy enough, re-attaching it could
be a little challenging. Let's try again.

Thanks!
-- 
Florian

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

* Re: [PATCH net] net: dsa: Keep a reference count on ethernet_dev
  2017-01-24 17:39 ` David Miller
  2017-01-24 17:56   ` Florian Fainelli
@ 2017-01-24 22:29   ` Florian Fainelli
  1 sibling, 0 replies; 4+ messages in thread
From: Florian Fainelli @ 2017-01-24 22:29 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, andrew, vivien.didelot, linux-kernel

On 01/24/2017 09:39 AM, David Miller wrote:
> From: Florian Fainelli <f.fainelli@gmail.com>
> Date: Sat, 21 Jan 2017 09:40:54 -0800
> 
>> of_find_net_device_by_node() just returns a reference to a net_device but does
>> not increment its reference count, which means that the master network device
>> can just vanish under our feet.
>>
>> Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation")
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> 
> This is fine, except now this netdev is completely locked into place with
> no way to dynamically unload it.
> 
> If someone tries to modunload the driver for this ethernet device,
> their screen will fill up with warning messages indicating that the
> reference taken here in the DSA code is not going away.
> 
> You need to implement a netdev notifier that tears down this DSA
> instance during an unregister event and releases the ethernet_dev.
> Similar to how we handle protocol addresses bound to a netdev, etc.

I have been thinking about this a bit more, and this is what is going on:

- upon master network device unregister we can look up the
dsa_switch_tree in dev->dsa_ptr and call dsa_dst_unapply() that is
actually exactly what we want since it detaches the dsa_switch_tree from
the master network device

- upon master network device register, we can look up whether this
master netdev is the one of interest and re-attach the dangling switch
tree, but here we have two cases:

	- if we have an OF enabled system, doing a reverse look up of
net_device to device to device_node, and then looking it up in the
Device Tree is possible and reasonably simple, this works

	- if we have a platform data enabled system, doing a reverse lookup is
possible, but won't necessarily yield the expected results, because
platform data will have a device reference to the original master
netdev, and this one could be totally different the second time we probe
the master network device due to to unregister/register

Thoughts?
-- 
Florian

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

end of thread, other threads:[~2017-01-24 22:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-21 17:40 [PATCH net] net: dsa: Keep a reference count on ethernet_dev Florian Fainelli
2017-01-24 17:39 ` David Miller
2017-01-24 17:56   ` Florian Fainelli
2017-01-24 22:29   ` Florian Fainelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).