On Friday 02 May 2008, Sebastian Siewior wrote:

> >> No, I mean that the issue is most likely a spidev bug.
> >
> > Does the appended patch resolve the problem you observed?
> 
> Nope. The backtrace:

... shows *new and different* behavior -- right? 

 
> Sending SPI_IOC_[    4.294967] ------------[ cut here ]------------
> [    4.294967] Badness at 
> /home/bigeasy/git/linux-2.6-powerpc/kernel/mutex.c:134
>                       ...
> [    4.294967] Call Trace:
> [    4.294967] [df273e10] [00000001] 0x1 (unreliable)
> [    4.294967] [df273e50] [c01b5148] spidev_ioctl+0x4c8/0x6ec
> [    4.294967] [df273ec0] [c00861c0] vfs_ioctl+0x88/0xa8
> [    4.294967] [df273ee0] [c00865e0] do_vfs_ioctl+0x400/0x444
> [    4.294967] [df273f10] [c0086664] sys_ioctl+0x40/0x70
> [    4.294967] [df273f40] [c000ded8] ret_from_syscall+0x0/0x3c
>                       ... 
> [    4.294967] Unable to handle kernel paging request for data at address 
> 0x6b6b6b6b
> 
> I started my spidev user, removed the module and then I started to write
> what results in an ioctl. spidev_ioctl+0x4c8/0x6ec is
> drivers/spi/spidev.c:228 and that is the first mutex_lock() in
> spidev_message().

Hmm, now it's referencing freed memory:  0x6b6b6b6b means it
used a pointer and got memory filled with POISON_FREE.  With
the particular memory dedicated to managing the spidev state.

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).


> However you are touching spidev->spi and this is gone isn't it?

The appended update should catch a few spidev_ioctl() references
which the initial patch overlooked ... it goes on top of the patch
I sent first time.

But such a reference *COULD NOT* cause references to a mutex
in memory which has been deleted.

- Dave


--- g26.orig/drivers/spi/spidev.c       2008-05-02 10:16:04.000000000 -0700
+++ g26/drivers/spi/spidev.c    2008-05-02 10:14:39.000000000 -0700
@@ -326,8 +326,16 @@ spidev_ioctl(struct inode *inode, struct
        if (err)
                return -EFAULT;
 
+       /* guard against device removal before, or while,
+        * we issue this ioctl.
+        */
        spidev = filp->private_data;
-       spi = spidev->spi;
+       spin_lock_irq(&spidev->spi_lock);
+       spi = spi_dev_get(spidev->spi);
+       spin_unlock_irq(&spidev->spi_lock);
+
+       if (spi == NULL)
+               return ESHUTDOWN;
 
        switch (cmd) {
        /* read requests */
@@ -413,8 +421,10 @@ spidev_ioctl(struct inode *inode, struct
        default:
                /* segmented and/or full-duplex I/O request */
                if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
-                               || _IOC_DIR(cmd) != _IOC_WRITE)
-                       return -ENOTTY;
+                               || _IOC_DIR(cmd) != _IOC_WRITE) {
+                       retval = -ENOTTY;
+                       break;
+               }
 
                tmp = _IOC_SIZE(cmd);
                if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
@@ -442,6 +452,7 @@ spidev_ioctl(struct inode *inode, struct
                kfree(ioc);
                break;
        }
+       spi_dev_put(spi);
        return retval;
 }
 


-------------------------------------------------------------------------
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

Reply via email to