内核里的__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!

相关推荐
杜子不疼.2 小时前
【Linux】基础IO(一):C 接口文件讲解
linux·c语言·开发语言·人工智能
每次学一点2 小时前
如何将网吧电脑加入ZeroTier虚拟局域网
运维·服务器·网络
勉灬之2 小时前
基于 Node.js + mysql2 的实用同步助手,适合开发/测试环境下快速对齐表数据
服务器·网络·node.js
很㗊2 小时前
Linux --- tar命令常见用法
linux·运维·服务器
2501_941329722 小时前
气压表智能读数检测:基于YOLOv8的指针与刻度识别实现自动化读数
运维·yolo·自动化
飞凌嵌入式2 小时前
嵌入式AI领域的主控选择
linux·arm开发·人工智能·嵌入式硬件
RisunJan2 小时前
Linux命令-ld(将目标文件连接为可执行程序)
linux·运维·服务器
猫猫的小茶馆2 小时前
【Linux 驱动开发】四. 平台总线驱动
linux·c语言·arm开发·驱动开发·嵌入式硬件·mcu·物联网
济6172 小时前
linux--Cortex-A7架构-- Ubuntu20.04
linux·运维·架构