tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: memcpy of struct buf, or similar?



On Sat, Jun 07, 2008 at 10:18:22PM +0100, Andrew Doran wrote:

> Does anyone know a point in the file system code, or ATA code, where outside
> of vfs_bio.c we issue memcpy() on a buffer, assign to it or copy it another
> way, or clear any part of it with memset()?
> 
> I am trying to fix PR 38761. Threads get stuck in biowait. The buffer always
> has DONE set on it and has a waiter, but the waiter is stuck on the condvar.
> It's on the sleep queue and it looks like no attempt has been made to wake
> it up. The last time I saw this was in the tty code, and something was doing
> memcpy() on clists.

I made biowait look like this:

int
biowait(buf_t *bp)
{

        KASSERT(ISSET(bp->b_cflags, BC_BUSY));
        KASSERT(bp->b_refcnt > 0);

        mutex_enter(bp->b_objlock);
        bp->b_oflags |= 0x80000000;
        while (!ISSET(bp->b_oflags, BO_DONE | BO_DELWRI))
                cv_wait(&bp->b_done, bp->b_objlock);
        bp->b_oflags &= ~0x80000000;
        mutex_exit(bp->b_objlock);

        return bp->b_error;
}

And changed the sync I/O case in biodone2 to do this:

        } else {
                /* Otherwise just wake up waiters in biowait(). */
                if ((bp->b_oflags & 0x80000000) != 0)
                        KASSERT(cv_has_waiters(&bp->b_done));
                cv_broadcast(&bp->b_done);
                mutex_exit(bp->b_objlock);
        }

And the assertion fires. So there is a waiter on the buffer, but it looks
like something has clobbered the condition variable. biodone2() is being
called from a soft interrupt so biodone() must have been called from
interrupt context.

Andrew


Home | Main Index | Thread Index | Old Index