调度子系统3_周期调度器

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介:
//	周期调度器
//	调用路径:update_process_times->scheduler_tick
//	函数任务:
//		1.更新rq的clock
//		2.更新队列负载
//		3.通知调度器类更新进程运行时间
//		4.更新下一次load balance的时间戳
//		5.触发load balance
1.1 void scheduler_tick(void)
{
	int cpu = smp_processor_id();
	struct rq *rq = cpu_rq(cpu);
	//当前运行的进程
	struct task_struct *curr = rq->curr;
	raw_spin_lock(&rq->lock);
	//更新rq的clock
	update_rq_clock(rq);
	//更新队列负载
	update_cpu_load_active(rq);
	//更新进程的运行时间
	curr->sched_class->task_tick(rq, curr, 0);
	raw_spin_unlock(&rq->lock);

#ifdef CONFIG_SMP
	//更新下一次load balance的时间戳
	rq->idle_balance = idle_cpu(cpu);
	//触发load balance软中断
	trigger_load_balance(rq, cpu);
#endif
}


//	更新队列负载(rq->cpu_load[])
//		每scheduler tick(TICK_NSEC)被调用一次
//	函数任务:
//		1.更新rq负载
//			1.1 通过CPU_LOAD_IDX_MAX个项记录rq的历史负载信息
//			1.2 更新方法
//				cpu_load[0] = load.weight
//				cpu_load[1] = (cpu_load[1]   + load.weight)/2
//				cpu_load[2] = (cpu_load[2]*3 + load.weight)/4
//				cpu_load[3] = (cpu_load[2]*7 + load.weight)/8
//		2.如果当前时间到达计算cpu负载的时间点
//			2.1 更新下一次计算cpu负载的时间点
//			2.2 计算cpu负载
//	调用路径:scheduler_tick->update_cpu_load
2.1 static void update_cpu_load(struct rq *this_rq)
{
	//rq中所有se负载的总和
	unsigned long this_load = this_rq->load.weight;
	int i, scale;
	this_rq->nr_load_updates++;
	//通过CPU_LOAD_IDX_MAX个项记录rq的历史负载信息
	for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
		unsigned long old_load, new_load;

		old_load = this_rq->cpu_load[i];
		//rq中所有se的load.weight之和
		new_load = this_load;
		if (new_load > old_load)
			new_load += scale-1;
		//cpu_load[0] = load.weight
		//cpu_load[1] = (cpu_load[1]   + load.weight)/2
		//cpu_load[2] = (cpu_load[2]*3 + load.weight)/4
		//cpu_load[3] = (cpu_load[2]*7 + load.weight)/8
		//....
		this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
	}
	//到达计算cpu负载的时间点
	if (time_after_eq(jiffies, this_rq->calc_load_update)) {
		//更新下一次计算cpu负载的时间点
		this_rq->calc_load_update += LOAD_FREQ;
		//计算系统负载
		calc_load_account_active(this_rq);
	}
}
//	计算系统负载
//		系统负载考虑就绪状态进程和不可中断睡眠的进程(I/O)进程
//	调用路径:update_cpu_load->calc_load_account_active
2.2 static void calc_load_account_active(struct rq *this_rq)
{
	long nr_active, delta;

	nr_active = this_rq->nr_running;	//就绪状态的进程
	nr_active += (long) this_rq->nr_uninterruptible;	//不可中断睡眠的进程

	if (nr_active != this_rq->calc_load_active) {	
		delta = nr_active - this_rq->calc_load_active;
		this_rq->calc_load_active = nr_active;
		atomic_long_add(delta, &calc_load_tasks);
	}
}

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
存储 Linux
linux【服务】kdump配置详解
linux【服务】kdump配置详解
成功解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 130: invalid continuation b
成功解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 130: invalid continuation b
成功解决UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 130: invalid continuation b
|
Linux 网络安全
在Linux中,如何设置防火墙规则?
在Linux中,如何设置防火墙规则?
|
存储 安全
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?
846 0
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?
孤儿进程、僵尸进程和进程退出(通俗易懂)
孤儿进程、僵尸进程和进程退出(通俗易懂)
|
Linux 编译器 C语言
Linux-GCC介绍+入门级Makefile使用
Linux-GCC介绍+入门级Makefile使用
276 0
|
人工智能 专有云 测试技术
|
监控 Linux 网络安全
Linux报错audit: backlog limit exceeded
Linux报错audit: backlog limit exceeded
1047 0
|
弹性计算 运维 前端开发