Measure time a task spends between 2 points in linux (task profiling)
I'll soon start banging my head on the wall:
It's very simple really, I want to measure the time a task spends between 2 points (in Linux - 1 core - 1 CPU). During this time the task must have total control over the CPU and NOT get interrupted by any other task or HW interrupts.
To achieve this, I'v created a kernel module to make sure the above criterions are met. In this kernel module I've tried to:
First, disable IRQs:
Then,
I've tried to increase the priority of my task by changing my_task->prio and my_task->static_prio to 1 -> highest real-time prio (my_task->policy = SCHED_FIFO)...
Did not work either (my_task->nvcsw and my_task->nivcsw show that a csw has occurred -> my-task got preempted) and my_task->prio got a new prio (120) by the scheduler I presume....
Is there any way to deterministically garantee that a task does not get interrupted/preeempted in Linux? Is there any way to force the scheduler to run a task (for a short time 50-500us) until it's done?
Here is my code to enable/disable parts of the OS (the task in question sends a enable/disable commands before and after the critical region using procfs and handled by this switch):
// Handle request
switch( enable ){
// Disable OS
case COS_OS_DISABLE:
// Disable preemption
preempt_disable()
// Save policy
last_policy = pTask->policy;
// Save task priorities
last_prio = pTask->prio;
last_static_prio = pTask->static_prio;
last_normal_prio = pTask->normal_prio;
last_rt_priority = pTask->rt_priority;
// Set priorities to highest real time prio
pTask->prio = 1;
pTask->static_prio = 1;
pTask->normal_prio = 1;
pTask->rt_priority = 1;
// Set scheduler policy to FIFO
pTask->policy = SCHED_FIFO;
// Lock kernel: It will disable interrupts _locally_, but the spinlock itself will guarantee the global lock, so it will guarantee that there is only one thread-of-control within the region(s) protected by that lock.
spin_lock_irqsave( &mr_lock , flags );
break;
// Default: Enable OS always
case COS_OS_ENABLE:
default:
// Reset task priorities
pTask->prio = last_prio;
pTask->static_prio = last_static_prio;
pTask->normal_prio = last_normal_prio;
pTask->rt_priority = last_rt_priority;
// Reset scheduler policy
pTask->policy = last_policy;
// Unlock kernel
spin_unlock_irqrestore( &mr_lock , flags );
// Enable preemption
preempt_enable();
break;
}
Disabling interrupts is allowed only for kernel code, and only for a short time. With the stock kernel, it is not possible to give a user-space task total control of the CPU.
If you want to measure only the time used by your user-space task, you could run your task normally and use the u
modifer of perf
to ignore interrupts; however, this would not prevent any cache effects of the interrupt handlers.
上一篇: Linux:禁止中断处理程序的中断