您的位置 首页 > 腾讯云社区

crash工具解读mutex锁---CD

crash> struct mutex ffffffffc05f1000

struct mutex {

count = {

counter = -2 //初始值为1,每增加一个等锁的进程则减1,-2代表当前有两个进程(不含已获取锁进程)正在等待该mutex锁。

},

wait_lock = {

{

rlock = {

raw_lock = {

val = {

counter = 0

}

}

}

}

},

wait_list = {

next = 0xffff960539f9fe40,

prev = 0xffff96057483be40

},

owner = 0xffff960574cdd140,//当前占有该mutex锁的进程

{

osq = {

tail = {

counter = 0

}

},

__UNIQUE_ID_rh_kabi_hide1 = {

spin_mlock = 0x0

},

{<No data fields>}

}

}

wait_list.next指向等待队列里第一个将获得锁的进程对应的mutex_waiter.list地址,

wait_list.prev指向最后一个将获得锁的进程的mutex_waiter.list地址。

next和prec相等代表只有一个进程在mutex锁等待队列里。

crash> bt 0xffff960574cdd140

PID: 7272 TASK: ffff960574cdd140 CPU: 2 COMMAND: "reader"

#0 [ffff96056078bd48] __schedule at ffffffffb8768a32

#1 [ffff96056078bdd8] schedule at ffffffffb8768ed9

#2 [ffff96056078bde8] schedule_timeout at ffffffffb8766928

#3 [ffff96056078be98] msleep at ffffffffb80aa98f

#4 [ffff96056078bec8] kthread at ffffffffb80c1da1

#5 [ffff96056078bf50] ret_from_fork_nospec_begin at ffffffffb8775c24

crash>

以mutex_waiter.list地址0xffff960539f9fe40为起点list出所有等待和当前已获得mutex锁的进程mutex_waiter信息,

当前占用锁的进程mutex_waiter.list地址会列出在最后面,这里是ffffffffc05f1008。

crash> list 0xffff960539f9fe40 -l mutex_waiter.list -s mutex_waiter

ffff960539f9fe40

struct mutex_waiter {

list = {

next = 0xffff96057483be40,

prev = 0xffffffffc05f1008

},

task = 0xffff960574cd9040

}

ffff96057483be40

struct mutex_waiter {

list = {

next = 0xffffffffc05f1008,

prev = 0xffff960539f9fe40

},

task = 0xffff960570f2b0c0

}

ffffffffc05f1008

struct mutex_waiter {

list = {

next = 0xffff960539f9fe40,

prev = 0xffff96057483be40

},

task = 0xffff960574cdd140

}

为什么已经获得锁的进程已经不在wait list里了,crash 工具的list命令还是会把其显示出来??有知道的欢迎留言告知!!

附上验证代码:

#include <linux/init.h>

#include <linux/module.h>

#include <linux/sched.h>

#include <linux/delay.h>

#include <linux/kthread.h>

#include <linux/rwsem.h>

#include <linux/mutex.h>

MODULE_LICENSE("Dual BSD/GPL");

static DEFINE_MUTEX(test_mutex);

static void print_sem(struct mutex *lock)

{

printk(KERN_DEBUG "lock=%p,count:%dn", lock,lock->count);

}

int reader(void *data)

{

char *name = (char *)data;

printk(KERN_DEBUG "%s is runningn", name);

mutex_lock(&test_mutex);

printk(KERN_DEBUG "%s is sleeping 200n", name);

msleep(300000);

mutex_unlock(&test_mutex);

do_exit(0);

}

int writer(void *data)

{

char *name = (char *)data;

printk(KERN_DEBUG "%s is runningn", name);

msleep(10);

mutex_lock(&test_mutex);

printk(KERN_DEBUG "%s is sleeping 200n", name);

msleep(300000);

mutex_unlock(&test_mutex);

do_exit(0);

}

static int hello_init(void)

{

struct task_struct *task = NULL;

printk(KERN_ALERT "Hello, worldn");

print_sem(&test_mutex);

task = kthread_create(reader, "reader_1", "reader");

if (IS_ERR(task)) {

printk(KERN_DEBUG "failed to create taskn");

return 1;

}

wake_up_process(task);

task = kthread_create(writer, "writer_1", "writer1");

if (IS_ERR(task)) {

printk(KERN_DEBUG "failed to create taskn");

return 1;

}

wake_up_process(task);

msleep(5);

task = kthread_create(writer, "writer_2", "writer2");

if (IS_ERR(task)) {

printk(KERN_DEBUG "failed to create taskn");

return 1;

}

wake_up_process(task);

#if 0

msleep(5);

task = kthread_create(writer, "writer_3", "writer3");

if (IS_ERR(task)) {

printk(KERN_DEBUG "failed to create taskn");

return 1;

}

wake_up_process(task);

#endif

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT"Goodbye, cruel worldn");

}

module_init(hello_init);

module_exit(hello_exit);

---来自腾讯云社区的---CD

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: