Linux——不同体系结构下获取current
2012-06-23 21:59
246 查看
current的含义:
内核代码可以引用当前进程, 通过存取全局项 current, 它在 <asm/current.h> 中定义, 它产生一个指针指向结构 task_struct, 在 <linux/sched.h> 定义. current 指针指向当前在运行的进程. 在一个系统调用执行期间, 例如 open 或者 read, 当前进程是发出调用的进程. 内核代码可以通过使用 current 来使用进程特定的信息, 如果它需要这样. 实际上, current 不真正地是一个全局变量. 支持 SMP 系统的需要强迫内核开发者去开发一种机制,
在相关的 CPU 上来找到当前进程. 这种机制也必须快速, 因为对 current 的引用非常频繁地发生. 结果就是一个依赖体系的机制, 常常, 隐藏了一个指向 task_struct 的指针在内核堆栈内. 实现的细节对别的内核子系统保持隐藏, 一个设备驱动可以只包含 <linux/sched.h> 并且引用当前进程.
在X86体系中如何获取current的:
在asm/current.h中我们看到代码如下方式实现:
在asm/percpu.h中我们找到了percpu_read_stable(current_task)的实现:
在这里很清晰,我们继续跟中percpu_from_op("mov", var, "p" (&(var)))
在asm/percpu.h中我们找了percpu_from_op("mov", var, "p" (&(var)))的实现如下:
asm(movl "%%fs:%P1","%0" : "=r" (pfo_ret__) :"p" (&(var))
即:将fs段中P1偏移处的值传送给pfo_ret__变量,那么fs段中P1偏移处存放的是什么呢?
注:本文没有写完,前面这块写了好多天了,接下来的内容还没有分析,求简单的指导:在我的记忆中应该是内核栈的分配的问题,以及thread_info在内核栈中的位置的问题,然后就能够找到task_struct了,求指导相关模块的内核源码位置
总结:
以前是通过如下汇编指令实现的:movl $-8192,%eax; andl %esp, %eax来实现的,执行完这两条指令后,eax中存放的就是thread_info的地址。而现在的代码中再也找不到这样的指令了,以前SMP共享数据很多依靠自旋锁来达到目的,自旋锁是一种忙等锁,在一定程度上造成了进行自旋的CPU上CPU利用率的下降,随着内核的不断发展,更多的使用每个CPU数据(per_cpu_data)的概念,在每一个处理器中各自维护一个以前在多个CPU之间进行共享的数据,如当前运行的任务结构体,以前就是在多个CPU之间共享的。
内核代码可以引用当前进程, 通过存取全局项 current, 它在 <asm/current.h> 中定义, 它产生一个指针指向结构 task_struct, 在 <linux/sched.h> 定义. current 指针指向当前在运行的进程. 在一个系统调用执行期间, 例如 open 或者 read, 当前进程是发出调用的进程. 内核代码可以通过使用 current 来使用进程特定的信息, 如果它需要这样. 实际上, current 不真正地是一个全局变量. 支持 SMP 系统的需要强迫内核开发者去开发一种机制,
在相关的 CPU 上来找到当前进程. 这种机制也必须快速, 因为对 current 的引用非常频繁地发生. 结果就是一个依赖体系的机制, 常常, 隐藏了一个指向 task_struct 的指针在内核堆栈内. 实现的细节对别的内核子系统保持隐藏, 一个设备驱动可以只包含 <linux/sched.h> 并且引用当前进程.
在X86体系中如何获取current的:
在asm/current.h中我们看到代码如下方式实现:
10 DECLARE_PER_CPU(struct task_struct *, current_task); 11 12 static __always_inline struct task_struct *get_current(void) 13 { 14 return percpu_read_stable(current_task); 15 } 16 17 #define current get_current()在上述代码中我们能过看到其实current其实是一个宏,真实的调用为get_current(),而在get_current()中又调用percpu_read_stable(current_task),下面看一下percpu_read_stable(current_task)的实现:(注:在上述代码中第10行的DECLARE_PER_CPU宏用于在编译时候声明一个perCPU变量该变量被放在一个特殊的段中,原型为DECLARE_PER_CPU(type,name),主要作用是为处理器创建一个type类型,名为name的变量)
在asm/percpu.h中我们找到了percpu_read_stable(current_task)的实现:
361 #define percpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var)))
在这里很清晰,我们继续跟中percpu_from_op("mov", var, "p" (&(var)))
在asm/percpu.h中我们找了percpu_from_op("mov", var, "p" (&(var)))的实现如下:
180 #define percpu_from_op(op, var, constraint) \ 181 ({ \ 182 typeof(var) pfo_ret__; \ 183 switch (sizeof(var)) { \ 184 case 1: \ 185 asm(op "b "__percpu_arg(1)",%0" \ 186 : "=q" (pfo_ret__) \ 187 : constraint); \ 188 break; \ 189 case 2: \ 190 asm(op "w "__percpu_arg(1)",%0" \ 191 : "=r" (pfo_ret__) \ 192 : constraint); \ 193 break; \ 194 case 4: \ 195 asm(op "l "__percpu_arg(1)",%0" \ 196 : "=r" (pfo_ret__) \ 197 : constraint); \ 198 break; \ 199 case 8: \ 200 asm(op "q "__percpu_arg(1)",%0" \ 201 : "=r" (pfo_ret__) \ 202 : constraint); \ 203 break; \ 204 default: __bad_percpu_size(); \ 205 } \ 206 pfo_ret__; \ 207 })percpu_from_op宏中根据不同的sizeof(var)选择不同的分支,执行不同的流程,因为这里是x86体系,所以sizeof(current_task)的值为4,在每个分支中使用了一条的內联汇编代码,其中__percpu_arg(1)为%%fs:%P1(X86)或者%%gs:%P1(X86_64),将上述代码整理后current获取代码如下:
asm(movl "%%fs:%P1","%0" : "=r" (pfo_ret__) :"p" (&(var))
即:将fs段中P1偏移处的值传送给pfo_ret__变量,那么fs段中P1偏移处存放的是什么呢?
注:本文没有写完,前面这块写了好多天了,接下来的内容还没有分析,求简单的指导:在我的记忆中应该是内核栈的分配的问题,以及thread_info在内核栈中的位置的问题,然后就能够找到task_struct了,求指导相关模块的内核源码位置
总结:
以前是通过如下汇编指令实现的:movl $-8192,%eax; andl %esp, %eax来实现的,执行完这两条指令后,eax中存放的就是thread_info的地址。而现在的代码中再也找不到这样的指令了,以前SMP共享数据很多依靠自旋锁来达到目的,自旋锁是一种忙等锁,在一定程度上造成了进行自旋的CPU上CPU利用率的下降,随着内核的不断发展,更多的使用每个CPU数据(per_cpu_data)的概念,在每一个处理器中各自维护一个以前在多个CPU之间进行共享的数据,如当前运行的任务结构体,以前就是在多个CPU之间共享的。
相关文章推荐
- linux网络体系结构
- 转:Linux MMC/SD/SDIO体系结构
- windows和Linux文件路径分隔符的不同及获取
- Linux 内核系统体系结构
- Linux中断处理体系结构分析(三)
- linux体系结构与内核结构图解
- Linux网络体系结构 (国嵌笔记)
- Linux异常处理体系结构
- Linux 内核系统体系结构
- Linux体系结构(五): 文件系统
- 深入Linux PAM 体系结构
- Linux中断处理体系结构
- 不同体系结构的处理器big endian和little endian 模式--"高高低低"原则的含义
- Linux网络体系结构概要
- linux下向dhcp服务器获取不同的ip
- linux的i2c体系结构
- Linux基础系列—Linux体系结构和Linux内核结构
- Linux高性能集群 - 硬件和网络体系结构
- 深入 Linux PAM 体系结构
- Linux中断处理体系结构