一般来说,如果我们想在Linux内核中使用当前宏,我们应该:
#include <asm/current.h>但是有一个asm通用版本:
#include <asm-generic/current.h>asm版本通过每个cpu变量实现当前宏,而asm-通用版本通过thread_info实现当前宏,这两者完全不同。Linux内核头的组织说我们应该使用asm版本,其中包括asm/current.h,但是很多博客或书籍说x86使用asm--通用的版本来实现当前宏,包括Linux内核开发、3、3进程管理,存储流程描述符。那么,x86 Linux内核真正使用的版本是asm还是如何确保Linux内核真正使用哪个版本?
发布于 2021-11-20 09:47:36
要使用的正确标题是asm/current.h,不要使用asm-generic。这确实适用于asm下的任何内容。asm-generic文件夹中的头作为宏/函数的“通用”默认实现提供(顾名思义),然后每个体系结构/arch/xxx都有自己的asm包含文件夹,如果需要,它可以以特定于体系结构的方式定义相同的宏/函数。
之所以这样做,是因为它可能是实际需要的(一些archs可能有一个与通用的实现不兼容的实现),以及性能的实现,因为在特定的arch下可能有一种更好、更优化的方法来实现相同的结果。
实际上,如果我们查看每个arch如何定义get_current()或get_current_thread_info(),我们可以看到它们中的一些(例如alpha、spark)在thread_info结构中保持对当前任务的引用,并在寄存器中保留一个指向当前thread_info的指针以提高性能。另一些则直接将指向current的指针保存在寄存器中(例如powerpc 32位),而另一些则定义全局的每个cpu变量(例如x86)。特别是在x86上,thread_info结构甚至没有指向当前任务的指针,它是一个非常简单的16字节结构,它适合缓存行以提高性能。
// example from /arch/powerpc/include/asm/current.h
/*
* We keep `current' in r2 for speed.
*/
register struct task_struct *current asm ("r2");如何确保Linux内核真正使用哪个版本?
好吧,让我们简单地看一下:
$ 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>
...如您所见,asm/current.h是唯一实际使用的头。
我们还可以看到(至少在第5.14版),只有弧形似乎在使用“通用”版本:
$ rg '#include.+generic.+current\.h' | cat
arch/arc/include/asm/current.h:#include <asm-generic/current.h>许多博客或书籍说,x86使用asm-泛型版本来实现当前的宏,包括。
我只能推测,这些资源是很久以前编写的,是基于非常老的内核版本编写的,在编写本报告时,内核版本可能使用了不同的包含系统(也许x86也使用了通用版本)。如果没有,那么这些资源很可能是错误的。
https://stackoverflow.com/questions/70042480
复制相似问题