linux汇编 约束条件m,在Linux内核中使用修饰符“P”和约束“p”超过“m”的gcc内联汇编...

我正在阅读Linux内核源代码(3.12.5 x86_64)以了解如何处理进程描述符.

我发现获取当前进程描述符我可以使用current_thread_info()函数,其实现如下:

static inline struct thread_info *current_thread_info(void)

{

struct thread_info *ti;

ti = (void *)(this_cpu_read_stable(kernel_stack) +

KERNEL_STACK_OFFSET - THREAD_SIZE);

return ti;

}

然后我查看了this_cpu_read_stable():

#define this_cpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var)))

#define percpu_from_op(op, var, constraint) \

({ \

typeof(var) pfo_ret__; \

switch (sizeof(var)) { \

...

case 8: \

asm(op "q "__percpu_arg(1)",%0" \

: "=r" (pfo_ret__) \

: constraint); \

break; \

default: __bad_percpu_size(); \

} \

pfo_ret__; \

})

#define __percpu_arg(x) __percpu_prefix "%P" #x

#ifdef CONFIG_SMP

#define __percpu_prefix "%%"__stringify(__percpu_seg)":"

#else

#define __percpu_prefix ""

#endif

#ifdef CONFIG_X86_64

#define __percpu_seg gs

#else

#define __percpu_seg fs

#endif

扩展的宏应该是内联asm代码,如下所示:

asm("movq %%gs:%P1,%0" : "=r" (pfo_ret__) : "p"(&(kernel_stack)));

根据this post,输入约束曾经是“m”(kernel_stack),这对我来说很有意义.但显然提高性能Linus将约束更改为“p”并传递变量的地址:

It uses a "p" (&var) constraint instead of a "m" (var) one, to make gcc

think there is no actual "load" from memory. This obviously _only_ works

for percpu variables that are stable within a thread, but 'current' and

'kernel_stack' should be that way.

同样在post Tejun Heo发表了这样的评论:

Added the magical undocumented "P" modifier to UP __percpu_arg()

to force gcc to dereference the pointer value passed in via the

"p" input constraint. Without this, percpu_read_stable() returns

the address of the percpu variable. Also added comment explaining

the difference between percpu_read() and percpu_read_stable().

但是我使用组合修饰符“P”修饰符和约束“p(& var)”的实验不起作用.如果未指定段寄存器,则“%P1”始终返回变量的地址.指针未被解除引用.我必须使用括号来取消引用它,例如“(%P1)”.如果指定了段寄存器,则不使用括号gcc甚至不编译.我的测试代码如下:

#include

#define current(var) ({\

typeof(var) pfo_ret__;\

asm(\

"movq %%es:%P1, %0\n"\

: "=r"(pfo_ret__)\

: "p" (&(var))\

);\

pfo_ret__;\

})

int main () {

struct foo {

int field1;

int field2;

} a = {

.field1 = 100,

.field2 = 200,

};

struct foo *var = &a;

printf ("field1: %d\n", current(var)->field1);

printf ("field2: %d\n", current(var)->field2);

return 0;

}

我的代码有什么问题吗?或者我是否需要为gcc附加一些选项?此外,当我使用gcc -S生成汇编代码时,我没有看到使用“p”超过“m”的优化.任何答案或评论都非常感谢.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值