最近在一次的稳定性测试中发现如下问题:

c7 BUG: spinlock bad magic on CPU#7, Binder_5/6373
c7  lock: system_int_lock+0x0/0x18, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
c7 CPU: 7 PID: 6373 Comm: Binder_5 Tainted:
c7 Call trace:
c7 [<ffffffc00008b480>] dump_backtrace+0x0/0x164
c7 [<ffffffc00008b600>] show_stack+0x1c/0x28
c7 [<ffffffc0009c9590>] dump_stack+0x74/0xb8
c7 [<ffffffc0000ef394>] spin_dump+0x78/0xa0
c7 [<ffffffc0000ef3e8>] spin_bug+0x2c/0x3c
c7 [<ffffffc0000ef508>] do_raw_spin_lock+0xac/0x1bc
c7 [<ffffffc0009d4ae0>] _raw_spin_lock_irq+0x2c/0x3c
c7 [<ffffffc0004d3cf0>] wait_for_irq+0x12c/0x420
c7 [<ffffffc0004d4bdc>] ispdrv_open+0xbf8/0xfd4
c7 [<ffffffc0004c95e8>] isp_ioctl+0x1594/0x2478
c7 [<ffffffc0004ceda4>] compat_isp_ioctl+0x864/0x1e78
c7 [<ffffffc000231434>] compat_SyS_ioctl+0xbc/0x1688

根据调用栈分析,在wait_for_irq函数中有如下代码:

spin_lock_irq(&system_int_lock);
g_latest_system_int &= ~event;
spin_unlock_irq(&system_int_lock);

可以看到这代码就是保证g_latest_system_int的原子操作而已。

void do_raw_spin_lock(raw_spinlock_t *lock)
{debug_spin_lock_before(lock);if (unlikely(!arch_spin_trylock(&lock->raw_lock)))__spin_lock_debug(lock);debug_spin_lock_after(lock);
}

上面是do_raw_spin_lock函数调用,如果开启CONFIG_DEBUG_SPINLOCK配置项的话,就会进入到debug_spin_lock_before函数中。

static inline void
debug_spin_lock_before(raw_spinlock_t *lock)
{SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");SPIN_BUG_ON(lock->owner == current, lock, "recursion");SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),lock, "cpu recursion");
}#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg)static void spin_bug(raw_spinlock_t *lock, const char *msg)
{if (!debug_locks_off())return;spin_dump(lock, msg);
}static void spin_dump(raw_spinlock_t *lock, const char *msg)
{struct task_struct *owner = NULL;if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)owner = lock->owner;printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",msg, raw_smp_processor_id(),current->comm, task_pid_nr(current));printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "".owner_cpu: %d\n",lock, lock->magic,owner ? owner->comm : "<none>",owner ? task_pid_nr(owner) : -1,lock->owner_cpu);dump_stack();
}

根据打印信息" BUG: spinlock bad magic on CPU#7    lock: system_int_lock+0x0/0x18, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0"

可以得出,lock是system_int_lock,  lock->magic=000000,  owner=<none>, lock->owner_cpu=0

那为什么是这样的? 是什么导致出现这个问题的?

不妨看下spin_lock的结构体定义:

typedef struct raw_spinlock {arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCKunsigned int magic, owner_cpu;void *owner;
#endif
} raw_spinlock_t;

在开启CONFIG_DEBUG_SPINLOCK的情况下, magic, owner_cpu, owner是有意义的。

那这几个值是在什么地方设置的?

#ifdef CONFIG_DEBUG_SPINLOCK
# define SPIN_DEBUG_INIT(lockname)      \.magic = SPINLOCK_MAGIC,      \.owner_cpu = -1,          \.owner = SPINLOCK_OWNER_INIT,
#else
# define SPIN_DEBUG_INIT(lockname)
#endif

可以看到SPIN_DEBUG_INIT宏中会对这几个变量设置值的。再沿着找下去。

最终确认是spinlock变量没有初始化,如果初始化,将走如下流程:

#define DEFINE_SPINLOCK(x)   spinlock_t x = __SPIN_LOCK_UNLOCKED(x)#define __SPIN_LOCK_UNLOCKED(lockname) \(spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname)#define __SPIN_LOCK_INITIALIZER(lockname) \{ { .rlock = __RAW_SPIN_LOCK_INITIALIZER(lockname) } }#define __RAW_SPIN_LOCK_INITIALIZER(lockname)   \{                  \.raw_lock = __ARCH_SPIN_LOCK_UNLOCKED,    \SPIN_DEBUG_INIT(lockname)      \SPIN_DEP_MAP_INIT(lockname) }#ifdef CONFIG_DEBUG_SPINLOCK
# define SPIN_DEBUG_INIT(lockname)      \.magic = SPINLOCK_MAGIC,      \.owner_cpu = -1,          \.owner = SPINLOCK_OWNER_INIT,
#else
# define SPIN_DEBUG_INIT(lockname)
#endif

这样下来magic,  owner_cpu,  owner就会有设置的值,不会出现系统的bug了。

spinlock变量没有初始化相关推荐

  1. java静态/动态成员变量、初始化块,父类/子类构造函数执行顺序问题

    2019独角兽企业重金招聘Python工程师标准>>> /* * 几大原则 * 一.静态成员变量(Static) * 1.静态成员变量为类变量,所有对象共享同一内存空间 * 2.静态 ...

  2. 关于C#中编译器保证变量必须初始化规则猜想

    现在两种情况: 第一种情况: using System; namespace Wrox {public class Program{static void Main(string[] args){in ...

  3. Java中final变量的初始化方式

    原文转自:http://blog.csdn.net/zhangjk1993/article/details/24196847 1 public class FinalTest1 { 2 //----- ...

  4. 【C 语言】结构体 ( 结构体类型变量初始化 | 定义变量时进行初始化 | 定义隐式结构体时声明变量并初始化 | 定义普通结构体时声明变量并初始化 )

    文章目录 一.结构体类型变量初始化 1.定义变量时进行初始化 2.定义普通结构体时声明变量并初始化 3.定义隐式结构体时声明变量并初始化 二.完整代码示例 一.结构体类型变量初始化 1.定义变量时进行 ...

  5. C++成员变量的初始化顺序问题

    C++成员变量的初始化顺序问题 由于面试题中,考官出了一道简单的程序输出结果值的题:如下, [cpp] view plain copy  print? class A { private: int n ...

  6. C++类中成员变量的初始化有两种方式

    C++类中成员变量的初始化有两种方式: 构造函数初始化列表和构造函数体内赋值.下面看看两种方式有何不同. 成员变量初始化的顺序是按照在那种定义的顺序. 1.内部数据类型(char,int--指针等) ...

  7. 静态成员变量的初始化,vector类型变量初始化

    静态成员变量的初始化,vector类型变量初始化 Posted on 2008-11-24 16:28 浪端之渡鸟 阅读(1620) 评论(0) 编辑 收藏 某些情况下,在写C++类的时候,希望能通过 ...

  8. STM32串口中断实验总结函数的初始化必须在变量的初始化之后在进行!

    在进行串口的实验的时候,自己没有看教程,写了一段代码,但是进行编译之后发现一直有错误,就算我把代码更改之后还是一直有错误.对比了官方给的教程之后发现唯一的不同之处就是我的有一个函数的初始化是在变量的初 ...

  9. java中的静态初始化是什么意思,Java中static静态变量的初始化完全解析

    静态变量初始化顺序 1.简单规则 首先先看一段最普遍的JAVA代码: ? 这里先猜下控制台输出结果是什么? OK, 或许你已经猜到下面了结果了,那么你还是熟悉Java的. 复制代码 代码如下: 0 1 ...

  10. Guru of the Week 条款01: 变量的初始化

    GotW #01 Variable Initialization 著者:Herb Sutter 翻译:kingofark [声明]:本文内容取自www.gotw.ca网站上的Guru of the W ...

最新文章

  1. 【剑指offer】Q38:数字在数组中出现的次数
  2. XML配置里的Bean自动装配与Bean之间的关系
  3. JAVA日期和时间API
  4. SSH整合方案二(不带hibernate.cfg.xml)
  5. 访问网络共享时出现“拒绝访问”
  6. win7在未关闭vmware情况下直接关机,导致虚拟机无法克隆
  7. 微服务精华问答 | 为什么需要微服务?
  8. Linux网络那点事
  9. Xcode误删Images.xcassets文件夹的恢复办法(Assets.xcassets)
  10. Django学习笔记二
  11. React router 路由 入门安装
  12. SVN分支管理最佳策略
  13. Buildroot笔记
  14. 有关USGS下载landsat 8影像的方法
  15. overshoot是什么matlab,Overshoot metrics of bilevel waveform transitions
  16. lo linux 环回端口,本地环回接口lo The Loopback Network Interface lo--用Enki学Linux系列(2)...
  17. Windows IRP
  18. 华为云AI随笔(8)
  19. 如何进入他人计算机硬盘,手机如何访问电脑硬盘
  20. python批量循环图片识别_批量识别图中文字自动命名,让你1秒找到骚图

热门文章

  1. 学习总结 java基础
  2. UIKit基础:17-基础控件的总结
  3. update与fixedupdate差别
  4. WinForm 单例模式实例
  5. HTML连续英文字符串强制换行
  6. html div 画半圆,css画变形的半圆
  7. 周报(1.13到1.20)
  8. cdn 导致跨域问题
  9. java实现验证码生成工具类
  10. ubuntu系统配置双网卡方法