Tuesday, June 25, 2013

IPC device using Linux Kernel "completions"

The Linux kernel provides a service named "completions" for  the purpose of intimating another process that a particular task has been completed. Here is the source code for a device driver for a simple Inter Process Communication device that can be used to send a string of 4 characters between two processes.

Completions

Here is some details about the "completions":

  • Completions is a technique that can be used to convey that particular task has been completed to the other process
  • <linux/completion.h> must be included to use this.
  • A completion can be declared by DECLARE_COMPLETION(my_completion)
  • If it has to be created and initialized dynamically then we may use the following method.           
struct completion my_completion;
init_completion(&my_completion);
  • Waiting can be done by wait_for_completion(struct completion *c)
  • It performs an uninterruptible wait and if nobody ever issues a complete() , then that results in an un-killable process.
  • Completion can be notified by
    • void complete(struct completion *c)
    • void complete_all(struct completion *c)
    • Both of the above functions behaves differently if more than one process is waiting
    • In that case complete() will only notify only one process. But the complete_all() will notify all the processes waiting.
    • The structure can be reused without any problem unless complete_all is used. If comlpete_all is used then re-initialization has to be done in the follwing way :- INIT_COMPLETION(struct completion c)

The Device

The structure of device is simple. Here is the write operation
copy_from_user(buff,buffer,4);
complete(&sig);
The write operation simply copies the data from user space to an array in the kernel space.Then it issues a complete(). This is anything but a declaration that a particular task that is associated with sig has been completed and a process waiting on sig can proceed.
The read operaion is as follows.
wait_for_completion(&sig);
copy_to_user(buffer,buff,4);
The read operation on the other hand waits on the sig using wait_for_completion(). So when another process issues a complete() on sig, then the reader can proceed.
The device has the following behavior
  • Read and write can only be done with data size as 4 characters.
  • The data written to the device persists unless a read operation is done on the the device. The write operations is non-blocking.
  • The read operation on the device has to wait unless something is written to the device. Hence read operation is blocking.
Reference : LDD 3e Chapter 5

2 comments:

  1. Good . "completions" were a brand new IPC mechanism for me. Is it what is called as mailboxes ?

    ReplyDelete
  2. @Vijeen I don't know what you exactly mean by a mailbox. Probably you are talking about a user space functionality. "completions" on the other hand is purely a Kernel functionality.

    ReplyDelete