ia64/xen-unstable

changeset 1222:78af768e6129

bitkeeper revision 1.825.2.2 (4062dbfdjYJh7FL2Kx-eM_Gi_X4N-w)

merge cleanup
author iap10@tetris.cl.cam.ac.uk
date Thu Mar 25 13:17:49 2004 +0000 (2004-03-25)
parents 0b18f5295cff
children 9eb1d25256fa
files .rootkeys xen/common/kernel.c xen/common/shadow.c xen/include/xen/shadow.h xen/include/xeno/shadow.h
line diff
     1.1 --- a/.rootkeys	Thu Mar 25 12:37:30 2004 +0000
     1.2 +++ b/.rootkeys	Thu Mar 25 13:17:49 2004 +0000
     1.3 @@ -575,6 +575,7 @@ 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/inclu
     1.4  40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h
     1.5  3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen/include/xen/sched.h
     1.6  403a06a7H0hpHcKpAiDe5BPnaXWTlA xen/include/xen/serial.h
     1.7 +405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/xen/shadow.h
     1.8  3ddb79c0VDeD-Oft5eNfMneTU3D1dQ xen/include/xen/skbuff.h
     1.9  3ddb79c14dXIhP7C2ahnoD08K90G_w xen/include/xen/slab.h
    1.10  3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/include/xen/smp.h
    1.11 @@ -591,7 +592,6 @@ 3ddb79c1-kVvF8cVa0k3ZHDdBMj01Q xen/inclu
    1.12  3f055a3dwldYR102YcSuBaxIf9t3Jw xen/include/xen/vbd.h
    1.13  3e8827bdaqPeZAWGVOwswgY9bWSx4g xen/include/xen/version.h
    1.14  3ddb79c2Ae5KpzhC9LCYG7mP_Vi4Aw xen/include/xen/vif.h
    1.15 -405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/xeno/shadow.h
    1.16  3ddb79c4YQCQ6r0xNLLu0jfbM7pVmA xen/net/Makefile
    1.17  3ddb79c4AkfDkTCw0comx4L8wsUOMg xen/net/dev.c
    1.18  3ddb79c4x1L_soh8b-r_1jQW_37Icw xen/net/dev_mcast.c
     2.1 --- a/xen/common/kernel.c	Thu Mar 25 12:37:30 2004 +0000
     2.2 +++ b/xen/common/kernel.c	Thu Mar 25 13:17:49 2004 +0000
     2.3 @@ -107,7 +107,7 @@ void cmain(unsigned long magic, multiboo
     2.4      module_t *mod;
     2.5      void *heap_start;
     2.6      int i;
     2.7 -    unsigned long frametable_pages, max_mem;
     2.8 +    unsigned long max_mem;
     2.9  
    2.10      /* Parse the command-line options. */
    2.11      cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
     3.1 --- a/xen/common/shadow.c	Thu Mar 25 12:37:30 2004 +0000
     3.2 +++ b/xen/common/shadow.c	Thu Mar 25 13:17:49 2004 +0000
     3.3 @@ -1,9 +1,9 @@
     3.4  /* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*- */
     3.5  
     3.6 -#include <xeno/config.h>
     3.7 -#include <xeno/types.h>
     3.8 -#include <xeno/mm.h>
     3.9 -#include <xeno/shadow.h>
    3.10 +#include <xen/config.h>
    3.11 +#include <xen/types.h>
    3.12 +#include <xen/mm.h>
    3.13 +#include <xen/shadow.h>
    3.14  #include <asm/domain_page.h>
    3.15  #include <asm/page.h>
    3.16  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/include/xen/shadow.h	Thu Mar 25 13:17:49 2004 +0000
     4.3 @@ -0,0 +1,344 @@
     4.4 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*- */
     4.5 +
     4.6 +#ifndef _XENO_SHADOW_H
     4.7 +#define _XENO_SHADOW_H
     4.8 +
     4.9 +#include <xen/config.h>
    4.10 +#include <xen/types.h>
    4.11 +#include <xen/mm.h>
    4.12 +#include <xen/perfc.h>
    4.13 +
    4.14 +/* Shadow PT flag bits in pfn_info */
    4.15 +#define PSH_shadowed	(1<<31) /* page has a shadow. PFN points to shadow */
    4.16 +#define PSH_pending	    (1<<29) /* page is in the process of being shadowed */
    4.17 +#define PSH_pfn_mask	((1<<21)-1)
    4.18 +
    4.19 +/* Shadow PT operation mode : shadowmode variable in mm_struct */
    4.20 +#define SHM_test        (1<<0) /* just run domain on shadow PTs */
    4.21 +#define SHM_logdirty    (1<<1) /* log pages that are dirtied */
    4.22 +#define SHM_cow         (1<<2) /* copy on write all dirtied pages */
    4.23 +#define SHM_translate   (1<<3) /* lookup machine pages in translation table */
    4.24 +
    4.25 +#define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START)
    4.26 +#define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
    4.27 +
    4.28 +extern pagetable_t shadow_mk_pagetable( struct task_struct *p, 
    4.29 +										unsigned long gptbase);
    4.30 +extern int shadow_fault( unsigned long va, long error_code );
    4.31 +extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte, 
    4.32 +										unsigned long *prev_spfn_ptr,
    4.33 +										l1_pgentry_t **prev_spl1e_ptr  );
    4.34 +extern void shadow_l2_normal_pt_update( unsigned long pa, unsigned long gpte );
    4.35 +extern void unshadow_table( unsigned long gpfn, unsigned int type );
    4.36 +extern int shadow_mode_enable( struct task_struct *p, unsigned int mode );
    4.37 +
    4.38 +#define SHADOW_DEBUG 0
    4.39 +#define SHADOW_HASH_DEBUG 0
    4.40 +#define SHADOW_OPTIMISE 1
    4.41 +
    4.42 +struct shadow_status {
    4.43 +    unsigned long pfn;            // gpfn 
    4.44 +    unsigned long spfn_and_flags; // spfn plus flags
    4.45 +    struct shadow_status *next;   // use pull-to-front list.
    4.46 +};
    4.47 +
    4.48 +#define shadow_ht_extra_size         128 /*128*/
    4.49 +#define shadow_ht_buckets            256 /*256*/
    4.50 +
    4.51 +#ifndef NDEBUG
    4.52 +#define SH_LOG(_f, _a...)                             \
    4.53 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    4.54 +         current->domain , __LINE__ , ## _a )
    4.55 +#else
    4.56 +#define SH_LOG(_f, _a...) 
    4.57 +#endif
    4.58 +
    4.59 +#if SHADOW_DEBUG
    4.60 +#define SH_VLOG(_f, _a...)                             \
    4.61 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    4.62 +         current->domain , __LINE__ , ## _a )
    4.63 +#else
    4.64 +#define SH_VLOG(_f, _a...) 
    4.65 +#endif
    4.66 +
    4.67 +#if 0
    4.68 +#define SH_VVLOG(_f, _a...)                             \
    4.69 +  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    4.70 +         current->domain , __LINE__ , ## _a )
    4.71 +#else
    4.72 +#define SH_VVLOG(_f, _a...) 
    4.73 +#endif
    4.74 +
    4.75 +
    4.76 +
    4.77 +#if SHADOW_HASH_DEBUG
    4.78 +static void shadow_audit(struct task_struct *p, int print)
    4.79 +{
    4.80 +	int live=0, free=0, j=0, abs;
    4.81 +	struct shadow_status *a;
    4.82 +	
    4.83 +    for(j=0;j<shadow_ht_buckets;j++)
    4.84 +    {
    4.85 +        a = &p->mm.shadow_ht[j];        
    4.86 +		if(a->pfn) live++;
    4.87 +        while(a->next && live<9999)
    4.88 +		{ 
    4.89 +			live++; 
    4.90 +			if(a->pfn == 0)
    4.91 +			{
    4.92 +				printk("XXX live=%d pfn=%08lx sp=%08lx next=%p\n",
    4.93 +					   live, a->pfn, a->spfn_and_flags, a->next);
    4.94 +				BUG();
    4.95 +			}
    4.96 +			a=a->next; 
    4.97 +		}
    4.98 +		ASSERT(live<9999);
    4.99 +	}
   4.100 +
   4.101 +    a = p->mm.shadow_ht_free;
   4.102 +    while(a) { free++; a=a->next; }
   4.103 +
   4.104 +    if(print) printk("live=%d free=%d\n",live,free);
   4.105 +
   4.106 +	abs=(perfc_value(shadow_l1_pages)+perfc_value(shadow_l2_pages))-live;
   4.107 +	if( abs < -1 || abs > 1 )
   4.108 +	{
   4.109 +		printk("live=%d free=%d l1=%d l2=%d\n",live,free,
   4.110 +			  perfc_value(shadow_l1_pages), perfc_value(shadow_l2_pages) );
   4.111 +		BUG();
   4.112 +    }
   4.113 +
   4.114 +}
   4.115 +
   4.116 +#else
   4.117 +#define shadow_audit(p, print)
   4.118 +#endif
   4.119 +
   4.120 +static inline struct shadow_status* hash_bucket( struct task_struct *p,
   4.121 +												 unsigned int gpfn )
   4.122 +{
   4.123 +    return &(p->mm.shadow_ht[gpfn % shadow_ht_buckets]);
   4.124 +}
   4.125 +
   4.126 +
   4.127 +static inline unsigned long __shadow_status( struct task_struct *p,
   4.128 +										   unsigned int gpfn )
   4.129 +{
   4.130 +	struct shadow_status **ob, *b, *B = hash_bucket( p, gpfn );
   4.131 +
   4.132 +    b = B;
   4.133 +    ob = NULL;
   4.134 +
   4.135 +	SH_VVLOG("lookup gpfn=%08lx bucket=%08lx", gpfn, b );
   4.136 +	shadow_audit(p,0);  // if in debug mode
   4.137 +
   4.138 +	do
   4.139 +	{
   4.140 +		if ( b->pfn == gpfn )
   4.141 +		{
   4.142 +			unsigned long t;
   4.143 +			struct shadow_status *x;
   4.144 +
   4.145 +			// swap with head
   4.146 +			t=B->pfn; B->pfn=b->pfn; b->pfn=t;
   4.147 +			t=B->spfn_and_flags; B->spfn_and_flags=b->spfn_and_flags; 
   4.148 +			    b->spfn_and_flags=t;
   4.149 +
   4.150 +			if(ob)
   4.151 +			{   // pull to front
   4.152 +				*ob=b->next;
   4.153 +				x=B->next;
   4.154 +				B->next=b;	
   4.155 +				b->next=x;
   4.156 +			}			
   4.157 +			return B->spfn_and_flags;
   4.158 +		}
   4.159 +#if SHADOW_HASH_DEBUG
   4.160 +		else
   4.161 +		{
   4.162 +			if(b!=B)ASSERT(b->pfn);
   4.163 +		}
   4.164 +#endif
   4.165 +		ob=&b->next;
   4.166 +		b=b->next;
   4.167 +	}
   4.168 +	while (b);
   4.169 +
   4.170 +	return 0;
   4.171 +}
   4.172 +
   4.173 +/* we can make this locking more fine grained e.g. per shadow page if it 
   4.174 +ever becomes a problem, but since we need a spin lock on the hash table 
   4.175 +anyway its probably not worth being too clever. */
   4.176 +
   4.177 +static inline unsigned long get_shadow_status( struct task_struct *p,
   4.178 +										   unsigned int gpfn )
   4.179 +{
   4.180 +	unsigned long res;
   4.181 +
   4.182 +	spin_lock(&p->mm.shadow_lock);
   4.183 +	res = __shadow_status( p, gpfn );
   4.184 +	if (!res) spin_unlock(&p->mm.shadow_lock);
   4.185 +	return res;
   4.186 +}
   4.187 +
   4.188 +
   4.189 +static inline void put_shadow_status( struct task_struct *p )
   4.190 +{
   4.191 +	spin_unlock(&p->mm.shadow_lock);
   4.192 +}
   4.193 +
   4.194 +
   4.195 +static inline void delete_shadow_status( struct task_struct *p,
   4.196 +									  unsigned int gpfn )
   4.197 +{
   4.198 +	struct shadow_status *b, *B, **ob;
   4.199 +
   4.200 +	B = b = hash_bucket( p, gpfn );
   4.201 +
   4.202 +	SH_VVLOG("delete gpfn=%08x bucket=%p", gpfn, b );
   4.203 +	shadow_audit(p,0);
   4.204 +	ASSERT(gpfn);
   4.205 +
   4.206 +	if( b->pfn == gpfn )
   4.207 +    {
   4.208 +		if (b->next)
   4.209 +		{
   4.210 +			struct shadow_status *D=b->next;
   4.211 +			b->spfn_and_flags = b->next->spfn_and_flags;
   4.212 +			b->pfn = b->next->pfn;
   4.213 +
   4.214 +			b->next = b->next->next;
   4.215 +			D->next = p->mm.shadow_ht_free;
   4.216 +			p->mm.shadow_ht_free = D;
   4.217 +		}
   4.218 +		else
   4.219 +		{
   4.220 +			b->pfn = 0;
   4.221 +			b->spfn_and_flags = 0;
   4.222 +		}
   4.223 +
   4.224 +#if SHADOW_HASH_DEBUG
   4.225 +		if( __shadow_status(p,gpfn) ) BUG();  
   4.226 +#endif
   4.227 +		return;
   4.228 +    }
   4.229 +
   4.230 +	ob = &b->next;
   4.231 +	b=b->next;
   4.232 +
   4.233 +	do
   4.234 +	{
   4.235 +		if ( b->pfn == gpfn )			
   4.236 +		{
   4.237 +			b->pfn = 0;
   4.238 +			b->spfn_and_flags = 0;
   4.239 +
   4.240 +			// b is in the list
   4.241 +            *ob=b->next;
   4.242 +			b->next = p->mm.shadow_ht_free;
   4.243 +			p->mm.shadow_ht_free = b;
   4.244 +
   4.245 +#if SHADOW_HASH_DEBUG
   4.246 +			if( __shadow_status(p,gpfn) ) BUG();
   4.247 +#endif
   4.248 +			return;
   4.249 +		}
   4.250 +
   4.251 +		ob = &b->next;
   4.252 +		b=b->next;
   4.253 +	}
   4.254 +	while (b);
   4.255 +
   4.256 +	// if we got here, it wasn't in the list
   4.257 +    BUG();
   4.258 +}
   4.259 +
   4.260 +
   4.261 +static inline void set_shadow_status( struct task_struct *p,
   4.262 +									  unsigned int gpfn, unsigned long s )
   4.263 +{
   4.264 +	struct shadow_status *b, *B, *extra, **fptr;
   4.265 +    int i;
   4.266 +
   4.267 +	B = b = hash_bucket( p, gpfn );
   4.268 +   
   4.269 +    ASSERT(gpfn);
   4.270 +    ASSERT(s);
   4.271 +    SH_VVLOG("set gpfn=%08x s=%08lx bucket=%p(%p)", gpfn, s, b, b->next );
   4.272 +    shadow_audit(p,0);
   4.273 +
   4.274 +	do
   4.275 +	{
   4.276 +		if ( b->pfn == gpfn )			
   4.277 +		{
   4.278 +			b->spfn_and_flags = s;
   4.279 +			return;
   4.280 +		}
   4.281 +
   4.282 +		b=b->next;
   4.283 +	}
   4.284 +	while (b);
   4.285 +
   4.286 +	// if we got here, this is an insert rather than update
   4.287 +
   4.288 +    ASSERT( s );  // deletes must have succeeded by here
   4.289 +
   4.290 +    if ( B->pfn == 0 )
   4.291 +	{
   4.292 +		// we can use this head
   4.293 +        ASSERT( B->next == 0 );
   4.294 +		B->pfn = gpfn;
   4.295 +		B->spfn_and_flags = s;
   4.296 +		return;
   4.297 +	}
   4.298 +
   4.299 +    if( unlikely(p->mm.shadow_ht_free == NULL) )
   4.300 +    {
   4.301 +        SH_LOG("allocate more shadow hashtable blocks");
   4.302 +
   4.303 +        // we need to allocate more space
   4.304 +        extra = kmalloc( sizeof(void*) + (shadow_ht_extra_size * 
   4.305 +							   sizeof(struct shadow_status)), GFP_KERNEL );
   4.306 +
   4.307 +	    if( ! extra ) BUG(); // should be more graceful here....
   4.308 +
   4.309 +	    memset( extra, 0, sizeof(void*) + (shadow_ht_extra_size * 
   4.310 +							   sizeof(struct shadow_status)) );
   4.311 +	
   4.312 +        // add extras to free list
   4.313 +	    fptr = &p->mm.shadow_ht_free;
   4.314 +	    for ( i=0; i<shadow_ht_extra_size; i++ )
   4.315 + 	    {
   4.316 +		    *fptr = &extra[i];
   4.317 +		    fptr = &(extra[i].next);
   4.318 +	    }
   4.319 +	    *fptr = NULL;
   4.320 +
   4.321 +	    *((struct shadow_status ** ) &p->mm.shadow_ht[shadow_ht_extra_size]) = 
   4.322 +                                            p->mm.shadow_ht_extras;
   4.323 +        p->mm.shadow_ht_extras = extra;
   4.324 +
   4.325 +    }
   4.326 +
   4.327 +	// should really put this in B to go right to front
   4.328 +	b = p->mm.shadow_ht_free;
   4.329 +    p->mm.shadow_ht_free = b->next;
   4.330 +    b->spfn_and_flags = s;
   4.331 +	b->pfn = gpfn;
   4.332 +	b->next = B->next;
   4.333 +	B->next = b;
   4.334 +
   4.335 +	return;
   4.336 +}
   4.337 +
   4.338 +
   4.339 +
   4.340 +#if SHADOW_DEBUG
   4.341 +extern int check_pagetable( struct task_struct *p, pagetable_t pt, char *s );
   4.342 +#else
   4.343 +#define check_pagetable( p, pt, s )
   4.344 +#endif
   4.345 +
   4.346 +
   4.347 +#endif
     5.1 --- a/xen/include/xeno/shadow.h	Thu Mar 25 12:37:30 2004 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,344 +0,0 @@
     5.4 -/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*- */
     5.5 -
     5.6 -#ifndef _XENO_SHADOW_H
     5.7 -#define _XENO_SHADOW_H
     5.8 -
     5.9 -#include <xeno/config.h>
    5.10 -#include <xeno/types.h>
    5.11 -#include <xeno/mm.h>
    5.12 -#include <xeno/perfc.h>
    5.13 -
    5.14 -/* Shadow PT flag bits in pfn_info */
    5.15 -#define PSH_shadowed	(1<<31) /* page has a shadow. PFN points to shadow */
    5.16 -#define PSH_pending	    (1<<29) /* page is in the process of being shadowed */
    5.17 -#define PSH_pfn_mask	((1<<21)-1)
    5.18 -
    5.19 -/* Shadow PT operation mode : shadowmode variable in mm_struct */
    5.20 -#define SHM_test        (1<<0) /* just run domain on shadow PTs */
    5.21 -#define SHM_logdirty    (1<<1) /* log pages that are dirtied */
    5.22 -#define SHM_cow         (1<<2) /* copy on write all dirtied pages */
    5.23 -#define SHM_translate   (1<<3) /* lookup machine pages in translation table */
    5.24 -
    5.25 -#define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START)
    5.26 -#define shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START+(SH_LINEAR_PT_VIRT_START>>(L2_PAGETABLE_SHIFT-L1_PAGETABLE_SHIFT))))
    5.27 -
    5.28 -extern pagetable_t shadow_mk_pagetable( struct task_struct *p, 
    5.29 -										unsigned long gptbase);
    5.30 -extern int shadow_fault( unsigned long va, long error_code );
    5.31 -extern void shadow_l1_normal_pt_update( unsigned long pa, unsigned long gpte, 
    5.32 -										unsigned long *prev_spfn_ptr,
    5.33 -										l1_pgentry_t **prev_spl1e_ptr  );
    5.34 -extern void shadow_l2_normal_pt_update( unsigned long pa, unsigned long gpte );
    5.35 -extern void unshadow_table( unsigned long gpfn, unsigned int type );
    5.36 -extern int shadow_mode_enable( struct task_struct *p, unsigned int mode );
    5.37 -
    5.38 -#define SHADOW_DEBUG 0
    5.39 -#define SHADOW_HASH_DEBUG 0
    5.40 -#define SHADOW_OPTIMISE 1
    5.41 -
    5.42 -struct shadow_status {
    5.43 -    unsigned long pfn;            // gpfn 
    5.44 -    unsigned long spfn_and_flags; // spfn plus flags
    5.45 -    struct shadow_status *next;   // use pull-to-front list.
    5.46 -};
    5.47 -
    5.48 -#define shadow_ht_extra_size         128 /*128*/
    5.49 -#define shadow_ht_buckets            256 /*256*/
    5.50 -
    5.51 -#ifndef NDEBUG
    5.52 -#define SH_LOG(_f, _a...)                             \
    5.53 -  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    5.54 -         current->domain , __LINE__ , ## _a )
    5.55 -#else
    5.56 -#define SH_LOG(_f, _a...) 
    5.57 -#endif
    5.58 -
    5.59 -#if SHADOW_DEBUG
    5.60 -#define SH_VLOG(_f, _a...)                             \
    5.61 -  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    5.62 -         current->domain , __LINE__ , ## _a )
    5.63 -#else
    5.64 -#define SH_VLOG(_f, _a...) 
    5.65 -#endif
    5.66 -
    5.67 -#if 0
    5.68 -#define SH_VVLOG(_f, _a...)                             \
    5.69 -  printk("DOM%llu: (file=shadow.c, line=%d) " _f "\n", \
    5.70 -         current->domain , __LINE__ , ## _a )
    5.71 -#else
    5.72 -#define SH_VVLOG(_f, _a...) 
    5.73 -#endif
    5.74 -
    5.75 -
    5.76 -
    5.77 -#if SHADOW_HASH_DEBUG
    5.78 -static void shadow_audit(struct task_struct *p, int print)
    5.79 -{
    5.80 -	int live=0, free=0, j=0, abs;
    5.81 -	struct shadow_status *a;
    5.82 -	
    5.83 -    for(j=0;j<shadow_ht_buckets;j++)
    5.84 -    {
    5.85 -        a = &p->mm.shadow_ht[j];        
    5.86 -		if(a->pfn) live++;
    5.87 -        while(a->next && live<9999)
    5.88 -		{ 
    5.89 -			live++; 
    5.90 -			if(a->pfn == 0)
    5.91 -			{
    5.92 -				printk("XXX live=%d pfn=%08lx sp=%08lx next=%p\n",
    5.93 -					   live, a->pfn, a->spfn_and_flags, a->next);
    5.94 -				BUG();
    5.95 -			}
    5.96 -			a=a->next; 
    5.97 -		}
    5.98 -		ASSERT(live<9999);
    5.99 -	}
   5.100 -
   5.101 -    a = p->mm.shadow_ht_free;
   5.102 -    while(a) { free++; a=a->next; }
   5.103 -
   5.104 -    if(print) printk("live=%d free=%d\n",live,free);
   5.105 -
   5.106 -	abs=(perfc_value(shadow_l1_pages)+perfc_value(shadow_l2_pages))-live;
   5.107 -	if( abs < -1 || abs > 1 )
   5.108 -	{
   5.109 -		printk("live=%d free=%d l1=%d l2=%d\n",live,free,
   5.110 -			  perfc_value(shadow_l1_pages), perfc_value(shadow_l2_pages) );
   5.111 -		BUG();
   5.112 -    }
   5.113 -
   5.114 -}
   5.115 -
   5.116 -#else
   5.117 -#define shadow_audit(p, print)
   5.118 -#endif
   5.119 -
   5.120 -static inline struct shadow_status* hash_bucket( struct task_struct *p,
   5.121 -												 unsigned int gpfn )
   5.122 -{
   5.123 -    return &(p->mm.shadow_ht[gpfn % shadow_ht_buckets]);
   5.124 -}
   5.125 -
   5.126 -
   5.127 -static inline unsigned long __shadow_status( struct task_struct *p,
   5.128 -										   unsigned int gpfn )
   5.129 -{
   5.130 -	struct shadow_status **ob, *b, *B = hash_bucket( p, gpfn );
   5.131 -
   5.132 -    b = B;
   5.133 -    ob = NULL;
   5.134 -
   5.135 -	SH_VVLOG("lookup gpfn=%08lx bucket=%08lx", gpfn, b );
   5.136 -	shadow_audit(p,0);  // if in debug mode
   5.137 -
   5.138 -	do
   5.139 -	{
   5.140 -		if ( b->pfn == gpfn )
   5.141 -		{
   5.142 -			unsigned long t;
   5.143 -			struct shadow_status *x;
   5.144 -
   5.145 -			// swap with head
   5.146 -			t=B->pfn; B->pfn=b->pfn; b->pfn=t;
   5.147 -			t=B->spfn_and_flags; B->spfn_and_flags=b->spfn_and_flags; 
   5.148 -			    b->spfn_and_flags=t;
   5.149 -
   5.150 -			if(ob)
   5.151 -			{   // pull to front
   5.152 -				*ob=b->next;
   5.153 -				x=B->next;
   5.154 -				B->next=b;	
   5.155 -				b->next=x;
   5.156 -			}			
   5.157 -			return B->spfn_and_flags;
   5.158 -		}
   5.159 -#if SHADOW_HASH_DEBUG
   5.160 -		else
   5.161 -		{
   5.162 -			if(b!=B)ASSERT(b->pfn);
   5.163 -		}
   5.164 -#endif
   5.165 -		ob=&b->next;
   5.166 -		b=b->next;
   5.167 -	}
   5.168 -	while (b);
   5.169 -
   5.170 -	return 0;
   5.171 -}
   5.172 -
   5.173 -/* we can make this locking more fine grained e.g. per shadow page if it 
   5.174 -ever becomes a problem, but since we need a spin lock on the hash table 
   5.175 -anyway its probably not worth being too clever. */
   5.176 -
   5.177 -static inline unsigned long get_shadow_status( struct task_struct *p,
   5.178 -										   unsigned int gpfn )
   5.179 -{
   5.180 -	unsigned long res;
   5.181 -
   5.182 -	spin_lock(&p->mm.shadow_lock);
   5.183 -	res = __shadow_status( p, gpfn );
   5.184 -	if (!res) spin_unlock(&p->mm.shadow_lock);
   5.185 -	return res;
   5.186 -}
   5.187 -
   5.188 -
   5.189 -static inline void put_shadow_status( struct task_struct *p )
   5.190 -{
   5.191 -	spin_unlock(&p->mm.shadow_lock);
   5.192 -}
   5.193 -
   5.194 -
   5.195 -static inline void delete_shadow_status( struct task_struct *p,
   5.196 -									  unsigned int gpfn )
   5.197 -{
   5.198 -	struct shadow_status *b, *B, **ob;
   5.199 -
   5.200 -	B = b = hash_bucket( p, gpfn );
   5.201 -
   5.202 -	SH_VVLOG("delete gpfn=%08x bucket=%p", gpfn, b );
   5.203 -	shadow_audit(p,0);
   5.204 -	ASSERT(gpfn);
   5.205 -
   5.206 -	if( b->pfn == gpfn )
   5.207 -    {
   5.208 -		if (b->next)
   5.209 -		{
   5.210 -			struct shadow_status *D=b->next;
   5.211 -			b->spfn_and_flags = b->next->spfn_and_flags;
   5.212 -			b->pfn = b->next->pfn;
   5.213 -
   5.214 -			b->next = b->next->next;
   5.215 -			D->next = p->mm.shadow_ht_free;
   5.216 -			p->mm.shadow_ht_free = D;
   5.217 -		}
   5.218 -		else
   5.219 -		{
   5.220 -			b->pfn = 0;
   5.221 -			b->spfn_and_flags = 0;
   5.222 -		}
   5.223 -
   5.224 -#if SHADOW_HASH_DEBUG
   5.225 -		if( __shadow_status(p,gpfn) ) BUG();  
   5.226 -#endif
   5.227 -		return;
   5.228 -    }
   5.229 -
   5.230 -	ob = &b->next;
   5.231 -	b=b->next;
   5.232 -
   5.233 -	do
   5.234 -	{
   5.235 -		if ( b->pfn == gpfn )			
   5.236 -		{
   5.237 -			b->pfn = 0;
   5.238 -			b->spfn_and_flags = 0;
   5.239 -
   5.240 -			// b is in the list
   5.241 -            *ob=b->next;
   5.242 -			b->next = p->mm.shadow_ht_free;
   5.243 -			p->mm.shadow_ht_free = b;
   5.244 -
   5.245 -#if SHADOW_HASH_DEBUG
   5.246 -			if( __shadow_status(p,gpfn) ) BUG();
   5.247 -#endif
   5.248 -			return;
   5.249 -		}
   5.250 -
   5.251 -		ob = &b->next;
   5.252 -		b=b->next;
   5.253 -	}
   5.254 -	while (b);
   5.255 -
   5.256 -	// if we got here, it wasn't in the list
   5.257 -    BUG();
   5.258 -}
   5.259 -
   5.260 -
   5.261 -static inline void set_shadow_status( struct task_struct *p,
   5.262 -									  unsigned int gpfn, unsigned long s )
   5.263 -{
   5.264 -	struct shadow_status *b, *B, *extra, **fptr;
   5.265 -    int i;
   5.266 -
   5.267 -	B = b = hash_bucket( p, gpfn );
   5.268 -   
   5.269 -    ASSERT(gpfn);
   5.270 -    ASSERT(s);
   5.271 -    SH_VVLOG("set gpfn=%08x s=%08lx bucket=%p(%p)", gpfn, s, b, b->next );
   5.272 -    shadow_audit(p,0);
   5.273 -
   5.274 -	do
   5.275 -	{
   5.276 -		if ( b->pfn == gpfn )			
   5.277 -		{
   5.278 -			b->spfn_and_flags = s;
   5.279 -			return;
   5.280 -		}
   5.281 -
   5.282 -		b=b->next;
   5.283 -	}
   5.284 -	while (b);
   5.285 -
   5.286 -	// if we got here, this is an insert rather than update
   5.287 -
   5.288 -    ASSERT( s );  // deletes must have succeeded by here
   5.289 -
   5.290 -    if ( B->pfn == 0 )
   5.291 -	{
   5.292 -		// we can use this head
   5.293 -        ASSERT( B->next == 0 );
   5.294 -		B->pfn = gpfn;
   5.295 -		B->spfn_and_flags = s;
   5.296 -		return;
   5.297 -	}
   5.298 -
   5.299 -    if( unlikely(p->mm.shadow_ht_free == NULL) )
   5.300 -    {
   5.301 -        SH_LOG("allocate more shadow hashtable blocks");
   5.302 -
   5.303 -        // we need to allocate more space
   5.304 -        extra = kmalloc( sizeof(void*) + (shadow_ht_extra_size * 
   5.305 -							   sizeof(struct shadow_status)), GFP_KERNEL );
   5.306 -
   5.307 -	    if( ! extra ) BUG(); // should be more graceful here....
   5.308 -
   5.309 -	    memset( extra, 0, sizeof(void*) + (shadow_ht_extra_size * 
   5.310 -							   sizeof(struct shadow_status)) );
   5.311 -	
   5.312 -        // add extras to free list
   5.313 -	    fptr = &p->mm.shadow_ht_free;
   5.314 -	    for ( i=0; i<shadow_ht_extra_size; i++ )
   5.315 - 	    {
   5.316 -		    *fptr = &extra[i];
   5.317 -		    fptr = &(extra[i].next);
   5.318 -	    }
   5.319 -	    *fptr = NULL;
   5.320 -
   5.321 -	    *((struct shadow_status ** ) &p->mm.shadow_ht[shadow_ht_extra_size]) = 
   5.322 -                                            p->mm.shadow_ht_extras;
   5.323 -        p->mm.shadow_ht_extras = extra;
   5.324 -
   5.325 -    }
   5.326 -
   5.327 -	// should really put this in B to go right to front
   5.328 -	b = p->mm.shadow_ht_free;
   5.329 -    p->mm.shadow_ht_free = b->next;
   5.330 -    b->spfn_and_flags = s;
   5.331 -	b->pfn = gpfn;
   5.332 -	b->next = B->next;
   5.333 -	B->next = b;
   5.334 -
   5.335 -	return;
   5.336 -}
   5.337 -
   5.338 -
   5.339 -
   5.340 -#if SHADOW_DEBUG
   5.341 -extern int check_pagetable( struct task_struct *p, pagetable_t pt, char *s );
   5.342 -#else
   5.343 -#define check_pagetable( p, pt, s )
   5.344 -#endif
   5.345 -
   5.346 -
   5.347 -#endif