Print this page
PVN_GETPAGE_{SZ,NUM} are misnamed and unnecessarily complicated
There is really no reason to not allow 8 pages all the time. With the
current logic, we get the following:
Assuming 4kB pages (x86):
_SZ = ptob(8) /* 32kB */
_NUM = 8
Assuming 8kB pages (sparc):
_SZ = ptob(8) /* 64kB */
_NUM = 8
We'd have to deal with 16kB base pages in order for the _NUM #define to not
be 8 (it'd be 4 in that case). So, in the spirit of simplicity, let's just
always grab 8 pages as there are no interesting systems with 16kB+ base pages.
Finally, the defines are poorly named.
*** 76,102 ****
#include <sys/zone.h>
#include <sys/shm_impl.h>
/*
* segvn_fault needs a temporary page list array. To avoid calling kmem all
! * the time, it creates a small (PVN_GETPAGE_NUM entry) array and uses it if
! * it can. In the rare case when this page list is not large enough, it
! * goes and gets a large enough array from kmem.
! *
! * This small page list array covers either 8 pages or 64kB worth of pages -
! * whichever is smaller.
*/
! #define PVN_MAX_GETPAGE_SZ 0x10000
! #define PVN_MAX_GETPAGE_NUM 0x8
!
! #if PVN_MAX_GETPAGE_SZ > PVN_MAX_GETPAGE_NUM * PAGESIZE
! #define PVN_GETPAGE_SZ ptob(PVN_MAX_GETPAGE_NUM)
! #define PVN_GETPAGE_NUM PVN_MAX_GETPAGE_NUM
! #else
! #define PVN_GETPAGE_SZ PVN_MAX_GETPAGE_SZ
! #define PVN_GETPAGE_NUM btop(PVN_MAX_GETPAGE_SZ)
! #endif
/*
* Private seg op routines.
*/
static int segvn_dup(struct seg *seg, struct seg *newseg);
--- 76,91 ----
#include <sys/zone.h>
#include <sys/shm_impl.h>
/*
* segvn_fault needs a temporary page list array. To avoid calling kmem all
! * the time, it creates a small (FAULT_TMP_PAGES_NUM entry) array and uses
! * it if it can. In the rare case when this page list is not large enough,
! * it goes and gets a large enough array from kmem.
*/
! #define FAULT_TMP_PAGES_NUM 0x8
! #define FAULT_TMP_PAGES_SZ ptob(FAULT_TMP_PAGES_NUM)
/*
* Private seg op routines.
*/
static int segvn_dup(struct seg *seg, struct seg *newseg);
*** 4923,4933 ****
u_offset_t off;
caddr_t a;
struct vpage *vpage;
uint_t vpprot, prot;
int err;
! page_t *pl[PVN_GETPAGE_NUM + 1];
size_t plsz, pl_alloc_sz;
size_t page;
ulong_t anon_index;
struct anon_map *amp;
int dogetpage = 0;
--- 4912,4922 ----
u_offset_t off;
caddr_t a;
struct vpage *vpage;
uint_t vpprot, prot;
int err;
! page_t *pl[FAULT_TMP_PAGES_NUM + 1];
size_t plsz, pl_alloc_sz;
size_t page;
ulong_t anon_index;
struct anon_map *amp;
int dogetpage = 0;
*** 5362,5372 ****
if (dogetpage) {
enum seg_rw arw;
struct as *as = seg->s_as;
! if (len > ptob((sizeof (pl) / sizeof (pl[0])) - 1)) {
/*
* Page list won't fit in local array,
* allocate one of the needed size.
*/
pl_alloc_sz =
--- 5351,5361 ----
if (dogetpage) {
enum seg_rw arw;
struct as *as = seg->s_as;
! if (len > FAULT_TMP_PAGES_SZ) {
/*
* Page list won't fit in local array,
* allocate one of the needed size.
*/
pl_alloc_sz =
*** 5390,5400 ****
} else {
/*
* Ask VOP_GETPAGE to return adjacent pages
* within the segment.
*/
! plsz = MIN((size_t)PVN_GETPAGE_SZ, (size_t)
((seg->s_base + seg->s_size) - addr));
ASSERT((addr + plsz) <=
(seg->s_base + seg->s_size));
}
--- 5379,5389 ----
} else {
/*
* Ask VOP_GETPAGE to return adjacent pages
* within the segment.
*/
! plsz = MIN((size_t)FAULT_TMP_PAGES_SZ, (size_t)
((seg->s_base + seg->s_size) - addr));
ASSERT((addr + plsz) <=
(seg->s_base + seg->s_size));
}