+ if (vcpu == me)
+ continue;
+ if (vcpu->spinning)
+ continue;
You may well want to wake up a spinner. Suppose
A takes a lock
B preempts A
B grabs a ticket, starts spinning, yields to A
A releases lock
A grabs ticket, starts spinning
at this point, we want A to yield to B, but it won't because of this check.
+ if (!task)
+ continue;
+ if (waitqueue_active(&vcpu->wq))
+ continue;
+ if (task->flags& PF_VCPU)
+ continue;
+ kvm->last_boosted_vcpu = i;
+ yield_to(task);
+ break;
+ }
I think a random selection algorithm will be a better fit against
special guest behaviour.
- /* Sleep for 100 us, and hope lock-holder got scheduled */
- expires = ktime_add_ns(ktime_get(), 100000UL);
- schedule_hrtimeout(&expires, HRTIMER_MODE_ABS);
+ if (first_round&& last_boosted_vcpu == kvm->last_boosted_vcpu) {
+ /* We have not found anyone yet. */
+ first_round = 0;
+ goto again;
Need to guarantee termination.