tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: vmpage race and deadlock
On Sun, Nov 28, 2010 at 09:03:30AM +0000, Mindaugas Rasiukevicius wrote:
> Juergen Hannken-Illjes <hannken%eis.cs.tu-bs.de@localhost> wrote:
> > Some weeks ago I started my fs stress test (5 x fsstress+fsx+dbench)
> > on a log enabled ffs1 file system backed by md(4).
> >
> > Usually within hours I get a deadlock where a thread is waiting on
> > "genput" but the page in question is neither BUSY nor WANTED. I suppose
> > I tracked (*1) it down to three places, where we change page flags
> > without holding the object lock. With this diff (*2) in place the test
> > runs for > 48 hours.
>
> Cool!
Indeed.
(It's a shame I couldn't find this while working on genfs.)
>
> > Using atomic ops here is not possible as flags is a 16bit value.
> >
>
> You cannot use them at one place; in such case all uses i.e. protocol
> would need to be converted to atomic ops.
Wrapping pg->flags manipulation with accessor macros would help
migration.
>
> > @@ -637,8 +639,9 @@ loopdone:
> > npages << PAGE_SHIFT, 0, cred);
> > UVMHIST_LOG(ubchist, "gop_alloc off 0x%x/0x%x -> %d",
> > startoffset, npages << PAGE_SHIFT, error,0);
> > if (!error) {
> > + mutex_enter(&uobj->vmobjlock);
> > for (i = 0; i < npages; i++) {
> > struct vm_page *pg = pgs[i];
> >
> > if (pg == NULL) {
> > @@ -647,8 +650,9 @@ loopdone:
> > pg->flags &= ~(PG_CLEAN|PG_RDONLY);
> > UVMHIST_LOG(ubchist, "mark dirty pg %p",
> > pg,0,0,0);
> > }
> > + mutex_exit(&uobj->vmobjlock);
> > }
> > }
> > if (!glocked) {
> > genfs_node_unlock(vp);
>
> I think this loop can actually be moved after mutex_enter(&uobj->vmobjlock)
> at line 660 (with condition check, of course).
We can abuse lower bits of struct vm_page * pointers, to remember
while slots are holes.
Home |
Main Index |
Thread Index |
Old Index