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)); }