Date: Sat, 04 Jun 2016 10:51:08 -0700 From: Matthew Macy <mmacy@nextbsd.org> To: "Konstantin Belousov" <kostikbel@gmail.com> Cc: "Michael Butler" <imb@protected-networks.net>, "freebsd-current@freebsd.org" <freebsd-current@freebsd.org>, "<alc@freebsd.org>" <alc@freebsd.org> Subject: Re: repeatable panic on pageout with 945GM Message-ID: <1551c8a3732.cbde57d0124455.2726151520830111171@nextbsd.org> In-Reply-To: <20160604174745.GB38613@kib.kiev.ua> References: <2490f1c7-8153-ece3-49ed-4b3886564fd7@protected-networks.net> <da19738b-6bf1-10a3-4428-43b6095ec35a@protected-networks.net> <205d4423-b834-9a21-785f-fa15d44c78ec@protected-networks.net> <CAHM0Q_PR5Aoak6A7f=tsRy0DJFCmLDVfRGpceZ0mXU3P%2BxO8DA@mail.gmail.com> <1551419a1db.12929035f45012.326107747932338888@nextbsd.org> <939f9d2b-e925-e8e0-0ff3-8d90623728c6@protected-networks.net> <1551c5dbd86.c68532b5123717.566503881838650848@nextbsd.org> <20160604174745.GB38613@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
> > 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; > } >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1551c8a3732.cbde57d0124455.2726151520830111171>