From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Sat, 1 Mar 2014 23:05:19 -0500 To: 9fans@9fans.net Message-ID: <0b927c978635da089774a72c0af3de19@mikro.quanstro.net> In-Reply-To: <122a1b862278abf61a07a806168993ac@felloff.net> References: <122a1b862278abf61a07a806168993ac@felloff.net> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] imagereclaim() Topicbox-Message-UUID: c0c6d288-ead8-11e9-9d60-3106f5b1d025 On Sat Mar 1 22:56:25 EST 2014, cinap_lenrek@felloff.net wrote: > checked nix/port/page.c. your duppage() is wrong. > > /* don't dup pages with no image */ > if(p->ref == 0 || p->image == nil || p->image->notext) > return 0; > > /* > * normal lock ordering is to call > * lock(&pga) before lock(p). > * To avoid deadlock, we have to drop > * our locks and try again. > */ > if(!canlock(&pga)){ > unlock(p); > if(up) > sched(); > lock(p); > goto retry; > } > > you need to check p->ref != 1 instead of p->ref == 0. the page > passed to duppage() is still cached. after you unlock(p), someone > can come in and take a reference to the page from the image > cache (lookpage()), making p->ref > 1 once you get the lock back. > > put an assert or print in there after the if(!canlock(&pga){} block > to check p->ref. why do i need an assert or print after the unlock? it should go back through the loop and notice p->ref != 1. - erik