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

相关推荐
聆风吟º11 小时前
CANN开源项目深度实践:基于amct-toolkit实现自动化模型量化与精度保障策略
运维·开源·自动化·cann
Coder个人博客11 小时前
Linux6.19-ARM64 mm mmu子模块深入分析
大数据·linux·车载系统·系统架构·系统安全·鸿蒙系统
较劲男子汉14 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
Doro再努力14 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
wypywyp14 小时前
8. ubuntu 虚拟机 linux 服务器 TCP/IP 概念辨析
linux·服务器·ubuntu
风流倜傥唐伯虎14 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Doro再努力14 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene14 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
不像程序员的程序媛14 小时前
Nginx日志切分
服务器·前端·nginx
忧郁的橙子.14 小时前
02-本地部署Ollama、Python
linux·运维·服务器