cpu子系统的组调度

匿名 (未验证) 提交于 2019-12-03 00:21:02
组调度属于cgroup中的cpu子系统 cpu子系统的所有操作都在cpu_cgrp_subsys 中有定义 struct cgroup_subsys cpu_cgrp_subsys = { 	.css_alloc	= cpu_cgroup_css_alloc, 	.css_online	= cpu_cgroup_css_online, 	.css_released	= cpu_cgroup_css_released, 	.css_free	= cpu_cgroup_css_free, 	.css_extra_stat_show = cpu_extra_stat_show, 	.fork		= cpu_cgroup_fork, 	.can_attach	= cpu_cgroup_can_attach, 	.attach		= cpu_cgroup_attach, 	.legacy_cftypes	= cpu_legacy_files, 	.dfl_cftypes	= cpu_files, 	.early_init	= true, 	.threaded	= true, }; 我们这里以css_alloc 为例 static struct cgroup_subsys_state * cpu_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) { 	struct task_group *parent = css_tg(parent_css); 	struct task_group *tg;  	if (!parent) { 		/* This is early initialization for the top cgroup */ 		return &root_task_group.css; 	} 	#创建调度组 	tg = sched_create_group(parent); 	if (IS_ERR(tg)) 		return ERR_PTR(-ENOMEM);  	return &tg->css; } struct task_group *sched_create_group(struct task_group *parent) { 	struct task_group *tg; 	 	tg = kmem_cache_alloc(task_group_cache, GFP_KERNEL | __GFP_ZERO); 	if (!tg) 		return ERR_PTR(-ENOMEM); 	#可见这里分别为fair和rt申请调度组 	if (!alloc_fair_sched_group(tg, parent)) 		goto err;  	if (!alloc_rt_sched_group(tg, parent)) 		goto err;  	return tg;  err: 	sched_free_group(tg); 	return ERR_PTR(-ENOMEM); } int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) { 	struct sched_entity *se; 	struct cfs_rq *cfs_rq; 	int i; 	#分别问cfs_rq和se申请内存 	tg->cfs_rq = kzalloc(sizeof(cfs_rq) * nr_cpu_ids, GFP_KERNEL); 	if (!tg->cfs_rq) 		goto err; 	tg->se = kzalloc(sizeof(se) * nr_cpu_ids, GFP_KERNEL); 	if (!tg->se) 		goto err;  	tg->shares = NICE_0_LOAD;  	init_cfs_bandwidth(tg_cfs_bandwidth(tg)); 	#为每个cpu 初始化cfs_rq和se 	for_each_possible_cpu(i) { 		cfs_rq = kzalloc_node(sizeof(struct cfs_rq), 				      GFP_KERNEL, cpu_to_node(i)); 		if (!cfs_rq) 			goto err;  		se = kzalloc_node(sizeof(struct sched_entity), 				  GFP_KERNEL, cpu_to_node(i)); 		if (!se) 			goto err_free_rq; 		#主要是初始化 		init_cfs_rq(cfs_rq); 		init_tg_cfs_entry(tg, cfs_rq, se, i, parent->se[i]); 		init_entity_runnable_average(se); 	}  } 当进程要加入组调度是会调用attach static void cpu_cgroup_attach(struct cgroup_taskset *tset) { 	struct task_struct *task; 	struct cgroup_subsys_state *css; 	#将cgroup_taskset 中的所有task通过sched_move_task 将进程迁移到组调度中 	cgroup_taskset_for_each(task, css, tset) 		sched_move_task(task); } void sched_move_task(struct task_struct *tsk) { #分别调用调度器的dequeue_task函数迁出task,然后在调用enqueue_task加入调度组 	if (queued) 		dequeue_task(rq, tsk, queue_flags); 	if (running) 		put_prev_task(rq, tsk);  	sched_change_group(tsk, TASK_MOVE_GROUP);  	if (queued) 		enqueue_task(rq, tsk, queue_flags); 	if (running) 		set_curr_task(rq, tsk); } 这里以enqueue_task 为例 static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags) { 	if (!(flags & ENQUEUE_NOCLOCK)) 		update_rq_clock(rq);  	if (!(flags & ENQUEUE_RESTORE)) 		sched_info_queued(rq, p); 	#这里最终调用fair的enqueue_task_fair 来加入组调度的fair的rq中 	p->sched_class->enqueue_task(rq, p, flags); }

转载请标明出处:cpu子系统的组调度
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!