Esempio n. 1
0
/**
 * Show the counters to the user
 *
 * @param m
 * @param v
 * @return
 */
static int proc_perf_show(struct seq_file *m, void *v)
{
	int cpu;
	int i;

	proc_perf_update();

	seq_printf(m, "       %16s %16s\n",
		   proc_perf_label[proc_perf_counter_control[0]],
		   proc_perf_label[proc_perf_counter_control[1]]);
	for (cpu = 0; cpu < NR_CPUS; cpu++) {
		if (cpu_online(cpu))
			seq_printf(m, "CPU%2d: %16lu %16lu\n", cpu,
				   proc_perf_counter_data[cpu][0],
				   proc_perf_counter_data[cpu][1]);
	}

	seq_printf(m, "\n");
	for (i = 0; i < 4; i++)
		seq_printf(m, "%s: %lu\n",
			   proc_perf_l2label[proc_perf_l2counter_control[i]],
			   proc_perf_l2counter_data[i]);

	seq_printf(m,
		   "\n"
		   "Configuration of the performance counters is controller by writing\n"
		   "one of the following values to:\n"
		   "    /sys/module/perf_counters/parameters/counter{0,1}\n"
		   "    /sys/module/perf_counters/parameters/l2counter{0-3}\n"
		   "\n" "Possible CPU counters:");
	for (i = 0; i < PROC_PERF_CORE_MAX; i++) {
		if ((i & 7) == 0)
			seq_printf(m, "\n    ");
		if (proc_perf_label[i])
			seq_printf(m, "%s ", proc_perf_label[i]);
	}

	seq_printf(m, "\n\nPossible L2 counters:");
	for (i = 0; i < PROC_PERF_L2_MAX; i++) {
		if ((i & 3) == 0)
			seq_printf(m, "\n    ");
		if (proc_perf_l2label[i])
			seq_printf(m, "%s ", proc_perf_l2label[i]);
	}
	seq_printf(m,
		   "\nWarning: Counter configuration doesn't update till you access /proc/octeon_perf.\n");

	proc_perf_setup();
	return 0;
}
Esempio n. 2
0
/**
 * Module initialization
 *
 * @return
 */
static int __init proc_perf_init(void)
{
    printk("/proc/octeon_perf: Octeon performace counter interface loaded\n");

    memset(proc_perf_label, 0, sizeof(proc_perf_label));
    memset(proc_perf_l2label, 0, sizeof(proc_perf_l2label));

    proc_perf_label[PROC_PERF_CORE_NONE] = "none";
    proc_perf_label[PROC_PERF_CORE_CLK] = "clk";
    proc_perf_label[PROC_PERF_CORE_ISSUE] = "issue";
    proc_perf_label[PROC_PERF_CORE_RET] = "ret";
    proc_perf_label[PROC_PERF_CORE_NISSUE] = "nissue";
    proc_perf_label[PROC_PERF_CORE_SISSUE] = "sissue";
    proc_perf_label[PROC_PERF_CORE_DISSUE] = "dissue";
    proc_perf_label[PROC_PERF_CORE_IFI] = "ifi";
    proc_perf_label[PROC_PERF_CORE_BR] = "br";
    proc_perf_label[PROC_PERF_CORE_BRMIS] = "brmis";
    proc_perf_label[PROC_PERF_CORE_J] = "j";
    proc_perf_label[PROC_PERF_CORE_JMIS] = "jmis";
    proc_perf_label[PROC_PERF_CORE_REPLAY] = "replay";
    proc_perf_label[PROC_PERF_CORE_IUNA] = "iuna";
    proc_perf_label[PROC_PERF_CORE_TRAP] = "trap";
    proc_perf_label[PROC_PERF_CORE_UULOAD] = "uuload";
    proc_perf_label[PROC_PERF_CORE_UUSTORE] = "uustore";
    proc_perf_label[PROC_PERF_CORE_ULOAD] = "uload";
    proc_perf_label[PROC_PERF_CORE_USTORE] = "ustore";
    proc_perf_label[PROC_PERF_CORE_EC] = "ec";
    proc_perf_label[PROC_PERF_CORE_MC] = "mc";
    proc_perf_label[PROC_PERF_CORE_CC] = "cc";
    proc_perf_label[PROC_PERF_CORE_CSRC] = "csrc";
    proc_perf_label[PROC_PERF_CORE_CFETCH] = "cfetch";
    proc_perf_label[PROC_PERF_CORE_CPREF] = "cpref";
    proc_perf_label[PROC_PERF_CORE_ICA] = "ica";
    proc_perf_label[PROC_PERF_CORE_II] = "ii";
    proc_perf_label[PROC_PERF_CORE_IP] = "ip";
    proc_perf_label[PROC_PERF_CORE_CIMISS] = "cimiss";
    proc_perf_label[PROC_PERF_CORE_WBUF] = "wbuf";
    proc_perf_label[PROC_PERF_CORE_WDAT] = "wdat";
    proc_perf_label[PROC_PERF_CORE_WBUFLD] = "wbufld";
    proc_perf_label[PROC_PERF_CORE_WBUFFL] = "wbuffl";
    proc_perf_label[PROC_PERF_CORE_WBUFTR] = "wbuftr";
    proc_perf_label[PROC_PERF_CORE_BADD] = "badd";
    proc_perf_label[PROC_PERF_CORE_BADDL2] = "baddl2";
    proc_perf_label[PROC_PERF_CORE_BFILL] = "bfill";
    proc_perf_label[PROC_PERF_CORE_DDIDS] = "ddids";
    proc_perf_label[PROC_PERF_CORE_IDIDS] = "idids";
    proc_perf_label[PROC_PERF_CORE_DIDNA] = "didna";
    proc_perf_label[PROC_PERF_CORE_LDS] = "lds";
    proc_perf_label[PROC_PERF_CORE_LMLDS] = "lmlds";
    proc_perf_label[PROC_PERF_CORE_IOLDS] = "iolds";
    proc_perf_label[PROC_PERF_CORE_DMLDS] = "dmlds";
    proc_perf_label[PROC_PERF_CORE_STS] = "sts";
    proc_perf_label[PROC_PERF_CORE_LMSTS] = "lmsts";
    proc_perf_label[PROC_PERF_CORE_IOSTS] = "iosts";
    proc_perf_label[PROC_PERF_CORE_IOBDMA] = "iobdma";
    proc_perf_label[PROC_PERF_CORE_DTLB] = "dtlb";
    proc_perf_label[PROC_PERF_CORE_DTLBAD] = "dtlbad";
    proc_perf_label[PROC_PERF_CORE_ITLB] = "itlb";
    proc_perf_label[PROC_PERF_CORE_SYNC] = "sync";
    proc_perf_label[PROC_PERF_CORE_SYNCIOB] = "synciob";
    proc_perf_label[PROC_PERF_CORE_SYNCW] = "syncw";

    proc_perf_l2label[PROC_PERF_L2_CYCLES] = "cycles";
    proc_perf_l2label[PROC_PERF_L2_IMISS] = "imiss";
    proc_perf_l2label[PROC_PERF_L2_IHIT] = "ihit";
    proc_perf_l2label[PROC_PERF_L2_DMISS] = "dmiss";
    proc_perf_l2label[PROC_PERF_L2_DHIT] = "dhit";
    proc_perf_l2label[PROC_PERF_L2_MISS] = "miss";
    proc_perf_l2label[PROC_PERF_L2_HIT] = "hit";
    proc_perf_l2label[PROC_PERF_L2_VICTIM_BUFFER_HIT] = "victim-buffer-hit";
    proc_perf_l2label[PROC_PERF_L2_LFB_NQ_INDEX_CONFLICT] = "lfb-nq-index-conflict";
    proc_perf_l2label[PROC_PERF_L2_TAG_PROBE] = "tag-probe";
    proc_perf_l2label[PROC_PERF_L2_TAG_UPDATE] = "tag-update";
    proc_perf_l2label[PROC_PERF_L2_TAG_PROBE_COMPLETED] = "tag-probe-completed";
    proc_perf_l2label[PROC_PERF_L2_TAG_DIRTY_VICTIM] = "tag-dirty-victim";
    proc_perf_l2label[PROC_PERF_L2_DATA_STORE_NOP] = "data-store-nop";
    proc_perf_l2label[PROC_PERF_L2_DATA_STORE_READ] = "data-store-read";
    proc_perf_l2label[PROC_PERF_L2_DATA_STORE_WRITE] = "data-store-write";
    proc_perf_l2label[PROC_PERF_L2_MEMORY_FILL_DATA_VALID] = "memory-fill-data-valid";
    proc_perf_l2label[PROC_PERF_L2_MEMORY_WRITE_REQUEST] = "memory-write-request";
    proc_perf_l2label[PROC_PERF_L2_MEMORY_READ_REQUEST] = "memory-read-request";
    proc_perf_l2label[PROC_PERF_L2_MEMORY_WRITE_DATA_VALID] = "memory-write-data-valid";
    proc_perf_l2label[PROC_PERF_L2_XMC_NOP] = "xmc-nop";
    proc_perf_l2label[PROC_PERF_L2_XMC_LDT] = "xmc-ldt";
    proc_perf_l2label[PROC_PERF_L2_XMC_LDI] = "xmc-ldi";
    proc_perf_l2label[PROC_PERF_L2_XMC_LDD] = "xmc-ldd";
    proc_perf_l2label[PROC_PERF_L2_XMC_STF] = "xmc-stf";
    proc_perf_l2label[PROC_PERF_L2_XMC_STT] = "xmc-stt";
    proc_perf_l2label[PROC_PERF_L2_XMC_STP] = "xmc-stp";
    proc_perf_l2label[PROC_PERF_L2_XMC_STC] = "xmc-stc";
    proc_perf_l2label[PROC_PERF_L2_XMC_DWB] = "xmc-dwb";
    proc_perf_l2label[PROC_PERF_L2_XMC_PL2] = "xmc-pl2";
    proc_perf_l2label[PROC_PERF_L2_XMC_PSL1] = "xmc-psl1";
    proc_perf_l2label[PROC_PERF_L2_XMC_IOBLD] = "xmc-iobld";
    proc_perf_l2label[PROC_PERF_L2_XMC_IOBST] = "xmc-iobst";
    proc_perf_l2label[PROC_PERF_L2_XMC_IOBDMA] = "xmc-iobdma";
    proc_perf_l2label[PROC_PERF_L2_XMC_IOBRSP] = "xmc-iobrsp";
    proc_perf_l2label[PROC_PERF_L2_XMD_BUS_VALID] = "xmd-bus-valid";
    proc_perf_l2label[PROC_PERF_L2_XMD_BUS_VALID_DST_L2C] = "xmd-bus-valid-dst-l2c";
    proc_perf_l2label[PROC_PERF_L2_XMD_BUS_VALID_DST_IOB] = "xmd-bus-valid-dst-iob";
    proc_perf_l2label[PROC_PERF_L2_XMD_BUS_VALID_DST_PP] = "xmd-bus-valid-dst-pp";
    proc_perf_l2label[PROC_PERF_L2_RSC_NOP] = "rsc-nop";
    proc_perf_l2label[PROC_PERF_L2_RSC_STDN] = "rsc-stdn";
    proc_perf_l2label[PROC_PERF_L2_RSC_FILL] = "rsc-fill";
    proc_perf_l2label[PROC_PERF_L2_RSC_REFL] = "rsc-refl";
    proc_perf_l2label[PROC_PERF_L2_RSC_STIN] = "rsc-stin";
    proc_perf_l2label[PROC_PERF_L2_RSC_SCIN] = "rsc-scin";
    proc_perf_l2label[PROC_PERF_L2_RSC_SCFL] = "rsc-scfl";
    proc_perf_l2label[PROC_PERF_L2_RSC_SCDN] = "rsc-scdn";
    proc_perf_l2label[PROC_PERF_L2_RSD_DATA_VALID] = "rsd-data-valid";
    proc_perf_l2label[PROC_PERF_L2_RSD_DATA_VALID_FILL] = "rsd-data-valid-fill";
    proc_perf_l2label[PROC_PERF_L2_RSD_DATA_VALID_STRSP] = "rsd-data-valid-strsp";
    proc_perf_l2label[PROC_PERF_L2_RSD_DATA_VALID_REFL] = "rsd-data-valid-refl";
    proc_perf_l2label[PROC_PERF_L2_LRF_REQ] = "lrf-req";
    proc_perf_l2label[PROC_PERF_L2_DT_RD_ALLOC] = "dt-rd-alloc";
    proc_perf_l2label[PROC_PERF_L2_DT_WR_INVA] = "dt-wr-inva";

	proc_perf_entry = create_proc_entry("octeon_perf", 0, NULL);
	if (proc_perf_entry)
		proc_perf_entry->proc_fops = &proc_perf_operations;

    proc_perf_setup();
	return 0;
}
Esempio n. 3
0
/**
 * IOCTL on /proc/octeon_perf
 *
 * @param inode
 * @param file
 * @param cmd
 * @param arg
 * @return
 */
static int proc_perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    //printk("proc_perf_ioctl(cmd=0x%x(%u), arg=0x%lx)\n", cmd, cmd, arg);
    switch (cmd)
    {
        case PROC_PERF_IOCTL_SETUP_COUNTER0:
            if ((arg<=PROC_PERF_CORE_MAX) && proc_perf_label[arg])
            {
                strcpy(counter0, proc_perf_label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_SETUP_COUNTER1:
            if ((arg<=PROC_PERF_CORE_MAX) && proc_perf_label[arg])
            {
                strcpy(counter1, proc_perf_label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_SETUP_L2COUNTER0:
            if ((arg<=PROC_PERF_L2_MAX) && proc_perf_l2label[arg])
            {
                strcpy(l2counter0, proc_perf_l2label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_SETUP_L2COUNTER1:
            if ((arg<=PROC_PERF_L2_MAX) && proc_perf_l2label[arg])
            {
                strcpy(l2counter1, proc_perf_l2label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_SETUP_L2COUNTER2:
            if ((arg<=PROC_PERF_L2_MAX) && proc_perf_l2label[arg])
            {
                strcpy(l2counter2, proc_perf_l2label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_SETUP_L2COUNTER3:
            if ((arg<=PROC_PERF_L2_MAX) && proc_perf_l2label[arg])
            {
                strcpy(l2counter3, proc_perf_l2label[arg]);
                proc_perf_setup();
                return 0;
            }
            return -EINVAL;
        case PROC_PERF_IOCTL_READ_COUNTER0:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_counter_data[smp_processor_id()] + 0, sizeof(long long));
            return 0;
        case PROC_PERF_IOCTL_READ_COUNTER1:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_counter_data[smp_processor_id()] + 1, sizeof(long long));
            return 0;
        case PROC_PERF_IOCTL_READ_L2COUNTER0:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_l2counter_data + 0, sizeof(long long));
            return 0;
        case PROC_PERF_IOCTL_READ_L2COUNTER1:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_l2counter_data + 1, sizeof(long long));
            return 0;
        case PROC_PERF_IOCTL_READ_L2COUNTER2:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_l2counter_data + 2, sizeof(long long));
            return 0;
        case PROC_PERF_IOCTL_READ_L2COUNTER3:
            proc_perf_update();
            copy_to_user((void*)arg, proc_perf_l2counter_data + 3, sizeof(long long));
            return 0;
        default:
            return -EINVAL;
    }
}
Esempio n. 4
0
/**
 * Show the counters to the user
 *
 * @param m
 * @param v
 * @return
 */
static int proc_perf_show(struct seq_file *m, void *v)
{
    int cpu;
    int i;
    uint64_t dram_clocks;
    uint64_t dram_operations;

    proc_perf_update();

    seq_printf(m, "       %16s %16s\n",
               proc_perf_label[proc_perf_counter_control[0]],
               proc_perf_label[proc_perf_counter_control[1]]);
    for (cpu=0; cpu<NR_CPUS; cpu++)
    {
        if (cpu_online(cpu))
		    seq_printf(m, "CPU%2d: %16lu %16lu\n", cpu, proc_perf_counter_data[cpu][0], proc_perf_counter_data[cpu][1]);
    }

    seq_printf(m, "\n");
    for (i=0; i<4; i++)
        seq_printf(m, "%s: %lu\n", proc_perf_l2label[proc_perf_l2counter_control[i]], proc_perf_l2counter_data[i]);

    /* Compute DRAM utilization */
    dram_operations = (octeon_read_csr(OCTEON_LMC_OPS_CNT_HI) << 32) | octeon_read_csr(OCTEON_LMC_OPS_CNT_LO);
    dram_clocks = (octeon_read_csr(OCTEON_LMC_DCLK_CNT_HI) << 32) | octeon_read_csr(OCTEON_LMC_DCLK_CNT_LO);
    if (dram_clocks > proc_perf_dram_clocks)
    {
        uint64_t delta_clocks = dram_clocks - proc_perf_dram_clocks;
        uint64_t delta_operations = dram_operations - proc_perf_dram_operations;
        uint64_t percent_x100 = 10000 * delta_operations / delta_clocks;
        seq_printf(m, "\nDRAM ops count: %lu, dclk count: %lu, utilization: %lu.%02lu%%\n",
                   delta_operations, delta_clocks, percent_x100 / 100, percent_x100 % 100);
    }
    proc_perf_dram_operations = dram_operations;
    proc_perf_dram_clocks = dram_clocks;

    seq_printf(m,
               "\n"
               "Configuration of the performance counters is controller by writing\n"
               "one of the following values to:\n"
               "    /sys/module/perf_counters/parameters/counter{0,1}\n"
               "    /sys/module/perf_counters/parameters/l2counter{0-3}\n"
               "\n"
               "Possible CPU counters:");
    for (i=0; i<PROC_PERF_CORE_MAX; i++)
    {
        if ((i & 7) == 0)
            seq_printf(m, "\n    ");
        if (proc_perf_label[i])
            seq_printf(m, "%s ", proc_perf_label[i]);
    }

    seq_printf(m, "\n\nPossible L2 counters:");
    for (i=0; i<PROC_PERF_L2_MAX; i++)
    {
        if ((i & 3) == 0)
            seq_printf(m, "\n    ");
        if (proc_perf_l2label[i])
            seq_printf(m, "%s ", proc_perf_l2label[i]);
    }
    seq_printf(m, "\nWarning: Counter configuration doesn't update till you access /proc/octeon_perf.\n");

    proc_perf_setup();
    return 0;
}