【问题标题】:Measure time a task spends between 2 points in linux (task profiling)测量任务在 linux 中 2 点之间花费的时间(任务分析)
【发布时间】:2014-02-11 14:19:11
【问题描述】:

我很快就会开始用头撞墙:

真的很简单,我想测量一个任务在 2 个点之间花费的时间(在 Linux - 1 个核心 - 1 个 CPU 中)。 在此期间,任务必须完全控制 CPU,并且不会被任何其他任务或硬件中断中断。

为了实现这一点,我创建了一个内核模块来确保满足上述条件。 在这个内核模块中,我尝试过:

首先,禁用 IRQ:

  • 我使用了 spin_lock_irqsave()/spin_lock_irqrestore() - 我认为这是确保禁用所有本地中断并且我的任务在关键区域期间拥有自己的 CPU 的正确方法。

那么,

  • 使用了 preempt_disable() -> 因为 current = my task,所以逻辑上内核应该继续运行我的任务,直到我重新启用抢占 -> 不起作用(my_task->nvcsw 和 my_task->nivcsw 表明 csw 具有发生 -> 我的任务被抢占)

我尝试通过将 my_task->prio 和 my_task->static_prio 更改为 1 -> 最高实时优先级 (my_task->policy = SCHED_FIFO) 来提高任务的优先级...

也没有工作(my_task->nvcsw 和 my_task->nivcsw 表明发生了 csw -> my-task 被抢占)并且 my_task->prio 得到了我认为的调度程序的新 prio (120).. ..

有什么方法可以确定地保证任务在 Linux 中不会被中断/抢占?有没有办法强制调度器运行一个任务(短时间 50-500us)直到它完成?

这是我启用/禁用部分操作系统的代码(相关任务使用 procfs 在关键区域之前和之后发送启用/禁用命令并由此开关处理):

// 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;
}

【问题讨论】:

  • 所以“任务”是指“用户空间任务”?
  • 是的,用户空间任务。它通过 procfs 与内核通信。它发送启用/禁用操作系统命令(由上面的代码处理)。用户空间任务还测量这两个命令之间的时间(这很奇怪,因为所有中断都应该被禁用)......但我仍然可以测量两者之间的时间(可能是无滴答内核行为)

标签: multithreading linux-kernel scheduler thread-priority preemption


【解决方案1】:

只允许内核代码禁用中断,而且只能在短时间内使用。 使用股票内核,不可能让用户空间任务完全控制 CPU。

如果您只想测量用户空间任务使用的时间,您可以正常运行您的任务并使用u modifer of perf 忽略中断;但是,这不会阻止中断处理程序的任何缓存效果。

【讨论】:

  • 感谢您的回答。这也是我所怀疑的(用户空间任务永远无法完全控制 CPU)......真可惜......我不能使用用户性能,因为我需要分析用户空间程序的一小部分(不是整个程序)...有没有办法在内核空间中执行应用程序?
猜你喜欢
  • 2015-12-11
  • 1970-01-01
  • 2015-05-27
  • 2020-06-30
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
相关资源
最近更新 更多