root/sys/vm/vm_page.h
/*
 * Copyright (c) 1991, 1993
 *      The Regents of the University of California.  All rights reserved.
 * Copyright (c) 2003-2019 The DragonFly Project.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * The Mach Operating System project at Carnegie-Mellon University.
 *
 * This code is derived from software contributed to The DragonFly Project
 * by Matthew Dillon <dillon@backplane.com>
 *
 * 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 University 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 REGENTS 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 REGENTS 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.
 *
 *      from: @(#)vm_page.h     8.2 (Berkeley) 12/13/93
 *
 *
 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
 * All rights reserved.
 *
 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
 *
 * Permission to use, copy, modify and distribute this software and
 * its documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */

/*
 * Resident memory system definitions.
 */

#ifndef _VM_VM_PAGE_H_
#define _VM_VM_PAGE_H_

#ifndef _SYS_TYPES_H_
#include <sys/types.h>
#endif
#ifndef _SYS_TREE_H_
#include <sys/tree.h>
#endif
#ifndef _MACHINE_PMAP_H_
#include <machine/pmap.h>
#endif
#ifndef _VM_PMAP_H_
#include <vm/pmap.h>
#endif
#include <machine/atomic.h>

#ifdef _KERNEL

#ifndef _SYS_SYSTM_H_
#include <sys/systm.h>
#endif
#ifndef _SYS_SPINLOCK_H_
#include <sys/spinlock.h>
#endif

#ifdef __x86_64__
#include <machine/vmparam.h>
#endif

#endif

/*
 * The vm_page structure is the heart of the entire system.  It's fairly
 * bulky, eating 3.125% of available memory (128 bytes vs 4K page size).
 * Most normal uses of the structure, representing physical memory, uses
 * the type-stable vm_page_array[].  Device mappings exposed to mmap()
 * (such as GPUs) generally use temporary vm_page's outside of this array
 * and will be flagged FICTITIOUS.  Devices which use the kernel's contig
 * memory allocator get normal pages, but for convenience the pages will
 * be temporarily flagged as FICTITIOUS.
 *
 * Soft-busying or Hard-busying guarantees a stable m->object, m->pindex,
 * and m->valid field.  A page cannot be validated or invalidated unless
 * hard-busied.
 *
 * The page must be hard-busied to make the following changes:
 *
 *      (1) Any change to m->object or m->pindex (also requires the
 *          related object to be exclusively locked).
 *
 *      (2) Any transition of m->wire_count to 0 or from 0.  Other
 *          transitions (e.g. 2->1, 1->2, etc) are allowed without
 *          locks.
 *
 *      (3) Any change to m->valid.
 *
 *      (4) Clearing PG_MAPPED or PG_WRITEABLE (note that because of
 *          this, these bits may be left lazily set until they can
 *          be cleared later on.
 *
 * Most other fields of the vm_page can change at any time with certain
 * restrictions.
 *
 *      (1) PG_WRITEABLE and PG_MAPPED may be set with the page soft-busied
 *          or hard-busied.
 *
 *      (2) m->dirty may be set to VM_PAGE_BITS_ALL by a page fault at
 *          any time if PG_WRITEABLE is flagged.  Tests of m->dirty are
 *          only tentative until all writeable mappings of the page are
 *          removed.  This may occur unlocked.  A hard-busy is required
 *          if modifying m->dirty under other conditions.
 *
 *      (3) PG_REFERENCED may be set at any time by the pmap code to
 *          synchronized the [A]ccessed bit, if PG_MAPPED is flagged,
 *          unlocked.  A hard-busy is required for any other time.
 *
 *      (3) hold_count can be incremented or decremented at any time,
 *          including transitions to or from 0.  Holding a page via
 *          vm_page_hold() does NOT stop major changes from being made
 *          to the page, but WILL prevent the page from being freed
 *          or reallocated.  If the hold is emplaced with the page in
 *          a known state it can prevent the underlying data from being
 *          destroyed.
 *
 *      (4) Each individual flag may have a different behavior.  Some flags
 *          can be set or cleared at any time, some require hard-busying,
 *          etc.
 *
 * Moving the page between queues (aka m->pageq and m->queue) requires
 * m->spin to be exclusively locked first, and then also the spinlock related
 * to the queue.
 *
 *      (1) This is the only use that requires m->spin any more.
 *
 *      (2) There is one special case and that is the pageout daemon is
 *          allowed to reorder the page within the same queue while just
 *          holding the queue's spin-lock.
 *
 * Please see the flags section below for flag documentation.
 */
TAILQ_HEAD(pglist, vm_page);

struct vm_object;

int rb_vm_page_compare(struct vm_page *, struct vm_page *);

struct vm_page_rb_tree;
RB_PROTOTYPE2(vm_page_rb_tree, vm_page, rb_entry,
              rb_vm_page_compare, vm_pindex_t);
RB_HEAD(vm_page_rb_tree, vm_page);

struct vm_page {
        TAILQ_ENTRY(vm_page) pageq;     /* vm_page_queues[] list        */
        RB_ENTRY(vm_page) rb_entry;     /* Red-Black tree based at object */
        struct spinlock spin;
        struct md_page md;              /* machine dependant stuff */
        uint32_t wire_count;            /* wired down maps refs (P) */
        uint32_t busy_count;            /* soft-busy and hard-busy */
        int     hold_count;             /* page hold count */
        int     ku_pagecnt;             /* help kmalloc() w/oversized allocs */
        struct vm_object *object;       /* which object am I in */
        vm_pindex_t pindex;             /* offset into object */
        vm_paddr_t phys_addr;           /* physical address of page */
        uint16_t queue;                 /* page queue index */
        uint16_t pc;                    /* page color */
        uint8_t act_count;              /* page usage count */
        uint8_t pat_mode;               /* hardware page attribute */
        uint8_t valid;                  /* map of valid DEV_BSIZE chunks */
        uint8_t dirty;                  /* map of dirty DEV_BSIZE chunks */
        uint32_t flags;                 /* see below */
        int     unused01;               /* available */
        /* 128 bytes */
#ifdef VM_PAGE_DEBUG
        const char *busy_func;
        int     busy_line;
#endif
};

#define PBUSY_LOCKED            0x80000000U
#define PBUSY_WANTED            0x40000000U
#define PBUSY_SWAPINPROG        0x20000000U
#define PBUSY_MASK              0x1FFFFFFFU

#ifndef __VM_PAGE_T_DEFINED__
#define __VM_PAGE_T_DEFINED__
typedef struct vm_page *vm_page_t;
#endif

/*
 * Page coloring parameters.  We use generous parameters designed to
 * statistically spread pages over available cpu cache space.  This has
 * become less important over time as cache associativity is higher
 * in modern times but we still use the core algorithm to help reduce
 * lock contention between cpus.
 *
 * Page coloring cannot be disabled.
 *
 * In today's world of many-core systems, we must be able to provide enough VM
 * page queues for each logical cpu thread to cover the L1/L2/L3 cache set
 * associativity.  If we don't, the cpu caches will not be properly utilized.
 *
 * Using 2048 allows 8-way set-assoc with 256 logical cpus, but seems to
 * have a number of downsides when queues are assymetrically starved.
 *
 * Using 1024 allows 4-way set-assoc with 256 logical cpus, and more with
 * fewer cpus.
 */
#define PQ_PRIME1 31    /* Prime number somewhat less than PQ_HASH_SIZE */
#define PQ_PRIME2 23    /* Prime number somewhat less than PQ_HASH_SIZE */
#define PQ_L2_SIZE 1024 /* Must be enough for maximal ncpus x hw set-assoc */
#define PQ_L2_MASK      (PQ_L2_SIZE - 1)

#define PQ_NONE         0
#define PQ_FREE         (1 + 0*PQ_L2_SIZE)
#define PQ_INACTIVE     (1 + 1*PQ_L2_SIZE)
#define PQ_ACTIVE       (1 + 2*PQ_L2_SIZE)
#define PQ_CACHE        (1 + 3*PQ_L2_SIZE)
#define PQ_HOLD         (1 + 4*PQ_L2_SIZE)
#define PQ_COUNT        (1 + 5*PQ_L2_SIZE)

/*
 * Scan support
 */
struct vm_map;

struct rb_vm_page_scan_info {
        vm_pindex_t     start_pindex;
        vm_pindex_t     end_pindex;
        int             limit;
        int             desired;
        int             error;
        int             pagerflags;
        int             count;
        int             unused01;
        vm_offset_t     addr;
        struct vm_map_entry *entry;
        struct vm_object *object;
        struct vm_object *dest_object;
        struct vm_page  *mpte;
        struct pmap     *pmap;
        struct vm_map   *map;
};

int rb_vm_page_scancmp(struct vm_page *, void *);

struct vpgqueues {
        struct spinlock spin;
        struct pglist pl;
        long    lcnt;
        long    adds;           /* heuristic, add operations */
        int     cnt_offset;     /* offset into vmstats structure (int) */
        int     lastq;          /* heuristic, skip empty queues */
} __aligned(64);

extern struct vpgqueues vm_page_queues[PQ_COUNT];

/*
 * The m->flags field is generally categorized as follows.  Unless otherwise
 * noted, a flag may only be updated while the page is hard-busied.
 *
 * PG_VPTMAPPED    - Indicates that this page MIGHT be mapped via a
 *                   VPAGETABLE region. Used by vkernels. The backing_list
 *                   scan cannot find these mappings, so cooperative
 *                   invalidation via MADV_INVAL is required.
 *
 * PG_UNQUEUED     - This prevents the page from being placed on any queue.
 *
 * PG_FICTITIOUS   - This indicates to the pmap subsystem that the
 *                   page might not be reverse-addressable via
 *                   PHYS_TO_VM_PAGE().   The vm_page_t might be
 *                   temporary and not exist in the vm_page_array[].
 *
 *                   This also generally means that the pmap subsystem
 *                   cannot synchronize the [M]odified and [A]ccessed
 *                   bits with the related vm_page_t, and in fact that
 *                   there might not even BE a related vm_page_t.
 *
 *                   Unlike the old system, the new pmap subsystem is
 *                   able to do bulk operations on virtual address ranges
 *                   containing fictitious pages, and can also pick-out
 *                   specific fictitious pages by matching m->phys_addr
 *                   if you supply a fake vm_page to it.
 *
 *                   Fictitious pages can still be organized into vm_objects
 *                   if desired.
 *
 * PG_MAPPED       - Indicates that the page MIGHT be mapped into a pmap.
 *                   If not set, guarantees that the page is not mapped.
 *
 *                   This bit can be set unlocked but only cleared while
 *                   vm_page is hard-busied.
 *
 *                   For FICTITIOUS pages, this bit will be set automatically
 *                   via a page fault (aka pmap_enter()), but must be cleared
 *                   manually.
 *
 * PG_MAPPEDMULTI  - Possibly mapped to multiple pmaps or to multiple locations
 *                   ine one pmap.
 *
 * PG_WRITEABLE    - Indicates that the page MIGHT be writeable via a pte.
 *                   If not set, guarantees that the page is not writeable.
 *
 *                   This bit can be set unlocked but only cleared while
 *                   vm_page is hard-busied.
 *
 *                   For FICTITIOUS pages, this bit will be set automatically
 *                   via a page fault (aka pmap_enter()), but must be cleared
 *                   manually.
 *
 * PG_SWAPPED      - Indicates that the page is backed by a swap block.
 *                   Any VM object type other than OBJT_DEFAULT can contain
 *                   swap-backed pages now.  The bit may only be adjusted
 *                   while the page is hard-busied.
 *
 * PG_RAM          - Heuristic read-ahead-marker.  When I/O brings pages in,
 *                   this bit is set on one of them to force a page fault on
 *                   it to proactively read-ahead additional pages.
 *
 *                   Can be set or cleared at any time unlocked.
 *
 * PG_WINATCFLS    - This is used to give dirty pages a second chance
 *                   on the inactive queue before getting flushed by
 *                   the pageout daemon.
 *
 * PG_REFERENCED   - Indicates that the page has been accessed.  If the
 *                   page is PG_MAPPED, this bit might not reflect the
 *                   actual state of the page.  The pmap code synchronizes
 *                   the [A]ccessed bit to this flag and then clears the
 *                   [A]ccessed bit.
 *
 * PG_MARKER       - Used by any queue-scanning code to recognize a fake
 *                   vm_page being used only as a scan marker.
 *
 * PG_NOTMETA      - Distinguish pages representing content from pages
 *                   representing meta-data.
 *
 * PG_NEED_COMMIT  - May only be modified while the page is hard-busied.
 *                   Indicates that even if the page might not appear to
 *                   be dirty, it must still be validated against some
 *                   remote entity (e.g. NFS) before it can be thrown away.
 *
 * PG_CLEANCHK     - Used by the vm_object subsystem to detect pages that
 *                   might have been inserted during a scan.  May be changed
 *                   at any time by the VM system (usually while holding the
 *                   related vm_object's lock).
 */
#if 0
#define PG_VPTMAPPED    0x00000001      /* mapped via VPAGETABLE */
#else
#define PG_UNUSED0001   0x00000001
#endif
#define PG_UNUSED0002   0x00000002
#define PG_WINATCFLS    0x00000004      /* flush dirty page on inactive q */
#define PG_FICTITIOUS   0x00000008      /* No reverse-map or tracking */
#define PG_WRITEABLE    0x00000010      /* page may be writeable */
#define PG_MAPPED       0x00000020      /* page may be mapped (managed) */
#define PG_MAPPEDMULTI  0x00000040      /* multiple mappings */
#define PG_REFERENCED   0x00000080      /* page has been referenced */
#define PG_CLEANCHK     0x00000100      /* page will be checked for cleaning */
#define PG_UNUSED0200   0x00000200
#define PG_NOSYNC       0x00000400      /* do not collect for syncer */
#define PG_UNQUEUED     0x00000800      /* No queue management for page */
#define PG_MARKER       0x00001000      /* special queue marker page */
#define PG_RAM          0x00002000      /* read ahead mark */
#define PG_SWAPPED      0x00004000      /* backed by swap */
#define PG_NOTMETA      0x00008000      /* do not back with swap */
#define PG_UNUSED10000  0x00010000
#define PG_UNUSED20000  0x00020000
#define PG_NEED_COMMIT  0x00040000      /* clean page requires commit */

#define PG_KEEP_NEWPAGE_MASK    (0)

/*
 * Misc constants.
 */

#define ACT_DECLINE             1
#define ACT_ADVANCE             3
#define ACT_INIT                5
#define ACT_MAX                 64

#ifdef VM_PAGE_DEBUG
#define VM_PAGE_DEBUG_EXT(name) name ## _debug
#define VM_PAGE_DEBUG_ARGS      , const char *func, int lineno
#else
#define VM_PAGE_DEBUG_EXT(name) name
#define VM_PAGE_DEBUG_ARGS
#endif

#ifdef _KERNEL
/*
 * Each pageable resident page falls into one of four lists:
 *
 *      free
 *              Available for allocation now.
 *
 * The following are all LRU sorted:
 *
 *      cache
 *              Almost available for allocation. Still in an
 *              object, but clean and immediately freeable at
 *              non-interrupt times.
 *
 *      inactive
 *              Low activity, candidates for reclamation.
 *              This is the list of pages that should be
 *              paged out next.
 *
 *      active
 *              Pages that are "active" i.e. they have been
 *              recently referenced.
 *
 *      zero
 *              Pages that are really free and have been pre-zeroed
 *
 */

extern struct vm_page *vm_page_array;   /* First resident page in table */
extern vm_pindex_t vm_page_array_size;  /* number of vm_page_t's */
extern vm_pindex_t first_page;          /* first physical page number */

#define VM_PAGE_TO_PHYS(entry)  \
                ((entry)->phys_addr)

#define PHYS_TO_VM_PAGE(pa)     \
                (&vm_page_array[atop(pa) - first_page])


#if PAGE_SIZE == 4096
#define VM_PAGE_BITS_ALL 0xff
#endif

/*
 * Note: the code will always use nominally free pages from the free list
 * before trying other flag-specified sources. 
 *
 * At least one of VM_ALLOC_NORMAL|VM_ALLOC_SYSTEM|VM_ALLOC_INTERRUPT 
 * must be specified.  VM_ALLOC_RETRY may only be specified if VM_ALLOC_NORMAL
 * is also specified.
 */
#define VM_ALLOC_NORMAL         0x0001  /* ok to use cache pages */
#define VM_ALLOC_SYSTEM         0x0002  /* ok to exhaust most of free list */
#define VM_ALLOC_INTERRUPT      0x0004  /* ok to exhaust entire free list */
#define VM_ALLOC_ZERO           0x0008  /* req pre-zero'd memory if avail */
#define VM_ALLOC_QUICK          0x0010  /* like NORMAL but do not use cache */
#define VM_ALLOC_FORCE_ZERO     0x0020  /* zero page even if already valid */
#define VM_ALLOC_NULL_OK        0x0040  /* ok to return NULL on collision */
#define VM_ALLOC_RETRY          0x0080  /* indefinite block (vm_page_grab()) */
#define VM_ALLOC_USE_GD         0x0100  /* use per-gd cache */
#define VM_ALLOC_CPU_SPEC       0x0200

#define VM_ALLOC_CPU_SHIFT      16
#define VM_ALLOC_CPU(n)         (((n) << VM_ALLOC_CPU_SHIFT) | \
                                 VM_ALLOC_CPU_SPEC)
#define VM_ALLOC_GETCPU(flags)  ((flags) >> VM_ALLOC_CPU_SHIFT)

void vm_page_queue_spin_lock(vm_page_t);
void vm_page_queues_spin_lock(u_short);
void vm_page_and_queue_spin_lock(vm_page_t);

void vm_page_queue_spin_unlock(vm_page_t);
void vm_page_queues_spin_unlock(u_short);
void vm_page_and_queue_spin_unlock(vm_page_t m);

void vm_page_init(vm_page_t m);
void vm_page_io_finish(vm_page_t m);
void vm_page_io_start(vm_page_t m);
void vm_page_need_commit(vm_page_t m);
void vm_page_clear_commit(vm_page_t m);
void vm_page_wakeup(vm_page_t m);
void vm_page_hold(vm_page_t);
void vm_page_unhold(vm_page_t);
void vm_page_activate (vm_page_t);
void vm_page_soft_activate (vm_page_t);

vm_size_t vm_contig_avail_pages(void);
vm_page_t vm_page_alloc (struct vm_object *, vm_pindex_t, int);
vm_page_t vm_page_alloczwq (vm_pindex_t, int);
void vm_page_freezwq (vm_page_t m);
vm_page_t vm_page_alloc_contig(vm_paddr_t low, vm_paddr_t high,
                     unsigned long alignment, unsigned long boundary,
                     unsigned long size, vm_memattr_t memattr);

vm_page_t vm_page_grab (struct vm_object *, vm_pindex_t, int);
void vm_page_cache (vm_page_t);
int vm_page_try_to_cache (vm_page_t);
int vm_page_try_to_free (vm_page_t);
void vm_page_dontneed (vm_page_t);
void vm_page_deactivate (vm_page_t);
void vm_page_deactivate_locked (vm_page_t);
void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr);
int vm_page_insert (vm_page_t, struct vm_object *, vm_pindex_t);

vm_page_t vm_page_hash_get(vm_object_t object, vm_pindex_t pindex);

vm_page_t vm_page_lookup (struct vm_object *, vm_pindex_t);
vm_page_t vm_page_lookup_sbusy_try(struct vm_object *object,
                vm_pindex_t pindex, int pgoff, int pgbytes);
vm_page_t VM_PAGE_DEBUG_EXT(vm_page_lookup_busy_wait)(
                struct vm_object *, vm_pindex_t, int, const char *
                VM_PAGE_DEBUG_ARGS);
vm_page_t VM_PAGE_DEBUG_EXT(vm_page_lookup_busy_try)(
                struct vm_object *, vm_pindex_t, int, int *
                VM_PAGE_DEBUG_ARGS);
void vm_page_remove (vm_page_t);
void vm_page_rename (vm_page_t, struct vm_object *, vm_pindex_t);
void vm_page_startup (void);
void vm_numa_organize(vm_paddr_t ran_beg, vm_paddr_t bytes, int physid);
void vm_numa_organize_finalize(void);
void vm_page_unwire (vm_page_t, int);
void vm_page_wire (vm_page_t);
void vm_page_unqueue (vm_page_t);
void vm_page_unqueue_nowakeup (vm_page_t);
vm_page_t vm_page_next (vm_page_t);
void vm_page_set_validclean (vm_page_t, int, int);
void vm_page_set_validdirty (vm_page_t, int, int);
void vm_page_set_valid (vm_page_t, int, int);
void vm_page_set_dirty (vm_page_t, int, int);
void vm_page_clear_dirty (vm_page_t, int, int);
void vm_page_set_invalid (vm_page_t, int, int);
int vm_page_is_valid (vm_page_t, int, int);
void vm_page_test_dirty (vm_page_t);
int vm_page_bits (int, int);
vm_page_t vm_page_list_find(int basequeue, int index);
void vm_page_zero_invalid(vm_page_t m, boolean_t setvalid);
void vm_page_free_toq(vm_page_t m);
void vm_page_free_contig(vm_page_t m, unsigned long size);
vm_page_t vm_page_free_fromq_fast(void);
void vm_page_dirty(vm_page_t m);
void vm_page_sleep_busy(vm_page_t m, int also_m_busy, const char *msg);
int vm_page_sbusy_try(vm_page_t m);
void VM_PAGE_DEBUG_EXT(vm_page_busy_wait)(vm_page_t m,
                        int also_m_busy, const char *wmsg VM_PAGE_DEBUG_ARGS);
int VM_PAGE_DEBUG_EXT(vm_page_busy_try)(vm_page_t m,
                        int also_m_busy VM_PAGE_DEBUG_ARGS);
u_short vm_get_pg_color(int cpuid, vm_object_t object, vm_pindex_t pindex);

#ifdef VM_PAGE_DEBUG

#define vm_page_lookup_busy_wait(object, pindex, alsob, msg)            \
        vm_page_lookup_busy_wait_debug(object, pindex, alsob, msg,      \
                                        __func__, __LINE__)

#define vm_page_lookup_busy_try(object, pindex, alsob, errorp)          \
        vm_page_lookup_busy_try_debug(object, pindex, alsob, errorp,    \
                                        __func__, __LINE__)

#define vm_page_busy_wait(m, alsob, msg)                                \
        vm_page_busy_wait_debug(m, alsob, msg, __func__, __LINE__)

#define vm_page_busy_try(m, alsob)                                      \
        vm_page_busy_try_debug(m, alsob, __func__, __LINE__)

#endif

#endif                          /* _KERNEL */
#endif                          /* !_VM_VM_PAGE_H_ */