static int show_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid) { int ret = 0; struct xc_px_stat pxstatinfo; ret = get_pxstat_by_cpuid(xc_handle, cpuid, &pxstatinfo); if ( ret ) return ret; print_pxstat(cpuid, &pxstatinfo); free(pxstatinfo.trans_pt); free(pxstatinfo.pt); return 0; }
void start_gather_func(int argc, char *argv[]) { int i; struct timeval tv; int timeout = 0; if ( argc == 1 ) { sscanf(argv[0], "%d", &timeout); if ( timeout <= 0 ) fprintf(stderr, "failed to set timeout seconds, falling back...\n"); else printf("Timeout set to %d seconds\n", timeout); } if ( gettimeofday(&tv, NULL) == -1 ) { fprintf(stderr, "failed to get timeofday\n"); return ; } usec_start = tv.tv_sec * 1000000UL + tv.tv_usec; sum = calloc(2 * max_cpu_nr, sizeof(*sum)); if ( sum == NULL ) return ; cxstat = calloc(2 * max_cpu_nr, sizeof(*cxstat)); if ( cxstat == NULL ) { free(sum); return ; } pxstat = calloc(2 * max_cpu_nr, sizeof(*pxstat)); if ( pxstat == NULL ) { free(sum); free(cxstat); return ; } avgfreq = calloc(max_cpu_nr, sizeof(*avgfreq)); if ( avgfreq == NULL ) { free(sum); free(cxstat); free(pxstat); return ; } sum_cx = sum; sum_px = sum + max_cpu_nr; cxstat_start = cxstat; cxstat_end = cxstat + max_cpu_nr; pxstat_start = pxstat; pxstat_end = pxstat + max_cpu_nr; if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV && get_pxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV ) { fprintf(stderr, "Xen cpu idle and frequency is disabled!\n"); return ; } for ( i = 0; i < max_cpu_nr; i++ ) { get_cxstat_by_cpuid(xc_handle, i, &cxstat_start[i]); get_pxstat_by_cpuid(xc_handle, i, &pxstat_start[i]); get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]); } if (signal(SIGINT, signal_int_handler) == SIG_ERR) { fprintf(stderr, "failed to set signal int handler\n"); free(sum); free(pxstat); free(cxstat); free(avgfreq); return ; } if ( timeout > 0 ) { if ( signal(SIGALRM, signal_int_handler) == SIG_ERR ) { fprintf(stderr, "failed to set signal alarm handler\n"); free(sum); free(pxstat); free(cxstat); free(avgfreq); return ; } alarm(timeout); } printf("Start sampling, waiting for CTRL-C or SIGINT or SIGALARM signal ...\n"); pause(); }
static void signal_int_handler(int signo) { int i, j, k; struct timeval tv; int cx_cap = 0, px_cap = 0; DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_core); DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket); DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node); xc_topologyinfo_t info = { 0 }; cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU); cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU); cpu_to_node = xc_hypercall_buffer_alloc(xc_handle, cpu_to_node, sizeof(*cpu_to_node) * MAX_NR_CPU); if ( cpu_to_core == NULL || cpu_to_socket == NULL || cpu_to_node == NULL ) { fprintf(stderr, "failed to allocate hypercall buffers\n"); goto out; } if ( gettimeofday(&tv, NULL) == -1 ) { fprintf(stderr, "failed to get timeofday\n"); goto out ; } usec_end = tv.tv_sec * 1000000UL + tv.tv_usec; if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV ) { cx_cap = 1; for ( i = 0; i < max_cpu_nr; i++ ) if ( !get_cxstat_by_cpuid(xc_handle, i, &cxstat_end[i]) ) for ( j = 0; j < cxstat_end[i].nr; j++ ) { int64_t diff = (int64_t)cxstat_end[i].residencies[j] - (int64_t)cxstat_start[i].residencies[j]; if ( diff >=0 ) sum_cx[i] += diff; } } if ( get_pxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV ) { px_cap = 1; for ( i = 0; i < max_cpu_nr; i++ ) if ( !get_pxstat_by_cpuid(xc_handle, i , &pxstat_end[i]) ) for ( j = 0; j < pxstat_end[i].total; j++ ) sum_px[i] += pxstat_end[i].pt[j].residency - pxstat_start[i].pt[j].residency; } for ( i = 0; i < max_cpu_nr; i++ ) get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]); printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL); for ( i = 0; i < max_cpu_nr; i++ ) { uint64_t res, triggers; double avg_res; printf("\nCPU%d:\tResidency(ms)\t\tAvg Res(ms)\n",i); if ( cx_cap && sum_cx[i] > 0 ) { for ( j = 0; j < cxstat_end[i].nr; j++ ) { int64_t diff = (int64_t)cxstat_end[i].residencies[j] - (int64_t)cxstat_start[i].residencies[j]; res = ( diff >= 0 ) ? diff : 0; triggers = cxstat_end[i].triggers[j] - cxstat_start[i].triggers[j]; /* * triggers may be zero if the CPU has been in this state for * the whole sample or if it never entered the state */ if ( triggers == 0 && cxstat_end[i].last == j ) avg_res = (double)sum_cx[i]/1000000.0; else avg_res = (triggers==0) ? 0: (double)res/triggers/1000000.0; printf(" C%d\t%"PRIu64"\t(%5.2f%%)\t%.2f\n", j, res/1000000UL, 100 * res / (double)sum_cx[i], avg_res ); } printf("\n"); } if ( px_cap && sum_px[i]>0 ) { for ( j = 0; j < pxstat_end[i].total; j++ ) { res = pxstat_end[i].pt[j].residency - pxstat_start[i].pt[j].residency; printf(" P%d\t%"PRIu64"\t(%5.2f%%)\n", j, res / 1000000UL, 100UL * res / (double)sum_px[i]); } } if ( px_cap && avgfreq[i] ) printf(" Avg freq\t%d\tKHz\n", avgfreq[i]); } set_xen_guest_handle(info.cpu_to_core, cpu_to_core); set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket); set_xen_guest_handle(info.cpu_to_node, cpu_to_node); info.max_cpu_index = MAX_NR_CPU - 1; if ( cx_cap && !xc_topologyinfo(xc_handle, &info) ) { uint32_t socket_ids[MAX_NR_CPU]; uint32_t core_ids[MAX_NR_CPU]; uint32_t socket_nr = 0; uint32_t core_nr = 0; if ( info.max_cpu_index > MAX_NR_CPU - 1 ) info.max_cpu_index = MAX_NR_CPU - 1; /* check validity */ for ( i = 0; i <= info.max_cpu_index; i++ ) { if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID || cpu_to_socket[i] == INVALID_TOPOLOGY_ID ) break; } if ( i > info.max_cpu_index ) { /* find socket nr & core nr per socket */ for ( i = 0; i <= info.max_cpu_index; i++ ) { for ( j = 0; j < socket_nr; j++ ) if ( cpu_to_socket[i] == socket_ids[j] ) break; if ( j == socket_nr ) { socket_ids[j] = cpu_to_socket[i]; socket_nr++; } for ( j = 0; j < core_nr; j++ ) if ( cpu_to_core[i] == core_ids[j] ) break; if ( j == core_nr ) { core_ids[j] = cpu_to_core[i]; core_nr++; } } /* print out CC? and PC? */ for ( i = 0; i < socket_nr; i++ ) { uint64_t res; for ( j = 0; j <= info.max_cpu_index; j++ ) { if ( cpu_to_socket[j] == socket_ids[i] ) break; } printf("\nSocket %d\n", socket_ids[i]); res = cxstat_end[j].pc2 - cxstat_start[j].pc2; printf("\tPC2\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); res = cxstat_end[j].pc3 - cxstat_start[j].pc3; printf("\tPC3\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); res = cxstat_end[j].pc6 - cxstat_start[j].pc6; printf("\tPC6\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); res = cxstat_end[j].pc7 - cxstat_start[j].pc7; printf("\tPC7\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); for ( k = 0; k < core_nr; k++ ) { for ( j = 0; j <= info.max_cpu_index; j++ ) { if ( cpu_to_socket[j] == socket_ids[i] && cpu_to_core[j] == core_ids[k] ) break; } printf("\t Core %d CPU %d\n", core_ids[k], j); res = cxstat_end[j].cc3 - cxstat_start[j].cc3; printf("\t\tCC3\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); res = cxstat_end[j].cc6 - cxstat_start[j].cc6; printf("\t\tCC6\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); res = cxstat_end[j].cc7 - cxstat_start[j].cc7; printf("\t\tCC7\t%"PRIu64" ms\t%.2f%%\n", res / 1000000UL, 100UL * res / (double)sum_cx[j]); } } } } /* some clean up and then exits */ for ( i = 0; i < 2 * max_cpu_nr; i++ ) { free(cxstat[i].triggers); free(cxstat[i].residencies); free(pxstat[i].trans_pt); free(pxstat[i].pt); } free(cxstat); free(pxstat); free(sum); free(avgfreq); out: xc_hypercall_buffer_free(xc_handle, cpu_to_core); xc_hypercall_buffer_free(xc_handle, cpu_to_socket); xc_hypercall_buffer_free(xc_handle, cpu_to_node); xc_interface_close(xc_handle); exit(0); }
static void signal_int_handler(int signo) { int i, j, k; struct timeval tv; int cx_cap = 0, px_cap = 0; xc_cputopo_t *cputopo = NULL; unsigned max_cpus = 0; if ( xc_cputopoinfo(xc_handle, &max_cpus, NULL) != 0 ) { fprintf(stderr, "failed to discover number of CPUs: %s\n", strerror(errno)); goto out; } cputopo = calloc(max_cpus, sizeof(*cputopo)); if ( cputopo == NULL ) { fprintf(stderr, "failed to allocate hypercall buffers\n"); goto out; } if ( gettimeofday(&tv, NULL) ) { fprintf(stderr, "failed to get timeofday\n"); goto out; } usec_end = tv.tv_sec * 1000000UL + tv.tv_usec; if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV ) { cx_cap = 1; for ( i = 0; i < max_cpu_nr; i++ ) if ( !get_cxstat_by_cpuid(xc_handle, i, &cxstat_end[i]) ) for ( j = 0; j < cxstat_end[i].nr; j++ ) { int64_t diff = (int64_t)cxstat_end[i].residencies[j] - (int64_t)cxstat_start[i].residencies[j]; if ( diff >=0 ) sum_cx[i] += diff; } } if ( get_pxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV ) { px_cap = 1; for ( i = 0; i < max_cpu_nr; i++ ) if ( !get_pxstat_by_cpuid(xc_handle, i , &pxstat_end[i]) ) for ( j = 0; j < pxstat_end[i].total; j++ ) sum_px[i] += pxstat_end[i].pt[j].residency - pxstat_start[i].pt[j].residency; } for ( i = 0; i < max_cpu_nr; i++ ) get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]); printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL); for ( i = 0; i < max_cpu_nr; i++ ) { uint64_t res, triggers; double avg_res; printf("\nCPU%d:\tResidency(ms)\t\tAvg Res(ms)\n",i); if ( cx_cap && sum_cx[i] > 0 ) { for ( j = 0; j < cxstat_end[i].nr; j++ ) { int64_t diff = (int64_t)cxstat_end[i].residencies[j] - (int64_t)cxstat_start[i].residencies[j]; res = ( diff >= 0 ) ? diff : 0; triggers = cxstat_end[i].triggers[j] - cxstat_start[i].triggers[j]; /* * triggers may be zero if the CPU has been in this state for * the whole sample or if it never entered the state */ if ( triggers == 0 && cxstat_end[i].last == j ) avg_res = (double)sum_cx[i]/1000000.0; else avg_res = (triggers==0) ? 0: (double)res/triggers/1000000.0; printf(" C%d\t%"PRIu64"\t(%5.2f%%)\t%.2f\n", j, res/1000000UL, 100 * res / (double)sum_cx[i], avg_res ); } printf("\n"); } if ( px_cap && sum_px[i]>0 ) { for ( j = 0; j < pxstat_end[i].total; j++ ) { res = pxstat_end[i].pt[j].residency - pxstat_start[i].pt[j].residency; printf(" P%d\t%"PRIu64"\t(%5.2f%%)\n", j, res / 1000000UL, 100UL * res / (double)sum_px[i]); } } if ( px_cap && avgfreq[i] ) printf(" Avg freq\t%d\tKHz\n", avgfreq[i]); } if ( cx_cap && !xc_cputopoinfo(xc_handle, &max_cpus, cputopo) ) { uint32_t socket_ids[MAX_NR_CPU]; uint32_t core_ids[MAX_NR_CPU]; uint32_t socket_nr = 0; uint32_t core_nr = 0; if ( max_cpus > MAX_NR_CPU ) max_cpus = MAX_NR_CPU; /* check validity */ for ( i = 0; i < max_cpus; i++ ) { if ( cputopo[i].core == XEN_INVALID_CORE_ID || cputopo[i].socket == XEN_INVALID_SOCKET_ID ) break; } if ( i >= max_cpus ) { /* find socket nr & core nr per socket */ for ( i = 0; i < max_cpus; i++ ) { for ( j = 0; j < socket_nr; j++ ) if ( cputopo[i].socket == socket_ids[j] ) break; if ( j == socket_nr ) { socket_ids[j] = cputopo[i].socket; socket_nr++; } for ( j = 0; j < core_nr; j++ ) if ( cputopo[i].core == core_ids[j] ) break; if ( j == core_nr ) { core_ids[j] = cputopo[i].core; core_nr++; } } /* print out CC? and PC? */ for ( i = 0; i < socket_nr; i++ ) { unsigned int n; uint64_t res; for ( j = 0; j < max_cpus; j++ ) { if ( cputopo[j].socket == socket_ids[i] ) break; } printf("\nSocket %d\n", socket_ids[i]); for ( n = 0; n < MAX_PKG_RESIDENCIES; ++n ) { if ( n >= cxstat_end[j].nr_pc ) continue; res = cxstat_end[j].pc[n]; if ( n < cxstat_start[j].nr_pc ) res -= cxstat_start[j].pc[n]; printf("\tPC%u\t%"PRIu64" ms\t%.2f%%\n", n + 1, res / 1000000UL, 100UL * res / (double)sum_cx[j]); } for ( k = 0; k < core_nr; k++ ) { for ( j = 0; j < max_cpus; j++ ) { if ( cputopo[j].socket == socket_ids[i] && cputopo[j].core == core_ids[k] ) break; } printf("\t Core %d CPU %d\n", core_ids[k], j); for ( n = 0; n < MAX_CORE_RESIDENCIES; ++n ) { if ( n >= cxstat_end[j].nr_cc ) continue; res = cxstat_end[j].cc[n]; if ( n < cxstat_start[j].nr_cc ) res -= cxstat_start[j].cc[n]; printf("\t\tCC%u\t%"PRIu64" ms\t%.2f%%\n", n + 1, res / 1000000UL, 100UL * res / (double)sum_cx[j]); } } } } } /* some clean up and then exits */ for ( i = 0; i < 2 * max_cpu_nr; i++ ) { free(cxstat[i].triggers); free(cxstat[i].residencies); free(cxstat[i].pc); free(cxstat[i].cc); free(pxstat[i].trans_pt); free(pxstat[i].pt); } free(cxstat); free(pxstat); free(sum); free(avgfreq); out: free(cputopo); xc_interface_close(xc_handle); exit(0); }