You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In file {chardev,chardev2,sleep}.c, the variable to determine
the exclusive access was of integer type, which led to race
condition.
This patch rewrote the above with atomic CAS respectively
to eliminate the race.
Close#93
Copy file name to clipboardExpand all lines: lkmpg.tex
+21-1Lines changed: 21 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -912,7 +912,7 @@ \subsection{Unregistering A Device}
912
912
This is bound to happen to you sooner or later during a module's development.
913
913
914
914
\subsection{chardev.c}
915
-
\label{sec:org7ce767e}
915
+
\label{sec:chardev_c}
916
916
The next code sample creates a char driver named \verb|chardev|.
917
917
You can cat its device file.
918
918
@@ -925,6 +925,13 @@ \subsection{chardev.c}
925
925
Don't worry if you don't see what we do with the data we read into the buffer; we don't do much with it.
926
926
We simply read in the data and print a message acknowledging that we received it.
927
927
928
+
In the multiple-threaded environment, without any protection, concurrent access to the same memory may lead to the race condition, and will not preserve the performance.
929
+
In the kernel module, this problem may happen due to multiple instances accessing the shared resources.
930
+
Therefore, a solution is to enforce the exclusive access.
931
+
We use atomic Compare-And-Swap (CAS), the single atomic operation, to determine whether the file is currently open by someone.
932
+
CAS compares the contents of a memory loaction with the expected value and, only if they are the same, modifies the contents of that memory location to the desired value.
933
+
See more concurrency details in the \ref{sec:synchronization} section.
934
+
928
935
\samplec{examples/chardev.c}
929
936
930
937
\subsection{Writing Modules for Multiple Kernel Versions}
@@ -1158,6 +1165,9 @@ \section{Talking To Device Files}
1158
1165
If you want to use ioctls in your own kernel modules, it is best to receive an official ioctl assignment, so if you accidentally get somebody else's ioctls, or if they get yours, you'll know something is wrong.
1159
1166
For more information, consult the kernel source tree at \src{Documentation/userspace-api/ioctl/ioctl-number.rst}.
1160
1167
1168
+
Also, we need to be careful that concurrent access to the shared resources will lead to the race condition.
1169
+
The solution is using atomic Compare-And-Swap (CAS), which we mentioned at \ref{sec:chardev_c} section, to enforce the exclusive access.
Before the C11 standard adopts the built-in atomic types, the kernel already provided a small set of atomic types by using a bunch of tricky architecture-specific codes.
1474
+
Implementing the atomic types by C11 atomics may allow the kernel to throw away the architecture-specific codes and letting the kernel code be more friendly to the people who understand the standard.
1475
+
But there are some problems, such as the memory model of the kernel doesn't match the model formed by the C11 atomics.
1476
+
For further details, see:
1477
+
\begin{itemize}
1478
+
\item\href{https://www.kernel.org/doc/Documentation/atomic_t.txt}{kernel documentation of atomic types}
1479
+
\item\href{https://lwn.net/Articles/691128/}{Time to move to C11 atomics?}
1480
+
\item\href{https://lwn.net/Articles/698315/}{Atomic usage patterns in the kernel}
0 commit comments