{
spinlock_t *lock;
s_time_t delta;
+ struct sched_unit *unit;
rcu_read_lock(&sched_res_rculock);
- lock = likely(v == current) ? NULL : unit_schedule_lock_irq(v->sched_unit);
+ /*
+ * Be careful in case of an idle vcpu: the assignment to a unit might
+ * change even with the scheduling lock held, so be sure to use the
+ * correct unit for locking in order to avoid triggering an ASSERT() in
+ * the unlock function.
+ */
+ unit = is_idle_vcpu(v) ? get_sched_res(v->processor)->sched_unit_idle
+ : v->sched_unit;
+ lock = likely(v == current) ? NULL : unit_schedule_lock_irq(unit);
memcpy(runstate, &v->runstate, sizeof(*runstate));
delta = NOW() - runstate->state_entry_time;
if ( delta > 0 )
runstate->time[runstate->state] += delta;
if ( unlikely(lock != NULL) )
- unit_schedule_unlock_irq(lock, v->sched_unit);
+ unit_schedule_unlock_irq(lock, unit);
rcu_read_unlock(&sched_res_rculock);
}