设为首页 收藏本站
查看: 1425|回复: 0

[经验分享] VMM CPU Scheduling in Xen

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-10-11 13:01:29 | 显示全部楼层 |阅读模式
  http://hi.baidu.com/%B0%B5%D4%C2%C1%F7%B9%E2/blog/item/0f68f850e5af7215377abe5d.html
  
  (有时间我会给原版打个patch,让其更完整:)
  
  文件:xen-3.4.2/xen/common/schedule.c
  
  
  0、Per-CPU schedule data
  struct schedule_data {
spinlock_tschedule_lock;/* spinlock protecting curr        */
struct vcpu *curr;/* current task                    */
struct vcpu*idle;/* idle task for this cpu          */
void *sched_priv;
struct timers_timer;/* scheduling timer                */
} __cacheline_aligned; (和cache line对齐)
  
  DECLARE_PER_CPU(struct schedule_data, schedule_data);
  
  
  1、SCHEDULE_SOFTIRQ
这个软中断用于触发调度器的执行。在调度器初始化的时候初始化,中断服务例程是调度函数schedule。
代码:
/* Initialise the data structures. */
void __init scheduler_init(void)
{
....................................
     open_softirq(SCHEDULE_SOFTIRQ, schedule);
....................................
使用:
raise_softirq(SCHEDULE_SOFTIRQ);   执行该代码之后会导致所在cpu执行调度

2、schedule
选择下一个待执行的vcpu,执行vcpu切换
/*
* The main function
* - deschedule the current domain (scheduler independent).
* - pick a new domain (scheduler dependent).
*/
static void schedule(void)
{
     struct vcpu          *prev = current, *next = NULL;
     s_time_t              now = NOW();
     struct schedule_data *sd;
     struct task_slice     next_slice;
....................................
     /* get policy-specific decision on scheduling... */
     next_slice = ops.do_schedule(now);         //对于credit调度算法,会执行credit调度器中注册的csched_schedule函数

     next = next_slice.task;

     sd->curr = next;

     if ( next_slice.time >= 0 ) /* -ve means no limit */
         set_timer(&sd->s_timer, now + next_slice.time);       //设置next需要运行的时间

     if ( unlikely(prev == next) )
     {
         spin_unlock_irq(&sd->schedule_lock);
         trace_continue_running(next);
         return continue_running(prev);             //直接执行schedule_tail函数,跳过vcpu切换
     }
  
..................................
if (test_bit(_VPF_blocked, &prev->pause_flags)) { // 原来那句太难懂啦,我弄个易懂的:)
vcpu_runstate_change(prev, RUNSTATE_blocked, now);
} else {
if (vcpu_runnable(prev))
vcpu_runstate_change(prev, RUNSTATE_runnable, now);
else
vcpu_runstate_change(prev, RUNSTATE_offline, now);
}
     prev->last_run_time = now;

     ASSERT(next->runstate.state != RUNSTATE_running);
     vcpu_runstate_change(next, RUNSTATE_running, now);

     ASSERT(!next->is_running);
     next->is_running = 1;              //设置正在运行标志位
.........................

     context_switch(prev, next);  //执行vcpu切换
}
  
  ----------------------------------------------------------------------------
Per-VCPU pause flags. All are for "bit" operation
  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  3rd2nd1st0th
  vvvv
  migrationblk-xendownblocked
  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  /* Domain is blocked waiting for an event. */
#define _VPF_blocked0
#define VPF_blocked1
  
  /* VCPU is offline. */
#define _VPF_down1
#define VPF_down2
  
  /* VCPU is blocked awaiting an event to be consumed by Xen. */
#define _VPF_blocked_in_xen2
#define VPF_blocked_in_xen4
  
  /* VCPU affinity has changed: migrating to a new CPU. */
#define _VPF_migrating3
#define VPF_migrating8
  ----------------------------------------------------------------------------
  
  
3、block
/* Block the currently-executing domain until a pertinent event occurs. */
static long do_block(void)
{
     struct vcpu *v = current;

     local_event_delivery_enable();
     set_bit(_VPF_blocked, &v->pause_flags);     //设置block标志位 _VPF_blocked

     /* Check for events /after/ blocking: avoids wakeup waiting race. */
     if ( local_events_need_delivery() ) { //检测current vcpu的pending位是否被设置以及event delivery是否被允许
         clear_bit(_VPF_blocked, &v->pause_flags);  
     } else {
         raise_softirq(SCHEDULE_SOFTIRQ);        //current vcpu被标识为block状态,调度其他vcpu运行
     }

     return 0;
}


4、wake
唤醒指定的vcpu,使其从block状态却换到可运行状态
void vcpu_wake(struct vcpu *v)
{
     unsigned long flags;

     vcpu_schedule_lock_irqsave(v, flags);

     if ( likely(vcpu_runnable(v)) ) {
         if ( v->runstate.state >= RUNSTATE_blocked )
             vcpu_runstate_change(v, RUNSTATE_runnable, NOW());
         SCHED_OP(wake, v);   //执行调度器中的wake函数
     } else if ( !test_bit(_VPF_blocked, &v->pause_flags) ) {
         if ( v->runstate.state == RUNSTATE_blocked )
             vcpu_runstate_change(v, RUNSTATE_offline, NOW());
     }
     vcpu_schedule_unlock_irqrestore(v, flags);
}



重要函数记录:
struct domain *d;
struct vcpu *v;
for_each_vcpu ( d, v )     遍历domain中的vcpu
{
if ( v != current )
vcpu_pause(v);
}


struct domain *rd;
domid_t dom;
rd = rcu_lock_domain_by_id(dom);  根据domid获取相应的数据结构

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-125451-1-1.html 上篇帖子: 【XEN】Dom0与DomU内存共享代码及原理分析 下篇帖子: Xen 架构
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表