[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 7 of 7] xenalyze: Analyze populate-on-demand reclamation patterns
# HG changeset patch # User George Dunlap <george.dunlap@xxxxxxxxxxxxx> # Date 1349264664 -3600 # Node ID 393e0ead61a506f8bd1dea55ed7b3611ec4c7c1f # Parent 703cd2301a0a04934d30c7e4f7357df82ed12677 xenalyze: Analyze populate-on-demand reclamation patterns This includes attempting to classify each reclamation to see if it was the result of a fault or of ballooning, as well as tracking the order of the pages reclaimed. Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> diff --git a/xenalyze.c b/xenalyze.c --- a/xenalyze.c +++ b/xenalyze.c @@ -1723,6 +1723,21 @@ char * domain_runstate_name[] = { [DOMAIN_RUNSTATE_LOST]="lost", }; +enum { + POD_RECLAIM_CONTEXT_UNKNOWN=0, + POD_RECLAIM_CONTEXT_FAULT, + POD_RECLAIM_CONTEXT_BALLOON, + POD_RECLAIM_CONTEXT_MAX +}; + +char * pod_reclaim_context_name[] = { + [POD_RECLAIM_CONTEXT_UNKNOWN]="unknown", + [POD_RECLAIM_CONTEXT_FAULT]="fault", + [POD_RECLAIM_CONTEXT_BALLOON]="balloon", +}; + +#define POD_ORDER_MAX 4 + struct domain_data { struct domain_data *next; int did; @@ -1747,6 +1762,14 @@ struct domain_data { int done_for[MEM_MAX]; int done_for_interval[MEM_MAX]; } memops; + + struct { + int reclaim_order[POD_ORDER_MAX]; + int reclaim_context[POD_RECLAIM_CONTEXT_MAX]; + int reclaim_context_order[POD_RECLAIM_CONTEXT_MAX][POD_ORDER_MAX]; + /* FIXME: Do a full cycle summary */ + int populate_order[POD_ORDER_MAX]; + } pod; }; struct domain_data * domain_list=NULL; @@ -7396,7 +7419,7 @@ void sched_process(struct pcpu_info *p) /* ---- Memory ---- */ void mem_summary_domain(struct domain_data *d) { - int i; + int i, j; printf(" Grant table ops:\n"); @@ -7413,23 +7436,103 @@ void mem_summary_domain(struct domain_da printf(" %-14s: %d\n", mem_name[i], d->memops.done_for[i]); + + printf(" Populate-on-demand:\n"); + printf(" Populated:\n"); + for(i=0; i<4; i++) + { + if ( d->pod.populate_order[i] ) + printf(" [%d] %d\n", i, + d->pod.populate_order[i]); + } + printf(" Reclaim order:\n"); + for(i=0; i<4; i++) + { + if ( d->pod.reclaim_order[i] ) + printf(" [%d] %d\n", i, + d->pod.reclaim_order[i]); + } + printf(" Reclaim contexts:\n"); + for(j=0; j<POD_RECLAIM_CONTEXT_MAX; j++) + { + if ( d->pod.reclaim_context[j] ) + { + printf(" * [%s] %d\n", + pod_reclaim_context_name[j], + d->pod.reclaim_context[j]); + for(i=0; i<4; i++) + { + if ( d->pod.reclaim_context_order[j][i] ) + printf(" [%d] %d\n", i, + d->pod.reclaim_context_order[j][i]); + } + } + } +} + +int p2m_canonical_order(int order) +{ + if ( order % 9 + || (order / 9) > 2 ) + { + fprintf(warn, "%s: Strange, non-canonical order %d\n", + __func__, order); + order = 4; + } else { + order /= 9; + } + return order; } void mem_pod_zero_reclaim_process(struct pcpu_info *p) { struct record_info *ri = &p->ri; + int context = POD_RECLAIM_CONTEXT_UNKNOWN; + struct vcpu_data *v = p->current; struct { uint64_t gfn, mfn; int d:16,order:16; } *r = (typeof(r))ri->d; + if ( v && v->hvm.vmexit_valid ) + { + switch(v->hvm.exit_reason) + { + case EXIT_REASON_EPT_VIOLATION: + case EXIT_REASON_EXCEPTION_NMI: + context = POD_RECLAIM_CONTEXT_FAULT; + break; + case EXIT_REASON_VMCALL: + context = POD_RECLAIM_CONTEXT_BALLOON; + break; + } + } + if ( opt.dump_all ) { - printf(" %s pod_zero_reclaim d%d o%d g %llx m %llx\n", + printf(" %s pod_zero_reclaim d%d o%d g %llx m %llx ctx %s\n", ri->dump_header, r->d, r->order, - (unsigned long long)r->gfn, (unsigned long long)r->mfn); + (unsigned long long)r->gfn, (unsigned long long)r->mfn, + pod_reclaim_context_name[context]); + + } + + if ( opt.summary_info ) + { + struct domain_data *d; + + if ( v && (d=v->d) ) + { + int order; + + order = p2m_canonical_order(r->order); + + d->pod.reclaim_order[order]++; + d->pod.reclaim_context[context]++; + d->pod.reclaim_context_order[context][order]++; + } } } @@ -7449,6 +7552,21 @@ void mem_pod_populate_process(struct pcp r->d, r->order, (unsigned long long)r->gfn, (unsigned long long)r->mfn); } + + if ( opt.summary_info ) + { + struct vcpu_data *v = p->current; + struct domain_data *d; + + if ( v && (d=v->d) ) + { + int order; + + order = p2m_canonical_order(r->order); + + d->pod.populate_order[order]++; + } + } } void mem_pod_superpage_splinter_process(struct pcpu_info *p) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |