Linux Device Driver Tutorial Part 22 – Mutex in Linux Kernel

This is the Series on Linux Device Driver. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Linux Device Driver Tutorial Part 22 – Mutex in Linux Kernel.


In the example section, I had used Kthread to explain Mutex. If you don’t know what is Kthread and How to use it, then I would recommend you to explore that by using the below link.

  1. Kthread Tutorial in Linux Kernel


Before getting to know about Mutex, let’s take an analogy first.

Let us assume we have a car designed to accommodate only one person at any instance of time, while all the four doors of the car are open. But, if any more than one person tries to enter the car, a bomb will set off an explosion! (Quite a fancy car manufactured by EmbeTronicX!! 😀 ) Now that four doors of the car are open, the car is vulnerable to the explosion as anyone can enter through one of the four doors.

Now how we can solve this issue? Yes, correct. We can provide a key for the car. So, the person who wants to enter the car must have access to the key. If they don’t have keys, they have to wait until that key is available or they can do some other work instead of waiting for the key.

Example Problems

Let’s correlate the analogy above to what happens in our software. Let’s explore situations like these through examples.

  1. You have one SPI connection. What if one thread wants to write something into that SPI device and another thread wants to read from that SPI device at the same time?
  2. You have one LED display. What if one thread is writing data at a different position of Display and another thread is writing different data at a different position of Display at the same time?
  3. You have one Linked List. What if one thread wants to insert something into the list and another one wants to delete something on the same Linked List at the same time?

In all the scenarios above, the problem encountered is the same. At any given point two threads are accessing a single resource. Now we will relate the above scenarios to our car example.

  1. In SPI example, CAR = SPI, Person = Threads, Blast = Software Crash/Software may get wrong data.
  2. In the LED display example,  CAR = LED Display, Person = Threads, Blast = Display will show some unwanted junks.
  3. In Linked List example, CAR = Linked List, Person = Threads, Blast = Software Crash/Software may get wrong data.

The cases above are termed as Race Condition.

Race Condition

A race condition occurs when two or more threads can access shared data and they try to change it at the same time. Because the thread scheduling algorithm can swap between threads at any time, we don’t know the order in which the threads will attempt to access the shared data. Therefore, the result of the change in data is dependent on the thread scheduling algorithm, i.e. both threads are “racing” to access/change the data.

To avoid race conditions, we have many ways like Semaphore, Spinlock, and Mutex. In this tutorial, we will concentrate on Mutex.


mutex is a mutual exclusion lock. Only one thread can hold the lock.

A mutex can be used to prevent the simultaneous execution of a block of code by multiple threads that are running in a single or multiple processes.

Mutex is used as a synchronization primitive in situations where a resource has to be shared by multiple threads simultaneously.

A mutex has ownership. The thread which locks a Mutex must also unlock it.

So whenever you are accessing a shared resource that time first we lock mutex and then access the shared resource. When we are finished with that shared resource then we unlock the Mutex.

I hope you got some idea about Mutex. Now, let us look at Mutex in the Linux Kernel.

Mutex in Linux Kernel

Today most major operating systems employ multitasking. Multitasking is where multiple threads can execute in parallel and thereby utilizing the CPU in optimum way. Even though, multitasking is useful, if not implemented cautiously can lead to concurrency issues (Race condition), which can be very difficult to handle.

The actual mutex type (minus debugging fields) is quite simple:

We will be using this structure for Mutex. Refer to Linux/include/linux/mutex.h

Initializing Mutex

We can initialize Mutex in two ways

  1. Static Method
  2. Dynamic Method

Static Method

This method will be useful while using global Mutex. This macro is defined below.


This call defines and initializes a mutex. Refer to Linux/include/linux/mutex.h

Dynamic Method

This method will be useful  for per-object mutexes when the mutex is just a field in a heap-allocated object. This macro is defined below.

mutex_init(struct mutex *lock);


struct mutex *lock – the mutex to be initialized.

This call initializes already allocated mutex. Initialize the mutex to the unlocked state.

It is not allowed to initialize an already locked mutex.


Mutex Lock

Once a mutex has been initialized, it can be locked by anyone of them explained below.


This is used to lock/acquire the mutex exclusively for the current task. If the mutex is not available, the current task will sleep until it acquires the Mutex.

The mutex must, later on, released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset-ing the mutex to 0 is not allowed.

void mutex_lock(struct mutex *lock);


struct mutex *lock – the mutex to be acquired


Locks the mutex like mutex_lock, and returns 0 if the mutex has been acquired or sleep until the mutex becomes available. If a signal arrives while waiting for the lock then this function returns -EINTR.

int mutex_lock_interruptible(struct mutex *lock);


struct mutex *lock – the mutex to be acquired


This will try to acquire the mutex, without waiting (will attempt to obtain the lock, but will not sleep). Returns 1 if the mutex has been acquired successfully, and 0 on contention.

int mutex_trylock(struct mutex *lock);


struct mutex *lock – the mutex to be acquired

This function must not be used in interrupt context. The mutex must be released by the same task that acquired it.

Mutex Unlock

This is used to unlock/release a mutex that has been locked by a task previously.

This function must not be used in interrupt context. Unlocking of a not locked mutex is not allowed.

void mutex_unlock(struct mutex *lock);


struct mutex *lock – the mutex to be released

Mutex Status

This function is used to check whether mutex has been locked or not.

int mutex_is_locked(struct mutex *lock);


struct mutex *lock – the mutex to check the status.

Returns 1 if the mutex is locked, 0 if unlocked.

Example Programming

This code snippet explains how to create two threads that access a global variable (etx_gloabl_variable). So before accessing the variable, it should lock the mutex. After that, it will release the mutex.

Driver Source Code

[Get the source code from the GitHub]



In our next tutorial, we will discuss spinlock in the Linux device driver.

4.5 2 votes
Article Rating
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Newest Most Voted
Inline Feedbacks
View all comments
July 15, 2019 4:43 AM

mutex_init should be done before threads are spawned

Reply to  neel
July 15, 2019 5:21 AM

Hi Neel,

Thanks for your input. We have updated. Keep supporting us.

May 2, 2020 5:37 PM

Thanks for your post.

Would love your thoughts, please comment.x
%d bloggers like this: