static inline void vperfctr_resume_with_overflow_check(struct vperfctr *perfctr)
{
#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
	if (perfctr_cpu_has_pending_interrupt(&perfctr->cpu_state)) {
		vperfctr_handle_overflow(current, perfctr);
		return;
	}
#endif
	vperfctr_resume(perfctr);
}
Exemple #2
0
/* PREEMPT note: called in IRQ context with preemption disabled. */
static void vperfctr_ihandler(unsigned long pc)
{
	struct task_struct *tsk = current;
	struct vperfctr *perfctr;

	perfctr = tsk->arch.thread.perfctr;
	if (!perfctr) {
		printk(KERN_ERR "%s: BUG! pid %d has no vperfctr\n",
		       __FUNCTION__, tsk->id);
		return;
	}
	if (!perfctr_cstatus_has_ictrs(perfctr->cpu_state.user.cstatus)) {
		printk(KERN_ERR "%s: BUG! vperfctr has cstatus %#x (pid %d, comm %s)\n",
		       __FUNCTION__, perfctr->cpu_state.user.cstatus, tsk->id, tsk->comm);
		return;
	}
	vperfctr_suspend(perfctr);
	vperfctr_handle_overflow(tsk, perfctr);
}
// PREEMPT note: called in IRQ context with preemption disabled.
static void vperfctr_ihandler(unsigned long pc)
{
	struct task_struct *tsk = current;
	struct vperfctr *perfctr;
	unsigned int pmc, cstatus, now = 0;
	int i;

	perfctr = tsk->thread.perfctr;
	if (!perfctr) {
		return;
	}
	if (!perfctr_cstatus_has_ictrs(perfctr->cpu_state.cstatus)) {
		return;
	}

	// if someone has really overflown then continue else return
	// just read, don't freeze them
	
	cstatus = perfctr->cpu_state.cstatus;
	for (i = perfctr_cstatus_nractrs(cstatus); (i < perfctr_cstatus_nrctrs(cstatus)) && ((int)now >= 0); ++i) {
		pmc = perfctr->cpu_state.pmc[i].map;
		now = read_pmc(pmc);
	}
	if ((int)now >= 0) {
		return;
	}

	// Fine, we are suspending the counters and reading them. vperfctr_suspend() 
	// in turn invokes _suspend() on i-mode ctrs (where they are frozen and read) 
	// and a-mode counters (where they are just read)

	vperfctr_suspend(perfctr);

	// Ok, Signal to the userland is sent in the following routine. But before that
	// the following routine calls vperfctr_resume() if the TSC counting is on.
	// what happens in that resume is just the TSC value is read and stored in the
	// 'start' state of the TSC

	vperfctr_handle_overflow(tsk, perfctr);
}