Пример #1
0
static int sys_vperfctr_iresume(struct vperfctr *perfctr, const struct task_struct *tsk)
{
#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
	unsigned int iresume_cstatus;

	if (!tsk)
		return -ESRCH;	/* attempt to update unlinked perfctr */

	iresume_cstatus = perfctr->iresume_cstatus;
	if (!perfctr_cstatus_has_ictrs(iresume_cstatus))
		return -EPERM;

	/* PREEMPT note: preemption is disabled over the entire
	   region because we're updating an active perfctr. */
	preempt_disable();

	if (IS_RUNNING(perfctr) && tsk == current)
		vperfctr_suspend(perfctr);

	perfctr->cpu_state.cstatus = iresume_cstatus;
	perfctr->iresume_cstatus = 0;

	/* remote access note: perfctr_cpu_ireload() is ok */
	perfctr_cpu_ireload(&perfctr->cpu_state);

	if (tsk == current)
		vperfctr_resume(perfctr);

	preempt_enable();

	return 0;
#else
	return -ENOSYS;
#endif
}
Пример #2
0
static inline void vperfctr_ireload(struct vperfctr *perfctr)
{
#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
	if (perfctr->ireload_needed) {
		perfctr->ireload_needed = 0;
		/* remote access note: perfctr_cpu_ireload() is ok */
		perfctr_cpu_ireload(&perfctr->cpu_state);
	}
#endif
}
Пример #3
0
static int do_vperfctr_iresume(struct vperfctr *perfctr, const struct task_struct *tsk)
{
#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
	unsigned int iresume_cstatus;

	if (!tsk)
		return -ESRCH;	/* attempt to update unlinked perfctr */

	iresume_cstatus = perfctr->iresume_cstatus;
	if (!perfctr_cstatus_has_ictrs(iresume_cstatus)) {
		return -EPERM;
	}

	/* PREEMPT note: preemption is disabled over the entire
	   region because we're updating an active perfctr. */
	preempt_disable();

	// this is for resuming a task whose signal was handled prior to this call
	// are the i-mode counters frozen before the overflow-signal is delivered
	// yes, they are. in the suspend call invoked in the handler

	// why exactly are we suspending the following? Makes sense ... if the
	// counters are already running, then one should not just resume the task
	// which will overwrite the PMC registers with old values. Nice. Under
	// what condition do counters continue to count after the signal is delivered
	// remember TSC was not suspend in the handler and continues to count

	if (IS_RUNNING(perfctr) && tsk == current)
		vperfctr_suspend(perfctr);

	// setting the cstatus of 'cpu_state' back to what it was prior to its
	// zeroing out in the interrupt handler
	perfctr->cpu_state.cstatus = iresume_cstatus;
	perfctr->iresume_cstatus = 0;

	/* remote access note: perfctr_cpu_ireload() is ok */
	// the following forces the reload of control registers that 
	// unfreezes the i-mode registers
	perfctr_cpu_ireload(&perfctr->cpu_state);

	if (tsk == current)
		vperfctr_resume(perfctr);

	preempt_enable();

	return 0;
#else
	return -ENOSYS;
#endif
}