From e32ad78d3c7ec2375b8d1a129340e596f1ea1fd8 Mon Sep 17 00:00:00 2001 From: Venkatesh Srinivas Date: Tue, 15 Feb 2011 15:59:44 -0800 Subject: [PATCH] kernel -- vm locking: Add vm_page_(un)lock and vm_object_(un)lock. Each vm_object and vm_page are associated with a token; for vm_pages, we use a pool token; for objects, a per-object token. For vm_pages, the token will interlock access to the pv_chain, at least. Also remove per-vm_object range locks. They were unused. --- sys/vm/vm_object.c | 13 ++++++ sys/vm/vm_object.h | 24 ++++------- sys/vm/vm_page.c | 12 ++++++ sys/vm/vm_page.h | 2 + sys/vm/vm_rangelock.c | 99 ------------------------------------------- 5 files changed, 35 insertions(+), 115 deletions(-) delete mode 100644 sys/vm/vm_rangelock.c diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 0ee4f12895..cc56add3e9 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -74,6 +74,7 @@ #include #include #include /* for curproc, pageproc */ +#include #include #include #include @@ -1812,6 +1813,18 @@ vm_object_set_writeable_dirty(vm_object_t object) lwkt_reltoken(&vm_token); } +void +vm_object_lock(vm_object_t object) +{ + lwkt_gettoken(&object->tok); +} + +void +vm_object_unlock(vm_object_t object) +{ + lwkt_reltoken(&object->tok); +} + #include "opt_ddb.h" #ifdef DDB #include diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 3350479fae..ec40039aa4 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -96,6 +96,10 @@ #ifdef _KERNEL +#ifndef _SYS_THREAD_H +#include +#endif + #ifndef _SYS_THREAD2_H_ #include #endif @@ -120,21 +124,6 @@ enum obj_type { }; typedef u_char objtype_t; -/* - * vm_object_lock A lock covering byte ranges within a VM object - * - */ -struct vm_object_lock { - struct vm_object_lock *next; - int type; /* type of lock */ - int waiting; /* someone is waiting on the lock */ - off_t base; /* byte offset into object */ - off_t bytes; /* extent in bytes */ -}; - -#define VMOBJ_LOCK_SHARED 1 -#define VMOBJ_LOCK_EXCL 2 - /* * vm_object A VM object which represents an arbitrarily sized * data store. @@ -163,7 +152,8 @@ struct vm_object { vm_ooffset_t backing_object_offset;/* Offset in backing object */ TAILQ_ENTRY(vm_object) pager_object_list; /* list of all objects of this pager type */ void *handle; - vm_object_lock_t range_locks; + struct lwkt_token tok; + union { /* * Device pager @@ -306,6 +296,8 @@ void vm_object_init2 (void); vm_page_t vm_fault_object_page(vm_object_t, vm_ooffset_t, vm_prot_t, int, int *); void vm_object_dead_sleep(vm_object_t, const char *); void vm_object_dead_wakeup(vm_object_t); +void vm_object_lock(vm_object_t); +void vm_object_unlock(vm_object_t); #endif /* _KERNEL */ diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 283afd542c..7bd94b9b2b 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1990,6 +1990,18 @@ vm_page_event_internal(vm_page_t m, vm_page_event_t event) } +void +vm_page_lock(vm_page_t m) +{ + lwkt_getpooltoken(m); +} + +void +vm_page_unlock(vm_page_t m) +{ + lwkt_relpooltoken(m); +} + #include "opt_ddb.h" #ifdef DDB #include diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index a6f7db1154..6dc4eb8f4a 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -534,6 +534,8 @@ void vm_page_event_internal(vm_page_t, vm_page_event_t); void vm_page_dirty(vm_page_t m); void vm_page_register_action(vm_page_action_t action, vm_page_event_t event); void vm_page_unregister_action(vm_page_action_t action); +void vm_page_lock(vm_page_t m); +void vm_page_unlock(vm_page_t m); /* * Reduce the protection of a page. This routine never raises the diff --git a/sys/vm/vm_rangelock.c b/sys/vm/vm_rangelock.c deleted file mode 100644 index 6797944779..0000000000 --- a/sys/vm/vm_rangelock.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved. - * - * This code is derived from software contributed to The DragonFly Project - * by Matthew Dillon - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of The DragonFly Project nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific, prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * VM range locking module. Range locks within VM objects are used to protect - * I/O operations and will eventually also be used in an extended form - * for cache coherency control. - * - * $DragonFly: src/sys/vm/vm_rangelock.c,v 1.2 2004/07/16 05:52:14 dillon Exp $ - */ -#include -#include -#include /* for curproc, pageproc */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Note: these routines are currently greatly simplified and unoptimized. - * - * Locks are sorted by base address. - */ -void -shlock_range(vm_object_lock_t lock, vm_object_t object, off_t base, off_t bytes) -{ - struct vm_object_lock **plock; - vm_object_lock_t scan; - - /* - * Locate the insertion point and check for conflicts - */ -again: - for (plock = &object->range_locks; - (scan = *plock) != NULL; - plock = &scan->next - ) { - if (base < scan->base + scan->bytes && base + bytes > scan->base) { - if (scan->type != VMOBJ_LOCK_SHARED) { - tsleep(scan - } - } - } -} - -void -exlock_range(vm_object_lock_t lock, vm_object_t object, off_t base, off_t bytes) -{ -} - -void -unlock_range(vm_object_lock_t lock) -{ -} - -- 2.41.0