* [PATCH net] amt: handle all upper amt devices in amt_device_event()
@ 2026-11-11 6:15 Wenbo Sun
2026-11-12 18:51 ` Jakub Kicinski
0 siblings, 1 reply; 2+ messages in thread
From: Wenbo Sun @ 2026-11-11 6:15 UTC (permalink / raw)
To: Taehee Yoo, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Cc: netdev, linux-kernel, sunwenbo, 1342116488
When multiple AMT interfaces are created over the same lower stream
device, each AMT interface links to the stream device as an upper
device and takes a reference to it via dev_get_by_index().
However, amt_device_event() uses amt_lookup_upper_dev(), which only
retrieves the first matching AMT device.
Consequently, when the lower stream device is unregistered
(NETDEV_UNREGISTER), only the first AMT device is detached and
unregistered. The remaining AMT interfaces remain attached to the
lower device, triggering WARN_ON(netdev_has_any_upper_dev(dev)) in
unregister_netdevice_many_notify(). Similarly, when the lower device
MTU changes (NETDEV_CHANGEMTU), only the first AMT device has its MTU
updated.
Fix this by iterating over all AMT interfaces associated with the
stream device in amt_device_event() for both NETDEV_UNREGISTER and
NETDEV_CHANGEMTU, and remove the now-redundant amt_lookup_upper_dev()
helper.
This issue was identified with the assistance of an LLM-based code
review tool, confirmed by reproducing the MTU update failure and kernel
WARNING on lower device unregistration in a User-Mode Linux (UML)
environment, and verified in UML that all upper AMT devices are cleanly
handled and unregistered without warnings.
Fixes: b9022b53adad ("amt: add control plane of amt interface")
Signed-off-by: Wenbo Sun <sunwenbo@cmss.chinamobile.com>
---
drivers/net/amt.c | 48 +++++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 27 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 81d26ef82cf5..568ff4f77be6 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -3404,22 +3404,6 @@ static struct rtnl_link_ops amt_link_ops __read_mostly = {
.fill_info = amt_fill_info,
};
-static struct net_device *amt_lookup_upper_dev(struct net_device *dev)
-{
- struct net_device *upper_dev;
- struct amt_dev *amt;
-
- for_each_netdev(dev_net(dev), upper_dev) {
- if (netif_is_amt(upper_dev)) {
- amt = netdev_priv(upper_dev);
- if (amt->stream_dev == dev)
- return upper_dev;
- }
- }
-
- return NULL;
-}
-
static int amt_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -3429,23 +3413,33 @@ static int amt_device_event(struct notifier_block *unused,
LIST_HEAD(list);
int new_mtu;
- upper_dev = amt_lookup_upper_dev(dev);
- if (!upper_dev)
- return NOTIFY_DONE;
- amt = netdev_priv(upper_dev);
-
switch (event) {
case NETDEV_UNREGISTER:
- amt_dellink(amt->dev, &list);
+ for_each_netdev(dev_net(dev), upper_dev) {
+ if (netif_is_amt(upper_dev)) {
+ amt = netdev_priv(upper_dev);
+ if (amt->stream_dev == dev)
+ amt_dellink(amt->dev, &list);
+ }
+ }
unregister_netdevice_many(&list);
break;
case NETDEV_CHANGEMTU:
- if (amt->mode == AMT_MODE_RELAY)
- new_mtu = dev->mtu - AMT_RELAY_HLEN;
- else
- new_mtu = dev->mtu - AMT_GW_HLEN;
+ for_each_netdev(dev_net(dev), upper_dev) {
+ if (netif_is_amt(upper_dev)) {
+ amt = netdev_priv(upper_dev);
+ if (amt->stream_dev == dev) {
+ if (amt->mode == AMT_MODE_RELAY)
+ new_mtu = dev->mtu -
+ AMT_RELAY_HLEN;
+ else
+ new_mtu = dev->mtu -
+ AMT_GW_HLEN;
- dev_set_mtu(amt->dev, new_mtu);
+ dev_set_mtu(amt->dev, new_mtu);
+ }
+ }
+ }
break;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH net] amt: handle all upper amt devices in amt_device_event()
2026-11-11 6:15 [PATCH net] amt: handle all upper amt devices in amt_device_event() Wenbo Sun
@ 2026-11-12 18:51 ` Jakub Kicinski
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Kicinski @ 2026-11-12 18:51 UTC (permalink / raw)
To: Wenbo Sun
Cc: Taehee Yoo, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, netdev, linux-kernel, 1342116488
On Wed, 11 Nov 2026 14:15:35 +0800 Wenbo Sun wrote:
> When multiple AMT interfaces are created over the same lower stream
> device, each AMT interface links to the stream device as an upper
> device and takes a reference to it via dev_get_by_index().
commit 7262e999ebe already fixed this
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-12 18:51 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-11 6:15 [PATCH net] amt: handle all upper amt devices in amt_device_event() Wenbo Sun
2026-11-12 18:51 ` Jakub Kicinski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox