Skip to content

Commit 6779846

Browse files
author
Jiri Slaby
committed
parport: parport_pc, do not remove parent devices early
commit 91905b6 upstream. When the parport_pc module is removed from the system, all parport devices are iterated in parport_pc_exit and removed by a call to parport_pc_unregister_port. Note that some parport devices have its 'struct device' parent, known as port->dev. And when port->dev is a platform device, it is destroyed in parport_pc_exit too. Now, when parport_pc_unregister_port is called for a going port, drv->detach(port) is called for every parport driver in the system. ppdev can be one of them. ppdev's detach() tears down its per-port sysfs directory, which established port->dev as a parent earlier. But since parport_pc_exit kills port->dev parents before unregisters ports proper, ppdev's sysfs directory has no living parent anymore. This results in the following warning: WARNING: CPU: 1 PID: 785 at fs/sysfs/group.c:219 sysfs_remove_group+0x9b/0xa0 sysfs group ffffffff81c69e20 not found for kobject 'parport1' Modules linked in: parport_pc(E-) ppdev(E) [last unloaded: ppdev] CPU: 1 PID: 785 Comm: rmmod Tainted: G W E 3.18.0-rc5-next-20141120+ raspberrypi#824 ... Call Trace: ... [<ffffffff810aff76>] warn_slowpath_fmt+0x46/0x50 [<ffffffff8123d81b>] sysfs_remove_group+0x9b/0xa0 [<ffffffff814c27e7>] dpm_sysfs_remove+0x57/0x60 [<ffffffff814b6ac9>] device_del+0x49/0x240 [<ffffffff814b6ce2>] device_unregister+0x22/0x70 [<ffffffff814b6dac>] device_destroy+0x3c/0x50 [<ffffffffc012209a>] pp_detach+0x4a/0x60 [ppdev] [<ffffffff814b32dd>] parport_remove_port+0x11d/0x150 [<ffffffffc0137328>] parport_pc_unregister_port+0x28/0xf0 [parport_pc] [<ffffffffc0138c0e>] parport_pc_exit+0x76/0x468 [parport_pc] [<ffffffff81128dbc>] SyS_delete_module+0x18c/0x230 It is also easily reproducible on qemu with two dummy ports '-parallel /dev/null -parallel /dev/null'. So switch the order of killing the two structures. But since port is freed by parport_pc_unregister_port, we have to remember port->dev in a local variable. Perhaps nothing worse than the warning happens thanks to the device refcounting. We *should* be on the safe side. Signed-off-by: Jiri Slaby <[email protected]> Reviewed-by: Takashi Iwai <[email protected]> Tested-by: Martin Pluskal <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Jiri Slaby <[email protected]>
1 parent 6b5b362 commit 6779846

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

drivers/parport/parport_pc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,13 +3312,14 @@ static void __exit parport_pc_exit(void)
33123312
while (!list_empty(&ports_list)) {
33133313
struct parport_pc_private *priv;
33143314
struct parport *port;
3315+
struct device *dev;
33153316
priv = list_entry(ports_list.next,
33163317
struct parport_pc_private, list);
33173318
port = priv->port;
3318-
if (port->dev && port->dev->bus == &platform_bus_type)
3319-
platform_device_unregister(
3320-
to_platform_device(port->dev));
3319+
dev = port->dev;
33213320
parport_pc_unregister_port(port);
3321+
if (dev && dev->bus == &platform_bus_type)
3322+
platform_device_unregister(to_platform_device(dev));
33223323
}
33233324
}
33243325

0 commit comments

Comments
 (0)