} 这里首先会调用might_sleep()一直睡眠,进行减少检查sem->count,如果当前sem->count的值是负数(说明减少前是0或者负数)就挂起,这时并没有真正获得信号量,会调用__down函数; 如果检查没问题之后,在汇编上调用__down_failed,即指令call __down_failed。 fastcall void __down_failed(void /* special register c...
其实内核源码对此也有明确的注释:might_sleep - annotation for functions that can sleep。所以对于release版的kernel image而言,might_sleep的作用仅仅是一个annotation,提醒使用者,一个使用might_sleep的函数在其后的代码执行中可能会sleep。 不过如果有调试需求介入的话,比如你的系统莫名其妙地随机性地crash掉,在经过...
我们已经在前一部分中遇到了might_sleep宏。简而言之,might_sleep宏的实现取决于CONFIG_DEBUG_ATOMIC_SLEEP内核配置选项,如果此选项启用,该宏只是在原子上下文中执行时打印堆栈跟踪。由于这个宏主要用于调试目的,我们将跳过它,并继续前进。此外,我们将跳过down_read函数中的下一个宏 -rwsem_acquire,它与 Linux 内核的...
这里的might_sleep说明调用mutex_lock函数有可能会因为未能获取到mutex锁而进入阻塞状态。在原子上下文中(中断上下文、软中断上下文、持有自旋锁、禁止抢占等),我们不能调用可以引起阻塞的函数,因此在might_sleep函数中嵌入了这个检查,当原子上下文中调用mutex_lock函数的时候,内核会打印出内核栈的信息,从而定位这个异常。
自愿内核抢占模型使用宏might_sleep()在内核里面增加抢占点,例如在函数mutex_lock()里面增加抢占点,如下。 kernel/locking/mutex.c void __sched mutex_lock(struct mutex *lock) { might_sleep(); if (!__mutex_trylock_fast(lock)) __mutex_lock_slowpath(lock); ...
内核代码在很多延时比较大的代码前调用函数might_sleep()。如函数名称所示,它只有在定义了CONFIG_PREEMPT_VOLUNTARY时候才有可能会把当前的进程挂起。_cond_resched中会去判断当前的进程是否可以被抢占,并且是否需要rescheduled,如果满足的话就触发重新调度,这样就避免了因为内核代码阻塞而导致其他任务出现比较大延时的情况(...
mutex_lock()函数调用might_sleep()函数判断锁的状态,调用__mutex_trylock_fast()函数尝试快速获取mutex锁,如果失败,则调用__mutex_lock_slowpath()函数获取mutex锁 void__schedmutex_lock(structmutex *lock){ might_sleep();if(!__mutex_trylock_fast(lock)) ...
#definewait_event_interruptible(wq_head,condition)\({\int__ret=0;\might_sleep();\if(!(condition))\__ret=__wait_event_interruptible(wq_head,condition);\__ret;\})intwait_event_interruptible(wait_queue_head_tq,CONDITION)/* 如果CONDITION条件为false,则阻塞等待队列中的当前任务 */ ...
might_sleep; /*fastpath*/ if(!__mutex_trylock_fast(lock)) /*midpath and slowpath*/ __mutex_lock_slowpath(lock); } __mutex_trylock_fast(lock) -> atomic_long_try_cmpxchg_acquire(&lock->owner, &zero, curr) -> atomic64_try_cmpxchg_acquire(v, (s64 *)old,new); ...
*/might_sleep();#ifdefCONFIG_DEBUG_VMif(!user_mode(regs)&&!search_exception_tables(regs->pc)){mmap_read_unlock(mm);gotono_context;}#endif}///进一步处理缺页以异常fault=__do_page_fault(mm,addr,mm_flags,vm_flags,regs);...no_context:__do_kernel_fault(addr,esr,regs);///报错处理retu...