Kernel Coding Style
The Linux kernel has strict coding conventions. Following them is essential for upstream acceptance and code readability.
Why Coding Style Matters
- Consistency: 20+ years of kernel code follows these rules
- Readability: Easier to review and maintain
- Upstream acceptance: Non-compliant patches are rejected
- Tooling: checkpatch.pl enforces style automatically
Core Rules
Indentation: Tabs, Not Spaces
/* CORRECT: Tab indentation */
static int foo(void)
{
→ if (condition) {
→ → do_something();
→ }
}
/* WRONG: Space indentation */
static int foo(void)
{
if (condition) {
do_something();
}
}
- Use tabs (8 characters wide)
- Tabs for indentation, spaces for alignment
Line Length: 80-100 Characters
Keep lines under 80 characters when possible, 100 max:
/* CORRECT: Break long lines sensibly */
ret = some_really_long_function_name(argument1, argument2,
argument3, argument4);
/* WRONG: Excessively long line */
ret = some_really_long_function_name(argument1, argument2, argument3, argument4, argument5);
Brace Placement
Opening braces on the same line as the statement:
/* CORRECT */
if (condition) {
do_something();
} else {
do_other();
}
for (i = 0; i < n; i++) {
process(i);
}
/* WRONG: K&R style for if/for/while */
if (condition)
{
do_something();
}
Exception: Functions have opening brace on new line:
/* CORRECT for functions */
static int my_function(int x)
{
return x * 2;
}
/* WRONG for functions */
static int my_function(int x) {
return x * 2;
}
Single-Statement Bodies
Omit braces for single statements (usually):
/* CORRECT */
if (condition)
do_something();
for (i = 0; i < n; i++)
process(i);
/* Also CORRECT (some prefer braces always) */
if (condition) {
do_something();
}
Exception: If one branch has braces, use them on all:
/* CORRECT */
if (condition) {
do_something();
do_more();
} else {
do_other(); /* Braces because if-branch has them */
}
Spaces
Around keywords:
if (condition) /* Space after if */
for (i = 0; ...) /* Space after for */
while (running) /* Space after while */
switch (value) /* Space after switch */
return value; /* Space after return if returning value */
Around operators:
x = a + b; /* Spaces around binary operators */
x += 1; /* Spaces around assignment */
if (a == b) /* Spaces around comparison */
No space after function names:
function(args); /* CORRECT */
function (args); /* WRONG */
No space inside parentheses:
if (condition) /* CORRECT */
if ( condition ) /* WRONG */
Naming Conventions
Functions and variables: lowercase with underscores
static int read_sensor_data(void);
int buffer_size = 1024;
Macros and constants: UPPERCASE
#define MAX_BUFFER_SIZE 4096
#define DRIVER_NAME "my_driver"
Types: lowercase with _t suffix (or no suffix)
typedef struct {
int x, y;
} point_t;
Global variables: Prefix with module name
static int mydrv_debug_level = 0;
static struct device *mydrv_dev;
Function Style
Declaration
/* Return type on same line if it fits */
static int my_function(int arg1, char *arg2)
/* Or on separate line if long */
static struct some_very_long_type *
create_new_object(struct parent *parent, const char *name)
Argument Alignment
/* Align continued arguments */
ret = register_device(dev, name,
flags, mode,
callback);
Function Length
- Aim for functions under 40-50 lines
- One function, one purpose
- If it’s too long, split it
Comments
C-style Comments
/* This is a single-line comment */
/*
* This is a multi-line comment.
* Note the leading asterisks aligned.
*/
Never use C++ comments in C files:
// WRONG: Don't use C++ style comments
Function Documentation
Use kernel-doc format for exported functions:
/**
* my_function - Brief description
* @arg1: Description of first argument
* @arg2: Description of second argument
*
* Longer description of what this function does.
* Can span multiple paragraphs.
*
* Context: Can be called from process context only.
* Return: 0 on success, negative errno on failure.
*/
int my_function(int arg1, char *arg2)
{
...
}
Using checkpatch.pl
The kernel includes a style checker:
# Check a file
/kernel/linux/scripts/checkpatch.pl --file mydriver.c
# Check a patch
/kernel/linux/scripts/checkpatch.pl mypatch.patch
# Stricter checking
/kernel/linux/scripts/checkpatch.pl --strict --file mydriver.c
Common checkpatch Warnings
| Warning | Fix |
|---|---|
| “code indent should use tabs” | Replace spaces with tabs |
| “line over 80 characters” | Break the line |
| “space required after ‘,’” | Add space |
| “braces {} not necessary” | Remove braces from single statement |
| “trailing whitespace” | Remove trailing spaces |
| “Missing Signed-off-by” | Add SOB line to patch |
SPDX License Identifier
Every source file must start with SPDX identifier:
// SPDX-License-Identifier: GPL-2.0
/*
* my_driver.c - My awesome driver
*/
Common licenses:
GPL-2.0- GNU GPL version 2 onlyGPL-2.0-only- Same as above (explicit)GPL-2.0-or-later- GPL v2 or any later versionGPL-2.0 OR BSD-2-Clause- Dual-licensed
Kernel-Specific Patterns
Error Codes
Return negative errno values:
if (error)
return -EINVAL; /* Not EINVAL, not -1 */
Goto for Cleanup
Standard cleanup pattern:
static int init_device(void)
{
int ret;
ret = allocate_resources();
if (ret)
return ret;
ret = setup_hardware();
if (ret)
goto err_setup;
ret = register_device();
if (ret)
goto err_register;
return 0;
err_register:
teardown_hardware();
err_setup:
free_resources();
return ret;
}
NULL Checks
/* CORRECT */
if (!ptr)
return -EINVAL;
if (ptr)
use_ptr(ptr);
/* Also acceptable but verbose */
if (ptr == NULL)
return -EINVAL;
Boolean Expressions
/* CORRECT: Use bare expression */
if (is_valid)
...
/* WRONG: Redundant comparison */
if (is_valid == true)
...
Static Analysis with Sparse
Sparse is a semantic checker for C that understands kernel address-space annotations:
# Check your module with Sparse
make C=1 modules
# Check the whole kernel build
make C=2 allmodconfig
Key Annotations
| Annotation | Purpose |
|---|---|
__user |
Pointer to user space memory |
__iomem |
Pointer to I/O mapped memory |
__kernel |
Pointer to kernel space memory |
__bitwise |
Type-restricted bitwise integer |
__force |
Override address space check (use sparingly) |
Sparse detects dangerous pointer confusions — for example, passing a __user pointer where a kernel pointer is expected, which would bypass copy_from_user() safety.
See Sparse Documentation for details.
Summary
Key style rules:
- Tabs for indentation (8 spaces wide)
- 80-100 character line limit
- K&R brace style for control structures, function-style for functions
- Spaces around operators and keywords
- lowercase_with_underscores for names
- Use checkpatch.pl before submitting
- Use Sparse (
make C=1) to catch address-space bugs
Resources
- Kernel Coding Style
scripts/checkpatch.plin kernel source- Sparse - Static analysis tool
Next
Learn about kernel data types and endianness handling.