前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spinlock变量没有初始化

spinlock变量没有初始化

作者头像
DragonKingZhu
发布2020-03-24 10:56:55
1.4K0
发布2020-03-24 10:56:55
举报

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

代码语言:javascript
复制
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函数中有如下代码:

代码语言:javascript
复制
spin_lock_irq(&system_int_lock);
g_latest_system_int &= ~event;
spin_unlock_irq(&system_int_lock);

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

代码语言:javascript
复制
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函数中。

代码语言:javascript
复制
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的结构体定义:

代码语言:javascript
复制
typedef struct raw_spinlock {
	arch_spinlock_t raw_lock;
#ifdef CONFIG_DEBUG_SPINLOCK
	unsigned int magic, owner_cpu;
	void *owner;
#endif
} raw_spinlock_t;

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

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

代码语言:javascript
复制
#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变量没有初始化,如果初始化,将走如下流程:

代码语言:javascript
复制
#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了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档