|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 3/4] VT-d PI: restrict the vcpu number on a given pcpu
>>> On 07.07.17 at 08:48, <chao.gao@xxxxxxxxx> wrote:
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -95,22 +95,91 @@ static DEFINE_PER_CPU(struct vmx_pi_blocking_vcpu,
> vmx_pi_blocking);
> uint8_t __read_mostly posted_intr_vector;
> static uint8_t __read_mostly pi_wakeup_vector;
>
> +/*
> + * Protect critical sections to avoid adding a blocked vcpu to a destroyed
> + * blocking list.
> + */
> +static DEFINE_SPINLOCK(remote_pbl_operation);
What is "pbl" supposed to stand for?
> +#define remote_pbl_operation_begin(flags) \
> +({ \
> + spin_lock_irqsave(&remote_pbl_operation, flags); \
> +})
> +
> +#define remote_pbl_operation_done(flags) \
> +({ \
> + spin_unlock_irqrestore(&remote_pbl_operation, flags); \
> +})
No need for the ({ }) here.
But then I don't understand what this is needed for in the first
place. If this is once again about CPU offlining, then I can only
repeat that such happens in stop_machine context. Otherwise
I'm afraid the comment ahead of this code section needs
adjustment, as I can't interpret it in another way.
> +/*
> + * By default, the local pcpu (means the one the vcpu is currently running
> on)
> + * is chosen as the destination of wakeup interrupt. But if the vcpu number
> of
> + * the pcpu exceeds a limit, another pcpu is chosen until we find a suitable
> + * one.
> + *
> + * Currently, choose (v_tot/p_tot) + K as the limit of vcpu count, where
> + * v_tot is the total number of hvm vcpus on the system, p_tot is the total
> + * number of pcpus in the system, and K is a fixed number. An experment on a
> + * skylake server which has 112 cpus and 64G memory shows the maximum time to
> + * wakeup a vcpu from a 128-entry blocking list takes about 22us, which is
> + * tolerable. So choose 128 as the fixed number K.
> + *
> + * This policy makes sure:
> + * 1) for common cases, the limit won't be reached and the local pcpu is used
> + * which is beneficial to performance (at least, avoid an IPI when unblocking
> + * vcpu).
> + * 2) for the worst case, the blocking list length scales with the vcpu count
> + * divided by the pcpu count.
> + */
> +#define PI_LIST_FIXED_NUM 128
> +#define PI_LIST_LIMIT (atomic_read(&num_hvm_vcpus) / num_online_cpus() +
> \
> + PI_LIST_FIXED_NUM)
> +static inline bool pi_over_limit(int cpu)
unsigned int
> +{
> + return per_cpu(vmx_pi_blocking, cpu).counter > PI_LIST_LIMIT;
> +}
> +
> static void vmx_vcpu_block(struct vcpu *v)
> {
> - unsigned long flags;
> - unsigned int dest;
> + unsigned long flags[2];
??? You almost never need two flags instances in a function.
> + unsigned int dest, pi_cpu;
> spinlock_t *old_lock;
> - spinlock_t *pi_blocking_list_lock =
> - &per_cpu(vmx_pi_blocking, v->processor).lock;
> struct pi_desc *pi_desc = &v->arch.hvm_vmx.pi_desc;
> + spinlock_t *pi_blocking_list_lock;
> + bool in_remote_operation = false;
> +
> + pi_cpu = v->processor;
> +
> + if ( unlikely(pi_over_limit(pi_cpu)) )
> + {
> + remote_pbl_operation_begin(flags[0]);
> + in_remote_operation = true;
> + while (true)
Coding style (and "for ( ; ; )" is generally better anyway).
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |