diff --git a/xen/Rules.mk b/xen/Rules.mk index 3f0b262..bc6b437 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -3,6 +3,7 @@ # If you change any of these configuration options then you must # 'make clean' before rebuilding. # +debug := y verbose ?= n perfc ?= n perfc_arrays ?= n diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index efda6af..af63d76 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -59,12 +59,12 @@ void __init mapcache_override_current(struct vcpu *v) void *map_domain_page(unsigned long mfn) { unsigned long flags; - unsigned int idx, i; + unsigned int idx, i, j = 0; struct vcpu *v; struct mapcache_domain *dcache; struct mapcache_vcpu *vcache; struct vcpu_maphash_entry *hashent; - + int branch = 0; #ifdef NDEBUG if ( mfn <= PFN_DOWN(__pa(HYPERVISOR_VIRT_END - 1)) ) return mfn_to_virt(mfn); @@ -115,31 +115,67 @@ void *map_domain_page(unsigned long mfn) /* /First/, clean the garbage map and update the inuse list. */ for ( i = 0; i < BITS_TO_LONGS(dcache->entries); i++ ) { + unsigned long garbage = dcache->garbage[i]; + unsigned long _inuse = dcache->inuse[i]; + barrier(); dcache->inuse[i] &= ~xchg(&dcache->garbage[i], 0); + if (v->domain->domain_id) { + if (~dcache->inuse[i]) { + gdprintk(XENLOG_INFO, "mfn: %lx, [%d]: %lx, ~%lx, idx: %d garbage: %lx, inuse: %lx\n", mfn, i, dcache->inuse[i], ~dcache->inuse[i], + find_first_zero_bit(dcache->inuse, dcache->entries), garbage, _inuse); + branch |= 8; + } + } accum |= ~dcache->inuse[i]; } - if ( accum ) + if ( accum ) { idx = find_first_zero_bit(dcache->inuse, dcache->entries); + branch |= 1; + } else { + branch |= 2; /* Replace a hash entry instead. */ i = MAPHASH_HASHFN(mfn); do { hashent = &vcache->hash[i]; if ( hashent->idx != MAPHASHENT_NOTINUSE && !hashent->refcnt ) { + branch |= 4; idx = hashent->idx; ASSERT(l1e_get_pfn(MAPCACHE_L1ENT(idx)) == hashent->mfn); l1e_write(&MAPCACHE_L1ENT(idx), l1e_empty()); hashent->idx = MAPHASHENT_NOTINUSE; hashent->mfn = ~0UL; + if (idx >= dcache->entries) { + branch |= 8; + gdprintk(XENLOG_INFO, "mfn (%lx) -> %ld idx (iter:%d)\n", mfn, MAPHASH_HASHFN(mfn), j); + + for (i = 0; i < MAPHASH_ENTRIES;i++) { + hashent = &vcache->hash[i]; + + gdprintk(XENLOG_INFO, "[%d] idx=%d, mfn=0x%lx, refcnt: %d\n", + i, hashent->idx, hashent->mfn, hashent->refcnt); + } + } break; } if ( ++i == MAPHASH_ENTRIES ) i = 0; + j++; } while ( i != MAPHASH_HASHFN(mfn) ); } + if (idx >= dcache->entries) { + gdprintk(XENLOG_INFO, "mfn (%lx) -> %ld idx: %d(i:%d,j:%d), branch:%x 0x%lx\n", mfn, MAPHASH_HASHFN(mfn), idx, i, j, branch, accum); + + for (i = 0; i < MAPHASH_ENTRIES;i++) { + hashent = &vcache->hash[i]; + + gdprintk(XENLOG_INFO, "[%d] idx=%d, mfn=0x%lx, refcnt: %d\n", + i, hashent->idx, hashent->mfn, hashent->refcnt); + } + } BUG_ON(idx >= dcache->entries); /* /Second/, flush TLBs. */ @@ -254,6 +290,7 @@ int mapcache_domain_init(struct domain *d) 2 * PFN_UP(BITS_TO_LONGS(MAPCACHE_ENTRIES) * sizeof(long))) > MAPCACHE_VIRT_START + (PERDOMAIN_SLOT_MBYTES << 20)); bitmap_pages = PFN_UP(BITS_TO_LONGS(MAPCACHE_ENTRIES) * sizeof(long)); + gdprintk(XENLOG_INFO, "domain bitmap pages: %d\n", bitmap_pages); dcache->inuse = (void *)MAPCACHE_VIRT_END + PAGE_SIZE; dcache->garbage = dcache->inuse + (bitmap_pages + 1) * PAGE_SIZE / sizeof(long); @@ -276,6 +313,7 @@ int mapcache_vcpu_init(struct vcpu *v) if ( is_hvm_vcpu(v) || !dcache->inuse ) return 0; + gdprintk(XENLOG_INFO, "ents: %d, entries: %d\n", ents, dcache->entries); if ( ents > dcache->entries ) { /* Populate page tables. */