per-VMA lock 如果Linux内核里面有什么锁最臭名昭著,那么一定是mmap_sem(后改名为mmap_lock)。这个锁位于mm_struct里面,很显然它应该是一个多线程共享的进程级别概念而不应该是per-VMA的概念:但是之前我们在page fault中,也是要拿mmap_sem读锁的,因为我们也不知道page fault处理过程中,对应的VMA会不会变化...
当sem->count加1后还是小于0,代表锁已经被写者持有了,读者获取锁失败,进入rwsem_down_read_failed函数; 如果sem->wait_list是空时,代表没有任务在等待列表中,首次加入时,sem->count值需要加上RWSEM_WAITING_BIAS,表示有任务在等待列表中; 如果此时sem->count == RWSEM_WAITING_BIAS或者count > RWSEM_WAITIN...
* * pte_alloc_map() is safe to use under down_write(mmap_sem) or when * parallel threads are excluded by other means. * * Here we only have down_read(mmap_sem). */ //如果直接页表不存在,那么分配页表 if (pte_alloc(vma->vm_mm, vmf->pmd, vmf->address)) return VM_FAULT_OOM; ...
调用copy_flags()更新task_struct的标记变量,比如标明进程是否拥有超级用户权限的 PFSUPERPRIV 被清零,标明进程没有调用 exec() 函数的 PFFORKNOEXEC 被设置。 调用alloc_pid()获得一个有效的 PID 根据clone()系统调用获得的参数来复制或者共享打开的文件、文件系统信息、信号处理函数、进程地址空间和命名空间等。 最...
static noinline void __do_page_fault(struct pt_regs *regs, unsigned long hw_error_code, unsigned long address) { // mmap_sem 是进程虚拟内存空间 mm_struct 的读写锁 // 内核这里将 mmap_sem 预取到 cacheline 中,并标记为独占状态( MESI 协议中的 X 状态) prefetchw(¤t->mm->mmap_sem)...
LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), LSM_HOOK_INIT(sem_associate, selinux_sem_associate), LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), LSM_HOOK_INIT(sem_semop, selinux_sem_semop), ...
up_read(&mm->mmap_sem);return;...out_of_memory:pagefault_out_of_memory();return;... }voidpagefault_out_of_memory(void) {structoom_control oc ={ .zonelist=NULL, .nodemask=NULL, .memcg=NULL, .gfp_mask=0, .order=0,---单个页面情况。};...out_of_memory(&oc);} 3. 影响OOM的...
init_rwsem(&mm->mmap_sem);// 初始化保护写访问的自旋锁。mm->page_table_lock = SPIN_LOCK_UNLOCKED;// 为该结构分配新的PGD。mm->pgd = pgd_alloc(mm);mm->def_flags = 0;if (mm->pgd)return mm;free_mm(mm);return NULL;} ① ⇒ pgd_alloc...
(&mm->mmap_sem)) return -EINTR; // 开始 mmap 内存映射,在进程虚拟内存空间中分配一段 vma,并建立相关映射关系 // ret 为映射虚拟内存区域的起始地址 ret = do_mmap_pgoff(file, addr, len, prot, flag, pgoff, &populate, &uf); // 释放写锁 up_write(&mm->mmap_sem); if (populate) // ...
使用kmem_cache_alloc分配一个kmem_cache_t,然后根据size计算cachep->gfporder,最后把这个kmem_cache_t加入到全局链表中。 ① ⇒ kmem_cache_alloc kmem_cache_alloc函数 ② ⇒ kmem_cache_estimate kmem_cache_estimate函数 ...