Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux printk中断禁用和锁定_Linux_Linux Kernel_Scheduler - Fatal编程技术网

Linux printk中断禁用和锁定

Linux printk中断禁用和锁定,linux,linux-kernel,scheduler,Linux,Linux Kernel,Scheduler,关于3.10内核中printk()的实现,我有一个问题。我在开头看到它local\u irq\u save。然后我看到它raw\u spin\u lock(&logbuf\u lock)。如果在此之前中断已经被禁用,那么logbuf_锁定的目的是什么?是否因为即使当前CPU上禁用了中断,其他CPU仍可以调用printk,因此需要停止它们写入日志缓冲区 基本上我有三个问题: 我看到printk获取logbuf_锁并写入日志缓冲区,然后尝试获取控制台信号量并释放logbuf_锁。然后在console

关于3.10内核中printk()的实现,我有一个问题。我在开头看到它
local\u irq\u save
。然后我看到它
raw\u spin\u lock(&logbuf\u lock)
。如果在此之前中断已经被禁用,那么logbuf_锁定的目的是什么?是否因为即使当前CPU上禁用了中断,其他CPU仍可以调用printk,因此需要停止它们写入日志缓冲区

基本上我有三个问题:

  • 我看到printk获取logbuf_锁并写入日志缓冲区,然后尝试获取控制台信号量并释放logbuf_锁。然后在
    console_unlock
    内循环中,它获取logbuf_lock并禁用中断,然后释放logbuf_lock并调用控制台驱动程序,然后恢复中断。这个锁定/禁用中断序列的目的是什么

  • 我在printk()中看到有关日志缓冲区可能再次被填满的注释,因此缓冲区可能必须再次刷新到控制台。考虑到我在上文第1部分中询问的所有锁定,这种情况会如何发生

  • 如果在任何给定时刻只有1个CPU上的代码调用printk(),SMP系统中的其他内核是否仍能处理中断?我还试图理解printk对中断延迟的影响

  • 谢谢

    一些后续行动:

    你能否澄清一下:

    local\u irq\u save()
    可防止本地CPU上的中断(并避免在使用CPU变量访问每个CPU数据时在另一个CPU上重新调度)

    您的意思是调用
    local\u irq\u save()?在printk()的情况下,local_irq_save()的用途是什么?我记得在LMKL上读到一个线程,它说禁用中断是为了确保日志缓冲区中条目的顺序反映printk()调用发生的实际顺序

    如果在此之前中断已经被禁用,那么logbuf_锁定的目的是什么?是否因为即使当前CPU上禁用了中断,其他CPU仍可以调用printk,因此需要停止它们写入日志缓冲区

    local\u irq\u save()
    可防止本地CPU上的中断(并且在使用
    CPU
    变量访问每CPU数据时避免在另一个CPU上重新调度),而自旋锁可防止其他CPU中断

    如果在任何给定时刻只有1个CPU上的代码调用printk(),SMP系统中的其他内核是否仍能处理中断

    我看到printk获取logbuf_锁并写入日志缓冲区,然后尝试获取控制台信号量并释放logbuf_锁。然后在控制台中解锁在循环中,它获取logbuf_锁并禁用中断,然后释放logbuf_锁并调用控制台驱动程序,然后恢复中断。这个锁定/禁用中断序列的目的是什么

    有两件事需要保护:日志缓冲区和控制台驱动程序
    logbuf_lock
    保护日志缓冲区,而
    console_sem
    保护对控制台驱动程序列表和实际控制台本身的访问

    打印内核消息需要两个步骤。首先将消息放入日志缓冲区,然后将日志缓冲区发送到
    console\u unlock()
    中的控制台。这两个步骤不需要同时调用
    printk()
    。此外,在注册/启动/恢复/时,可能会将日志缓冲区刷新到控制台。。。控制台

    将消息放入日志缓冲区后,
    printk()
    尝试获取
    控制台\u sem
    。它甚至可以在中断上下文中执行此操作,因为
    down\u trylock()
    不睡眠。如果它获取了信号量,它可以继续向控制台发送日志缓冲区内容。如果它没有获取信号量,控制台信号量的持有者有责任在
    console\u unlock()
    上向控制台发送日志缓冲区内容。 当
    console\u unlock()
    发送到控制台时,可能会有其他CPU调用
    printk()
    。所以
    console\u unlock()
    循环,直到没有更多的东西发送到控制台。在每个循环中,它获取指向日志缓冲区部分的指针,以发送到控制台
    logbuf_锁下的
    ,然后不再在
    logbuf_锁下的
    ,将输出发送到控制台。在向控制台发送内容时,由于未使用
    logbuf_锁
    ,其他CPU可以继续向日志缓冲区添加内容

    我在printk()中看到有关日志缓冲区可能再次被填满的注释,因此缓冲区可能必须再次刷新到控制台。考虑到我在上文第1部分中询问的所有锁定,这种情况会如何发生

    在释放
    logbuf\u lock
    后,但在
    up()
    ing
    console\u sem
    之前,缓冲区可能已填满。而
    logbuf\u lock
    up()
    ing
    console\u sem
    之前被释放,因为
    up()
    可能会导致唤醒,而唤醒需要获取运行队列锁,这可能会对使用运行队列锁()调用的
    printk()
    产生优先级反转问题

    有人建议使用补丁来更改此锁定方案:,其中包括,尝试避免CPU在
    控制台上无限期地循环\u unlock()
    (这种情况发生在通过缓慢的串行控制台记录大量启动事件的大系统上),将该工作移交给其他CPU;试着