Implementing correct inter-module synchronization in the Linux kernel

I am implementing a custom serial bus driver for a specific ARM-based board (actually, a UART custom driver, actually). This driver must communicate with a specific MCU on the other end of the bus through a user protocol. The driver will not (and really should not ) show any of its functions in user space, and also cannot be implemented in user space at all (therefore, the need to use a custom driver instead of using the TTY subsystem).

The driver implements the UART communication and read / write protocol, and it must export a set of higher-level functions to its users so that they can communicate with the MCU (for example, read_register() , drive_gpios() , all this stuff). There will be only one user in this module.

The calling module will have to wait for the operation to complete (the above read_register() and others). I am currently considering using semaphores: the user module calls my driver function, which initiates the transfer and waits for the semaphore; my driver’s IRQ handler will send requests to the MCU and read the answers, and when this is done, send a message to the semaphore, thus waking up the calling module. But I'm not very good at kernel programming, and I am puzzled by the many possible alternative implementations (task queues? Waiting queues?).

The question arises: is my approach to semaphore okay or too naive? What are the possible alternatives? Are there any pitfalls that I can lose?

+7
source share
1 answer

Linux IRQ processing has traditionally been done in two parts:

  • The so-called "upper half" is valid in the context of IRQ (IRQ handler itself). This part should come out as quickly as possible. Therefore, it basically checks the source of the interrupts, and then starts the lower half.

  • "Bottom half". It can be implemented as a work queue. This is where the actual work is done. It works in a normal context, so it can use blocking functions, etc.

If you only want to wait for the IRQ in the workflow, it is better to use a special object called completion . It is precisely created for this task.

+5
source

All Articles