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

相关推荐
maosheng11462 小时前
RHCSA的第一次作业
linux·运维·服务器
wifi chicken2 小时前
Linux 端口扫描及拓展
linux·端口扫描·网络攻击
旺仔.2912 小时前
Linux 信号详解
linux·运维·网络
放飞梦想C2 小时前
CPU Cache
linux·cache
Hoshino.413 小时前
基于Linux中的数据库操作——下载与安装(1)
linux·运维·数据库
恒创科技HK4 小时前
通用型云服务器与计算型云服务器:您真正需要哪些配置?
运维·服务器
吴佳浩 Alben4 小时前
GPU 生产环境实践:硬件拓扑、显存管理与完整运维体系
运维·人工智能·pytorch·语言模型·transformer·vllm
播播资源5 小时前
CentOS系统 + 宝塔面板 部署 OpenClaw源码开发版完整教程
linux·运维·centos
源远流长jerry5 小时前
在 Ubuntu 22.04 上配置 Soft-RoCE 并运行 RDMA 测试程序
linux·服务器·网络·tcp/ip·ubuntu·架构·ip
学不完的5 小时前
Docker数据卷管理及优化
运维·docker·容器·eureka