[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v1 1/6] sched: track time spent in IRQ handler
Add code that saves time spent in IRQ handler, so later we can make adjustments to schedule unit run time. This and following changes are called upon to provide fair scheduling. Problem is that any running vCPU can be interrupted by to handle IRQ which is bound to some other vCPU. Thus, current vCPU can be charged for a time, it actually didn't used. TODO: move vcpu_{begin|end}_irq_handler() calls to entry.S for even more fair time tracking. Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx> --- xen/arch/arm/irq.c | 2 ++ xen/arch/x86/irq.c | 2 ++ xen/common/sched/core.c | 29 +++++++++++++++++++++++++++++ xen/include/xen/sched.h | 13 +++++++++++++ 4 files changed, 46 insertions(+) diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index 3877657a52..51b517c0cd 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -201,6 +201,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq) struct irq_desc *desc = irq_to_desc(irq); struct irqaction *action; + vcpu_begin_irq_handler(); perfc_incr(irqs); ASSERT(irq >= 16); /* SGIs do not come down this path */ @@ -267,6 +268,7 @@ out: out_no_end: spin_unlock(&desc->lock); irq_exit(); + vcpu_end_irq_handler(); } void release_irq(unsigned int irq, const void *dev_id) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index a69937c840..3ef4221b64 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1895,6 +1895,7 @@ void do_IRQ(struct cpu_user_regs *regs) int irq = this_cpu(vector_irq)[vector]; struct cpu_user_regs *old_regs = set_irq_regs(regs); + vcpu_begin_irq_handler(); perfc_incr(irqs); this_cpu(irq_count)++; irq_enter(); @@ -2024,6 +2025,7 @@ void do_IRQ(struct cpu_user_regs *regs) out_no_unlock: irq_exit(); set_irq_regs(old_regs); + vcpu_end_irq_handler(); } static inline bool is_free_pirq(const struct domain *d, diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c index cb49a8bc02..8f642ada05 100644 --- a/xen/common/sched/core.c +++ b/xen/common/sched/core.c @@ -916,6 +916,35 @@ void vcpu_unblock(struct vcpu *v) vcpu_wake(v); } +void vcpu_begin_irq_handler(void) +{ + if (is_idle_vcpu(current)) + return; + + /* XXX: Looks like ASSERT_INTERRUPTS_DISABLED() is available only for x86 */ + if ( current->irq_nesting++ ) + return; + + current->irq_entry_time = NOW(); +} + +void vcpu_end_irq_handler(void) +{ + int delta; + + if (is_idle_vcpu(current)) + return; + + ASSERT(current->irq_nesting); + + if ( --current->irq_nesting ) + return; + + /* We assume that irq handling time will not overflow int */ + delta = NOW() - current->irq_entry_time; + atomic_add(delta, ¤t->sched_unit->irq_time); +} + /* * Do the actual movement of an unit from old to new CPU. Locks for *both* * CPUs needs to have been taken already when calling this! diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index ac53519d7f..ceed53364b 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -237,6 +237,9 @@ struct vcpu evtchn_port_t virq_to_evtchn[NR_VIRQS]; spinlock_t virq_lock; + /* Fair scheduling state */ + uint64_t irq_entry_time; + unsigned int irq_nesting; /* Tasklet for continue_hypercall_on_cpu(). */ struct tasklet continue_hypercall_tasklet; @@ -276,6 +279,9 @@ struct sched_unit { /* Vcpu state summary. */ unsigned int runstate_cnt[4]; + /* Fair scheduling correction value */ + atomic_t irq_time; + /* Bitmask of CPUs on which this VCPU may run. */ cpumask_var_t cpu_hard_affinity; /* Used to save affinity during temporary pinning. */ @@ -690,6 +696,13 @@ long vcpu_yield(void); void vcpu_sleep_nosync(struct vcpu *v); void vcpu_sleep_sync(struct vcpu *v); +/* + * Report IRQ handling time to scheduler. As IRQs can be nested, + * next two functions are re-enterable. + */ +void vcpu_begin_irq_handler(void); +void vcpu_end_irq_handler(void); + /* * Force synchronisation of given VCPU's state. If it is currently descheduled, * this call will ensure that all its state is committed to memory and that -- 2.27.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |