From owner-freebsd-current@freebsd.org Sat Jun 4 17:51:13 2016 Return-Path: Delivered-To: freebsd-current@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D47C1B6A99D for ; Sat, 4 Jun 2016 17:51:13 +0000 (UTC) (envelope-from mmacy@nextbsd.org) Received: from sender163-mail.zoho.com (sender163-mail.zoho.com [74.201.84.163]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C40101DEB; Sat, 4 Jun 2016 17:51:13 +0000 (UTC) (envelope-from mmacy@nextbsd.org) Received: from mail.zoho.com by mx.zohomail.com with SMTP id 146506266813942.65633986838202; Sat, 4 Jun 2016 10:51:08 -0700 (PDT) Date: Sat, 04 Jun 2016 10:51:08 -0700 From: Matthew Macy To: "Konstantin Belousov" Cc: "Michael Butler" , "freebsd-current@freebsd.org" , "" Message-ID: <1551c8a3732.cbde57d0124455.2726151520830111171@nextbsd.org> In-Reply-To: <20160604174745.GB38613@kib.kiev.ua> References: <2490f1c7-8153-ece3-49ed-4b3886564fd7@protected-networks.net> <205d4423-b834-9a21-785f-fa15d44c78ec@protected-networks.net> <1551419a1db.12929035f45012.326107747932338888@nextbsd.org> <939f9d2b-e925-e8e0-0ff3-8d90623728c6@protected-networks.net> <1551c5dbd86.c68532b5123717.566503881838650848@nextbsd.org> <20160604174745.GB38613@kib.kiev.ua> Subject: Re: repeatable panic on pageout with 945GM MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Priority: Medium User-Agent: Zoho Mail X-Mailer: Zoho Mail X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Jun 2016 17:51:13 -0000 > > I believe that this is a bug in amd64 pmap. Fictitious pages are not > promoted, in particular, the pv_table array does not span over the > dynamically registered fictitious ranges. As result, pa_to_pvh() returns > garbage and pvh must not be accessed in the case of 'small_mappings' in > several pmap functions. It is typically not accessed, except in case > when we have to drop and reacquire pv lock, to avoid LOR with pmap. Cool. Thanks for explaining that. -M > i386 does not have the issue, due to pvh_global_lock. > > Below is the supposed fix (not tested). > > diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c > index 7a93e76..e514b07 100644 > --- a/sys/amd64/amd64/pmap.c > +++ b/sys/amd64/amd64/pmap.c > @@ -3947,12 +3947,14 @@ small_mappings: > while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > rw_wunlock(lock); > PMAP_UNLOCK(pmap); > goto retry; > @@ -5775,13 +5777,14 @@ small_mappings: > TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || > - md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > rw_wunlock(lock); > goto retry_pv_loop; > @@ -5985,12 +5988,14 @@ small_mappings: > pvf = pv; > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > md_gen = m->md.pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > goto retry; > } > @@ -6248,11 +6253,13 @@ small_mappings: > pmap = PV_PMAP(pv); > if (!PMAP_TRYLOCK(pmap)) { > md_gen = m->md.pv_gen; > - pvh_gen = pvh->pv_gen; > + if ((m->flags & PG_FICTITIOUS) == 0) > + pvh_gen = pvh->pv_gen; > rw_wunlock(lock); > PMAP_LOCK(pmap); > rw_wlock(lock); > - if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { > + if (((m->flags & PG_FICTITIOUS) == 0 && > + pvh_gen != pvh->pv_gen) || md_gen != m->md.pv_gen) { > PMAP_UNLOCK(pmap); > goto restart; > } >