"Current" in Linux Kernel Code

current in Linux kernel code

It is a pointer to the current process ie, the process which has issued the system call.

From the docs:

The Current Process

Although kernel modules don't execute sequentially as applications do,
most actions performed by the kernel are related to a specific
process. Kernel code can know the current process driving it by
accessing the global item current, a pointer to struct task_struct,
which as of version 2.4 of the kernel is declared in
<asm/current.h>, included by <linux/sched.h>. The current pointer
refers to the user process currently executing. During the execution
of a system call, such as open or read, the current process is the one
that invoked the call.
Kernel code can use process-specific
information by using current, if it needs to do so. An example of this
technique is presented in "Access Control on a Device File", in
Chapter 5, "Enhanced Char Driver Operations".

Actually, current is not properly a global variable any more, like it
was in the first Linux kernels. The developers optimized access to the
structure describing the current process by hiding it in the stack
page. You can look at the details of current in <asm/current.h>. While
the code you'll look at might seem hairy, we must keep in mind that
Linux is an SMP-compliant system, and a global variable simply won't
work when you are dealing with multiple CPUs. The details of the
implementation remain hidden to other kernel subsystems though, and a
device driver can just include and refer to the
current process.

From a module's point of view, current is just like the external
reference printk. A module can refer to current wherever it sees fit.
For example, the following statement prints the process ID and the
command name of the current process by accessing certain fields in
struct task_struct:

 printk("The process is \"%s\" (pid %i)\n",
current->comm, current->pid);

The command name stored in current->comm is the base name of the
program file that is being executed by the current process.

What is the current in Linux kernel source?

It's a pointer to the current process (i.e. the process that issued the system call).

On x86, it's defined in arch/x86/include/asm/current.h (similar files for other archs).

#ifndef _ASM_X86_CURRENT_H
#define _ASM_X86_CURRENT_H

#include <linux/compiler.h>
#include <asm/percpu.h>

#ifndef __ASSEMBLY__
struct task_struct;

DECLARE_PER_CPU(struct task_struct *, current_task);

static __always_inline struct task_struct *get_current(void)
{
return percpu_read_stable(current_task);
}

#define current get_current()

#endif /* __ASSEMBLY__ */

#endif /* _ASM_X86_CURRENT_H */

More information in Linux Device Drivers chapter 2:

The current pointer refers to the user process currently executing. During the execution of a system call, such as open or read, the current process is the one that invoked the call. Kernel code can use process-specific information by using current, if it needs to do so. [...]

Naming a variable `current` in a kernel module leads to function declaration isn’t a prototype error

The kernel has a macro called current which is pointing to users currently executing process. As this book states,

The current pointer refers to the user process currently executing. During the execution of a system call, such as open or read, the current process is the one that invoked the call.

In other words, as @GilHamilton mentioned in the comments, current is #defined to the function get_current() in the kernel. Using current as a variable name will give a compile-time error!

The implementation of Linux kernel current macro

The correct header to use is asm/current.h, do not use asm-generic. This applies to anything under asm really. Headers in the asm-generic folder are provided (as the name suggests) as a "generic" default implementation of macros/functions, then each architecture /arch/xxx has its own asm include folder, where if needed it can define the same macros/functions in an architecture-specific way.

This is done both because it could be actually needed (some archs might have an implementation that is not compatible with the generic one) and for performance since there might be a better and more optimized way of achieving the same result under a specific arch.

Indeed, if we look at how each arch defines get_current() or get_current_thread_info() we can see that some of them (e.g. alpha, spark) keep a reference to the current task in the thread_info struct and keep a pointer to the current thread_info in a register for performance. Others directly keep a pointer to current in a register (e.g. powerpc 32bit), and others define a global per-cpu variable (e.g. x86). On x86 in particular, the thread_info struct doesn't even have a pointer to the current task, it's a very simple 16-byte structure made to fit in a cache line for performance.

// example from /arch/powerpc/include/asm/current.h

/*
* We keep `current' in r2 for speed.
*/
register struct task_struct *current asm ("r2");

How could I make sure which version the Linux kernel really use?

Well, let's just take a simple look:

$ rg '#include.+current\.h' | cat
security/landlock/ptrace.c:#include <asm/current.h>
security/landlock/syscalls.c:#include <asm/current.h>
sound/pci/rme9652/hdsp.c:#include <asm/current.h>
sound/pci/rme9652/rme9652.c:#include <asm/current.h>
net/ipv4/raw.c:#include <asm/current.h>
net/core/dev.c:#include <asm/current.h>
ipc/msg.c:#include <asm/current.h>
fs/quota/quota.c:#include <asm/current.h>
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c:#include <asm/current.h>
fs/jfs/ioctl.c:#include <asm/current.h>
fs/hugetlbfs/inode.c:#include <asm/current.h>
drivers/parport/daisy.c:#include <asm/current.h>
...

As you can see asm/current.h is the only header actually used.

We can also see that (as of v5.14 at least) only arc seems to be using the "generic" version:

$ rg '#include.+generic.+current\.h' | cat     
arch/arc/include/asm/current.h:#include <asm-generic/current.h>

many blogs or books says x86 use asm-generic version to implement current macro, including Linux Kernel Development, 3rd

I can only speculate that these resources were written a long time ago and based on pretty old kernel versions, which at the time of writing might have used a different include system (maybe x86 used to use the generic version as well). If not, then those resources are most probably wrong.

how does current- pid work for linux?

You're looking for #include <linux/sched.h>. That's where task_struct is declared.

How to print the current register values from kernel code?

Got it, below code works! :)

struct pt_regs regs;
prepare_frametrace(®s);
show_regs(®s);


Related Topics



Leave a reply



Submit