Page MenuHomeFreeBSD

D22731.id65397.diff
No OneTemporary

D22731.id65397.diff

Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -974,9 +974,9 @@
int
exec_map_first_page(struct image_params *imgp)
{
- int rv, i, after, initial_pagein;
- vm_page_t ma[VM_INITIAL_PAGEIN];
vm_object_t object;
+ vm_page_t m;
+ int error;
if (imgp->firstpage != NULL)
exec_unmap_first_page(imgp);
@@ -988,70 +988,14 @@
#if VM_NRESERVLEVEL > 0
vm_object_color(object, 0);
#endif
-retry:
- ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY |
- VM_ALLOC_WIRED);
- if (!vm_page_all_valid(ma[0])) {
- if (vm_page_busy_acquire(ma[0], VM_ALLOC_WAITFAIL) == 0) {
- vm_page_unwire_noq(ma[0]);
- goto retry;
- }
- if (vm_page_all_valid(ma[0])) {
- vm_page_xunbusy(ma[0]);
- goto out;
- }
- if (!vm_pager_has_page(object, 0, NULL, &after)) {
- if (vm_page_unwire_noq(ma[0]))
- vm_page_free(ma[0]);
- else
- vm_page_xunbusy(ma[0]);
- VM_OBJECT_WUNLOCK(object);
- return (EIO);
- }
- initial_pagein = min(after, VM_INITIAL_PAGEIN);
- KASSERT(initial_pagein <= object->size,
- ("%s: initial_pagein %d object->size %ju",
- __func__, initial_pagein, (uintmax_t )object->size));
- for (i = 1; i < initial_pagein; i++) {
- if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) {
- if (ma[i]->valid)
- break;
- if (!vm_page_tryxbusy(ma[i]))
- break;
- } else {
- ma[i] = vm_page_alloc(object, i,
- VM_ALLOC_NORMAL);
- if (ma[i] == NULL)
- break;
- }
- }
- initial_pagein = i;
- VM_OBJECT_WUNLOCK(object);
- rv = vm_pager_get_pages(object, ma, initial_pagein, NULL, NULL);
- VM_OBJECT_WLOCK(object);
- if (rv != VM_PAGER_OK) {
- if (vm_page_unwire_noq(ma[0]))
- vm_page_free(ma[0]);
- else
- vm_page_xunbusy(ma[0]);
- for (i = 1; i < initial_pagein; i++) {
- if (!vm_page_wired(ma[i]))
- vm_page_free(ma[i]);
- else
- vm_page_xunbusy(ma[i]);
- }
- VM_OBJECT_WUNLOCK(object);
- return (EIO);
- }
- vm_page_xunbusy(ma[0]);
- for (i = 1; i < initial_pagein; i++)
- vm_page_readahead_finish(ma[i]);
- }
-
-out:
+ error = vm_page_grab_valid(&m, object, 0,
+ VM_ALLOC_COUNT(VM_INITIAL_PAGEIN) |
+ VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED);
VM_OBJECT_WUNLOCK(object);
- imgp->firstpage = sf_buf_alloc(ma[0], 0);
+ if (error != 0)
+ return (EIO);
+ imgp->firstpage = sf_buf_alloc(m, 0);
imgp->image_header = (char *)sf_buf_kva(imgp->firstpage);
return (0);
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ sys/vm/vm_page.c
@@ -4337,15 +4337,17 @@
/*
* Grab a page and make it valid, paging in if necessary. Pages missing from
- * their pager are zero filled and validated.
+ * their pager are zero filled and validated. If a VM_ALLOC_COUNT is supplied
+ * and the page is not valid as many as VM_INITIAL_PAGEIN pages can be brought
+ * in simultaneously.
*/
int
vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, int allocflags)
{
vm_page_t m;
+ vm_page_t ma[VM_INITIAL_PAGEIN];
bool sleep, xbusy;
- int pflags;
- int rv;
+ int after, i, pflags, rv;
KASSERT((allocflags & VM_ALLOC_SBUSY) == 0 ||
(allocflags & VM_ALLOC_IGN_SBUSY) != 0,
@@ -4404,17 +4406,42 @@
vm_page_assert_xbusied(m);
MPASS(xbusy);
- if (vm_pager_has_page(object, pindex, NULL, NULL)) {
+ if (vm_pager_has_page(object, pindex, NULL, &after)) {
+ after = MIN(after, VM_INITIAL_PAGEIN);
+ after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT);
+ after = MAX(after, 1);
+ ma[0] = m;
+ for (i = 1; i < after; i++) {
+ if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) {
+ if (ma[i]->valid || !vm_page_tryxbusy(ma[i]))
+ break;
+ } else {
+ ma[i] = vm_page_alloc(object, m->pindex + i,
+ VM_ALLOC_NORMAL);
+ if (ma[i] == NULL)
+ break;
+ }
+ }
+ after = i;
VM_OBJECT_WUNLOCK(object);
- rv = vm_pager_get_pages(object, &m, 1, NULL, NULL);
+ rv = vm_pager_get_pages(object, ma, after, NULL, NULL);
VM_OBJECT_WLOCK(object);
+ /* Pager may have replaced a page. */
+ m = ma[0];
if (rv != VM_PAGER_OK) {
- if (allocflags & VM_ALLOC_WIRED)
+ if ((allocflags & VM_ALLOC_WIRED) != 0)
vm_page_unwire_noq(m);
- vm_page_free(m);
+ for (i = 0; i < after; i++) {
+ if (!vm_page_wired(ma[i]))
+ vm_page_free(ma[i]);
+ else
+ vm_page_xunbusy(ma[i]);
+ }
*mp = NULL;
return (rv);
}
+ for (i = 1; i < after; i++)
+ vm_page_readahead_finish(ma[i]);
MPASS(vm_page_all_valid(m));
} else {
vm_page_zero_invalid(m, TRUE);

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 25, 7:24 PM (39 m, 49 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35485440
Default Alt Text
D22731.id65397.diff (4 KB)

Event Timeline