[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnumach] 01/03: New upstream version 1.7+git20161202
From: |
Samuel Thibault |
Subject: |
[gnumach] 01/03: New upstream version 1.7+git20161202 |
Date: |
Fri, 02 Dec 2016 11:07:19 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository gnumach.
commit edd25941056a7cf231cca23020f7342085bfaf30
Author: Samuel Thibault <address@hidden>
Date: Fri Dec 2 10:58:26 2016 +0000
New upstream version 1.7+git20161202
---
ChangeLog | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure | 20 +++++++-------
doc/mach.info | 2 +-
doc/mach.info-1 | 4 +--
doc/mach.info-2 | 2 +-
doc/stamp-vti | 4 +--
doc/version.texi | 4 +--
ipc/ipc_kmsg.c | 2 ++
version.m4 | 2 +-
vm/vm_map.c | 2 +-
vm/vm_page.c | 65 ++++++++++++++--------------------------------
vm/vm_page.h | 3 ++-
vm/vm_pageout.c | 30 +++++++++++++++++----
vm/vm_resident.c | 23 +++++++++--------
14 files changed, 159 insertions(+), 83 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f8f10ff..f8397b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,82 @@
+2032-05-12 Richard Braun <address@hidden>
+
+ VM: fix pageout throttling to external pagers
+ Since the VM system has been tracking whether pages belong to internal
+ or external objects, pageout throttling to external pagers has simply
+ not been working. The reason is that, on pageout, requests for external
+ pages are correctly tracked, but on page release (which is used to
+ acknowledge the request), external pages are not marked external
+ any more. This is because the external bit tracks whether a page
+ belongs to an external object, and all pages, including external
+ ones, are moved to an internal object during pageout.
+
+ To solve this issue, a new "external_laundry" bit is added. It has
+ the same purpose as the laundry bit, but for external pagers.
+
+ * vm/vm_page.c (vm_page_seg_min_page_available): Function unused,
remove.
+ (vm_page_seg_evict): Use vm_page_external_laundry_count instead of
+ vm_page_external_pagedout. Add an assertion about double paging.
+ (vm_page_check_usable): Use vm_page_external_laundry_count instead of
+ vm_page_external_pagedout.
+ (vm_page_evict): Likewise.
+ * vm/vm_page.h (struct vm_page): New `external_laundry' member.
+ (vm_page_external_pagedout): Rename to ...
+ (vm_page_external_laundry_count): ... this.
+ * vm/vm_pageout.c: Include kern/printf.h.
+ (DEBUG): New macro.
+ (VM_PAGEOUT_TIMEOUT): Likewise.
+ (vm_pageout_setup): Use vm_page_external_laundry_count instead of
+ vm_page_external_pagedout. Set `external_laundry' where appropriate.
+ (vm_pageout): Use VM_PAGEOUT_TIMEOUT with thread_set_timeout.
+ Add debugging code, commented out by default.
+ * vm/vm_resident.c (vm_page_external_pagedout): Rename to ...
+ (vm_page_external_laundry_count): ... this.
+ (vm_page_init_template): Set `external_laundry' member to FALSE.
+ (vm_page_release): Rename external parameter to external_laundry.
+ Slightly change pageout resuming.
+ (vm_page_free): Rename external variable to external_laundry.
+
+2016-11-30 Richard Braun <address@hidden>
+
+ VM: fix pageout on low memory
+ Instead of determining if memory is low, directly use the
+ vm_page_alloc_paused variable, which is true when memory has reached
+ a minimum threshold until it gets back above the high thresholds.
+
+ This makes sure double paging is used when external pagers are unable
+ to allocate memory.
+
+ * vm/vm_page.c (vm_page_seg_evict): Rename low_memory to alloc_paused.
+ (vm_page_evict_once): Remove low_memory and its computation. Blindly
+ pass the new alloc_paused argument instead.
+ (vm_page_evict): Pass the value of vm_page_alloc_paused to
+ vm_page_evict_once.
+
+2016-11-30 Richard Braun <address@hidden>
+
+ VM: fix eviction logic error
+ * vm/vm_page.c (vm_page_evict): Test both vm_page_external_pagedout
+ and vm_page_laundry_count in order to determine there was "no pageout".
+
+2016-11-30 Richard Braun <address@hidden>
+
+ VM: fix pageout stop condition
+ When checking whether to continue paging out or not, the pageout daemon
+ only considers the high free page threshold of a segment. But if e.g.
+ the default pager had to allocate reserved pages during a previous
+ pageout cycle, it could have exhausted a segment (this is currently
+ only seen with the DMA segment). In that case, the high threshold
+ cannot be reached because the segment has currently no pageable page.
+
+ This change makes the pageout daemon identify this condition and
+ consider the segment as usable in order to make progress. The segment
+ will simply be ignored on the allocation path for unprivileged threads,
+ and if this happens with too many segments, the system will fail at
+ allocation time.
+
+ * vm/vm_page.c (vm_page_seg_usable): Report usable if the segment has
+ no pageable page.
+
2016-11-10 Brent Baccala <address@hidden>
gsync: Avoid NULL pointer dereference
diff --git a/configure b/configure
index 31ac702..e7a4219 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for GNU Mach 1.7+git20161115.
+# Generated by GNU Autoconf 2.69 for GNU Mach 1.7+git20161202.
#
# Report bugs to <address@hidden>.
#
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='GNU Mach'
PACKAGE_TARNAME='gnumach'
-PACKAGE_VERSION='1.7+git20161115'
-PACKAGE_STRING='GNU Mach 1.7+git20161115'
+PACKAGE_VERSION='1.7+git20161202'
+PACKAGE_STRING='GNU Mach 1.7+git20161202'
PACKAGE_BUGREPORT='address@hidden'
PACKAGE_URL=''
@@ -1599,7 +1599,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures GNU Mach 1.7+git20161115 to adapt to many kinds of
systems.
+\`configure' configures GNU Mach 1.7+git20161202 to adapt to many kinds of
systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1670,7 +1670,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of GNU Mach 1.7+git20161115:";;
+ short | recursive ) echo "Configuration of GNU Mach 1.7+git20161202:";;
esac
cat <<\_ACEOF
@@ -2026,7 +2026,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-GNU Mach configure 1.7+git20161115
+GNU Mach configure 1.7+git20161202
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2118,7 +2118,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by GNU Mach $as_me 1.7+git20161115, which was
+It was created by GNU Mach $as_me 1.7+git20161202, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2984,7 +2984,7 @@ fi
# Define the identity of the package.
PACKAGE='gnumach'
- VERSION='1.7+git20161115'
+ VERSION='1.7+git20161202'
# Some tools Automake needs.
@@ -12189,7 +12189,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by GNU Mach $as_me 1.7+git20161115, which was
+This file was extended by GNU Mach $as_me 1.7+git20161202, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12260,7 +12260,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //;
s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-GNU Mach config.status 1.7+git20161115
+GNU Mach config.status 1.7+git20161202
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/doc/mach.info b/doc/mach.info
index 957c2df..cf13082 100644
--- a/doc/mach.info
+++ b/doc/mach.info
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from
mach.texi.
This file documents the GNU Mach microkernel.
This is edition 0.4, last updated on 16 October 2016, of 'The GNU
-Mach Reference Manual', for version 1.7+git20161115.
+Mach Reference Manual', for version 1.7+git20161202.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/mach.info-1 b/doc/mach.info-1
index 0790f8a..126d593 100644
--- a/doc/mach.info-1
+++ b/doc/mach.info-1
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from
mach.texi.
This file documents the GNU Mach microkernel.
This is edition 0.4, last updated on 16 October 2016, of 'The GNU
-Mach Reference Manual', for version 1.7+git20161115.
+Mach Reference Manual', for version 1.7+git20161202.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
@@ -46,7 +46,7 @@ Main Menu
This file documents the GNU Mach microkernel.
This is edition 0.4, last updated on 16 October 2016, of 'The GNU
-Mach Reference Manual', for version 1.7+git20161115.
+Mach Reference Manual', for version 1.7+git20161202.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/mach.info-2 b/doc/mach.info-2
index a18e09d..6163fd8 100644
--- a/doc/mach.info-2
+++ b/doc/mach.info-2
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from
mach.texi.
This file documents the GNU Mach microkernel.
This is edition 0.4, last updated on 16 October 2016, of 'The GNU
-Mach Reference Manual', for version 1.7+git20161115.
+Mach Reference Manual', for version 1.7+git20161202.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/stamp-vti b/doc/stamp-vti
index d99bd24..1d1d8d7 100644
--- a/doc/stamp-vti
+++ b/doc/stamp-vti
@@ -1,4 +1,4 @@
@set UPDATED 16 October 2016
@set UPDATED-MONTH October 2016
address@hidden EDITION 1.7+git20161115
address@hidden VERSION 1.7+git20161115
address@hidden EDITION 1.7+git20161202
address@hidden VERSION 1.7+git20161202
diff --git a/doc/version.texi b/doc/version.texi
index d99bd24..1d1d8d7 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
@set UPDATED 16 October 2016
@set UPDATED-MONTH October 2016
address@hidden EDITION 1.7+git20161115
address@hidden VERSION 1.7+git20161115
address@hidden EDITION 1.7+git20161202
address@hidden VERSION 1.7+git20161202
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 28ed23c..527fbfc 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1391,6 +1391,8 @@ ipc_kmsg_copyin_body(
if (length == 0)
data = 0;
else if (is_port) {
+ if (length > 1<<20)
+ printf("allocating %llu for message
%u\n", length, kmsg->ikm_header.msgh_id);
data = kalloc(length);
if (data == 0)
goto invalid_memory;
diff --git a/version.m4 b/version.m4
index 80b8354..2d1efff 100644
--- a/version.m4
+++ b/version.m4
@@ -1,4 +1,4 @@
m4_define([AC_PACKAGE_NAME],[GNU Mach])
-m4_define([AC_PACKAGE_VERSION],[1.7+git20161115])
+m4_define([AC_PACKAGE_VERSION],[1.7+git20161202])
m4_define([AC_PACKAGE_BUGREPORT],address@hidden)
m4_define([AC_PACKAGE_TARNAME],[gnumach])
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 003694d..604177e 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -744,7 +744,7 @@ restart:
return entry;
error:
- printf("no more room in %p (%s)\n", map, map->name);
+ printf("no more room in %p (%s) for allocating %u\n", map, map->name,
size);
return NULL;
}
diff --git a/vm/vm_page.c b/vm/vm_page.c
index 2a9f27b..92e36a1 100644
--- a/vm/vm_page.c
+++ b/vm/vm_page.c
@@ -925,12 +925,6 @@ vm_page_seg_pull_cache_page(struct vm_page_seg *seg,
}
static boolean_t
-vm_page_seg_min_page_available(const struct vm_page_seg *seg)
-{
- return (seg->nr_free_pages > seg->min_free_pages);
-}
-
-static boolean_t
vm_page_seg_page_available(const struct vm_page_seg *seg)
{
return (seg->nr_free_pages > seg->high_free_pages);
@@ -939,6 +933,11 @@ vm_page_seg_page_available(const struct vm_page_seg *seg)
static boolean_t
vm_page_seg_usable(const struct vm_page_seg *seg)
{
+ if ((seg->nr_active_pages + seg->nr_inactive_pages) == 0) {
+ /* Nothing to page out, assume segment is usable */
+ return TRUE;
+ }
+
return (seg->nr_free_pages >= seg->high_free_pages);
}
@@ -1084,8 +1083,8 @@ vm_page_seg_balance(struct vm_page_seg *seg)
}
static boolean_t
-vm_page_seg_evict(struct vm_page_seg *seg,
- boolean_t external_only, boolean_t low_memory)
+vm_page_seg_evict(struct vm_page_seg *seg, boolean_t external_only,
+ boolean_t alloc_paused)
{
struct vm_page *page;
boolean_t reclaim, laundry;
@@ -1094,6 +1093,7 @@ vm_page_seg_evict(struct vm_page_seg *seg,
page = NULL;
object = NULL;
+ laundry = FALSE;
restart:
vm_page_lock_queues();
@@ -1151,8 +1151,9 @@ restart:
*/
assert(!page->laundry);
+ assert(!(laundry && page->external));
- if (object->internal || !low_memory) {
+ if (object->internal || !alloc_paused) {
laundry = FALSE;
} else {
laundry = page->laundry = TRUE;
@@ -1873,7 +1874,7 @@ vm_page_check_usable(void)
}
}
- vm_page_external_pagedout = -1;
+ vm_page_external_laundry_count = -1;
vm_page_alloc_paused = FALSE;
thread_wakeup(&vm_page_alloc_paused);
return TRUE;
@@ -1940,48 +1941,19 @@ vm_page_balance(void)
}
static boolean_t
-vm_page_evict_once(boolean_t external_only)
+vm_page_evict_once(boolean_t external_only, boolean_t alloc_paused)
{
- struct vm_page_seg *seg;
- boolean_t low_memory, min_page_available, evicted;
+ boolean_t evicted;
unsigned int i;
/*
- * XXX Page allocation currently only uses the DIRECTMAP selector,
- * allowing us to know which segments to look at when determining
- * whether we're very low on memory.
- */
- low_memory = TRUE;
-
- simple_lock(&vm_page_queue_free_lock);
-
- for (i = 0; i < vm_page_segs_size; i++) {
- if (i > VM_PAGE_SEG_DIRECTMAP) {
- break;
- }
-
- seg = vm_page_seg_get(i);
-
- simple_lock(&seg->lock);
- min_page_available = vm_page_seg_min_page_available(seg);
- simple_unlock(&seg->lock);
-
- if (min_page_available) {
- low_memory = FALSE;
- break;
- }
- }
-
- simple_unlock(&vm_page_queue_free_lock);
-
- /*
* It's important here that pages are evicted from lower priority
* segments first.
*/
for (i = vm_page_segs_size - 1; i < vm_page_segs_size; i--) {
evicted = vm_page_seg_evict(vm_page_seg_get(i),
- external_only, low_memory);
+ external_only, alloc_paused);
if (evicted) {
return TRUE;
@@ -1997,14 +1969,15 @@ vm_page_evict_once(boolean_t external_only)
boolean_t
vm_page_evict(boolean_t *should_wait)
{
- boolean_t pause, evicted, external_only;
+ boolean_t pause, evicted, external_only, alloc_paused;
unsigned int i;
*should_wait = TRUE;
external_only = TRUE;
simple_lock(&vm_page_queue_free_lock);
- vm_page_external_pagedout = 0;
+ vm_page_external_laundry_count = 0;
+ alloc_paused = vm_page_alloc_paused;
simple_unlock(&vm_page_queue_free_lock);
again:
@@ -2018,7 +1991,7 @@ again:
}
for (i = 0; i < VM_PAGE_MAX_EVICTIONS; i++) {
- evicted = vm_page_evict_once(external_only);
+ evicted = vm_page_evict_once(external_only, alloc_paused);
if (!evicted) {
break;
@@ -2031,7 +2004,7 @@ again:
* Keep in mind eviction may not cause pageouts, since non-precious
* clean pages are simply released.
*/
- if ((vm_page_external_pagedout == 0) || (vm_page_laundry_count == 0)) {
+ if ((vm_page_laundry_count == 0) && (vm_page_external_laundry_count == 0))
{
/*
* No pageout, but some clean pages were freed. Start a complete
* scan again without waiting.
diff --git a/vm/vm_page.h b/vm/vm_page.h
index eb684c1..2a0ad2c 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -105,6 +105,7 @@ struct vm_page {
/* boolean_t */ inactive:1, /* page is in inactive list (P) */
active:1, /* page is in active list (P) */
laundry:1, /* page is being cleaned now (P)*/
+ external_laundry:1, /* same as laundry for external
pagers (P)*/
free:1, /* page is on free list (P) */
reference:1, /* page has been used (P) */
external:1, /* page in external object (P) */
@@ -165,7 +166,7 @@ int vm_page_wire_count; /* How many pages are wired? */
extern
int vm_page_laundry_count; /* How many pages being laundered? */
extern
-int vm_page_external_pagedout; /* How many external pages being paged
out? */
+int vm_page_external_laundry_count; /* How many external pages being paged
out? */
decl_simple_lock_data(extern,vm_page_queue_lock)/* lock on active and inactive
page queues */
diff --git a/vm/vm_pageout.c b/vm/vm_pageout.c
index 85db021..7dc9c12 100644
--- a/vm/vm_pageout.c
+++ b/vm/vm_pageout.c
@@ -46,6 +46,7 @@
#include <kern/slab.h>
#include <kern/task.h>
#include <kern/thread.h>
+#include <kern/printf.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
@@ -53,6 +54,13 @@
#include <vm/vm_pageout.h>
#include <machine/locore.h>
+#define DEBUG 0
+
+/*
+ * Maximum delay, in milliseconds, between two pageout scans.
+ */
+#define VM_PAGEOUT_TIMEOUT 50
+
/*
* Event placeholder for pageout requests, synchronized with
* the free page queue lock.
@@ -251,17 +259,19 @@ vm_pageout_setup(
vm_page_wire(m);
} else {
- vm_page_activate(m);
+ m->external_laundry = TRUE;
/*
- * If vm_page_external_pagedout is negative,
+ * If vm_page_external_laundry_count is negative,
* the pageout daemon isn't expecting to be
* notified.
*/
- if (vm_page_external_pagedout >= 0) {
- vm_page_external_pagedout++;
+ if (vm_page_external_laundry_count >= 0) {
+ vm_page_external_laundry_count++;
}
+
+ vm_page_activate(m);
}
vm_page_unlock_queues();
@@ -460,9 +470,19 @@ void vm_pageout(void)
FALSE);
} else if (should_wait) {
assert_wait(&vm_pageout_continue, FALSE);
- thread_set_timeout(500);
+ thread_set_timeout(VM_PAGEOUT_TIMEOUT);
simple_unlock(&vm_page_queue_free_lock);
thread_block(NULL);
+
+#if DEBUG
+ if (current_thread()->wait_result != THREAD_AWAKENED) {
+ printf("vm_pageout: timeout,"
+ " vm_page_laundry_count:%d"
+ " vm_page_external_laundry_count:%d\n",
+ vm_page_laundry_count,
+ vm_page_external_laundry_count);
+ }
+#endif
} else {
simple_unlock(&vm_page_queue_free_lock);
}
diff --git a/vm/vm_resident.c b/vm/vm_resident.c
index e3e34dc..b5096e0 100644
--- a/vm/vm_resident.c
+++ b/vm/vm_resident.c
@@ -140,7 +140,7 @@ int vm_page_wire_count;
* pageout daemon.
*/
int vm_page_laundry_count = 0;
-int vm_page_external_pagedout = 0;
+int vm_page_external_laundry_count = 0;
/*
@@ -611,6 +611,7 @@ static void vm_page_init_template(vm_page_t m)
m->inactive = FALSE;
m->active = FALSE;
m->laundry = FALSE;
+ m->external_laundry = FALSE;
m->free = FALSE;
m->external = FALSE;
@@ -811,7 +812,7 @@ phys_addr_t vm_page_grab_phys_addr(void)
void vm_page_release(
vm_page_t mem,
boolean_t laundry,
- boolean_t external)
+ boolean_t external_laundry)
{
simple_lock(&vm_page_queue_free_lock);
if (mem->free)
@@ -825,20 +826,20 @@ void vm_page_release(
vm_pageout_resume();
}
}
- if (external) {
+ if (external_laundry) {
/*
- * If vm_page_external_pagedout is negative,
+ * If vm_page_external_laundry_count is negative,
* the pageout daemon isn't expecting to be
* notified.
*/
- if (vm_page_external_pagedout > 0) {
- vm_page_external_pagedout--;
- }
+ if (vm_page_external_laundry_count > 0) {
+ vm_page_external_laundry_count--;
- if (vm_page_external_pagedout == 0) {
- vm_pageout_resume();
+ if (vm_page_external_laundry_count == 0) {
+ vm_pageout_resume();
+ }
}
}
@@ -977,9 +978,9 @@ void vm_page_free(
vm_page_release_fictitious(mem);
} else {
boolean_t laundry = mem->laundry;
- boolean_t external = mem->external;
+ boolean_t external_laundry = mem->external_laundry;
vm_page_init(mem);
- vm_page_release(mem, laundry, external);
+ vm_page_release(mem, laundry, external_laundry);
}
}
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/gnumach.git