第37章 优化驱动稳定性和效率实验

第37章 优化驱动稳定性和效率实验

在Linux中应用程序运行在用户空间,应用程序错误之后,并不会影响其他程序的运行,而驱动工作在内核层,是内核代码的一部分,当驱动出现问题之后,可能会导致整个系统的崩溃。所以在驱动中,需要对各种判断、预处理等进行排查等,在本小节将对如何优化驱动稳定性和提高驱动效率进行学习。

37.1 方法一:检测ioctl命令

ioctl的cmd命令是由合成宏合成得到的,也有相应的分解宏得到各个参数,四个分解宏如下所示:

分解cmd命令,得到命令的类型:

_IOC_TYPE(cmd)

分解cmd命令,得到数据(args)的传输方向:

_IOC_DIR(cmd)

分解cmd命令,得到命令的序号:

_IOC_NR(cmd)

分解cmd命令,得到数据(args)的大小:

_IOC_SIZE(cmd)

可以在驱动中通过上述分解宏对传入的ioctl命令类型等参数进行判断,从而得到判断传入的参数是否正确,以此优化驱动的稳定性。

if(_IOC_TYPE(cmd) != 'L'){
   printk("cmd type error \n");
   return -1;
}

例如可以通过上述代码对传入参数的类型进行判断,如果传入的参数类型不为“L”,就返回错误,其他参数的检测方法相同。

37.2 方法二:检测传递地址是否合理

access_ok()函数

函数原型:

​ access_ok(addr,size);

函数作用:

检查用户空间内存块是否可用

参数含义:

addr : 用户空间的指针变量,其指向一个要检查的内存块开始处。

size : 要检查内存块的大小。

返回值:

成功返回1,失败返回0

以第35章的ioctl地址传参实验为例,对传入的args地址进行判断,具体代码如下所示:

struct args test;
int len;
switch(cmd){
	case CMD_TEST0:
		len = sizeof(struct args);
		if(!access_ok(arg,len)){
			 return -1;
		}
		if(copy_from_user(&test,(int *)arg,sizeof(test)) != 0){
			 printk("copy_from_user error\n");
		}
	break;

在第6行对传入的args参数地址进行判断,如果不合法则返回-1,从而保证了驱动运行的稳定性。

37.3 方法三:分支预测优化

现在的CPU都有ICache和流水线机制。即运行当前指令时,ICache会预读取后面的指令,从而提升效率。但是如果条件分支的结果是跳转到了其他指令,那预取下一条指令就浪费时间了。而本章节要用到的likely和unlikely宏,会让编译器总是将大概率执行的代码放在靠前的位置,从而提高驱动的效率。

likely和unlikely宏定义在“内核源码/include/linux/compiler.h”文件中,具体定义如下所示:

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

__builtin_expect的作用是告知编译器预期表达式exp等于c的可能性更大,编译器可以根据该因素更好的对代码进行优化,所以likely与unlikely的作用就是表达性x为真的可能性更大(likely)和更小(unlikely)。

这里以上一小节添加传递地址检测内容后的代码为例,对copy_from_user函数添加分支预测优化函数,添加完成如下所示:

struct args test;
int len;
switch(cmd){
	case CMD_TEST0:
		len = sizeof(struct args);
		if(!access_ok(arg,len)){
			 return -1;
		}
		if(unlikely(copy_from_user(&test,(int *)arg,sizeof(test)) != 0)){
			 printk("copy_from_user error\n");
		}
	break;

传递地址检测成功之后才会使用执行copy_from_user函数,在传递地址正确的前提下copy_from_user函数运行失败为小概率事件,所以这里使用unlikely函数进行驱动效率的优化。

至此,关于分支预测优化相关的知识就讲解完成了。

【最新驱动资料(文档+例程)】

链接 https://pan.baidu.com/s/1M4smUG2vw_hnn0Hye-tkog

提取码:hbh6

【B 站配套视频】

https://b23.tv/XqYa6Hm

【RK3568 购买链接】

https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-2245

2452613.11.2fec74a6elWNeA&id=669939423234

你可能感兴趣的:(java,前端,算法,驱动开发)