内核里的__private变量的使用及sparse

一、背景

在阅读rcu的代码时,会发现有些变量使用了看似冗余的包裹,如下图里的这个函数:

这个raw_spin_lock_irqsave_rcu_node函数如下图仅仅是调用了raw_spin_lock_irqsave而已,但是是多了这一层包装是为啥呢?

那是因为上图里使用了ACCESS_PRIVATE宏,这个宏是用来引用带有__private表示的结构体里的变量。

我们在第二章里给出一个使用__private来标识变量的例子,通过实验来说明其用途。

二、内核代码里使用__private标识符的例子

2.1 例子源码

测试__private标识符的实验的内核模块代码如下:

cpp 复制代码
#include <linux/poll.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/errno.h>
#include <linux/stddef.h>
#include <linux/lockdep.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <asm/atomic.h>
#include <trace/events/workqueue.h>
#include <linux/sched/clock.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/tracepoint.h>
#include <trace/events/osmonitor.h>
#include <trace/events/sched.h>
#include <trace/events/irq.h>
#include <trace/events/kmem.h>
#include <linux/ptrace.h>
#include <linux/uaccess.h>
#include <asm/processor.h>
#include <linux/sched/task_stack.h>
#include <linux/nmi.h>
#include <asm/apic.h>
#include <linux/version.h>
#include <linux/sched/mm.h>
#include <asm/irq_regs.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhaoxin");
MODULE_DESCRIPTION("Module for kernel test __private.");
MODULE_VERSION("1.0");

//#define __CHECKER__

struct testprivate {
    int __private abc;
};

static int __init testprivate_init(void)
{
    struct testprivate pri;
    pri.abc = 1;
    ACCESS_PRIVATE(&pri, abc) = 1;
    return 0;
}

static void __exit testprivate_exit(void)
{
}

module_init(testprivate_init);
module_exit(testprivate_exit);

2.2 实验步骤及说明

先尝试编译上面 2.1 里的代码,无论是带__CHECKER__宏还是不带:

用普通的make都是能编过的:

事实上,要让编译的时候进行__private变量的相关检查,得依赖sparse工具,sparse工具是Linux本人编写的,要让sparse工具参与编译,则要如下进行编译。

使用下面的命令可以重新编译代码,并且使用sparse工具进行静态检查:

bash 复制代码
make C=2

如果没有安装sparse,会有如下报错:

装一下sparse工具:

bash 复制代码
apt-get install sparse

然后再make C=2:

可以发现有如下检查到的warning:

也能和代码上对应上:

意思就是__private的变量需要用ACCESS_PRIVATE宏来进行引用。

我们把这句话注释掉,相关的warning就没有了:

要注意,这只是一句warning,不影响编译出ko!

相关推荐
YoungStudyAI7 小时前
QA的下一个自动化阶段,可能不是再写更多脚本,而是设计测试Agent
运维·自动化
筝筝ba7 小时前
openBMC功耗封顶GUI测试
服务器
分布式存储与RustFS8 小时前
纠删码到底吃掉了多少容量:EC:4、EC:8 的利用率与容错怎么算
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
遇见小修修8 小时前
3步解决打印机0x00000709报错 ,广州深圳程序员可自行排查
运维·打印机·维修·打印机报错·打印机运维·打印机故障自查
顺顺 尼8 小时前
linux 进程信号(上)
linux·c++·算法
niuTaylor9 小时前
飞腾 FT-2000/4 Ubuntu 内存卡 / NVMe SSD 系统制作完整指南
linux·服务器·人工智能·驱动开发·单片机
傲世仙尊10 小时前
信号量环形队列与线程池起步-把临界资源拆成很多份
linux
Huangjin007_10 小时前
【Linux 系统篇(二十五)】文件(二) 系统文件I/O详解
linux·运维·服务器
微小冷10 小时前
Mermaid画甘特图
运维·markdown·甘特图·mermaid·时间图
ShineWinsu10 小时前
对于ProtoBuffer:ProtoBuffer的介绍以及安装
linux·网络·google·协议·序列化·反序列化·protobuffer