* David Brownell | 2008-05-02 12:58:06 [-0700]: >On Friday 02 May 2008, Sebastian Siewior wrote: >> >That memory is freed only by spidev_classdev_release(), so >> >it looks like this particular issue is a refcounting bug. >> >I'll look at it later (unless you make time for it first). >> >> I try what I can do tomorrow but I probably can't before sunday. > >Looks to me like the refcounting on spidev->users is insufficient. >That covers the buffer. Separately, each open and each release >should probably update the refcount on spidev->dev itself.
Yep, spidev->users protects only spidev->buffer while the spidev struct is unprotected. Here an example: I remove my spi device driver (the pointer is the address of my spidev struct): | Removing: df159460 | ------------[ cut here ]------------ | Badness at /home/bigeasy/git/linux-2.6-powerpc/drivers/spi/spidev.c:617 | NIP: c01b4518 LR: c01b4518 CTR: 00000000 | REGS: df1f9c40 TRAP: 0700 Not tainted (2.6.25) | MSR: 00029000 <EE,ME> CR: 28000488 XER: 20000000 | TASK = df894000[2155] 'rmmod' THREAD: df1f8000 | GPR00: c01b4518 df1f9cf0 df894000 00000025 bbbbbbbb 00000004 df395bcc c0be52a0 | GPR08: 00000000 00000000 00000040 df1f8000 00000000 1001a2a8 28004422 00000000 | GPR16: 100e9fa8 100d0000 100b0000 100d0000 00000000 100b0000 10013008 00000000 | GPR24: bf8082f0 00000000 e1065158 df159690 df159460 df159690 c037bc54 df159690 | NIP [c01b4518] spidev_remove+0x28/0xcc | LR [c01b4518] spidev_remove+0x28/0xcc | Call Trace: | [df1f9cf0] [c01b4518] spidev_remove+0x28/0xcc (unreliable) | [df1f9d10] [c01b433c] spi_drv_remove+0x2c/0x3c | [df1f9d20] [c0185f08] __device_release_driver+0x88/0xb4 | [df1f9d30] [c0186024] device_release_driver+0x28/0x44 | [df1f9d50] [c0185208] bus_remove_device+0x8c/0xb8 | [df1f9d70] [c018389c] device_del+0xf8/0x16c | [df1f9d90] [c0183928] device_unregister+0x18/0x30 | [df1f9db0] [c01b3d38] __unregister+0x20/0x34 | [df1f9dc0] [c01830dc] device_for_each_child+0x30/0x74 | [df1f9df0] [c01b3cfc] spi_unregister_master+0x28/0x44 | [df1f9e10] [e10641ac] fpga_spi_of_remove+0x48/0xb0 [fpga_spi] | [df1f9e30] [c01e27fc] of_platform_device_remove+0x30/0x44 | [df1f9e40] [c0185f08] __device_release_driver+0x88/0xb4 | [df1f9e50] [c0185fd4] driver_detach+0xa0/0xc8 | [df1f9e70] [c018509c] bus_remove_driver+0x98/0xd4 | [df1f9e90] [c01864f8] driver_unregister+0x48/0x5c | [df1f9eb0] [c01e2908] of_unregister_driver+0x14/0x24 | [df1f9ec0] [e1064c04] fpga_spi_exit+0x18/0x28 [fpga_spi] | [df1f9ed0] [c004c38c] sys_delete_module+0x1b4/0x204 | [df1f9f40] [c000ded8] ret_from_syscall+0x0/0x3c | Instruction dump: | 7c0803a6 4e800020 9421ffe0 7c0802a6 bf410008 7c7b1b78 90010024 8383010c | 3c60c031 3863a4d8 7f84e378 4be720fd <0fe00000> 3bbc0178 7fa3eb78 3b400000 Now, I use my userspace program to do an ioctl: | Touching: df159460 | BUG: spinlock bad magic on CPU#0, spidev_test/2153 | Unable to handle kernel paging request for data at address 0x6b6b6d5f | Faulting instruction address: 0xc0142d74 | PREEMPT | Modules linked in: bluetooth libertas [last unloaded: fg | REGS: df2efd50 TRAP: 0300 Not tainted (2.6.25) | MSR: 00021000 <ME> CR: 22000424 XER: 20000000 | TASK = df895840[2153] 'spidev_test' THREAD: df2ee000 | GPR00: c0142d5c df2efe00 df895840 00000045 00000001 6b6b6b6b c02e64e4 ffffffff | GPR08: 00000000 c02e0000 00005634 df2ee000 ffffe3c0 10019ad4 28004422 00000000 | GPR16: 100e9ac8 100d0000 100b0000 100d0000 00000000 100b0000 100e9948 100e9be8 | GPR24: 00000000 100e0008 df159460 80206b00 00000004 c02fa3f8 df1595d8 6b6b6b6b | NIP [c0142d74] spin_bug+0x6c/0xd0 | LR [c0142d5c] spin_bug+0x54/0xd0 | Call Trace: | [df2efe00] [c0142d5c] spin_bug+0x54/0xd0 (unreliable) | [df2efe20] [c0142f18] _raw_spin_lock+0x34/0x118 | [df2efe40] [c025e50c] _spin_lock_irq+0x24/0x34 | [df2efe50] [c01b4d50] spidev_ioctl+0xac/0x748 | [df2efec0] [c00861c0] vfs_ioctl+0x88/0xa8 | [df2efee0] [c00865e0] do_vfs_ioctl+0x400/0x444 | [df2eff10] [c0086664] sys_ioctl+0x40/0x70 | [df2eff40] [c000ded8] ret_from_syscall+0x0/0x3c | Instruction dump: | 386aa41c 38c20304 38a00000 419d0048 80e201f4 4bee38b9 2f9f0000 3d20c02e | 80be0004 38c964e4 38e0ffff 419e000c <80ff01f4> 38df0304 811e0008 3c60c030 | ---[ end trace 4ccbf52b28cfbf39 ]--- "Touching" is just before the spinlock. So, spidev is all gone while userspace has still an open handle. Now, what do recommend? Solving this by refcounting in spidev_remove() or spi_drv_remove()? > >- dave Sebastian ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ spi-devel-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/spi-devel-general
