简体   繁体   中英

why same TASKLET can't execute on two core simultaneously?

In linux Kernel implementation for ARM platform, deferred work in tasklet is added to percpu vec|vec_hi list.

  1. now while returning from ISR execution it goes to address deferred work in softirq and tasklets.
  2. now this deferred work can be taken care of here in interrupt context with IRQs enabled or there are ksoftirq threads that can process it in process context.
  3. same tasklet will be executed on the same CPU as ksoftirq thread is percpu.
  4. I have been seeing that in many books eg LDD, Robert Love's book, it's claimed that same tasklet can't be executed on two cores simultaneously?

how? can someone help me with this... If this is so, what am I missing?

It's true. While the tasklet can be scheduled (ie tasklet execution requested) on any number of CPUs, it will only be executed on one.

The reason for this is I believe to simplify the development model: to make it easier to implement what is essentially an interrupt handler without needing to worry about races due to simultaneous execution on multiple processors -- and while not disabling other interrupts. (Obviously there are still many other opportunities for races that a driver developer needs to be aware of, but these are among the most difficult to solve.)

If you're asking about the implementation, it's actually pretty simple. In tasklet_action , tasklet_trylock is called. It uses the guaranteed-atomic function test_and_set_bit to set the TASKLET_STATE_RUN bit. This can only succeed on one processor. Hence, all other processors are prevented from executing the tasklet until the bit has been cleared -- which is only done by the processor that set it after the tasklet has completed.

EDIT:
Clarifying: calling tasklet_schedule on any number of CPUs (prior to execution) results in the tasklet being executed exactly once: on the first CPU that made the call. The same mechanism ( test_and_set_bit ) ensures that if the tasklet has already been scheduled on some other CPU but has not yet been executed, it will not be added to the tasklets-to-run queue on the later CPU (and hence won't be executed on the later CPU at all).

On the other hand, if it has already begun executing on the first CPU, the TASKLET_STATE_SCHEDULE bit will have been cleared (and hence may be set again), and so another call to tasklet_schedule ensures that the tasklet will eventually be re-executed on the later CPU, but not until after it has run to completion on the first CPU.

softirqs are bottom half interrupt processing, is based on a an index based function call mechanism where the function implement the functionality of softirq.

An array of function pointer is maintained. When a softirq is registered a valid function pointer is written into the appropriate index. The index represent the number of the softirq, 0 being the highest priority softirq. A word is maintained as a mask for the pending softirq.

The number of softirqs currently 9 are represented by each bit of an word, when sofirqs are raised the appropriate bit in the mask are set.Next when kernel wants to run the pending softirqs it uses the masked word to identify the pending softirqs ,and appropriate function calls are invoked using the array, whose 0th index is mapped with the 0th bit of the mask word.

Tasklets are implemented over softirqs, index 0 and index 5 of the array contains pointers to functions which handles high and normal tasklets respectively. Tasklets are identified with a structure which contains a function pointer and a state flag among other members.

Whenever tasklets are created, a structure is created, populating the function pointer with the address of the function that implements the tasklet. A link list of all such structures are maintained. When tasklet is scheduled, it(kernel) add a corresponding structure to the head of the link list and raise the softirq of the tasklets ie set the appropriate bits in the mask word.

Next when the function to handle the tasklets are invoked, it checked all elements of the link list, and invokes the function in the structure provided the state flag is not running, which indicates it already running in a processor.

Thus kernel make sure no 2 same tasklets are running in more than one processor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM