• Ian Abbott's avatar
    staging: comedi: fix bug destroying subdevice files after parent · 52ef9e7c
    Ian Abbott authored
    `comedi_free_board_dev()` is called (via `comedi_auto_unconfig()` -->
    `comedi_release_hardware_device()`) when an auto-configured comedi
    device is removed.  This destroys the main sysfs class device and then
    calls `comedi_device_cleanup()` to clean up the comedi device.  For
    comedi devices that have comedi subdevices that asynchronous commands,
    the clean up involves destroying the sysfs class devices associated with
    those subdevices.
    
    There is a bug in the above sequence because the sysfs class devices
    associated with the comedi subdevices are children of the sysfs class
    device associated with the main comedi device.  Therefore they will have
    been automatically destroyed when the main sysfs class device is
    destroyed.  When they are destroyed again as part of the clean-up, they
    will not be found, leading to a warning and a stack trace similar to
    this:
    
    ------------[ cut here ]------------
    WARNING: CPU: 1 PID: 1213 at fs/sysfs/group.c:214
    sysfs_remove_group+0x4e/0xa7()
    sysfs group ffffffff817504c0 not found for kobject 'comedi4_subd0'
    Modules linked in: nfsd auth_rpcgss oid_registry exportfs nfs_acl lockd
    bridge stp llc sunrpc fuse binfmt_misc cpufreq_userspace sr_mod
    snd_hda_codec_analog cdrom powernow_k8 kvm_amd kvm amplc_pci230(C)
    8255(C) comedi(C) pcmcia xhci_hcd ehci_pci pcmcia_core ohci_pci ohci_hcd
    ehci_hcd usbcore snd_hda_intel snd_hda_codec snd_pcm k8temp
    snd_page_alloc 8139too snd_timer snd soundcore mii usb_common forcedeth
    pata_amd
    CPU: 1 PID: 1213 Comm: kworker/u4:6 Tainted: G         C
    3.13.0-rc5-ija1+ #20
    Hardware name: System manufacturer System Product Name/M2N-E, BIOS ASUS
    M2N-E ACPI BIOS Revision 5001 03/23/2010
    Workqueue: sysfsd sysfs_schedule_callback_work
     0000000000000000 ffff8800bf17fb38 ffffffff814672ce ffff8800bf17fb80
     ffff8800bf17fb70 ffffffff8103470b ffffffff8114f780 0000000000000000
     ffffffff817504c0 ffff8800bf39f410 ffff880139b68670 ffff8800bf17fbd0
    Call Trace:
     [<ffffffff814672ce>] dump_stack+0x45/0x56
     [<ffffffff8103470b>] warn_slowpath_common+0x7a/0x93
     [<ffffffff8114f780>] ? sysfs_remove_group+0x4e/0xa7
     [<ffffffff8103476b>] warn_slowpath_fmt+0x47/0x49
     [<ffffffff8114e92d>] ? sysfs_get_dirent_ns+0x5e/0x66
     [<ffffffff8114f780>] sysfs_remove_group+0x4e/0xa7
     [<ffffffff8132aac0>] dpm_sysfs_remove+0x37/0x3b
     [<ffffffff81323781>] device_del+0x3e/0x173
     [<ffffffff813238c3>] device_unregister+0xd/0x18
     [<ffffffff8132392e>] device_destroy+0x33/0x37
     [<ffffffffa0212086>] comedi_free_subdevice_minor+0x80/0x92 [comedi]
     [<ffffffffa02128bb>] comedi_device_detach+0x79/0x152 [comedi]
     [<ffffffffa020f223>] comedi_device_cleanup+0x36/0x57 [comedi]
     [<ffffffffa020f275>] comedi_free_board_dev+0x31/0x3c [comedi]
     [<ffffffffa0211f2a>] comedi_release_hardware_device+0x5a/0x73 [comedi]
     [<ffffffffa0212547>] comedi_auto_unconfig+0xe/0x10 [comedi]
     [<ffffffffa021357c>] comedi_pci_auto_unconfig+0x10/0x12 [comedi]
     [<ffffffff811d2335>] pci_device_remove+0x40/0x8a
     [<ffffffff813261d0>] __device_release_driver+0x84/0xda
     [<ffffffff81326244>] device_release_driver+0x1e/0x2b
     [<ffffffff811cdcb5>] pci_stop_bus_device+0x44/0x87
     [<ffffffff811cdde2>] pci_stop_and_remove_bus_device+0xd/0x18
     [<ffffffff811d3f3d>] remove_callback+0x20/0x2f
     [<ffffffff8114d1f7>] sysfs_schedule_callback_work+0xf/0x70
     [<ffffffff81049498>] process_one_work+0x1d6/0x34c
     [<ffffffff81049a5f>] worker_thread+0x1cf/0x2b5
     [<ffffffff81049890>] ? rescuer_thread+0x258/0x258
     [<ffffffff8104e0e6>] kthread+0xd6/0xde
     [<ffffffff8104e010>] ? kthread_create_on_node+0x160/0x160
     [<ffffffff81472cbc>] ret_from_fork+0x7c/0xb0
     [<ffffffff8104e010>] ? kthread_create_on_node+0x160/0x160
    ---[ end trace 94722aa2936a7adf ]---
    
    To correct the bug, rearrange `comedi_free_board_dev()` to destroy the
    main sysfs class device *after* the clean-up operation.
    
    Thanks to Bernd Porr for finding the bug and his initial attempt to fix
    it.
    Reported-by: default avatarBernd Porr <mail@berndporr.me.uk>
    Signed-off-by: default avatarIan Abbott <abbotti@mev.co.uk>
    Cc: Bernd Porr <mail@berndporr.me.uk>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    52ef9e7c
comedi_fops.c 59.6 KB