Ejemplo n.º 1
0
static int op_powerpc_setup(void)
{
	int err;

	op_per_cpu_rc = 0;

	/* Grab the hardware */
	err = reserve_pmc_hardware(op_handle_interrupt);
	if (err)
		return err;

	/* Pre-compute the values to stuff in the hardware registers.  */
	op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters);

	if (op_per_cpu_rc)
		goto out;

	/* Configure the registers on all cpus.	 If an error occurs on one
	 * of the cpus, op_per_cpu_rc will be set to the error */
	on_each_cpu(op_powerpc_cpu_setup, NULL, 1);

out:	if (op_per_cpu_rc) {
		/* error on setup release the performance counter hardware */
		release_pmc_hardware();
	}

	return op_per_cpu_rc;
}
Ejemplo n.º 2
0
static int op_powerpc_setup(void)
{
	int err;

	op_per_cpu_rc = 0;

	
	err = reserve_pmc_hardware(op_handle_interrupt);
	if (err)
		return err;

	
	op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters);

	if (op_per_cpu_rc)
		goto out;

	on_each_cpu(op_powerpc_cpu_setup, NULL, 1);

out:	if (op_per_cpu_rc) {
		
		release_pmc_hardware();
	}

	return op_per_cpu_rc;
}
/*
 * proc handler for /proc/sys/tile/userspace_perf_counters
 */
int userspace_perf_counters_handler(struct ctl_table *table, int write,
		void __user *buffer, size_t *lenp,
		loff_t *ppos)
{
	int ret, changed;
	unsigned int old_userspace_perf_counters;

	/* Read /proc/sys/tile/userspace_perf_counters */
	if (!write) {
		ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
		return ret;
	}

	/* Write /proc/sys/tile/userspace_perf_counters */
	old_userspace_perf_counters = userspace_perf_counters;
	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
	changed = userspace_perf_counters != old_userspace_perf_counters;

	/*
	 * Do something only if the value of userspace_perf_counters
	 * is changed.
	 */
	if  (ret == 0 && changed) {

		if (userspace_perf_counters == 1) {
			if (reserve_pmc_hardware(userspace_perf_handler)) {
				pr_warning("PMC hardware busy (reserved "
					"by perf_event or oprofile)\n");
				userspace_perf_counters =
					old_userspace_perf_counters;
				return -EBUSY;
			}
		} else
			release_pmc_hardware();

		/* Set MPL_PERF_COUNT_SET_X on each tile. */
		on_each_cpu(set_perf_count_sprs, NULL, 1);
	}

	return ret;
}
Ejemplo n.º 4
0
int perfctr_reserve_pmc_hardware(void)
{
	return reserve_pmc_hardware(do_perfctr_interrupt);
}
static int __init setup_watchpoint(char *str)
{
	char *p;
	unsigned long va, width;
	int mode;

	va = simple_strtoul(str, &p, 0);
	if (p == str) {
		pr_err("Unknown 'watch=' numeric value: %s\n", str);
		return -EINVAL;
	}
	str = p;
	if (*str == '/') {
		++str;
		width = simple_strtoul(str, &p, 0);
		if (p == str) {
			pr_err("Unknown 'watch=' width qualifier: %s\n", str);
			return -EINVAL;
		}
		if (__builtin_popcount(width) != 1) {
			pr_err("'watch=' width value not power of two: %ld\n",
			       width);
			return -EINVAL;
		}
		str = p;
	} else {
		width = 1;
	}
	if (*str == ',') {
		mode = string_to_mode(++str);
		if (mode == -1) {
			pr_err("Unknown 'watch=' qualifier '%s'\n", str);
			return -EINVAL;
		}
	} else {
		mode = string_to_mode("default");
	}

	/* FIXME: we only need to reserve PERF_COUNT_0. */
	if (reserve_pmc_hardware(handle_watch_interrupt))
		return -EINVAL;

	pr_notice("Watching VAs %#lx..%#lx,%s\n",
		  va, va + width - 1, mode_to_string(mode));

	__insn_mtspr(SPR_WATCH_VAL, va);

#ifdef __tilegx__
	/* Watch only the VA bits, not the high bits. */
	__insn_mtspr(SPR_WATCH_MASK, (-1ULL << 42) | (width - 1));

	/*
	 * We assume SPR_DIAG_MUX_CTL is set for Mbox output in the hv.
	 * Select "special" for perf counter zero, using "watch SPR" output.
	 */
	__insn_mtspr(SPR_PERF_COUNT_CTL, (7 << 6) | 0);
#else
	/* Watch requested VA bits. */
	__insn_mtspr(SPR_WATCH_MASK, width - 1);
	/* Choose watching the appropriate type of access. */
	__insn_mtspr(SPR_WATCH_CTL, mode);
	/* Select DIAG_SPCL_EVENT_WATCH for performance counter 0. */
	__insn_mtspr(SPR_PERF_COUNT_CTL, 106);
#endif

	__insn_mtspr(SPR_PERF_COUNT_0, -1);
	unmask_pmc_interrupts();

	return 0;
}