修复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;

相关推荐
玖石书27 分钟前
WSL2 手动安装 Ubuntu 24.04 到指定磁盘位置
linux·运维·ubuntu·wsl
库玛西1 小时前
深入浅出传输层:UDP 与 TCP 协议全景指南
linux·服务器·网络·c++·笔记·tcp/ip·udp
薛定谔的悦5 小时前
储能 EMS 的功率策略:从一块电表到一次逆流的 200 毫秒
大数据·linux·能源·储能·bms
新时代牛马8 小时前
Linux 内核入门地图:架构、源码目录与五大子系统
linux·运维·架构
Julien20048 小时前
控制 SELinux 文件上下文
linux·运维·服务器
sulikey8 小时前
Linux Core Dump 完全指南:从原理到实战的崩溃调试手册。什么是core dump?程序报错core dumped怎么办?
linux·服务器·操作系统·调试·coredump
MayZork11 小时前
Windows 与 Linux 下 vcpkg 的安装部署指南
linux·运维·windows
zbyyd12 小时前
Linux 进程间通信学习笔记
linux·笔记·学习
hongmai66688813 小时前
MP2348GTL-Z:这颗24V/4A同步降压芯片,把性能和体积平衡得恰到好处
c语言·开发语言·arm开发·单片机·5g
sukalot14 小时前
windows 驱动实例分析系列: libusb驱动分析-应用层源码篇(三)
windows·驱动开发