commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnumach] 01/03: Imported Upstream version 1.7+git20160809


From: Samuel Thibault
Subject: [gnumach] 01/03: Imported Upstream version 1.7+git20160809
Date: Wed, 10 Aug 2016 00:06:07 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository gnumach.

commit 1251f73d13773e825260d58182e1fc44671ffa15
Author: Samuel Thibault <address@hidden>
Date:   Tue Aug 9 21:47:15 2016 +0000

    Imported Upstream version 1.7+git20160809
---
 ChangeLog           |  78 ++++++++++++++++++++++++++++++++++++++++
 configure           |  20 +++++------
 doc/mach.info       |   2 +-
 doc/mach.info-1     |   4 +--
 doc/mach.info-2     |   2 +-
 doc/stamp-vti       |   4 +--
 doc/version.texi    |   4 +--
 i386/i386/io_perm.c |   1 -
 kern/debug.c        |   2 +-
 kern/slab.c         | 101 ++++++++++++++++++++++++++++------------------------
 kern/slab.h         |   3 ++
 kern/task.c         |   3 ++
 kern/thread.c       |  12 +++++++
 version.m4          |   2 +-
 vm/vm_map.c         |  49 +++++++++++++++++++++----
 vm/vm_map.h         |   8 +++++
 vm/vm_object.c      |  16 ++++++---
 vm/vm_object.h      |  17 ++-------
 vm/vm_resident.c    |  25 +++++++------
 vm/vm_user.c        |   4 +--
 20 files changed, 251 insertions(+), 106 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 96c1da1..dce289c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,81 @@
+2016-08-07  Richard Braun  <address@hidden>
+
+       VM: fix pageout-related deadlock
+       * vm/vm_map.c (_vm_map_entry_create): Temporarily set the current thread
+       as VM privileged.
+
+2016-08-06  Richard Braun  <address@hidden>
+
+       Augment VM maps with task names
+       This change improves the clarity of "no more room for ..." VM map
+       allocation errors.
+
+       * kern/task.c (task_init): Call vm_map_set_name for the kernel map.
+       (task_create): Call vm_map_set_name where appropriate.
+       * vm/vm_map.c (vm_map_setup): Set map name to NULL.
+       (vm_map_find_entry_anywhere): Update error message to include map name.
+       * vm/vm_map.h (struct vm_map): New `name' member.
+       (vm_map_set_name): New inline function.
+
+2016-06-29  Richard Braun  <address@hidden>
+
+       Fix page fault in critical section in the slab allocator
+       * kern/slab.c (host_slab_info): Use wired kernel memory to build the
+       cache info.
+
+       Fix locking error in the slab allocator
+       * kern/slab.c (kmem_slab_create): Set `slab->cache` member.
+       (kmem_cache_reap): Return dead slabs instead of destroying in place.
+       (slab_collect): Destroy slabs outside of critical section.
+       * kern/slab.h (struct kmem_slab): New `cache` member.
+
+2016-06-27  Richard Braun  <address@hidden>
+
+       Fix locking error
+       * i386/i386/io_perm.c (no_senders): Remove bogus call to ip_lock.
+
+2016-06-17  Richard Braun  <address@hidden>
+
+       Change page cache statistics
+       Instead of reporting statistics about unreferenced objects (the object
+       cache), report statistics about external objects (the page cache).
+
+       * vm/vm_object.c (vm_object_cached_count): Remove variable.
+       (vm_object_cache_add): Remove object cache stats updates.
+       (vm_object_cache_remove): Likewise.
+       (vm_object_terminate): Update page cache stats.
+       * vm/vm_object.h (vm_object_cached_count): Remove variable.
+       (vm_object_cached_pages): Likewise.
+       (vm_object_cached_pages_lock_data): Likewise.
+       (vm_object_cached_pages_update): Remove macro.
+       (vm_object_external_count): New extern variable.
+       (vm_object_external_pages): Likewise.
+       * vm/vm_resident.c (vm_object_external_count): New variable.
+       (vm_object_external_pages): Likewise.
+       (vm_page_insert): Remove object cache stats updates and
+       update page cache stats.
+       (vm_page_replace): Likewise.
+       (vm_page_remove): Likewise.
+       * vm/vm_user.c (vm_cache_statistics): Report page cache stats instead
+       of object cache stats.
+
+2016-06-10  Samuel Thibault  <address@hidden>
+
+       Allow setting x86 debug flags for the current thread
+       * kern/thread.c (thread_get_state): Allow call for the current thread,
+       without suspending it.
+       (thread_set_status): Likewise.
+
+       Use int3 on x86_64 build too
+       * kern/debug.c (SoftDebugger) [__x86_64__]: Use int3 instruction to 
trigger
+       debugger.
+
+2016-06-09  Richard Braun  <address@hidden>
+
+       Fix overflow checking on VM map copyin
+       * vm/vm_map (vm_map_copyin, vm_map_copyin_page_list): Check overflow
+       before page alignment of source data.
+
 2016-06-07  Richard Braun  <address@hidden>
 
        Fix deadlock
diff --git a/configure b/configure
index 2ba3469..b529a51 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+git20160607.
+# Generated by GNU Autoconf 2.69 for GNU Mach 1.7+git20160809.
 #
 # 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+git20160607'
-PACKAGE_STRING='GNU Mach 1.7+git20160607'
+PACKAGE_VERSION='1.7+git20160809'
+PACKAGE_STRING='GNU Mach 1.7+git20160809'
 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+git20160607 to adapt to many kinds of 
systems.
+\`configure' configures GNU Mach 1.7+git20160809 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+git20160607:";;
+     short | recursive ) echo "Configuration of GNU Mach 1.7+git20160809:";;
    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+git20160607
+GNU Mach configure 1.7+git20160809
 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+git20160607, which was
+It was created by GNU Mach $as_me 1.7+git20160809, 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+git20160607'
+ VERSION='1.7+git20160809'
 
 
 # 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+git20160607, which was
+This file was extended by GNU Mach $as_me 1.7+git20160809, 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+git20160607
+GNU Mach config.status 1.7+git20160809
 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 9a4c09f..a728886 100644
--- a/doc/mach.info
+++ b/doc/mach.info
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.1 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
-Reference Manual', for version 1.7+git20160607.
+Reference Manual', for version 1.7+git20160809.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/mach.info-1 b/doc/mach.info-1
index 5fef384..aabe01d 100644
--- a/doc/mach.info-1
+++ b/doc/mach.info-1
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.1 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
-Reference Manual', for version 1.7+git20160607.
+Reference Manual', for version 1.7+git20160809.
 
    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 20 April 2016, of 'The GNU Mach
-Reference Manual', for version 1.7+git20160607.
+Reference Manual', for version 1.7+git20160809.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/mach.info-2 b/doc/mach.info-2
index 50e97f5..847cb6d 100644
--- a/doc/mach.info-2
+++ b/doc/mach.info-2
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.1 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
-Reference Manual', for version 1.7+git20160607.
+Reference Manual', for version 1.7+git20160809.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/stamp-vti b/doc/stamp-vti
index 06c8e2a..5bfda11 100644
--- a/doc/stamp-vti
+++ b/doc/stamp-vti
@@ -1,4 +1,4 @@
 @set UPDATED 20 April 2016
 @set UPDATED-MONTH April 2016
address@hidden EDITION 1.7+git20160607
address@hidden VERSION 1.7+git20160607
address@hidden EDITION 1.7+git20160809
address@hidden VERSION 1.7+git20160809
diff --git a/doc/version.texi b/doc/version.texi
index 06c8e2a..5bfda11 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
 @set UPDATED 20 April 2016
 @set UPDATED-MONTH April 2016
address@hidden EDITION 1.7+git20160607
address@hidden VERSION 1.7+git20160607
address@hidden EDITION 1.7+git20160809
address@hidden VERSION 1.7+git20160809
diff --git a/i386/i386/io_perm.c b/i386/i386/io_perm.c
index d5c7103..3224fdd 100644
--- a/i386/i386/io_perm.c
+++ b/i386/i386/io_perm.c
@@ -131,7 +131,6 @@ no_senders (mach_no_senders_notification_t *notification)
 
   assert (io_perm != IO_PERM_NULL);
 
-  ip_lock (io_perm->port);  /* TODO.  Actually needed?  */
   ipc_kobject_set (io_perm->port, IKO_NULL, IKOT_NONE);
   ipc_port_dealloc_kernel (io_perm->port);
 
diff --git a/kern/debug.c b/kern/debug.c
index fce9ba6..0d01b84 100644
--- a/kern/debug.c
+++ b/kern/debug.c
@@ -93,7 +93,7 @@ void SoftDebugger(message)
        gimmeabreak();
 #endif
 
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
        asm("int3");
 #endif
 }
diff --git a/kern/slab.c b/kern/slab.c
index eeb94f8..1f8e000 100644
--- a/kern/slab.c
+++ b/kern/slab.c
@@ -495,6 +495,7 @@ static struct kmem_slab * kmem_slab_create(struct 
kmem_cache *cache,
         slab = (struct kmem_slab *)(slab_buf + cache->slab_size) - 1;
     }
 
+    slab->cache = cache;
     list_node_init(&slab->list_node);
     rbtree_node_init(&slab->tree_node);
     slab->nr_refs = 0;
@@ -925,29 +926,17 @@ static int kmem_cache_grow(struct kmem_cache *cache)
     return !empty;
 }
 
-static void kmem_cache_reap(struct kmem_cache *cache)
+static void kmem_cache_reap(struct kmem_cache *cache, struct list *dead_slabs)
 {
-    struct kmem_slab *slab;
-    struct list dead_slabs;
-    unsigned long nr_free_slabs;
-
     simple_lock(&cache->lock);
-    list_set_head(&dead_slabs, &cache->free_slabs);
+
+    list_concat(dead_slabs, &cache->free_slabs);
     list_init(&cache->free_slabs);
-    nr_free_slabs = cache->nr_free_slabs;
-    cache->nr_bufs -= cache->bufs_per_slab * nr_free_slabs;
-    cache->nr_slabs -= nr_free_slabs;
+    cache->nr_bufs -= cache->bufs_per_slab * cache->nr_free_slabs;
+    cache->nr_slabs -= cache->nr_free_slabs;
     cache->nr_free_slabs = 0;
-    simple_unlock(&cache->lock);
 
-    while (!list_empty(&dead_slabs)) {
-        slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node);
-        list_remove(&slab->list_node);
-        kmem_slab_destroy(slab, cache);
-        nr_free_slabs--;
-    }
-
-    assert(nr_free_slabs == 0);
+    simple_unlock(&cache->lock);
 }
 
 /*
@@ -1286,18 +1275,28 @@ slab_free:
 void slab_collect(void)
 {
     struct kmem_cache *cache;
+    struct kmem_slab *slab;
+    struct list dead_slabs;
 
     if (elapsed_ticks <= (kmem_gc_last_tick + KMEM_GC_INTERVAL))
         return;
 
     kmem_gc_last_tick = elapsed_ticks;
 
+    list_init(&dead_slabs);
+
     simple_lock(&kmem_cache_list_lock);
 
     list_for_each_entry(&kmem_cache_list, cache, node)
-        kmem_cache_reap(cache);
+        kmem_cache_reap(cache, &dead_slabs);
 
     simple_unlock(&kmem_cache_list_lock);
+
+    while (!list_empty(&dead_slabs)) {
+        slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node);
+        list_remove(&slab->list_node);
+        kmem_slab_destroy(slab, slab->cache);
+    }
 }
 
 void slab_bootstrap(void)
@@ -1503,39 +1502,33 @@ kern_return_t host_slab_info(host_t host, 
cache_info_array_t *infop,
     struct kmem_cache *cache;
     cache_info_t *info;
     unsigned int i, nr_caches;
-    vm_size_t info_size = 0;
+    vm_size_t info_size;
     kern_return_t kr;
 
     if (host == HOST_NULL)
         return KERN_INVALID_HOST;
 
-    /*
-     * Assume the cache list is unaltered once the kernel is ready.
-     */
+    /* Assume the cache list is mostly unaltered once the kernel is ready */
 
-    simple_lock(&kmem_cache_list_lock);
+retry:
+    /* Harmless unsynchronized access, real value checked later */
     nr_caches = kmem_nr_caches;
-    simple_unlock(&kmem_cache_list_lock);
-
-    if (nr_caches <= *infoCntp)
-        info = *infop;
-    else {
-        vm_offset_t info_addr;
-
-        info_size = round_page(nr_caches * sizeof(*info));
-        kr = kmem_alloc_pageable(ipc_kernel_map, &info_addr, info_size);
-
-        if (kr != KERN_SUCCESS)
-            return kr;
-
-        info = (cache_info_t *)info_addr;
-    }
+    info_size = nr_caches * sizeof(*info);
+    info = (cache_info_t *)kalloc(info_size);
 
     if (info == NULL)
         return KERN_RESOURCE_SHORTAGE;
 
     i = 0;
 
+    simple_lock(&kmem_cache_list_lock);
+
+    if (nr_caches != kmem_nr_caches) {
+        simple_unlock(&kmem_cache_list_lock);
+        kfree((vm_offset_t)info, info_size);
+        goto retry;
+    }
+
     list_for_each_entry(&kmem_cache_list, cache, node) {
         simple_lock(&cache->lock);
         info[i].flags = cache->flags;
@@ -1560,24 +1553,38 @@ kern_return_t host_slab_info(host_t host, 
cache_info_array_t *infop,
         i++;
     }
 
-    if (info != *infop) {
+    simple_unlock(&kmem_cache_list_lock);
+
+    if (nr_caches <= *infoCntp) {
+        memcpy(*infop, info, info_size);
+    } else {
+        vm_offset_t info_addr;
+        vm_size_t total_size;
         vm_map_copy_t copy;
-        vm_size_t used;
 
-        used = nr_caches * sizeof(*info);
+        kr = kmem_alloc_pageable(ipc_kernel_map, &info_addr, info_size);
 
-        if (used != info_size)
-            memset((char *)info + used, 0, info_size - used);
+        if (kr != KERN_SUCCESS)
+            goto out;
 
-        kr = vm_map_copyin(ipc_kernel_map, (vm_offset_t)info, used, TRUE,
-                           &copy);
+        memcpy((char *)info_addr, info, info_size);
+        total_size = round_page(info_size);
 
+        if (info_size < total_size)
+            memset((char *)(info_addr + info_size),
+                   0, total_size - info_size);
+
+        kr = vm_map_copyin(ipc_kernel_map, info_addr, info_size, TRUE, &copy);
         assert(kr == KERN_SUCCESS);
         *infop = (cache_info_t *)copy;
     }
 
     *infoCntp = nr_caches;
+    kr = KERN_SUCCESS;
+
+out:
+    kfree((vm_offset_t)info, info_size);
 
-    return KERN_SUCCESS;
+    return kr;
 }
 #endif /* MACH_DEBUG */
diff --git a/kern/slab.h b/kern/slab.h
index 8527c9d..9d8a115 100644
--- a/kern/slab.h
+++ b/kern/slab.h
@@ -56,6 +56,8 @@
 #include <sys/types.h>
 #include <vm/vm_types.h>
 
+struct kmem_cache;
+
 #if SLAB_USE_CPU_POOLS
 
 /*
@@ -117,6 +119,7 @@ struct kmem_buftag {
  * Page-aligned collection of unconstructed buffers.
  */
 struct kmem_slab {
+    struct kmem_cache *cache;
     struct list list_node;
     struct rbtree_node tree_node;
     unsigned long nr_refs;
diff --git a/kern/task.c b/kern/task.c
index d721f17..673a437 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -75,6 +75,7 @@ void task_init(void)
         */
        (void) task_create(TASK_NULL, FALSE, &kernel_task);
        (void) task_set_name(kernel_task, "gnumach");
+       vm_map_set_name(kernel_map, kernel_task->name);
 }
 
 kern_return_t task_create(
@@ -99,10 +100,12 @@ kern_return_t task_create(
                new_task->map = kernel_map;
        } else if (inherit_memory) {
                new_task->map = vm_map_fork(parent_task->map);
+               vm_map_set_name(new_task->map, new_task->name);
        } else {
                new_task->map = vm_map_create(pmap_create(0),
                                        round_page(VM_MIN_ADDRESS),
                                        trunc_page(VM_MAX_ADDRESS), TRUE);
+               vm_map_set_name(new_task->map, new_task->name);
        }
 
        simple_lock_init(&new_task->lock);
diff --git a/kern/thread.c b/kern/thread.c
index a821149..7db1f3d 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -1425,6 +1425,12 @@ kern_return_t thread_get_state(
 {
        kern_return_t           ret;
 
+#if defined(__i386__) || defined(__x86_64__)
+       if (flavor == i386_DEBUG_STATE && thread == current_thread())
+               /* This state can be obtained directly for the curren thread.  
*/
+               return thread_getstatus(thread, flavor, old_state, 
old_state_count);
+#endif
+
        if (thread == THREAD_NULL || thread == current_thread()) {
                return KERN_INVALID_ARGUMENT;
        }
@@ -1449,6 +1455,12 @@ kern_return_t thread_set_state(
 {
        kern_return_t           ret;
 
+#if defined(__i386__) || defined(__x86_64__)
+       if (flavor == i386_DEBUG_STATE && thread == current_thread())
+               /* This state can be set directly for the curren thread.  */
+               return thread_setstatus(thread, flavor, new_state, 
new_state_count);
+#endif
+
        if (thread == THREAD_NULL || thread == current_thread()) {
                return KERN_INVALID_ARGUMENT;
        }
diff --git a/version.m4 b/version.m4
index 96cfef9..3a7512a 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+git20160607])
+m4_define([AC_PACKAGE_VERSION],[1.7+git20160809])
 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 4476812..acac66e 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -195,6 +195,7 @@ void vm_map_setup(
        map->wait_for_space = FALSE;
        map->first_free = vm_map_to_entry(map);
        map->hint = vm_map_to_entry(map);
+       map->name = NULL;
        vm_map_lock_init(map);
        simple_lock_init(&map->ref_lock);
        simple_lock_init(&map->hint_lock);
@@ -240,8 +241,26 @@ vm_map_entry_t _vm_map_entry_create(map_header)
        const struct vm_map_header *map_header;
 {
        vm_map_entry_t  entry;
+       boolean_t vm_privilege;
 
+       /*
+        *      XXX Map entry creation may occur while a map is locked,
+        *      for example when clipping entries. If the system is running
+        *      low on memory, allocating an entry may block until pages
+        *      are available. But if a map used by the default pager is
+        *      kept locked, a deadlock occurs.
+        *
+        *      This workaround temporarily elevates the current thread
+        *      VM privileges to avoid that particular deadlock, and does
+        *      so regardless of the map for convenience, and because it's
+        *      currently impossible to predict which map the default pager
+        *      may depend on.
+        */
+       vm_privilege = current_thread()->vm_privilege;
+       current_thread()->vm_privilege = TRUE;
        entry = (vm_map_entry_t) kmem_cache_alloc(&vm_map_entry_cache);
+       current_thread()->vm_privilege = vm_privilege;
+
        if (entry == VM_MAP_ENTRY_NULL)
                panic("vm_map_entry_create");
 
@@ -704,7 +723,7 @@ restart:
        return entry;
 
 error:
-       printf("no more room in %p\n", map);
+       printf("no more room in %p (%s)\n", map, map->name);
        return NULL;
 }
 
@@ -3145,6 +3164,14 @@ kern_return_t vm_map_copyin(
        }
 
        /*
+        *      Check that the end address doesn't overflow
+        */
+
+       if ((src_addr + len) <= src_addr) {
+               return KERN_INVALID_ADDRESS;
+       }
+
+       /*
         *      Compute start and end of region
         */
 
@@ -3152,12 +3179,12 @@ kern_return_t vm_map_copyin(
        src_end = round_page(src_addr + len);
 
        /*
-        *      Check that the end address doesn't overflow
+        *      XXX VM maps shouldn't end at maximum address
         */
 
-       if (src_end <= src_start)
-               if ((src_end < src_start) || (src_start != 0))
-                       return(KERN_INVALID_ADDRESS);
+       if (src_end == 0) {
+               return KERN_INVALID_ADDRESS;
+       }
 
        /*
         *      Allocate a header element for the list.
@@ -3622,6 +3649,14 @@ kern_return_t vm_map_copyin_page_list(
        }
 
        /*
+        *      Check that the end address doesn't overflow
+        */
+
+       if ((src_addr + len) <= src_addr) {
+               return KERN_INVALID_ADDRESS;
+       }
+
+       /*
         *      Compute start and end of region
         */
 
@@ -3629,10 +3664,10 @@ kern_return_t vm_map_copyin_page_list(
        src_end = round_page(src_addr + len);
 
        /*
-        *      Check that the end address doesn't overflow
+        *      XXX VM maps shouldn't end at maximum address
         */
 
-       if (src_end <= src_start && (src_end < src_start || src_start != 0)) {
+       if (src_end == 0) {
                return KERN_INVALID_ADDRESS;
        }
 
diff --git a/vm/vm_map.h b/vm/vm_map.h
index 74c86a7..9e946c5 100644
--- a/vm/vm_map.h
+++ b/vm/vm_map.h
@@ -194,6 +194,8 @@ struct vm_map {
        /* boolean_t */ wiring_required:1;      /* All memory wired? */
 
        unsigned int            timestamp;      /* Version number */
+
+       const char              *name;          /* Associated name */
 };
 
 #define vm_map_to_entry(map)   ((struct vm_map_entry *) &(map)->hdr.links)
@@ -466,6 +468,12 @@ boolean_t vm_map_lookup_entry(
        vm_offset_t     address,
        vm_map_entry_t  *entry); /* OUT */
 
+static inline void vm_map_set_name(vm_map_t map, const char *name)
+{
+       map->name = name;
+}
+
+
 /*
  *     Functions implemented as macros
  */
diff --git a/vm/vm_object.c b/vm/vm_object.c
index 046b6c4..1e80bbc 100644
--- a/vm/vm_object.c
+++ b/vm/vm_object.c
@@ -181,7 +181,6 @@ vm_object_t         kernel_object = &kernel_object_store;
  *     not be held to make simple references.
  */
 queue_head_t   vm_object_cached_list;
-int            vm_object_cached_count;
 
 decl_simple_lock_data(,vm_object_cached_lock_data)
 
@@ -362,8 +361,6 @@ static void vm_object_cache_add(
 {
        assert(!object->cached);
        queue_enter(&vm_object_cached_list, object, vm_object_t, cached_list);
-       vm_object_cached_count++;
-       vm_object_cached_pages_update(object->resident_page_count);
        object->cached = TRUE;
 }
 
@@ -372,8 +369,6 @@ static void vm_object_cache_remove(
 {
        assert(object->cached);
        queue_remove(&vm_object_cached_list, object, vm_object_t, cached_list);
-       vm_object_cached_count--;
-       vm_object_cached_pages_update(-object->resident_page_count);
        object->cached = FALSE;
 }
 
@@ -621,6 +616,14 @@ void vm_object_terminate(
        assert(object->paging_in_progress == 0);
        assert(!object->cached);
 
+       if (!object->internal) {
+               assert(object->resident_page_count == 0);
+
+               vm_page_lock_queues();
+               vm_object_external_count--;
+               vm_page_unlock_queues();
+       }
+
        /*
         *      Throw away port rights... note that they may
         *      already have been thrown away (by vm_object_destroy
@@ -2091,6 +2094,9 @@ restart:
                        object->internal = FALSE;
                        object->temporary = FALSE;
 
+                       assert(object->resident_page_count == 0);
+                       vm_object_external_count++;
+
                        /* user pager objects are not ready until marked so */
                        object->pager_ready = FALSE;
 
diff --git a/vm/vm_object.h b/vm/vm_object.h
index e1dd0ba..1914e8e 100644
--- a/vm/vm_object.h
+++ b/vm/vm_object.h
@@ -394,20 +394,9 @@ MACRO_END
 /*
  *     Page cache accounting.
  *
- *     The number of cached objects and pages can be read
- *     without holding any lock.
+ *     The page queues must be locked when changing these counters.
  */
-
-extern int     vm_object_cached_count;
-
-extern int     vm_object_cached_pages;
-decl_simple_lock_data(extern,vm_object_cached_pages_lock_data)
-
-#define vm_object_cached_pages_update(page_count)                      \
-       MACRO_BEGIN                                                     \
-       simple_lock(&vm_object_cached_pages_lock_data);                 \
-       vm_object_cached_pages += (page_count);                         \
-       simple_unlock(&vm_object_cached_pages_lock_data);               \
-       MACRO_END
+extern int     vm_object_external_count;
+extern int     vm_object_external_pages;
 
 #endif /* _VM_VM_OBJECT_H_ */
diff --git a/vm/vm_resident.c b/vm/vm_resident.c
index 79481a7..ed867f5 100644
--- a/vm/vm_resident.c
+++ b/vm/vm_resident.c
@@ -100,6 +100,8 @@ decl_simple_lock_data(,vm_page_queue_free_lock)
 unsigned int   vm_page_free_wanted;
 int            vm_page_fictitious_count;
 int            vm_page_external_count;
+int            vm_object_external_count;
+int            vm_object_external_pages;
 
 /*
  * This variable isn't directly used. It's merely a placeholder for the
@@ -374,9 +376,6 @@ void vm_page_insert(
        object->resident_page_count++;
        assert(object->resident_page_count != 0);
 
-       if (object->can_persist && (object->ref_count == 0))
-               vm_object_cached_pages_update(1);
-
        /*
         *      Detect sequential access and inactivate previous page.
         *      We ignore busy pages.
@@ -391,6 +390,10 @@ void vm_page_insert(
                        vm_page_deactivate(last_mem);
        }
        object->last_alloc = offset;
+
+       if (!object->internal) {
+               vm_object_external_pages++;
+       }
 }
 
 /*
@@ -444,9 +447,9 @@ void vm_page_replace(
                                m->tabled = FALSE;
                                object->resident_page_count--;
 
-                               if (object->can_persist
-                                   && (object->ref_count == 0))
-                                       vm_object_cached_pages_update(-1);
+                               if (!object->internal) {
+                                       vm_object_external_pages--;
+                               }
 
                                /*
                                 * Return page to the free list.
@@ -481,8 +484,9 @@ void vm_page_replace(
        object->resident_page_count++;
        assert(object->resident_page_count != 0);
 
-       if (object->can_persist && (object->ref_count == 0))
-               vm_object_cached_pages_update(1);
+       if (!object->internal) {
+               vm_object_external_pages++;
+       }
 }
 
 /*
@@ -539,8 +543,9 @@ void vm_page_remove(
 
        mem->tabled = FALSE;
 
-       if (mem->object->can_persist && (mem->object->ref_count == 0))
-               vm_object_cached_pages_update(-1);
+       if (!mem->object->internal) {
+               vm_object_external_pages--;
+       }
 }
 
 /*
diff --git a/vm/vm_user.c b/vm/vm_user.c
index e65f6d5..7fc0fe8 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -197,8 +197,8 @@ kern_return_t vm_cache_statistics(
        if (map == VM_MAP_NULL)
                return KERN_INVALID_ARGUMENT;
 
-       stats->cache_object_count = vm_object_cached_count;
-       stats->cache_count = vm_object_cached_pages;
+       stats->cache_object_count = vm_object_external_count;
+       stats->cache_count = vm_object_external_pages;
 
        /* XXX Not implemented yet */
        stats->active_tmp_count = 0;

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/gnumach.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]