Skip site navigation (1)Skip section navigation (2)
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>