version = src->version;
virt_rmb(); /* Make sure that the version is read before the steal */
steal = src->steal;
virt_rmb(); /* Make sure that the steal is read before the next version */
} while ((version & 1) || (version != src->version));
if (unlikely(action == ACTION_BOOT_CPU)) {
native_ops.send_ipi_single(cpu, action); return;
}
old = atomic_fetch_or(BIT(action), &info->message); if (old) return;
min = cpu_logical_map(cpu);
kvm_hypercall3(KVM_HCALL_FUNC_IPI, 1, 0, min);
}
#define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG)
staticvoid pv_send_ipi_mask(conststruct cpumask *mask, unsignedint action)
{ int i, cpu, min = 0, max = 0, old;
__uint128_t bitmap = 0;
irq_cpustat_t *info;
if (cpumask_empty(mask)) return;
if (unlikely(action == ACTION_BOOT_CPU)) {
native_ops.send_ipi_mask(mask, action); return;
}
action = BIT(action);
for_each_cpu(i, mask) {
info = &per_cpu(irq_stat, i);
old = atomic_fetch_or(action, &info->message); if (old) continue;
cpu = cpu_logical_map(i); if (!bitmap) {
min = max = cpu;
} elseif (cpu < min && cpu > (max - KVM_IPI_CLUSTER_SIZE)) { /* cpu < min, and bitmap still enough */
bitmap <<= min - cpu;
min = cpu;
} elseif (cpu > min && cpu < (min + KVM_IPI_CLUSTER_SIZE)) { /* cpu > min, and bitmap still enough */
max = cpu > max ? cpu : max;
} else { /* * With cpu, bitmap will exceed KVM_IPI_CLUSTER_SIZE, * send IPI here directly and skip the remaining CPUs.
*/
kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsignedlong)bitmap,
(unsignedlong)(bitmap >> BITS_PER_LONG), min);
min = max = cpu;
bitmap = 0;
}
__set_bit(cpu - min, (unsignedlong *)&bitmap);
}
if (bitmap)
kvm_hypercall3(KVM_HCALL_FUNC_IPI, (unsignedlong)bitmap,
(unsignedlong)(bitmap >> BITS_PER_LONG), min);
}
staticint pv_enable_steal_time(void)
{ int cpu = smp_processor_id(); unsignedlong addr; struct kvm_steal_time *st;
if (!has_steal_clock) return -EPERM;
st = &per_cpu(steal_time, cpu);
addr = per_cpu_ptr_to_phys(st);
/* The whole structure kvm_steal_time should be in one page */ if (PFN_DOWN(addr) != PFN_DOWN(addr + sizeof(*st))) {
pr_warn("Illegal PV steal time addr %lx\n", addr); return -EFAULT;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.