linux内核中,mm_struct 使用avl树或红黑树搜索vm_area_struct,而不直接用vm_area_struct指针指向?

fourye007 2016-09-25 04:50:41
linux内核,进程控制块数据结构
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct vm_area_struct * mmap_avl; /* tree of VMAs */
struct vm_area_struct * mmap_cache; /* last find_vma result */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
int map_count; /* number of VMAs */
struct semaphore mmap_sem;
spinlock_t page_table_lock;

struct list_head mmlist; /* List of all active mm's */

unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss, total_vm, locked_vm;
unsigned long def_flags;
unsigned long cpu_vm_mask;
unsigned long swap_cnt; /* number of pages to swap on next pass */
unsigned long swap_address;

/* Architecture-specific MM context */
mm_context_t context;
};

该控制结构通过使用 struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);搜索与之对应的vm_area_struct,即通过avl树或红黑树来搜索,而不是直接指定一个vm_area_struct 指针直接指向vm_area_struct 数据结构??????
...全文
890 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
fourye007 2016-10-03
  • 打赏
  • 举报
回复
恩恩,已经看懂了,谢谢
weifenghai 2016-10-02
  • 打赏
  • 举报
回复
可以参考《深入理解linux内核》的第九章“进程地址空间”中的线性区一节,期中的线性区处理有该函数的详解
fourye007 2016-09-25
  • 打赏
  • 举报
回复
有点尴尬,函数贴错了。
struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
{
	struct vm_area_struct *vma = NULL;

	if (mm) {
		/* Check the cache first. */
		/* (Cache hit rate is typically around 35%.) */
		vma = mm->mmap_cache;
		if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) {
			if (!mm->mmap_avl) {
				/* Go through the linear list. */
				vma = mm->mmap;
				while (vma && vma->vm_end <= addr)
					vma = vma->vm_next;
			} else {
				/* Then go through the AVL tree quickly. */
				struct vm_area_struct * tree = mm->mmap_avl;
				vma = NULL;
				for (;;) {
					if (tree == vm_avl_empty)
						break;
					if (tree->vm_end > addr) {
						vma = tree;
						if (tree->vm_start <= addr)
							break;
						tree = tree->vm_avl_left;
					} else
						tree = tree->vm_avl_right;
				}
			}
			if (vma)
				mm->mmap_cache = vma;
		}
	}
	return vma;
}
fourye007 2016-09-25
  • 打赏
  • 举报
回复
我好像懂了,应该是一个mm_struct 有多个虚拟空间 段,这一点可以从vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)函数的具体实现可以看出。
struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
				      struct vm_area_struct **pprev)
{
	if (mm) {
		if (!mm->mmap_avl) {
			/* Go through the linear list. */
			struct vm_area_struct * prev = NULL;
			struct vm_area_struct * vma = mm->mmap;
			while (vma && vma->vm_end <= addr) {
				prev = vma;
				vma = vma->vm_next;
			}
			*pprev = prev;
			return vma;
		} else {
			/* Go through the AVL tree quickly. */
			struct vm_area_struct * vma = NULL;
			struct vm_area_struct * last_turn_right = NULL;
			struct vm_area_struct * prev = NULL;
			struct vm_area_struct * tree = mm->mmap_avl;
			for (;;) {
				if (tree == vm_avl_empty)
					break;
				if (tree->vm_end > addr) {
					vma = tree;
					prev = last_turn_right;
					if (tree->vm_start <= addr)
						break;
					tree = tree->vm_avl_left;
				} else {
					last_turn_right = tree;
					tree = tree->vm_avl_right;
				}
			}
			if (vma) {
				if (vma->vm_avl_left != vm_avl_empty) {
					prev = vma->vm_avl_left;
					while (prev->vm_avl_right != vm_avl_empty)
						prev = prev->vm_avl_right;
				}
				if ((prev ? prev->vm_next : mm->mmap) != vma)
					printk("find_vma_prev: tree inconsistent with list\n");
				*pprev = prev;
				return vma;
			}
		}
	}
	*pprev = NULL;
	return NULL;
}

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧