[other]-linux kernel的问与答

一、内存

1、kmalloc、valloc、kzalloc、devm_kmalloc的区别

  • kmalloc和valloc的区别:

kmalloc是在线性映射区分配内存,它的物理地址是连续的; vmalloc是在高端内存区(非线性区/valloc区)分配内存,它的虚拟地址是连续的、物理地址非连续;
kmalloc在分配内存的时候,通过传入GFP_ATOMIC可以进行原子操作;

  • kmalloc kzalloc的区别

kzalloc申请内存后,并将这段内存清0

  • kmalloc devm_kmalloc的区别

kmalloc申请的内存,在不使用时需要主动free释放
devm_kmalloc申请的内存,在不使用时无需主动free释放.

二、同步机制

1、spinlock

(1)、请问自旋锁spinlock中都干了哪些事?
在spin_lock中,先关闭抢占preempt_disable、再加入排队序列(有ower和next两个变量,排队就是next++)、再进入低功耗模式等到wfe
在spin_unlock中,先让cpu退出低功耗模式(armv7使用sev指令,armv8使用staddlh指令),更新排队序列(onwer++),在打开抢占preempt_enable

(2)、spin_lock中,为何要关闭抢占preempt_disable ?
如果不关闭抢占,单核的情况下, 进程A获取spinlock后,在临界区干活,发生了抢占,进程B尝试获取spinlock,进程B拿不到,就会自旋等待那里.
等到B的时间片耗完,再次调度到进程A,且A释放了该锁,然后再调用B,B才能拿到该锁.
在B自旋的时候,造成cpu资源很大的浪费; 因为那个时候:A拿着锁,A并没有在执行,CPU在B上自旋等待

(3)、cpu0调用的A进程,刚获取lock->next值后,正准备给该变量+1计数、此时cpu1调用的B进程,也获取了lock->next值; 这样A和B进程都能拿到该锁? 请问linux是怎样解决这个问题的?

在ARMV8上使用了exclusive机制,是一种独占访问的状态,在A进程操作lock->next值时,在读取时,使用了ldaxr指令,将global monitor状态从open切换成exclusive状态, 然后写入数据到变量时使用stxr指令,将global monitor状态从exclusive切换成open状态。
在global monitor状态未exclusive时,B是再去使用ldaxr指令读取数据时,会返回错误,然后B会再继续读取该数据。

而在ARMv7上,虽然没有exclusive机制,但是提供了类似的指令,ldrex和strex;

2、信号量semaphore

(1)、在信号量semaphore的down()中,都干了哪些事情?
检查count值,大于0则获得该锁,进入临界区;
否则的话,未获得该锁,先将task加入到wait_list,再调用schedule_timeout进入睡眠

(2)、信号量的实现为何要依赖spinlock ?
在信号量的实现中,要对count值进行加加或减减操作,使用spinlock防止该变量产生竞争;

猜你喜欢

转载自blog.csdn.net/weixin_42135087/article/details/107388393