From mboxrd@z Thu Jan 1 00:00:00 1970 From: tinnycloud Subject: [memory sharing] bug on get_page_and_type Date: Mon, 31 Jan 2011 18:13:24 +0800 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_000F_01CBC172.8D721E90" Return-path: Content-Language: zh-cn List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: 'xen devel' Cc: george.dunlap@eu.citrix.com, tim.deegan@citrix.com, juihaochiang@gmail.com List-Id: xen-devel@lists.xenproject.org ------=_NextPart_000_000F_01CBC172.8D721E90 Content-Type: multipart/alternative; boundary="----=_NextPart_001_0010_01CBC172.8D721E90" ------=_NextPart_001_0010_01CBC172.8D721E90 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi: Attached is the whole patch suit for latest xen-4.0-testing,changeset 21443, It comes from George, Tim and JuiHao, also, has some extra debug info. On most occasion, memory sharing works fine, but still exists a bug. I've been tracing this problem for a while. There is a bug on get_page_and_type() in mem_sharing_share_pages() --------------------------------------------mem_sharing_share_pages()------- ---------------- 789 if(!get_page_and_type(spage, dom_cow, PGT_shared_page)){ 790 mem_sharing_debug_gfn(cd, gfn->gfn); 791 mem_sharing_debug_gfn(sd, sgfn->gfn); 792 printk("c->dying %d s->dying %d spage %p se->mfn %lx\n", cd->is_dying, sd->is_dying, spage, se->mfn); 793 printk("Debug page: MFN=%lx is ci=%lx, ti=%lx, owner_id=%d\n", 794 mfn_x(page_to_mfn(spage)), 795 spage->count_info, 796 spage->u.inuse.type_info, 797 page_get_owner(spage)->domain_id); 798 BUG(); 799 } Below painc log contains the debug info from line 790-798. We saw that 180000000000000 which is PGC_state_free, So it looks like a shared page has been freed unexpectly. (XEN) teardown 64 (XEN) teardown 66 blktap_sysfs_destroy blktap_sysfs_create: adding attributes for dev ffff880109d0c200 blktap_sysfs_destroy __ratelimit: 1 callbacks suppressed blktap_sysfs_destroy (XEN) Debug for domain=83, gfn=1e8dc, Debug page: MFN=1306dc is ci=8000000000000005, ti=8400000000000001, owner_id=32755 (XEN) Debug for domain=79, gfn=1dc95, Invalid MFN=ffffffffffffffff (XEN) c->dying 0 s->dying 0 spage ffff82f60a0f12a0 se->mfn 507895 (XEN) Debug page: MFN=507895 is ci= 180000000000000, ti=8400000000000001, owner_id=32755 (XEN) Xen BUG at mem_sharing.c:798 (XEN) ----[ Xen-4.0.2-rc2-pre x86_64 debug=n Not tainted ]---- (XEN) CPU: 0 (XEN) RIP: e008:[] mem_sharing_share_pages+0x5b0/0x5d0 (XEN) RFLAGS: 0000000000010286 CONTEXT: hypervisor (XEN) rax: 0000000000000000 rbx: ffff83044ef76000 rcx: 0000000000000092 (XEN) rdx: 000000000000000a rsi: 000000000000000a rdi: ffff82c4802237c4 (XEN) rbp: ffff83030d99e310 rsp: ffff82c48035fc48 r8: 0000000000000001 (XEN) r9: 0000000000000001 r10: 00000000fffffff8 r11: 0000000000000005 (XEN) r12: ffff83050b558000 r13: ffff830626ec5740 r14: 0000000000347967 (XEN) r15: ffff83030d99e068 cr0: 0000000080050033 cr4: 00000000000026f0 (XEN) cr3: 000000010e642000 cr2: 00002abdc4809000 (XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: e010 cs: e008 (XEN) Xen stack trace from rsp=ffff82c48035fc48: (XEN) 000000000001e8dc ffff83030d99e068 0000000000507895 ffff83030d99e050 (XEN) ffff82f60a0f12a0 ffff82f60260db80 ffff83030d99e300 ffff830626afbbd0 (XEN) 0000000080372980 ffff82c48035fe38 ffff83023febe000 00000000008f7000 (XEN) 0000000000305000 0000000000000006 0000000000000006 ffff82c4801c44a4 (XEN) ffff82c480258188 ffff82c48011cb89 000000000001e8dc fffffffffffffff3 (XEN) ffff82c48035fe28 ffff82c480148503 000003d932971281 0000000000000080 (XEN) 000003d9329611d6 ffff82c48018aedf ffff82c4803903a8 ffff82c48035fd38 (XEN) ffff82c480390380 ffff82c48035fe28 0000000000000002 0000000000000000 (XEN) 0000000000000002 0000000000000000 ffff83023febe000 ffff83023ff80080 (XEN) ffff82c48035fe58 0000000000000000 ffff82c48022ca80 0000000000000000 (XEN) 0000000000000002 ffff82c48018a452 0000000000000000 ffff82c48016f6bb (XEN) ffff82c48035fe58 ffff82c4801538ea 000000023ab79067 fffffffffffffff3 (XEN) ffff82c48035fe28 00000000008f7000 0000000000305000 0000000000000006 (XEN) 0000000000000006 ffff82c4801042b3 0000000000000000 ffff82c48010d2a5 (XEN) ffff830477fb51e8 0000000000000000 00007ff000000200 ffff8300bf76e000 (XEN) 0000000600000039 0000000000000000 00007fc09d744003 0000000000325258 (XEN) 0000000000347967 ffffffffff600429 000000004d463b17 0000000000062fe2 (XEN) 0000000000000000 00007fc09d744070 00007fc09d744000 00007fffcfec0d20 (XEN) 00007fc09d744078 0000000000430fd8 00007fffcfec0d88 00000000019f1ca8 (XEN) 0000f05c00000000 00007fc09f4c2718 0000000000000000 0000000000000246 (XEN) Xen call trace: (XEN) [] mem_sharing_share_pages+0x5b0/0x5d0 (XEN) [] mem_sharing_domctl+0xe4/0x130 (XEN) [] cpumask_raise_softirq+0x89/0xa0 (XEN) [] arch_do_domctl+0x14f3/0x22d0 (XEN) [] handle_hpet_broadcast+0x16f/0x1d0 (XEN) [] hpet_legacy_irq_tick+0x42/0x50 (XEN) [] timer_interrupt+0xb/0x130 (XEN) [] ack_edge_ioapic_irq+0x2a/0x70 (XEN) [] do_domctl+0x163/0xfe0 (XEN) [] do_grant_table_op+0x75/0x1ad0 (XEN) [] syscall_enter+0xa9/0xae (XEN) (XEN) (XEN) **************************************** (XEN) Panic on CPU 0: (XEN) Xen BUG at mem_sharing.c:798 (XEN) **************************************** (XEN) (XEN) Manual reset required ('noreboot' specified) ------=_NextPart_001_0010_01CBC172.8D721E90 Content-Type: text/html; boundary="_b6cf8373-573c-4978-bfbe-b0633844eeb3_"; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hi:
 

Attached is the whole patch suit for latest = xen-4.0-testing,changeset 21443,

It comes from George, Tim and JuiHao, also, has some extra = debug info.

 

On most occasion, memory sharing works fine, but still = exists a bug.

       I’ve been = tracing this problem for a while.=

  = ;     There is a bug on get_page_and_type() in = mem_sharing_share_pages()

 =

-----------= ---------------------------------mem_sharing_share_pages()---------------= --------

789 &n= bsp;       if(!get_page_and_type(spage, = dom_cow, PGT_shared_page)){

= 790           &nbs= p; mem_sharing_debug_gfn(cd, gfn->gfn);

= 791           &nbs= p; mem_sharing_debug_gfn(sd, sgfn->gfn);

= 792           &nbs= p; printk("c->dying %d s->dying %d spage %p se->mfn = %lx\n", cd->is_dying, sd->is_dying, spage, = se->mfn);

= 793           &nbs= p; printk("Debug page: MFN=3D%lx is ci=3D%lx, ti=3D%lx, = owner_id=3D%d\n",

= 794           &nbs= p;         = mfn_x(page_to_mfn(spage)),

= 795           &nbs= p;         spage->count_info, =

 796&n= bsp;           &nb= sp;        = spage->u.inuse.type_info,

= 797           &nbs= p;         = page_get_owner(spage)->domain_id);

= 798           &nbs= p; BUG();

= 799         = }

 =

 =

Below = painc log contains the debug info from line = 790-798.

We saw = that 180000000000000 which is PGC_state_free,

So it = looks like a shared page has been freed = unexpectly.

 =

 =

(XEN) = teardown 64

(XEN) = teardown 66

blktap_sysf= s_destroy

blktap_sysf= s_create: adding attributes for dev = ffff880109d0c200

blktap_sysf= s_destroy

__ratelimit= : 1 callbacks suppressed

blktap_sysf= s_destroy

(XEN) = Debug for domain=3D83, gfn=3D1e8dc, Debug page: MFN=3D1306dc is = ci=3D8000000000000005, ti=3D8400000000000001, = owner_id=3D32755

(XEN) = Debug for domain=3D79, gfn=3D1dc95, Invalid = MFN=3Dffffffffffffffff

(XEN) = c->dying 0 s->dying 0 spage ffff82f60a0f12a0 se->mfn = 507895

(XEN) = Debug page: MFN=3D507895 is ci=3D 180000000000000, = ti=3D8400000000000001, owner_id=3D32755

(XEN) Xen = BUG at mem_sharing.c:798

(XEN) = ----[ Xen-4.0.2-rc2-pre  x86_64  debug=3Dn  Not tainted = ]----

(XEN) = CPU:    0

(XEN) = RIP:    e008:[<ffff82c4801c3760>] = mem_sharing_share_pages+0x5b0/0x5d0

(XEN) = RFLAGS: 0000000000010286   CONTEXT: = hypervisor

(XEN) rax: = 0000000000000000   rbx: ffff83044ef76000   rcx: = 0000000000000092

(XEN) rdx: = 000000000000000a   rsi: 000000000000000a   rdi: = ffff82c4802237c4

(XEN) rbp: = ffff83030d99e310   rsp: ffff82c48035fc48   r8:  = 0000000000000001

(XEN) = r9:  0000000000000001   r10: 00000000fffffff8   = r11: 0000000000000005

(XEN) r12: = ffff83050b558000   r13: ffff830626ec5740   r14: = 0000000000347967

(XEN) r15: = ffff83030d99e068   cr0: 0000000080050033   cr4: = 00000000000026f0

(XEN) cr3: = 000000010e642000   cr2: = 00002abdc4809000

(XEN) ds: = 0000   es: 0000   fs: 0000   gs: = 0000   ss: e010   cs: e008

(XEN) Xen = stack trace from rsp=3Dffff82c48035fc48:

(XEN) =    000000000001e8dc ffff83030d99e068 0000000000507895 = ffff83030d99e050

(XEN) =    ffff82f60a0f12a0 ffff82f60260db80 ffff83030d99e300 = ffff830626afbbd0

(XEN) =    0000000080372980 ffff82c48035fe38 ffff83023febe000 = 00000000008f7000

(XEN) =    0000000000305000 0000000000000006 0000000000000006 = ffff82c4801c44a4

(XEN) =    ffff82c480258188 ffff82c48011cb89 000000000001e8dc = fffffffffffffff3

(XEN) =    ffff82c48035fe28 ffff82c480148503 000003d932971281 = 0000000000000080

(XEN) =    000003d9329611d6 ffff82c48018aedf ffff82c4803903a8 = ffff82c48035fd38

(XEN) =    ffff82c480390380 ffff82c48035fe28 0000000000000002 = 0000000000000000

(XEN) =    0000000000000002 0000000000000000 ffff83023febe000 = ffff83023ff80080

(XEN) =    ffff82c48035fe58 0000000000000000 ffff82c48022ca80 = 0000000000000000

(XEN) =    0000000000000002 ffff82c48018a452 0000000000000000 = ffff82c48016f6bb

(XEN) =    ffff82c48035fe58 ffff82c4801538ea 000000023ab79067 = fffffffffffffff3

(XEN) =    ffff82c48035fe28 00000000008f7000 0000000000305000 = 0000000000000006

(XEN) =    0000000000000006 ffff82c4801042b3 0000000000000000 = ffff82c48010d2a5

(XEN) =    ffff830477fb51e8 0000000000000000 00007ff000000200 = ffff8300bf76e000

(XEN) =    0000000600000039 0000000000000000 00007fc09d744003 = 0000000000325258

(XEN) =    0000000000347967 ffffffffff600429 000000004d463b17 = 0000000000062fe2

(XEN) =    0000000000000000 00007fc09d744070 00007fc09d744000 = 00007fffcfec0d20

(XEN) =    00007fc09d744078 0000000000430fd8 00007fffcfec0d88 = 00000000019f1ca8

(XEN) =    0000f05c00000000 00007fc09f4c2718 0000000000000000 = 0000000000000246

(XEN) Xen = call trace:

(XEN) =    [<ffff82c4801c3760>] = mem_sharing_share_pages+0x5b0/0x5d0

(XEN) =    [<ffff82c4801c44a4>] = mem_sharing_domctl+0xe4/0x130

(XEN) =    [<ffff82c48011cb89>] = cpumask_raise_softirq+0x89/0xa0

(XEN) =    [<ffff82c480148503>] = arch_do_domctl+0x14f3/0x22d0

(XEN) =    [<ffff82c48018aedf>] = handle_hpet_broadcast+0x16f/0x1d0

(XEN) =    [<ffff82c48018a452>] = hpet_legacy_irq_tick+0x42/0x50

(XEN) =    [<ffff82c48016f6bb>] = timer_interrupt+0xb/0x130

(XEN) =    [<ffff82c4801538ea>] = ack_edge_ioapic_irq+0x2a/0x70

(XEN) =    [<ffff82c4801042b3>] = do_domctl+0x163/0xfe0

(XEN) =    [<ffff82c48010d2a5>] = do_grant_table_op+0x75/0x1ad0

(XEN) =    [<ffff82c4801e7169>] = syscall_enter+0xa9/0xae

(XEN) =   

(XEN) =

(XEN) = ****************************************

(XEN) = Panic on CPU 0:

(XEN) Xen = BUG at mem_sharing.c:798

(XEN) = ****************************************

(XEN) =

(XEN) = Manual reset required ('noreboot' specified)

 

------=_NextPart_001_0010_01CBC172.8D721E90-- ------=_NextPart_000_000F_01CBC172.8D721E90 Content-Type: application/octet-stream; name="memsharing.patch.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="memsharing.patch.patch" diff -rubN b/xen/arch/x86/mm/hap/p2m-ept.c = a/xen/arch/x86/mm/hap/p2m-ept.c=0A= --- b/xen/arch/x86/mm/hap/p2m-ept.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/arch/x86/mm/hap/p2m-ept.c 2011-01-19 16:36:27.000000000 +0800=0A= @@ -38,17 +38,22 @@=0A= p2m_query_t q)=0A= {=0A= int r;=0A= + int do_locking =3D !p2m_locked_by_me(d->arch.p2m);=0A= +=0A= + if(do_locking)=0A= p2m_lock(d->arch.p2m);=0A= =0A= /* Check to make sure this is still PoD */=0A= if ( entry->avail1 !=3D p2m_populate_on_demand )=0A= {=0A= + if(do_locking)=0A= p2m_unlock(d->arch.p2m);=0A= return 0;=0A= }=0A= =0A= r =3D p2m_pod_demand_populate(d, gfn, order, q);=0A= =0A= + if(do_locking)=0A= p2m_unlock(d->arch.p2m);=0A= =0A= return r;=0A= diff -rubN b/xen/arch/x86/mm/mem_sharing.c = a/xen/arch/x86/mm/mem_sharing.c=0A= --- b/xen/arch/x86/mm/mem_sharing.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/arch/x86/mm/mem_sharing.c 2011-01-30 19:12:24.000000000 +0800=0A= @@ -57,6 +57,7 @@=0A= =0A= static shr_handle_t next_handle =3D 1;=0A= static atomic_t nr_saved_mfns =3D ATOMIC_INIT(0); =0A= +int mem_sharing_debug_mfn(unsigned long mfn);=0A= =0A= typedef struct shr_hash_entry =0A= {=0A= @@ -168,6 +169,65 @@=0A= xfree(gfn);=0A= }=0A= =0A= +static shr_hash_entry_t* mem_sharing_hash_lookup_by_gfn(=0A= + struct domain *d,=0A= + unsigned long gfn =0A= + )=0A= +{=0A= + shr_hash_entry_t *ce;=0A= + int i;=0A= + =0A= + for(i =3D 0; i < SHR_HASH_LENGTH; i++){=0A= + ce =3D shr_hash[i];=0A= + while(ce !=3D NULL)=0A= + {=0A= + struct list_head *le, *te;=0A= + struct gfn_info *sgfn;=0A= + list_for_each_safe(le, te, &ce->gfns)=0A= + {=0A= + sgfn =3D list_entry(le, struct gfn_info, list);=0A= + if(sgfn->domain =3D=3D d->domain_id && sgfn->gfn =3D=3D = gfn){=0A= + mem_sharing_debug_mfn(mfn_x(ce->mfn));=0A= + printk("gfn handle %lu\n", ce->handle);=0A= + }=0A= + }=0A= + ce =3D ce->next;=0A= + }=0A= + }=0A= +=0A= + return NULL;=0A= +}=0A= +static unsigned long mem_sharing_hash_lookup_by_mfn(=0A= + unsigned long mfn=0A= + )=0A= +{=0A= + shr_hash_entry_t *ce;=0A= + int i;=0A= + =0A= + for(i =3D 0; i < SHR_HASH_LENGTH; i++){=0A= + ce =3D shr_hash[i];=0A= + while(ce !=3D NULL )=0A= + {=0A= + if(mfn_x(ce->mfn) =3D=3D mfn){=0A= + struct list_head *le, *te;=0A= + struct gfn_info *sgfn =3D NULL;=0A= + mem_sharing_debug_mfn(mfn_x(ce->mfn));=0A= + printk("handle %lu ", ce->handle);=0A= + list_for_each_safe(le, te, &ce->gfns)=0A= + {=0A= + sgfn =3D list_entry(le, struct gfn_info, list);=0A= + printk("did %u, gfn %lu ", sgfn->domain, sgfn->gfn);=0A= + }=0A= + printk("end\n");=0A= + return sgfn->gfn;=0A= + }=0A= + ce =3D ce->next;=0A= + }=0A= + }=0A= +=0A= + return 0;=0A= +}=0A= +=0A= static shr_hash_entry_t* mem_sharing_hash_lookup(shr_handle_t handle)=0A= {=0A= shr_hash_entry_t *e;=0A= @@ -183,6 +243,73 @@=0A= return NULL;=0A= }=0A= =0A= +void mem_sharing_hash_iter_detail(void)=0A= +{=0A= + shr_hash_entry_t *ce;=0A= + int i,j;=0A= + int count_e=3D 0;=0A= +=0A= + shr_lock();=0A= + j =3D 0;=0A= + for(i =3D 0; i < SHR_HASH_LENGTH; i++){=0A= +=0A= + ce =3D shr_hash[i];=0A= + if(ce && ce->next !=3D NULL)=0A= + printk("=3D=3D=3D> %d <=3D=3D=3D=3D ", i);=0A= +=0A= + while(ce !=3D NULL)=0A= + {=0A= + struct list_head *le, *te;=0A= + struct gfn_info *gfn;=0A= + j =3D 0;=0A= + printk("--%lu--", ce->handle);=0A= + list_for_each_safe(le, te, &ce->gfns)=0A= + {=0A= + gfn =3D list_entry(le, struct gfn_info, list);=0A= + j++;=0A= + printk("%d ", gfn->domain);=0A= + }=0A= + printk(",(%d)\n", j);=0A= + count_e++;=0A= + ce =3D ce->next;=0A= + }=0A= + }=0A= + printk("=3D=3D=3D>total handles %d total gfns %d next_handle = %lu\n", count_e, j, next_handle);=0A= + shr_unlock();=0A= +}=0A= +=0A= +=0A= +void mem_sharing_hash_iter(void)=0A= +{=0A= + shr_hash_entry_t *ce;=0A= + int i,j;=0A= + int count_e=3D 0;=0A= +=0A= + shr_lock();=0A= + j =3D 0;=0A= + for(i =3D 0; i < SHR_HASH_LENGTH; i++){=0A= +// printk("=3D=3D=3D=3D=3D=3D=3D=3D> %d <\n", i);=0A= + ce =3D shr_hash[i];=0A= + while(ce !=3D NULL)=0A= + {=0A= + struct list_head *le, *te;=0A= + struct gfn_info *gfn;=0A= +// printk("--%lu--", ce->handle);=0A= + list_for_each_safe(le, te, &ce->gfns)=0A= + {=0A= + gfn =3D list_entry(le, struct gfn_info, list);=0A= + j++;=0A= +// printk("%d ", gfn->domain);=0A= + }=0A= +// printk(",(%d)\n", j);=0A= + count_e++;=0A= + ce =3D ce->next;=0A= + }=0A= + }=0A= + printk("=3D=3D=3D>total handles %d total gfns %d next_handle: = %lu\n", count_e, j, next_handle);=0A= + shr_unlock();=0A= +}=0A= +=0A= static shr_hash_entry_t* mem_sharing_hash_insert(shr_handle_t handle, = mfn_t mfn)=0A= {=0A= shr_hash_entry_t *e, **ee;=0A= @@ -293,6 +420,7 @@=0A= #endif=0A= =0A= =0A= +extern void pagealloc_info(unsigned char key);=0A= static struct page_info* mem_sharing_alloc_page(struct domain *d, =0A= unsigned long gfn,=0A= int must_succeed)=0A= @@ -310,6 +438,7 @@=0A= /* We do not support 'must_succeed' any more. External = operations such=0A= * as grant table mappings may fail with OOM condition! =0A= */=0A= + pagealloc_info('m');=0A= BUG();=0A= }=0A= else=0A= @@ -402,7 +531,7 @@=0A= static grant_entry_header_t *=0A= shared_entry_header(struct grant_table *t, grant_ref_t ref)=0A= {=0A= - ASSERT(t->gt_version !=3D 0);=0A= + BUG_ON(t->gt_version =3D=3D 0);=0A= if (t->gt_version =3D=3D 1)=0A= return (grant_entry_header_t*)&shared_entry_v1(t, ref);=0A= else=0A= @@ -451,16 +580,18 @@=0A= if(list_has_one_entry(&gfn->list))=0A= {=0A= d =3D get_domain_by_id(gfn->domain);=0A= + if(!d){=0A= + printk("=3D=3D=3D=3D=3D=3D=3D=3D>did is %d\n", gfn->domain);=0A= + return -1;=0A= + }=0A= BUG_ON(!d);=0A= if(sharing) =0A= atomic_inc(&d->shr_pages);=0A= else=0A= atomic_dec(&d->shr_pages);=0A= put_domain(d);=0A= -=0A= return 1;=0A= }=0A= - mem_sharing_audit();=0A= =0A= return 0;=0A= }=0A= @@ -505,6 +636,7 @@=0A= =0A= *phandle =3D 0UL;=0A= =0A= + shr_lock();=0A= mfn =3D gfn_to_mfn(d, gfn, &p2mt);=0A= =0A= /* Check if mfn is valid */=0A= @@ -512,29 +644,33 @@=0A= if (!mfn_valid(mfn))=0A= goto out;=0A= =0A= + /* Return the handle if the page is already shared */=0A= + page =3D mfn_to_page(mfn);=0A= + if (p2m_is_shared(p2mt)) {=0A= + *phandle =3D page->shr_handle;=0A= + ret =3D 0;=0A= + goto out;=0A= + }=0A= +=0A= /* Check p2m type */=0A= if (!p2m_is_sharable(p2mt))=0A= goto out;=0A= =0A= /* Try to convert the mfn to the sharable type */=0A= - page =3D mfn_to_page(mfn);=0A= ret =3D page_make_sharable(d, page, expected_refcnt); =0A= if(ret) =0A= goto out;=0A= =0A= /* Create the handle */=0A= ret =3D -ENOMEM;=0A= - shr_lock(); =0A= handle =3D next_handle++; =0A= if((hash_entry =3D mem_sharing_hash_insert(handle, mfn)) =3D=3D = NULL)=0A= {=0A= - shr_unlock();=0A= goto out;=0A= }=0A= if((gfn_info =3D mem_sharing_gfn_alloc()) =3D=3D NULL)=0A= {=0A= mem_sharing_hash_destroy(hash_entry);=0A= - shr_unlock();=0A= goto out;=0A= }=0A= =0A= @@ -545,10 +681,14 @@=0A= * it a few lines above.=0A= * The mfn needs to revert back to rw type. This should never = fail,=0A= * since no-one knew that the mfn was temporarily sharable */=0A= + =0A= + printk("=3D=3Dmake share fail");=0A= + mem_sharing_debug_gfn(d, gfn);=0A= BUG_ON(page_make_private(d, page) !=3D 0);=0A= mem_sharing_hash_destroy(hash_entry);=0A= mem_sharing_gfn_destroy(gfn_info, 0);=0A= - shr_unlock();=0A= + printk("=3D=3Dmake share fail2");=0A= + mem_sharing_debug_gfn(d, gfn);=0A= goto out;=0A= }=0A= =0A= @@ -562,11 +702,13 @@=0A= gfn_info->domain =3D d->domain_id;=0A= page->shr_handle =3D handle;=0A= *phandle =3D handle;=0A= - shr_unlock();=0A= =0A= ret =3D 0;=0A= =0A= out:=0A= + shr_unlock();=0A= + if(0)=0A= + mem_sharing_hash_lookup_by_mfn(mfn_x(mfn));=0A= return ret;=0A= }=0A= =0A= @@ -575,9 +717,16 @@=0A= shr_hash_entry_t *se, *ce;=0A= struct page_info *spage, *cpage;=0A= struct list_head *le, *te;=0A= - struct gfn_info *gfn;=0A= - struct domain *d;=0A= + struct gfn_info *gfn =3D NULL;=0A= + struct domain *cd =3D NULL;=0A= + struct domain *sd =3D NULL;=0A= + struct gfn_info *sgfn;=0A= int ret;=0A= + int count =3D 0;=0A= +=0A= + BUG_ON(ch =3D=3D sh);=0A= + BUG_ON(ch > next_handle);=0A= + BUG_ON(sh > next_handle);=0A= =0A= shr_lock();=0A= =0A= @@ -590,30 +739,97 @@=0A= spage =3D mfn_to_page(se->mfn); =0A= cpage =3D mfn_to_page(ce->mfn); =0A= /* gfn lists always have at least one entry =3D> save to call = list_entry */=0A= - mem_sharing_gfn_account(gfn_get_info(&ce->gfns), 1);=0A= - mem_sharing_gfn_account(gfn_get_info(&se->gfns), 1);=0A= + gfn =3D gfn_get_info(&ce->gfns);=0A= + if(!list_has_one_entry(&gfn->list)){=0A= + list_for_each_safe(le, te, &ce->gfns)=0A= + gfn =3D list_entry(le, struct gfn_info, list);=0A= + printk("gfn %lx did %u\n", gfn->gfn, gfn->domain);=0A= + BUG();=0A= + }=0A= +=0A= + if(mem_sharing_gfn_account(gfn_get_info(&ce->gfns), 1) =3D=3D -1){=0A= + printk("=3D=3D=3D=3D=3Dclient not found, server %d client = %d\n", gfn_get_info(&se->gfns)->domain, gfn_get_info(&ce->gfns)->domain);=0A= + ret =3D XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID;=0A= + goto err_out;=0A= + }=0A= +=0A= + sgfn =3D gfn_get_info(&se->gfns);=0A= + if(mem_sharing_gfn_account(sgfn, 1)=3D=3D-1){=0A= + printk("=3D=3D=3D=3D=3Dserver not found, server %d client = %d\n", gfn_get_info(&se->gfns)->domain, gfn_get_info(&ce->gfns)->domain);=0A= + ret =3D XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID;=0A= + goto err_out;=0A= + }=0A= +=0A= list_for_each_safe(le, te, &ce->gfns)=0A= {=0A= gfn =3D list_entry(le, struct gfn_info, list);=0A= /* Get the source page and type, this should never fail =0A= * because we are under shr lock, and got non-null se */=0A= - BUG_ON(!get_page_and_type(spage, dom_cow, PGT_shared_page));=0A= + cd =3D rcu_lock_domain_by_id(gfn->domain);=0A= + sd =3D rcu_lock_domain_by_id(sgfn->domain);=0A= + if(!cd || cd->is_dying || !sd || sd->is_dying){=0A= + if(!cd)=0A= + printk("cd is NULL %d\n", gfn->domain);=0A= + else if(cd->is_dying)=0A= + printk("cd is dying %d %d\n", cd->is_dying, = gfn->domain);=0A= + else if(!sd)=0A= + printk("sd is NULL %d\n", gfn->domain);=0A= + else if(sd->is_dying){=0A= + printk("sd is dying %d %d %d c %d\n", sd->is_dying, = sgfn->domain, gfn->domain, count++);=0A= + }=0A= +=0A= + /*release lock if we have d*/=0A= + if(cd)=0A= + rcu_unlock_domain(cd);=0A= + if(sd)=0A= + rcu_unlock_domain(sd);=0A= + continue;=0A= + }=0A= +=0A= + if(!get_page_and_type(spage, dom_cow, PGT_shared_page)){=0A= + mem_sharing_debug_gfn(cd, gfn->gfn);=0A= + mem_sharing_debug_gfn(sd, sgfn->gfn);=0A= + printk("c->dying %d s->dying %d spage %p se->mfn %lx\n", = cd->is_dying, sd->is_dying, spage, se->mfn);=0A= + printk("Debug page: MFN=3D%lx is ci=3D%lx, ti=3D%lx, = owner_id=3D%d\n",=0A= + mfn_x(page_to_mfn(spage)), =0A= + spage->count_info, =0A= + spage->u.inuse.type_info,=0A= + page_get_owner(spage)->domain_id);=0A= + BUG();=0A= + }=0A= /* Move the gfn_info from ce list to se list */=0A= list_del(&gfn->list);=0A= - d =3D get_domain_by_id(gfn->domain);=0A= - BUG_ON(!d);=0A= - BUG_ON(set_shared_p2m_entry(d, gfn->gfn, se->mfn) =3D=3D 0);=0A= - put_domain(d);=0A= + //d =3D get_domain_by_id(gfn->domain);=0A= + //mem_sharing_debug_gfn(d, gfn->gfn);=0A= + BUG_ON(set_shared_p2m_entry(cd, gfn->gfn, se->mfn) =3D=3D 0);=0A= list_add(&gfn->list, &se->gfns);=0A= put_page_and_type(cpage);=0A= + rcu_unlock_domain(cd);=0A= + rcu_unlock_domain(sd);=0A= + //mem_sharing_debug_gfn(d, gfn->gfn);=0A= } =0A= - ASSERT(list_empty(&ce->gfns));=0A= + /* Free the client page when no gfn refer to*/=0A= + if (list_empty(&ce->gfns) && test_and_clear_bit(_PGC_allocated, = &cpage->count_info)){=0A= + put_page(cpage);=0A= mem_sharing_hash_delete(ch);=0A= atomic_inc(&nr_saved_mfns);=0A= - /* Free the client page */=0A= - if(test_and_clear_bit(_PGC_allocated, &cpage->count_info))=0A= - put_page(cpage);=0A= ret =3D 0;=0A= + }else{=0A= + ret =3D XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID;=0A= + }=0A= +=0A= +/* mem_sharing_debug_gfn(d, gfn->gfn);=0A= + printk("Debug page: MFN=3D%lx is ci=3D%lx, ti=3D%lx, owner_id=3D%d, = h=3D%lu\n",=0A= + mfn_x(page_to_mfn(cpage)), =0A= + cpage->count_info, =0A= + cpage->u.inuse.type_info,=0A= + page_get_owner(cpage)->domain_id, cpage->shr_handle);=0A= + printk("Debug page: MFN=3D%lx is ci=3D%lx, ti=3D%lx, owner_id=3D%d, = h=3D%lu\n",=0A= + mfn_x(page_to_mfn(cpage)), =0A= + spage->count_info, =0A= + spage->u.inuse.type_info,=0A= + page_get_owner(spage)->domain_id, spage->shr_handle);=0A= +*/=0A= =0A= err_out:=0A= shr_unlock();=0A= @@ -634,16 +850,35 @@=0A= struct gfn_info *gfn_info =3D NULL;=0A= shr_handle_t handle;=0A= struct list_head *le;=0A= + struct domain *ld =3D NULL;=0A= =0A= + mem_sharing_audit();=0A= + /* Remove the gfn_info from the list */=0A= + shr_lock();=0A= mfn =3D gfn_to_mfn(d, gfn, &p2mt);=0A= + /* Has someone already unshared it? */=0A= +=0A= + if (!p2m_is_shared(p2mt)){=0A= + printk("=3D=3D=3D>already unshared, flag %u\n", flags);=0A= + shr_unlock();=0A= + return 0;=0A= + }=0A= +=0A= + if (!mfn_valid(mfn)){=0A= + mem_sharing_debug_gfn(d, gfn);=0A= + }=0A= =0A= page =3D mfn_to_page(mfn);=0A= handle =3D page->shr_handle;=0A= =0A= - mem_sharing_audit();=0A= /* Remove the gfn_info from the list */=0A= - shr_lock();=0A= hash_entry =3D mem_sharing_hash_lookup(handle); =0A= +=0A= + if(!hash_entry){=0A= + printk("entry handle %lu\n",handle);=0A= + mem_sharing_debug_gfn(d, gfn);=0A= + mem_sharing_hash_lookup_by_gfn(d,gfn);=0A= + }=0A= list_for_each(le, &hash_entry->gfns)=0A= {=0A= gfn_info =3D list_entry(le, struct gfn_info, list);=0A= @@ -677,18 +912,51 @@=0A= return 0;=0A= }=0A= =0A= + ld =3D rcu_lock_domain_by_id(d->domain_id); = = =0A= + BUG_ON(!ld);=0A= +=0A= ret =3D page_make_private(d, page);=0A= BUG_ON(last_gfn & ret);=0A= if(ret =3D=3D 0) goto private_page_found;=0A= =0A= + if(ld->is_dying )=0A= + {=0A= + if(!ld)=0A= + printk("d is NULL %d\n", d->domain_id);=0A= + else=0A= + printk("d is dying %d %d\n", d->is_dying, d->domain_id);=0A= +=0A= + /*decrease page type count and destory gfn*/=0A= + put_page_and_type(page);=0A= + mem_sharing_gfn_destroy(gfn_info, !last_gfn);=0A= +=0A= + if(last_gfn) =0A= + mem_sharing_hash_delete(handle);=0A= + else =0A= + /* Even though we don't allocate a private page, we have to = account=0A= + * for the MFN that originally backed this PFN. */=0A= + atomic_dec(&nr_saved_mfns);=0A= +=0A= + /*set mfn invalid*/=0A= + printk("did %d gfn %lx to invalid\n", d->domain_id, gfn);=0A= + BUG_ON(set_shared_p2m_entry_invalid(d, gfn)=3D=3D0);=0A= + rcu_unlock_domain(ld);=0A= + shr_unlock();=0A= + return -EAGAIN;=0A= + }=0A= +=0A= old_page =3D page;=0A= page =3D mem_sharing_alloc_page(d, gfn, flags & = MEM_SHARING_MUST_SUCCEED);=0A= - BUG_ON(!page && (flags & MEM_SHARING_MUST_SUCCEED));=0A= if(!page) =0A= {=0A= + mem_sharing_debug_gfn(d, gfn);=0A= + printk("---domain is %d, max_pages %u, total_pages %u \n", = d->is_dying, d->max_pages, d->tot_pages);=0A= + BUG_ON(!d);=0A= + BUG_ON(!page && (flags & MEM_SHARING_MUST_SUCCEED));=0A= /* We've failed to obtain memory for private page. Need to = re-add the=0A= * gfn_info to relevant list */=0A= list_add(&gfn_info->list, &hash_entry->gfns);=0A= + rcu_unlock_domain(ld);=0A= shr_unlock();=0A= return -ENOMEM;=0A= }=0A= @@ -709,7 +977,6 @@=0A= mem_sharing_hash_delete(handle);=0A= else=0A= atomic_dec(&nr_saved_mfns);=0A= - shr_unlock();=0A= =0A= if(p2m_change_type(d, gfn, p2m_ram_shared, p2m_ram_rw) !=3D =0A= p2m_ram_shared) =0A= @@ -719,7 +986,8 @@=0A= }=0A= /* Update m2p entry */=0A= set_gpfn_from_mfn(mfn_x(page_to_mfn(page)), gfn);=0A= -=0A= + rcu_unlock_domain(ld);=0A= + shr_unlock();=0A= return 0;=0A= }=0A= =0A= diff -rubN b/xen/arch/x86/mm/p2m.c a/xen/arch/x86/mm/p2m.c=0A= --- b/xen/arch/x86/mm/p2m.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/arch/x86/mm/p2m.c 2011-01-30 22:20:53.000000000 +0800=0A= @@ -1720,6 +1720,8 @@=0A= #endif=0A= =0A= p2m_lock(p2m);=0A= + printk(KERN_INFO "teardown %d\n",d->domain_id);=0A= + printk("teardown %d\n",d->domain_id);=0A= =0A= =0A= #ifdef __x86_64__=0A= @@ -2426,11 +2428,35 @@=0A= return rc;=0A= }=0A= =0A= +int=0A= +set_shared_p2m_entry_invalid(struct domain *d, unsigned long gfn)=0A= +{=0A= + int rc =3D 0;=0A= + int need_lock =3D !p2m_locked_by_me(d->arch.p2m);=0A= +=0A= + if ( !paging_mode_translate(d) )=0A= + return 0;=0A= +=0A= + if ( need_lock ) =0A= + p2m_lock(d->arch.p2m);=0A= + =0A= + rc =3D set_p2m_entry(d, gfn, _mfn(INVALID_MFN), 0, p2m_invalid);=0A= +=0A= + if ( need_lock ) =0A= + p2m_unlock(d->arch.p2m);=0A= +=0A= + if ( 0 =3D=3D rc )=0A= + gdprintk(XENLOG_ERR,=0A= + "set_mmio_p2m_entry: set_p2m_entry failed! mfn=3D%08lx = %d\n",=0A= + gmfn_to_mfn(d, gfn), d->is_dying);=0A= + return rc;=0A= +}=0A= #ifdef __x86_64__=0A= int=0A= set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)=0A= {=0A= int rc =3D 0;=0A= + int need_lock =3D !p2m_locked_by_me(d->arch.p2m);=0A= p2m_type_t ot;=0A= mfn_t omfn;=0A= =0A= @@ -2446,7 +2472,15 @@=0A= set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);=0A= =0A= P2M_DEBUG("set shared %lx %lx\n", gfn, mfn_x(mfn));=0A= + if ( need_lock ) =0A= + p2m_lock(d->arch.p2m);=0A= + if(!mfn_valid(mfn)){=0A= + printk("did %d gfn %lx =3D=3D\n", d->domain_id, gfn);=0A= + BUG();=0A= + }=0A= rc =3D set_p2m_entry(d, gfn, mfn, 0, p2m_ram_shared);=0A= + if ( need_lock ) =0A= + p2m_unlock(d->arch.p2m);=0A= if ( 0 =3D=3D rc )=0A= gdprintk(XENLOG_ERR,=0A= "set_mmio_p2m_entry: set_p2m_entry failed! mfn=3D%08lx\n",=0A= diff -rubN b/xen/arch/x86/mm.c a/xen/arch/x86/mm.c=0A= --- b/xen/arch/x86/mm.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/arch/x86/mm.c 2011-01-31 11:26:21.000000000 +0800=0A= @@ -116,6 +116,7 @@=0A= #include =0A= #include =0A= =0A= +extern int mem_sharing_debug_mfn(unsigned long mfn);=0A= /*=0A= * Mapping of first 2 or 4 megabytes of memory. This is mapped with 4kB=0A= * mappings to avoid type conflicts with fixed-range MTRRs covering the=0A= @@ -2342,7 +2343,8 @@=0A= =0A= /* No special validation needed for writable pages. */=0A= /* Page tables and GDT/LDT need to be scanned for = validity. */=0A= - if ( type =3D=3D PGT_writable_page )=0A= + if ( type =3D=3D PGT_writable_page || type =3D=3D =0A= + PGT_shared_page )=0A= nx |=3D PGT_validated;=0A= }=0A= }=0A= @@ -3167,15 +3169,12 @@=0A= else if ( p2m_ram_shared =3D=3D l1e_p2mt )=0A= {=0A= /* Unshare the page for RW foreign mappings */=0A= - if ( l1e_get_flags(l1e) & _PAGE_RW )=0A= - {=0A= rc =3D mem_sharing_unshare_page(pg_owner, =0A= = l1e_get_pfn(l1e), =0A= 0);=0A= if ( rc )=0A= break; =0A= }=0A= - } =0A= #endif=0A= =0A= okay =3D mod_l1_entry(va, l1e, mfn,=0A= @@ -3857,32 +3856,24 @@=0A= struct page_info *page, =0A= int expected_refcnt)=0A= {=0A= - unsigned long x, nx, y;=0A= -=0A= - /* Acquire ref first, so that the page doesn't dissapear from us */=0A= - if(!get_page(page, d))=0A= - return -EINVAL;=0A= -=0A= spin_lock(&d->page_alloc_lock);=0A= =0A= /* Change page type and count atomically */=0A= - y =3D page->u.inuse.type_info;=0A= - nx =3D PGT_shared_page | PGT_validated | 1; =0A= - do {=0A= - x =3D y;=0A= - /* We can only change the type if count is zero, and =0A= - type is PGT_none */=0A= - if((x & (PGT_type_mask | PGT_count_mask)) !=3D PGT_none)=0A= + if (!get_page_and_type(page, d, PGT_shared_page) )=0A= {=0A= - put_page(page);=0A= spin_unlock(&d->page_alloc_lock);=0A= - return -EEXIST;=0A= + return -EINVAL;=0A= }=0A= - y =3D cmpxchg(&page->u.inuse.type_info, x, nx);=0A= - } while(x !=3D y);=0A= =0A= - /* Check if the ref count is 2. The first from PGT_allocated, and = the second=0A= - * from get_page at the top of this function */=0A= + /* Check it wasn't already sharable and undo if it was */=0A= + if ( (page->u.inuse.type_info & PGT_count_mask) !=3D 1 )=0A= + {=0A= + put_page_and_type(page);=0A= + spin_unlock(&d->page_alloc_lock);=0A= + return -EEXIST;=0A= + }=0A= + /* Check if the ref count is 2. The first from PGT_allocated, and=0A= + + * the second from get_page_and_type at the top of this = function */=0A= if(page->count_info !=3D (PGC_allocated | (2 + expected_refcnt)))=0A= {=0A= /* Return type count back to zero */=0A= @@ -3895,39 +3886,26 @@=0A= d->tot_pages--;=0A= page_list_del(page, &d->page_list);=0A= spin_unlock(&d->page_alloc_lock);=0A= -=0A= - /* NOTE: We are not putting the page back. In effect this function = acquires=0A= - * one ref and type ref for the caller */=0A= -=0A= return 0;=0A= }=0A= =0A= int page_make_private(struct domain *d, struct page_info *page)=0A= {=0A= - unsigned long x, y;=0A= -=0A= if(!get_page(page, dom_cow))=0A= return -EINVAL;=0A= =0A= spin_lock(&d->page_alloc_lock);=0A= =0A= - /* Change page type and count atomically */=0A= - y =3D page->u.inuse.type_info;=0A= - do {=0A= - x =3D y;=0A= /* We can only change the type if count is one */=0A= - if((x & (PGT_type_mask | PGT_count_mask)) !=3D =0A= - (PGT_shared_page | 1))=0A= + if ( (page->u.inuse.type_info & (PGT_type_mask | PGT_count_mask))=0A= + !=3D (PGT_shared_page | 1) )=0A= {=0A= put_page(page);=0A= spin_unlock(&d->page_alloc_lock);=0A= return -EEXIST;=0A= }=0A= - y =3D cmpxchg(&page->u.inuse.type_info, x, PGT_none);=0A= - } while(x !=3D y);=0A= -=0A= - /* We dropped type ref above, drop one ref count too */=0A= - put_page(page);=0A= + /* Drop the final typecount */=0A= + put_page_and_type(page);=0A= =0A= /* Change the owner */=0A= ASSERT(page_get_owner(page) =3D=3D dom_cow);=0A= diff -rubN b/xen/common/keyhandler.c a/xen/common/keyhandler.c=0A= --- b/xen/common/keyhandler.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/common/keyhandler.c 2011-01-31 11:10:54.000000000 +0800=0A= @@ -19,6 +19,8 @@=0A= =0A= static struct keyhandler *key_table[256];=0A= static unsigned char keypress_key;=0A= +extern void mem_sharing_hash_iter(void);=0A= +extern void mem_sharing_hash_iter_detail(void);=0A= =0A= char keyhandler_scratch[1024];=0A= =0A= @@ -63,6 +65,7 @@=0A= if ( key_table[i] !=3D NULL ) =0A= printk(" key '%c' (ascii '%02x') =3D> %s\n", =0A= isprint(i) ? i : ' ', i, key_table[i]->desc);=0A= + mem_sharing_hash_iter();=0A= }=0A= =0A= static struct keyhandler show_handlers_keyhandler =3D {=0A= @@ -119,6 +122,9 @@=0A= {=0A= struct vcpu *v;=0A= =0A= + mem_sharing_hash_iter_detail();=0A= + return;=0A= +=0A= if ( dom0 =3D=3D NULL )=0A= return;=0A= =0A= diff -rubN b/xen/common/page_alloc.c a/xen/common/page_alloc.c=0A= --- b/xen/common/page_alloc.c 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/common/page_alloc.c 2011-01-19 16:40:48.000000000 +0800=0A= @@ -69,6 +69,7 @@=0A= /* Broken page list, protected by heap_lock. */=0A= PAGE_LIST_HEAD(page_broken_list);=0A= =0A= +void pagealloc_info(unsigned char key);=0A= /*************************=0A= * BOOT-TIME ALLOCATOR=0A= */=0A= @@ -1260,7 +1261,7 @@=0A= -1);=0A= }=0A= =0A= -static void pagealloc_info(unsigned char key)=0A= +void pagealloc_info(unsigned char key)=0A= {=0A= unsigned int zone =3D MEMZONE_XEN;=0A= unsigned long n, total =3D 0;=0A= diff -rubN b/xen/include/asm-x86/p2m.h a/xen/include/asm-x86/p2m.h=0A= --- b/xen/include/asm-x86/p2m.h 2011-01-31 10:51:55.000000000 +0800=0A= +++ a/xen/include/asm-x86/p2m.h 2011-01-31 11:06:02.000000000 +0800=0A= @@ -316,15 +316,22 @@=0A= int must_succeed)=0A= {=0A= mfn_t mfn;=0A= + int ret;=0A= =0A= mfn =3D gfn_to_mfn(d, gfn, p2mt);=0A= #ifdef __x86_64__=0A= if ( p2m_is_shared(*p2mt) )=0A= {=0A= - if ( mem_sharing_unshare_page(d, gfn,=0A= - must_succeed =0A= - ? MEM_SHARING_MUST_SUCCEED : 0) )=0A= + ret =3D mem_sharing_unshare_page(d, gfn,=0A= + must_succeed ? MEM_SHARING_MUST_SUCCEED : 0);=0A= + if(ret < 0)=0A= {=0A= + if ( must_succeed && d->is_dying )=0A= + {=0A= + printk("unshare failed dying %d\n", d->is_dying);=0A= + mfn =3D _mfn(INVALID_MFN);=0A= + *p2mt=3Dp2m_invalid;=0A= + }else=0A= BUG_ON(must_succeed);=0A= return mfn;=0A= }=0A= @@ -437,6 +444,8 @@=0A= #ifdef __x86_64__=0A= /* Modify p2m table for shared gfn */=0A= int set_shared_p2m_entry(struct domain *d, unsigned long gfn, mfn_t = mfn);=0A= +int=0A= +set_shared_p2m_entry_invalid(struct domain *d, unsigned long gfn);=0A= /* Check if a nominated gfn is valid to be paged out */=0A= int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn);=0A= /* Evict a frame */=0A= ------=_NextPart_000_000F_01CBC172.8D721E90 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel ------=_NextPart_000_000F_01CBC172.8D721E90--