CodingStyle for Linux kernel

Chapter 1: indentation

Indent using the tab key, and the width of the tab key is 8 characters

switch and case no indent

    switch (suffix) {
    case 'G':
    case 'g':
        mem <<= 30;
        break;
    case 'M':
    case 'm':
        mem <<= 20;
        break;
    case 'K':
    case 'k':
        mem <<= 10;
        /* fall through */
    default:
        break;
    }

There is only one expression per line. Don't write it like this

if (condition) do_this;
      do_something_everytime;

Chapter 2: Breaking long lines and strings

The length of the code shall be controlled within 80 characters. If the code is too long, it shall be wrapped and the code shall be readable

printk(KERN_WARNING "Warning this is a long printk with "
                       "3 parameters a: %u b: %u "
                       "c: %u \n", a, b, c);

Chapter 3: Placing Braces and Spaces

3.1 braces

Non functional code block, the left brace does not need to start another line

if (x is true) {
        we do y
    }
switch (action) {
    case KOBJ_ADD:
        return "add";
    case KOBJ_REMOVE:
        return "remove";
    case KOBJ_CHANGE:
        return "change";
    default:
        return NULL;
    }
do {
        body of do-loop
    } while (condi)
    
if (x == y) {
        ..
    } else if (x > y) {
        ...
    } else {
        ....
    }

No braces for statement blocks with only one line

if (condition)
    action();

The code block of the function should occupy a separate line

int function(int x)
{
    body of function
}

3.2 spaces

Append a space after the following keywords

if, switch, case, for, do, while

The following keywords are not followed by spaces

sizeof, typeof, alignof, or __attribute__. 
s = sizeof( struct file );

Binocular and ternary operators shall be separated by spaces

=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :

Unary operator, with no spaces before or after

&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined
++  --

No space after struct member access operator

. ->

Chapter 4: Naming

Global variables and functions need a descriptive name

count_active_users(); 
cntusr();

Local variables should be named concisely, for example: tmp

Chapter 5: Typedefs

Try not to use typedef. Typedef is mainly used for the following purposes

  1. Completely opaque types (access to these types also requires corresponding access functions)

ex. pid_t, uid_t, pte_t... Wait

  1. Avoid the problem of integer data, such as the inconsistent length of int and long types in different architectures, and use u8/u16/u32 to replace the integer definition
  2. When you use the kernel's spark tool for variable type checking, you can typedef a type
  3. Define new types in C99 standard
  4. For type safety of user space

typedef is used when mapping the structure of the kernel space to the user space, so that the user space can operate normally even if the data structure of the kernel space changes

Chapter 6: Functions

Functions should be short. A function only does one thing

The length of the function generally does not exceed 2 screens (the size of one screen is 80x24), that is, 48 lines

If the switch in the function has many simple case statements, you can use more than 2 screens

The number of local variables in a function cannot exceed 5~10

There is an empty line between functions, but not between functions and EXPORT*

int one_func(void)
{
        return 0;
}

int system_is_up(void)
{
    return system_state == SYSTEM_RUNNING;
}
EXPORT_SYMBOL(system_is_up);

Chapter 7: Centralized exiting of functions

Gather function exits together, especially when memory needs to be cleaned up (goto is not a monster. Sometimes it is useful.)

int fun(int a)
{
    int result = 0;
    char *buffer = kmalloc(SIZE);

    if (buffer == NULL)
        return -ENOMEM;

    if (condition1) {
        while (loop1) {
            ...
        }
        result = 1;
        goto out;
    }
    ...
out:
    kfree(buffer);
    return result;
}

Chapter 8: Commenting

Comment on what code does, not how

Use the annotation style of C89 (/ *... * /), not C99 (/ /...)

Chapter 9: You 've made a mess of it

(defun c-lineup-arglist-tabs-only (ignored)
  "Line up argument lists by tabs, not spaces"
  (let* ((anchor (c-langelem-pos c-syntactic-element))
     (column (c-langelem-2nd-pos c-syntactic-element))
     (offset (- (1+ column) anchor))
     (steps (floor offset c-basic-offset)))
    (* (max steps 1)
       c-basic-offset)))

(add-hook 'c-mode-common-hook
          (lambda ()
            ;; Add kernel style
            (c-add-style
             "linux-tabs-only"
             '("linux" (c-offsets-alist
                        (arglist-cont-nonempty
                         c-lineup-gcc-asm-reg
                         c-lineup-arglist-tabs-only))))))

(add-hook 'c-mode-hook
          (lambda ()
            (let ((filename (buffer-file-name)))
              ;; Enable kernel mode for the appropriate files
              (when (and filename
                         (string-match (expand-file-name "~/src/linux-trees")
                                       filename))
                (setq indent-tabs-mode t)
                (c-set-style "linux-tabs-only")))))

Chapter 10: Kconfig configuration files

config AUDIT
    bool "Auditing support"
    depends on NET
    help
      Enable auditing infrastructure that can be used with another
      kernel subsystem, such as SELinux (which requires this for
      logging of avc messages output).  Does not do system-call
      auditing without CONFIG_AUDITSYSCALL.

Unstable features should be added with exceptional

config SLUB
    depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
    bool "SLUB (Unqueued Allocator)"
    ...

DANGEROUS characteristics shall be added with DANGEROUS

config ADFS_FS_RW
    bool "ADFS write support (DANGEROUS)"
    depends on ADFS_FS
    ...

Chapter 11: data structures

The structure should contain a reference count field (there is no automatic garbage collection in the kernel, and the memory needs to be released manually)

Lock when it is necessary to ensure the consistency of structure data

Sometimes even multiple reference counts are required in a structure

ex. struc mm_struct, struct super_block

Chapter 12: Macros, Enums and RTL

Macro definition constants often use uppercase letters

#define CONSTANT 0x12345

When a macro defines a multiline statement, it should be put into do - while. In this case, the name of the macro should be in lowercase

#define macrofun(a, b, c)           \
    do {                    \
        if (a == 5)         \
            do_this(b, c);      \
    } while (0)

Macro definition expression to be placed in ()

#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)

Chapter 13: Printing kernel messages

Keep printed information concise and clear

For example, instead of "don't", use "do not" or "don't"

Kernel information does not require "." ending

Printing "(%d)" and so on is meaningless and should be avoided

Select the appropriate print level (debug, warning, error, etc.)

Chapter 14: Allocating memory

Sizeof (pointer) instead of sizeof (structure) when allocating memory

p = kmalloc(sizeof(*p), ...);

Chapter 15: The inline disease

If a function has more than 3 lines, do not use inline to mark it

Chapter 16: Function return values and names

If the function function is an action or a command, an error code of type int is returned

For example, add_ The work() function returns 0 upon successful execution and the corresponding error code (ex. -ebusy) upon failure

If the function function is a judgment, return "0" to indicate failure and "1" to indicate success

All Exported functions and public functions shall meet the above two requirements

All private (static) functions are not mandatory, but it is best to meet the above two requirements

If the function returns the actual calculation result instead of success, it indicates failure by returning a value outside the range of the calculation result

For example, a function that returns a pointer indicates failure by returning NULL

Chapter 17: Don't re invent the kernel macros

The macro defined by the kernel is in the header file include/linux/kernel H, to define a new macro, first check whether there are similar macros available

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

Chapter 18: Editor modelines and other cruft

Do not add the content of a specific editor or the configuration of other tools to the code,

-*- mode: c -*-
/*
Local Variables:
compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
End:
*/
/* vim:set sw=8 noet */

Chapter 19: Inline assembly

Try not to use inline assembly, the general assembly code should be in In the S file, you may use the volatile key to ensure that the value is removed from the register, but gcc may ignore this request

Tags: Linux

Posted by EODC on Thu, 02 Jun 2022 20:49:04 +0530