| From foo@baz Wed Sep 30 05:25:07 CEST 2015 |
| From: Mark Salter <msalter@redhat.com> |
| Date: Tue, 1 Sep 2015 09:36:05 -0400 |
| Subject: phylib: fix device deletion order in mdiobus_unregister() |
| |
| From: Mark Salter <msalter@redhat.com> |
| |
| [ Upstream commit b6c6aedcbcbacd7b0cb4b64ed5ac835bc1c60a03 ] |
| |
| commit 8b63ec1837fa ("phylib: Make PHYs children of their MDIO bus, not |
| the bus' parent.") uncovered a problem in mdiobus_unregister() which |
| leads to this warning when I reboot an APM Mustang (arm64) platform: |
| |
| WARNING: CPU: 7 PID: 4239 at fs/sysfs/group.c:224 sysfs_remove_group+0xa0/0xa4() |
| sysfs group fffffe0000e07a10 not found for kobject 'xgene-mii-eth0:03' |
| ... |
| CPU: 7 PID: 4239 Comm: reboot Tainted: G E 4.2.0-0.18.el7.test15.aarch64 #1 |
| Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0 Aug 26 2015 |
| Call Trace: |
| [<fffffe000009739c>] dump_backtrace+0x0/0x170 |
| [<fffffe000009752c>] show_stack+0x20/0x2c |
| [<fffffe00007436f0>] dump_stack+0x78/0x9c |
| [<fffffe00000c2cb4>] warn_slowpath_common+0xa0/0xd8 |
| [<fffffe00000c2d60>] warn_slowpath_fmt+0x74/0x88 |
| [<fffffe0000293d3c>] sysfs_remove_group+0x9c/0xa4 |
| [<fffffe00004a8bac>] dpm_sysfs_remove+0x5c/0x70 |
| [<fffffe000049b388>] device_del+0x44/0x208 |
| [<fffffe000049b578>] device_unregister+0x2c/0x7c |
| [<fffffe000050dc68>] mdiobus_unregister+0x48/0x94 |
| [<fffffe000052afd0>] xgene_enet_mdio_remove+0x28/0x44 |
| [<fffffe000052d3f0>] xgene_enet_remove+0xd0/0xd8 |
| [<fffffe000052d424>] xgene_enet_shutdown+0x2c/0x3c |
| [<fffffe00004a204c>] platform_drv_shutdown+0x24/0x40 |
| [<fffffe000049d4f4>] device_shutdown+0xf0/0x1b4 |
| [<fffffe00000e31ec>] kernel_restart_prepare+0x40/0x4c |
| [<fffffe00000e32f8>] kernel_restart+0x1c/0x80 |
| [<fffffe00000e3670>] SyS_reboot+0x17c/0x250 |
| |
| The problem is that mdiobus_unregister() deletes the bus device before |
| unregistering the phy devices on the bus. This wasn't a problem before |
| because the phys were not children of the bus: |
| |
| /sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0:03 |
| /sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0 |
| |
| But now that they are: |
| |
| /sys/devices/platform/APMC0D05:00/net/eth0/xgene-mii-eth0/xgene-mii-eth0:03 |
| |
| when mdiobus_unregister deletes the bus device, the phy subdirs are |
| removed from sysfs also. So when the phys are unregistered afterward, |
| we get the warning. This patch changes the order so that phys are |
| unregistered before the bus device is deleted. |
| |
| Fixes: 8b63ec1837fa ("phylib: Make PHYs children of their MDIO bus, not the bus' parent.") |
| Signed-off-by: Mark Salter <msalter@redhat.com> |
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> |
| Tested-by: Mark Langsdorf <mlangsdo@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/phy/mdio_bus.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/net/phy/mdio_bus.c |
| +++ b/drivers/net/phy/mdio_bus.c |
| @@ -303,12 +303,12 @@ void mdiobus_unregister(struct mii_bus * |
| BUG_ON(bus->state != MDIOBUS_REGISTERED); |
| bus->state = MDIOBUS_UNREGISTERED; |
| |
| - device_del(&bus->dev); |
| for (i = 0; i < PHY_MAX_ADDR; i++) { |
| if (bus->phy_map[i]) |
| device_unregister(&bus->phy_map[i]->dev); |
| bus->phy_map[i] = NULL; |
| } |
| + device_del(&bus->dev); |
| } |
| EXPORT_SYMBOL(mdiobus_unregister); |
| |