修复kernel编译栈帧大小异常问题error: the frame size of 1928 bytes is larger than 1024 bytes

上图为编译异常时:

在原本代码上增加了一个spin原子锁,然后就编译不过

复制代码
diff --git a/nvidia/drivers/optcamera_xdma/cdev_sgdma.c b/nvidia/drivers/optcamera_xdma/cdev_sgdma.c
index 94bdf43e9..5c8c912b5 100755
--- a/nvidia/drivers/optcamera_xdma/cdev_sgdma.c
+++ b/nvidia/drivers/optcamera_xdma/cdev_sgdma.c
@@ -575,6 +575,7 @@ static ssize_t char_sgdma_read_write(struct file *file, const char __user *buf,
 	struct xdma_dev *xdev;
 	struct xdma_engine *engine;
 	struct xdma_io_cb cb;
+//	unsigned long irq_flag;  //自旋锁 中断状态
 
 #ifdef  DBG_CHAR_SGDMA_READ_WRITE_TIMES
 	ktime_t curTime, curTime_wait_flag, curTime_align, curTime_memset, curTime_map, curTime_submit, curTime_unmap;
@@ -587,7 +588,8 @@ static ssize_t char_sgdma_read_write(struct file *file, const char __user *buf,
 		return rv;
 	xdev = xcdev->xdev;
 	engine = xcdev->engine;
-
+	
+//	spin_lock_irqsave(&xcdev->lock, irq_flag); //保存中断状态,禁止本地中断,并获取自旋锁
 	clean_fpga_irq();  //add by tab to call xdma
 	
 #ifdef  DBG_CHAR_SGDMA_READ_WRITE_TIMES
@@ -673,6 +675,7 @@ static ssize_t char_sgdma_read_write(struct file *file, const char __user *buf,
 	printk(" %s wait_ts = %lld us, align_ts = %lld us, memset_ts = %lld us, map_ts = %lld us, submits_ts = %lld us, umap_ts = %lld us \n", __func__, curTime_wait_flagst, curTime_alignst, curTime_memsetst, curTime_mapst, curTime_submitst, curTime_unmapst);
 #endif
 	//printk("enter %s end, line =%d \n", __func__, __LINE__);
+//	spin_unlock_irqrestore(&xcdev->lock, irq_flag);   //
 
 	return res;
 }

加入修改好,则编译异常:

1、报错信息:

error: the frame size of 1928 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

那么解决方案:

2、报错打印分析

(1)编译器编译内核时,发现栈帧大小是1024字节,但是栈使用是1928字节,超过了默认栈帧大小;

(2)默认编译器是报警告信息,上面报错误信息是因为在编译器选项中添加了-Wall,把警告当错误处理;

3、报错解决

3.1、报错原因分析

(1)栈内存申请过大,或者函数调用层次太深都会导致栈溢出,引起系统崩溃,在编译时会去检查栈使用大小是否超过配置的栈大小;

(2)内核编译时会通过"-Wframe-larger-than=xxx"选项,传递给编译器栈大小,当编译器检测到栈使用大于阈值时,会产生一条警告信息;

转自大佬解说:

编译时内核栈溢出:the frame size of 1928 bytes is larger than 1024 bytes_the frame size of 2048 bytes is larger than 1024 b-CSDN博客

具体解决方案:

复制代码
yahboom@yahboom-vm:~/r32.7.2_sources-sdk/Linux_for_Tegra/source/src_out/kernel_src_build/kernel$ git diff   kernel-4.9/arch/arm64/configs/tegra_defconfig
diff --git a/kernel-4.9/arch/arm64/configs/tegra_defconfig b/kernel-4.9/arch/arm64/configs/tegra_defconfig
index a3904fa79..5fa971b20 100644
--- a/kernel-4.9/arch/arm64/configs/tegra_defconfig
+++ b/kernel-4.9/arch/arm64/configs/tegra_defconfig
@@ -1209,3 +1209,4 @@ CONFIG_ARCH_TEGRA_23x_SOC=y
 CONFIG_TEGRA_SAFETY=y
 CONFIG_VIDEO_OPTCAMERA_XDMA=y
 CONFIG_OPT_IDE1_DIO=y
+CONFIG_FRAME_WARN=4096
yahboom@yahboom-vm:~/r32.7.2_sources-sdk/Linux_for_Tegra/source/src_out/kernel_src_build/kernel$ 

3.3、栈大小的影响

3.3.1、栈比较大

比如栈大小使用8K

(1)优点:栈比较大,不容易导致栈溢出;

(2)缺点:浪费内存,有些时候根本用不到这么大的栈内存;并且内存是4K分页,创建一个内核栈就需要申请连续2块的4K页,内存紧张的时候,申请8K的连续内存比申请4K困难的多;

3.3.2、栈比较小

比如栈大小1K

(1)优点:节省内存,都占用不到一个4K页,创建内核栈时比较容易;

(2)缺点:因为栈比较小,容易栈溢出;

3.4解决措施

(1)修改内核配置项,把"CONFIG_FRAME_WARN"配置项改大一点;

(2)修改程序,不要超过内核配置的栈大小;

补充:目前我所接触到的内核配置,32位的系统配置的栈大小一般是1K,64位的系统栈大小一般是4K;

相关推荐
xuanzdhc4 小时前
Linux 基础IO
linux·运维·服务器
愚润求学4 小时前
【Linux】网络基础
linux·运维·网络
bantinghy5 小时前
Linux进程单例模式运行
linux·服务器·单例模式
小和尚同志5 小时前
29.4k!使用 1Panel 来管理你的服务器吧
linux·运维
帽儿山的枪手6 小时前
为什么Linux需要3种NAT地址转换?一探究竟
linux·网络协议·安全
shadon1789 天前
回答 如何通过inode client的SSLVPN登录之后,访问需要通过域名才能打开的服务
linux
小米里的大麦9 天前
014 Linux 2.6内核进程调度队列(了解)
linux·运维·驱动开发
算法练习生9 天前
Linux文件元信息完全指南:权限、链接与时间属性
linux·运维·服务器
忘了ʷºᵇₐ9 天前
Linux系统能ping通ip但无法ping通域名的解决方法
linux·服务器·tcp/ip
浩浩测试一下9 天前
渗透测试指南(CS&&MSF):Windows 与 Linux 系统中的日志与文件痕迹清理
linux·运维·windows·安全·web安全·网络安全·系统安全