Skip to content

Commit fd6c976

Browse files
authored
Merge pull request #309 from eleanorLYJ/mutex
Add explanation of mutexes and function variants
2 parents 0800ceb + c81a686 commit fd6c976

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

lkmpg.tex

+33
Original file line numberDiff line numberDiff line change
@@ -1682,8 +1682,41 @@ \subsection{Mutex}
16821682
You can use kernel mutexes (mutual exclusions) in much the same manner that you might deploy them in userland.
16831683
This may be all that is needed to avoid collisions in most cases.
16841684

1685+
Mutexes in the Linux kernel enforce strict ownership: only the task that successfully acquired the mutex can release (or unlock) it.
1686+
Attempting to release a mutex held by another task or releasing an unheld mutex multiple times by the same task typically leads to errors or undefined behavior.
1687+
If a task tries to lock a mutex it already holds, it may be blocked or sleep, where the task waits for itself to release the lock.
1688+
1689+
Before use, a mutex must be initialized through specific APIs (such as \cpp|mutex_init| or by using the \cpp|DEFINE_MUTEX| macro for compile-time initialization).
1690+
And it is prohibited to directly modify the internal structure of a mutex using a memory manipulation function like \cpp|memset|.
1691+
16851692
\samplec{examples/example_mutex.c}
16861693

1694+
The various suffixes appended to mutex functions in the Linux kernel primarily dictate how a task waiting to acquire a lock will behave,
1695+
particularly concerning its interruptibility.
1696+
1697+
When a task calls \cpp|mutex_lock()|, and if the mutex is currently unavailable,
1698+
the task enters a sleep state until it can successfully obtain the lock.
1699+
During this period, the task cannot be interrupted.
1700+
In contrast, functions with the \cpp|_interruptible| suffix, such as \cpp|mutex_lock_interruptible()|,
1701+
behave similarly to \cpp|mutex_lock()| but allow the waiting process to be interrupted by signals.
1702+
If a task receives a signal (like a termination signal) while waiting for the lock,
1703+
it will exit the waiting state and return an error code (\cpp|-EINTR|).
1704+
This is useful for applications that need to handle external events even while waiting for a lock.
1705+
1706+
Beyond these fundamental locking behaviors, other mutex functions offer specialized capabilities.
1707+
Functions like \cpp|mutex_lock_nested| and \cpp|mutex_lock_interruptible_nested()| incorporate the \cpp|__nested()| functionality,
1708+
providing support for nested locking.
1709+
This prior locking mechanism aids in managing lock acquisition and preventing deadlocks,
1710+
often employing a subclass parameter for more precise deadlock detection.
1711+
The latter variant combines nested locking with the ability for the waiting process to be interrupted by signals.
1712+
Another function is \cpp|mutex_trylock()|, which attempts to acquire the mutex without blocking.
1713+
It returns 1 if the lock is successfully acquired and 0 if the mutex is already held by another task.
1714+
1715+
Despite the fact that \cpp|mutex_trylock| does not sleep,
1716+
it is still generally not safe for use in interrupt context because its implementation isn't atomic.
1717+
If an interrupt occurs between checking the lock's availability and its acquisition,
1718+
this can lead to race conditions and potential data corruption.
1719+
16871720
\subsection{Spinlocks}
16881721
\label{sec:spinlock}
16891722
As the name suggests, spinlocks lock up the CPU that the code is running on, taking 100\% of its resources.

0 commit comments

Comments
 (0)