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
微信扫一扫打赏
支付宝扫一扫打赏