linux内核源码分析之per-CPU

目录

静态声明与定义

申请动态per-CPU变量

使用静态per-CPU变量

使用一、CPU并行访问计数

使用二、在软中断中唤醒

使用三、静/动态per-CPU验证


 

 

per_cpu机制就是让每个处理器都分配了该变量的副本,有自己的私有数据段,不需要考虑与其他它处理器的竞争的问题,该副本可以充分利用处理器本地的硬件缓冲cache来提供访问速度。

 

per-CPU按照存储变量的空间来源分为

  • 静态per-CPU变量:存储空间是在代码编译时静态分配的
  • 动态per-CPU变量,存储空间是在代码的执行期间动态分配的

 

静态声明与定义

#define DECLARE_PER_CPU(type, name)                 \
    DECLARE_PER_CPU_SECTION(type, name, "")

#define DECLARE_PER_CPU_SECTION(type, name, sec)            \
    extern __PCPU_ATTRS(sec) __typeof__(type) name

#define __PCPU_ATTRS(sec)                       \
    __percpu __attribute__((section(PER_CPU_BASE_SECTION sec))) \
    PER_CPU_ATTRIBUTES

 

申请动态per-CPU变量

分配per-CPU变量

#define alloc_percpu(type)                      \
    (typeof(type) __percpu *)__alloc_percpu(sizeof(type),       \
                        __alignof__(type))

释放:

void free_percpu(void __percpu *ptr)

 

使用静态per-CPU变量

#define get_cpu_var(var)                        \
(*({                                    \
    preempt_disable();                      \
    this_cpu_ptr(&var);                     \
}))

#define put_cpu_var(var)                        \
do {                                    \
    (void)&(var);                           \
    preempt_enable();                       \
} while (0)

使用一、CPU并行访问计数

多线程中,每个CPU执行的次数

long DriverIOControl( struct file *pslFileStruct, unsigned int uiCmd, unsigned long ulArg )
{
    long *pUsage = NULL;
    /* printk( KERN_ALERT DEVICE_NAME ": pUsage = 0x%lx %lx %ld", (unsigned long) pUsage, (unsigned long) (&gUsage), (*pUsage) ); */
    preempt_disable();
    pUsage = this_cpu_ptr( (long *) (&gUsage) );
    (*pUsage)++;
    preempt_enable();
    return(0);
}

 

使用二、在软中断中唤醒

softirq软中断源码,__this_cpu_read()

static void wakeup_softirqd(void)
{
	/* Interrupts are disabled: no need to stop preemption */
	struct task_struct *tsk = __this_cpu_read(ksoftirqd);

	if (tsk && tsk->state != TASK_RUNNING)
		wake_up_process(tsk);
}

 

使用三、静/动态per-CPU验证

静态和动态变量的使用,遍历每个CPU的值

#include <linux/module.h>
#include <linux/init.h>
#include <linux/percpu.h>
#include <linux/cpumask.h>
static DEFINE_PER_CPU(long, cpuvar) = 5;
static long __percpu *cpualloc;

static int __init my_init(void)
{
    int cpu;
    pr_info("module loaded at 0x%p\n", my_init);
    /* modify the cpuvar value */
    for_each_possible_cpu(cpu)
    {
        per_cpu(cpuvar, cpu) = 10;
        pr_info("init: cpuvar on cpu%d = %ld\n",
                cpu, get_cpu_var(cpuvar));
        put_cpu_var(cpuvar);
    }
    __this_cpu_write(cpuvar, 10);
    /* alloc a percpu value */
    cpualloc = alloc_percpu(long);
    /* set all cpu for this value */
    for_each_possible_cpu(cpu)
    {
        *per_cpu_ptr(cpualloc, cpu) = 666;
        pr_info("init: cpu:%d cpualloc = %ld\n",
                cpu, *per_cpu_ptr(cpualloc, cpu));
    }
    return 0;
}
static void __exit my_exit(void)
{
    int cpu;
    pr_info("exit module...\n");
    for_each_possible_cpu(cpu)
    {
        pr_info("cpuvar cpu%d = %ld\n", cpu, per_cpu(cpuvar, cpu));
        pr_info("exit: cpualloc%d = %ld\n", cpu, *per_cpu_ptr(cpualloc, cpu));
    }
    free_percpu(cpualloc);
    pr_info("Bye: module unloaded from 0x%p\n", my_exit);
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("WY");
MODULE_LICENSE("GPL");
[134657.935134] init: cpuvar on cpu0 = 5
[134657.935134] init: cpuvar on cpu1 = 5
[134657.935134] init: cpuvar on cpu2 = 10
[134657.935135] init: cpuvar on cpu3 = 10
[134657.935135] init: cpuvar on cpu4 = 10
[134657.935135] init: cpuvar on cpu5 = 10
[134657.935135] init: cpuvar on cpu6 = 10
[134657.935135] init: cpuvar on cpu7 = 10
[134657.935136] init: cpuvar on cpu8 = 10
[134657.935136] init: cpuvar on cpu9 = 10
[134657.935136] init: cpuvar on cpu10 = 10
[134657.935137] init: cpuvar on cpu11 = 10
[134657.935137] init: cpuvar on cpu12 = 10
[134657.935137] init: cpuvar on cpu13 = 10
[134657.935137] init: cpuvar on cpu14 = 10
[134657.935137] init: cpuvar on cpu15 = 10
[134657.935138] init: cpuvar on cpu16 = 10
[134657.935138] init: cpuvar on cpu17 = 10
[134657.935138] init: cpuvar on cpu18 = 10
[134657.935138] init: cpuvar on cpu19 = 10
[134657.935139] init: cpuvar on cpu20 = 10
[134657.935139] init: cpuvar on cpu21 = 10
[134657.935139] init: cpuvar on cpu22 = 10
[134657.935139] init: cpuvar on cpu23 = 10
[134657.935140] init: cpuvar on cpu24 = 10
[134657.935140] init: cpuvar on cpu25 = 10
[134657.935140] init: cpuvar on cpu26 = 10
[134657.935140] init: cpuvar on cpu27 = 10
[134657.935141] init: cpuvar on cpu28 = 10
[134657.935141] init: cpuvar on cpu29 = 10
[134657.935141] init: cpuvar on cpu30 = 10
[134657.935141] init: cpuvar on cpu31 = 10
[134657.935142] init: cpuvar on cpu32 = 10
[134657.935142] init: cpuvar on cpu33 = 10
[134657.935142] init: cpuvar on cpu34 = 10
[134657.935142] init: cpuvar on cpu35 = 10
[134657.935142] init: cpuvar on cpu36 = 10
[134657.935143] init: cpuvar on cpu37 = 10
[134657.935143] init: cpuvar on cpu38 = 10
[134657.935143] init: cpuvar on cpu39 = 10
[134657.935143] init: cpuvar on cpu40 = 10
[134657.935144] init: cpuvar on cpu41 = 10
[134657.935144] init: cpuvar on cpu42 = 10
[134657.935144] init: cpuvar on cpu43 = 10
[134657.935144] init: cpuvar on cpu44 = 10
[134657.935145] init: cpuvar on cpu45 = 10
[134657.935145] init: cpuvar on cpu46 = 10
[134657.935145] init: cpuvar on cpu47 = 10
[134657.935145] init: cpuvar on cpu48 = 10
[134657.935146] init: cpuvar on cpu49 = 10
[134657.935146] init: cpuvar on cpu50 = 10
[134657.935146] init: cpuvar on cpu51 = 10
[134657.935146] init: cpuvar on cpu52 = 10
[134657.935147] init: cpuvar on cpu53 = 10
[134657.935147] init: cpuvar on cpu54 = 10
[134657.935147] init: cpuvar on cpu55 = 10
[134657.935147] init: cpuvar on cpu56 = 10
[134657.935148] init: cpuvar on cpu57 = 10
[134657.935148] init: cpuvar on cpu58 = 10
[134657.935148] init: cpuvar on cpu59 = 10
[134657.935148] init: cpuvar on cpu60 = 10
[134657.935149] init: cpuvar on cpu61 = 10
[134657.935149] init: cpuvar on cpu62 = 10
[134657.935149] init: cpuvar on cpu63 = 10
[134657.935149] init: cpuvar on cpu64 = 10
[134657.935150] init: cpuvar on cpu65 = 10
[134657.935150] init: cpuvar on cpu66 = 10
[134657.935150] init: cpuvar on cpu67 = 10
[134657.935150] init: cpuvar on cpu68 = 10
[134657.935151] init: cpuvar on cpu69 = 10
[134657.935151] init: cpuvar on cpu70 = 10
[134657.935151] init: cpuvar on cpu71 = 10
[134657.935151] init: cpuvar on cpu72 = 10
[134657.935151] init: cpuvar on cpu73 = 10
[134657.935152] init: cpuvar on cpu74 = 10
[134657.935152] init: cpuvar on cpu75 = 10
[134657.935152] init: cpuvar on cpu76 = 10
[134657.935152] init: cpuvar on cpu77 = 10
[134657.935153] init: cpuvar on cpu78 = 10
[134657.935153] init: cpuvar on cpu79 = 10
[134657.935153] init: cpuvar on cpu80 = 10
[134657.935153] init: cpuvar on cpu81 = 10
[134657.935154] init: cpuvar on cpu82 = 10
[134657.935154] init: cpuvar on cpu83 = 10
[134657.935154] init: cpuvar on cpu84 = 10
[134657.935154] init: cpuvar on cpu85 = 10
[134657.935155] init: cpuvar on cpu86 = 10
[134657.935155] init: cpuvar on cpu87 = 10
[134657.935155] init: cpuvar on cpu88 = 10
[134657.935155] init: cpuvar on cpu89 = 10
[134657.935156] init: cpuvar on cpu90 = 10
[134657.935156] init: cpuvar on cpu91 = 10
[134657.935156] init: cpuvar on cpu92 = 10
[134657.935156] init: cpuvar on cpu93 = 10
[134657.935156] init: cpuvar on cpu94 = 10
[134657.935157] init: cpuvar on cpu95 = 10
[134657.935157] init: cpuvar on cpu96 = 10
[134657.935157] init: cpuvar on cpu97 = 10
[134657.935157] init: cpuvar on cpu98 = 10
[134657.935158] init: cpuvar on cpu99 = 10
[134657.935158] init: cpuvar on cpu100 = 10
[134657.935158] init: cpuvar on cpu101 = 10
[134657.935158] init: cpuvar on cpu102 = 10
[134657.935159] init: cpuvar on cpu103 = 10
[134657.935159] init: cpuvar on cpu104 = 10
[134657.935159] init: cpuvar on cpu105 = 10
[134657.935159] init: cpuvar on cpu106 = 10
[134657.935160] init: cpuvar on cpu107 = 10
[134657.935160] init: cpuvar on cpu108 = 10
[134657.935160] init: cpuvar on cpu109 = 10
[134657.935160] init: cpuvar on cpu110 = 10
[134657.935161] init: cpuvar on cpu111 = 10
[134657.935161] init: cpuvar on cpu112 = 10
[134657.935161] init: cpuvar on cpu113 = 10
[134657.935161] init: cpuvar on cpu114 = 10
[134657.935162] init: cpuvar on cpu115 = 10
[134657.935162] init: cpuvar on cpu116 = 10
[134657.935162] init: cpuvar on cpu117 = 10
[134657.935162] init: cpuvar on cpu118 = 10
[134657.935163] init: cpuvar on cpu119 = 10
[134657.935163] init: cpuvar on cpu120 = 10
[134657.935163] init: cpuvar on cpu121 = 10
[134657.935163] init: cpuvar on cpu122 = 10
[134657.935164] init: cpuvar on cpu123 = 10
[134657.935164] init: cpuvar on cpu124 = 10
[134657.935164] init: cpuvar on cpu125 = 10
[134657.935164] init: cpuvar on cpu126 = 10
[134657.935165] init: cpuvar on cpu127 = 10
[134657.935171] init: cpu:0 cpualloc = 666
[134657.935171] init: cpu:1 cpualloc = 666
[134657.935172] init: cpu:2 cpualloc = 666
[134657.935172] init: cpu:3 cpualloc = 666
[134657.935172] init: cpu:4 cpualloc = 666
[134657.935172] init: cpu:5 cpualloc = 666
[134657.935172] init: cpu:6 cpualloc = 666
[134657.935173] init: cpu:7 cpualloc = 666
[134657.935173] init: cpu:8 cpualloc = 666
[134657.935173] init: cpu:9 cpualloc = 666
[134657.935173] init: cpu:10 cpualloc = 666
[134657.935173] init: cpu:11 cpualloc = 666
[134657.935174] init: cpu:12 cpualloc = 666
[134657.935174] init: cpu:13 cpualloc = 666
[134657.935174] init: cpu:14 cpualloc = 666
[134657.935174] init: cpu:15 cpualloc = 666
[134657.935175] init: cpu:16 cpualloc = 666
[134657.935175] init: cpu:17 cpualloc = 666
[134657.935175] init: cpu:18 cpualloc = 666
[134657.935175] init: cpu:19 cpualloc = 666
[134657.935175] init: cpu:20 cpualloc = 666
[134657.935176] init: cpu:21 cpualloc = 666
[134657.935176] init: cpu:22 cpualloc = 666
[134657.935176] init: cpu:23 cpualloc = 666
[134657.935176] init: cpu:24 cpualloc = 666
[134657.935177] init: cpu:25 cpualloc = 666
[134657.935177] init: cpu:26 cpualloc = 666
[134657.935177] init: cpu:27 cpualloc = 666
[134657.935177] init: cpu:28 cpualloc = 666
[134657.935178] init: cpu:29 cpualloc = 666
[134657.935178] init: cpu:30 cpualloc = 666
[134657.935178] init: cpu:31 cpualloc = 666
[134657.935178] init: cpu:32 cpualloc = 666
[134657.935179] init: cpu:33 cpualloc = 666
[134657.935179] init: cpu:34 cpualloc = 666
[134657.935179] init: cpu:35 cpualloc = 666
[134657.935179] init: cpu:36 cpualloc = 666
[134657.935179] init: cpu:37 cpualloc = 666
[134657.935180] init: cpu:38 cpualloc = 666
[134657.935180] init: cpu:39 cpualloc = 666
[134657.935180] init: cpu:40 cpualloc = 666
[134657.935180] init: cpu:41 cpualloc = 666
[134657.935181] init: cpu:42 cpualloc = 666
[134657.935181] init: cpu:43 cpualloc = 666
[134657.935181] init: cpu:44 cpualloc = 666
[134657.935181] init: cpu:45 cpualloc = 666
[134657.935181] init: cpu:46 cpualloc = 666
[134657.935182] init: cpu:47 cpualloc = 666
[134657.935182] init: cpu:48 cpualloc = 666
[134657.935182] init: cpu:49 cpualloc = 666
[134657.935182] init: cpu:50 cpualloc = 666
[134657.935183] init: cpu:51 cpualloc = 666
[134657.935183] init: cpu:52 cpualloc = 666
[134657.935183] init: cpu:53 cpualloc = 666
[134657.935183] init: cpu:54 cpualloc = 666
[134657.935183] init: cpu:55 cpualloc = 666
[134657.935184] init: cpu:56 cpualloc = 666
[134657.935184] init: cpu:57 cpualloc = 666
[134657.935184] init: cpu:58 cpualloc = 666
[134657.935184] init: cpu:59 cpualloc = 666
[134657.935184] init: cpu:60 cpualloc = 666
[134657.935185] init: cpu:61 cpualloc = 666
[134657.935185] init: cpu:62 cpualloc = 666
[134657.935185] init: cpu:63 cpualloc = 666
[134657.935185] init: cpu:64 cpualloc = 666
[134657.935194] init: cpu:65 cpualloc = 666
[134657.935194] init: cpu:66 cpualloc = 666
[134657.935194] init: cpu:67 cpualloc = 666
[134657.935195] init: cpu:68 cpualloc = 666
[134657.935195] init: cpu:69 cpualloc = 666
[134657.935195] init: cpu:70 cpualloc = 666
[134657.935195] init: cpu:71 cpualloc = 666
[134657.935196] init: cpu:72 cpualloc = 666
[134657.935196] init: cpu:73 cpualloc = 666
[134657.935196] init: cpu:74 cpualloc = 666
[134657.935196] init: cpu:75 cpualloc = 666
[134657.935196] init: cpu:76 cpualloc = 666
[134657.935197] init: cpu:77 cpualloc = 666
[134657.935197] init: cpu:78 cpualloc = 666
[134657.935197] init: cpu:79 cpualloc = 666
[134657.935197] init: cpu:80 cpualloc = 666
[134657.935198] init: cpu:81 cpualloc = 666
[134657.935198] init: cpu:82 cpualloc = 666
[134657.935198] init: cpu:83 cpualloc = 666
[134657.935198] init: cpu:84 cpualloc = 666
[134657.935198] init: cpu:85 cpualloc = 666
[134657.935199] init: cpu:86 cpualloc = 666
[134657.935199] init: cpu:87 cpualloc = 666
[134657.935199] init: cpu:88 cpualloc = 666
[134657.935200] init: cpu:89 cpualloc = 666
[134657.935200] init: cpu:90 cpualloc = 666
[134657.935200] init: cpu:91 cpualloc = 666
[134657.935200] init: cpu:92 cpualloc = 666
[134657.935201] init: cpu:93 cpualloc = 666
[134657.935201] init: cpu:94 cpualloc = 666
[134657.935201] init: cpu:95 cpualloc = 666
[134657.935201] init: cpu:96 cpualloc = 666
[134657.935202] init: cpu:97 cpualloc = 666
[134657.935202] init: cpu:98 cpualloc = 666
[134657.935202] init: cpu:99 cpualloc = 666
[134657.935202] init: cpu:100 cpualloc = 666
[134657.935203] init: cpu:101 cpualloc = 666
[134657.935203] init: cpu:102 cpualloc = 666
[134657.935203] init: cpu:103 cpualloc = 666
[134657.935203] init: cpu:104 cpualloc = 666
[134657.935203] init: cpu:105 cpualloc = 666
[134657.935204] init: cpu:106 cpualloc = 666
[134657.935204] init: cpu:107 cpualloc = 666
[134657.935204] init: cpu:108 cpualloc = 666
[134657.935204] init: cpu:109 cpualloc = 666
[134657.935205] init: cpu:110 cpualloc = 666
[134657.935205] init: cpu:111 cpualloc = 666
[134657.935205] init: cpu:112 cpualloc = 666
[134657.935205] init: cpu:113 cpualloc = 666
[134657.935206] init: cpu:114 cpualloc = 666
[134657.935206] init: cpu:115 cpualloc = 666
[134657.935206] init: cpu:116 cpualloc = 666
[134657.935206] init: cpu:117 cpualloc = 666
[134657.935206] init: cpu:118 cpualloc = 666
[134657.935207] init: cpu:119 cpualloc = 666
[134657.935207] init: cpu:120 cpualloc = 666
[134657.935207] init: cpu:121 cpualloc = 666
[134657.935207] init: cpu:122 cpualloc = 666
[134657.935208] init: cpu:123 cpualloc = 666
[134657.935208] init: cpu:124 cpualloc = 666
[134657.935208] init: cpu:125 cpualloc = 666
[134657.935208] init: cpu:126 cpualloc = 666
[134657.935209] init: cpu:127 cpualloc = 666

 

 参考

内核必须懂(五): per-CPU变量 - 简书 (jianshu.com)

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为了维护世界和平_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值