• ULK --- Chap 4: Softirqs and Tasklets (Note)


    We mentioned earlier in the section "Interrupt Handling" that several tasks among those executed 

    by the kernel are not critical: they can be deferred for along period of time, if necessary. Remember

    that the interrupt service routines of an interrupt handler are serialized, and often there should be

    no occurrence of an interrupt until the corresponding interrupt handler has terminated. Conversely,

    the deferrable tasks can execute with all interrupts enabled. Taking them out of the interrupt handler

    helps keep kernel response time small. This is a very important property of many time-critical applications

    that expect their interrupt requests to be serviced in a few milliseconds.

    Linux 2.6 answers such a challenge by using two kinds of non-urgent interruptible kernel functions:

    the so-called deferrable functions (softirqs and tasklets), and those executed by means of some work 

    queues.

    Softirqs and tasklets are strictly correlated, because tasklets are implemented on top of softirqs.

    As a matter of fact, the term "softirq", which appears in the kernel source code, often denotes both

    kinds of deferrable functions. Another widely used term is interrupt context: it specifies that the kernel

    is currently executing either an interrupt handler or a deferrable function.

    Softirqs are statically allocated (i.e., defined at compile time), while tasklets can also be allocated and

    initialized at runtime (for instance, when loading a kernel module). Softirqs can run concurrently on several

    CPUs, even if they are of the same type. Thus, softirqs are reentrant functions and must explicitly protect

    their data structures with spin locks. Tasklets do not have to worry about this, because their execution is

    controlled more strictly by the kernel. Tasklets of the same type are always serialized: in other words, the

    same type of takslet cannot be executed by two CPUs at the same time. However, tasklets of different types

    can be executed concurrently on several CPUs. Serializing the tasklet simplifies the life of device driver 

    developers, because the tasklet function needs not be reentrant.

    Generally speaking, four kinds of operations can be performed on deferrable functions:

    Initialization: Defines a new deferrable function; this operation is usually done when the kernel initializes

    itself or a module is loaded.

    Activation: Marks a deferrable function as "pending" --- to be run the next time the kernel schedules a round

    of executions of deferrable functions.

    Masking: Selectively disables a deferrable function so that it will not be executed by the kernel even if activated.

    Execution: Executes a pending deferrable function together with all other pending deferrable functions of the

    same type; execution is performed at well-specified times, explained later.

    Activation and execution are bound together: a deferrable function that has been activated by a given CPU

    must be executed on the same CPU. There is no self-evident reason suggesting that this rule is beneficial

    for system performance. Binding the deferrable function to the activating CPU could in theory make better use of

    the CPU hardware cache. After all, it is conceivable that the activating kernel thread accesses some data structures

    that will also be used by the deferrable function. However, the relevant lines could esasily be no longer in the cache

    when the deferrable function is run because its execution can be delayed a long time. Moreover, binding a function

    to a CPU is always a potentially dangerous operation, because one CPU might end up very busy while the others

    are mostly idle.

                            Softirqs

    Linux 2.6 uses a limited number of irqs. For most purposes, tasklets are good enough and are much easier to

    write because they do not need to be reentrant.

    As a matter of fact, only the six kinds of softirqs listed in following table are currently defined.

    softirq                              Index(priority)                              Description

    HI_SOFTIRQ                     0                            Handles high priority tasklets

    TIMER_SOFTIRQ               1                   Tasklets related to timer interrupts

    NET_TX_SOFTIRQ             2                   Transmits packets to network cards

    NET_RX_SOFTIRQ             3                   Receives packets from network cards

    SCSI_SOFTIRQ              4                   Post-interrupt processing of SCSI commands

    TASKLET_SOFTIRQ            5                   Handles regular tasklets

    The index of a softirq determines its priority: a lower index means higher priority because softirq function

    will be executed starting from index 0.

    The main data structures used to represent softirqs is the softirq_vec array, which includes 32 elements of

    type softirq_action. The priority of a softirq is the index of the corresponding softirq_action element inside

    the array. As shown in above list, only the first six entries of the array are effectively used. The softirq_action

    data structure consists of two fields: an action pointer to the softirq function and a data pointer to a generic

    data structure that may be needed by the softirq function.

    Another critical field used to keep track both of kernel preemption and of the nesting of kernel control paths

    is the 32 bit preempt_count field stored in the thread_info field of each process descriptor. This field encodes

    three distinct counters plus a flag shown in following table.

    Bits              Description

    0-7              Preemption counter (max value = 255)

    8-15              Softirq counter (max value = 255)

    16-27              Hardirq counter (max value = 4096)

    28               PREEMPT_ACTIVE flag

    The first counter keeps track of how many times kernel preemption has been explicitly disabled on the local CPU;

    the value zero means that kernel preemption has not been explicitly disabled at all. 

  • 相关阅读:
    Mongodb 查询时间类型
    Python更新所有pip package
    Python selenium on windows
    Redis cluster setup on windows
    CAP定理(theorem)
    error: Microsoft Visual C++ 14.0 is required when installing python package
    using RNGCryptoServiceProvider to generate random string
    <map>的使用
    二维vector的使用
    vector做形参时的三种传参方式
  • 原文地址:https://www.cnblogs.com/miaoyong/p/5014896.html
Copyright © 2020-2023  润新知