|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 01/11] memory: batch processing in acquire_resource()
On Tue, Jul 07, 2020 at 09:39:40PM +0200, Michał Leszczyński wrote:
> From: Michal Leszczynski <michal.leszczynski@xxxxxxx>
>
> Allow to acquire large resources by allowing acquire_resource()
> to process items in batches, using hypercall continuation.
>
> Be aware that this modifies the behavior of acquire_resource
> call with frame_list=NULL. While previously it would return
> the size of internal array (32), with this patch it returns
> the maximal quantity of frames that could be requested at once,
> i.e. UINT_MAX >> MEMOP_EXTENT_SHIFT.
>
> Signed-off-by: Michal Leszczynski <michal.leszczynski@xxxxxxx>
> ---
FWIW, I think I've also said on a previous version, I would prefer if
the changelog between versions is added to each patch, having it on
the cover letter is not very helpful as I usually care about specific
changes made to each patch.
I've just got one comment that needs addressing below.
> xen/common/memory.c | 49 ++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 44 insertions(+), 5 deletions(-)
>
> diff --git a/xen/common/memory.c b/xen/common/memory.c
> index 714077c1e5..eb42f883df 100644
> --- a/xen/common/memory.c
> +++ b/xen/common/memory.c
> @@ -1046,10 +1046,12 @@ static int acquire_grant_table(struct domain *d,
> unsigned int id,
> }
>
> static int acquire_resource(
> - XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg)
> + XEN_GUEST_HANDLE_PARAM(xen_mem_acquire_resource_t) arg,
> + unsigned long *start_extent)
> {
> struct domain *d, *currd = current->domain;
> xen_mem_acquire_resource_t xmar;
> + uint32_t total_frames;
> /*
> * The mfn_list and gfn_list (below) arrays are ok on stack for the
> * moment since they are small, but if they need to grow in future
> @@ -1069,7 +1071,7 @@ static int acquire_resource(
> if ( xmar.nr_frames )
> return -EINVAL;
>
> - xmar.nr_frames = ARRAY_SIZE(mfn_list);
> + xmar.nr_frames = UINT_MAX >> MEMOP_EXTENT_SHIFT;
>
> if ( __copy_field_to_guest(arg, &xmar, nr_frames) )
> return -EFAULT;
> @@ -1077,8 +1079,28 @@ static int acquire_resource(
> return 0;
> }
>
> + total_frames = xmar.nr_frames;
> +
> + /* Is the size too large for us to encode a continuation? */
> + if ( unlikely(xmar.nr_frames > (UINT_MAX >> MEMOP_EXTENT_SHIFT)) )
> + return -EINVAL;
> +
> + if ( *start_extent )
> + {
> + /*
> + * Check whether start_extent is in bounds, as this
> + * value if visible to the calling domain.
> + */
> + if ( *start_extent > xmar.nr_frames )
> + return -EINVAL;
> +
> + xmar.frame += *start_extent;
> + xmar.nr_frames -= *start_extent;
> + guest_handle_add_offset(xmar.frame_list, *start_extent);
> + }
> +
> if ( xmar.nr_frames > ARRAY_SIZE(mfn_list) )
> - return -E2BIG;
> + xmar.nr_frames = ARRAY_SIZE(mfn_list);
>
> rc = rcu_lock_remote_domain_by_id(xmar.domid, &d);
> if ( rc )
> @@ -1135,6 +1157,14 @@ static int acquire_resource(
> }
> }
>
> + if ( !rc )
> + {
> + *start_extent += xmar.nr_frames;
> +
> + if ( *start_extent != total_frames )
> + rc = -ERESTART;
> + }
> +
> out:
> rcu_unlock_domain(d);
>
> @@ -1599,8 +1629,17 @@ long do_memory_op(unsigned long cmd,
> XEN_GUEST_HANDLE_PARAM(void) arg)
> #endif
>
> case XENMEM_acquire_resource:
> - rc = acquire_resource(
> - guest_handle_cast(arg, xen_mem_acquire_resource_t));
> + do {
> + rc = acquire_resource(
> + guest_handle_cast(arg, xen_mem_acquire_resource_t),
> + &start_extent);
I think it would be interesting from a performance PoV to move the
xmar copy_from_guest here, so that each call to acquire_resource
in the loop doesn't need to perform a copy from guest. That's
more relevant for translated callers, where a copy_from_guest involves
a guest page table and a p2m walk.
> +
> + if ( hypercall_preempt_check() )
You are missing a rc == -ERESTART check here, you don't want to encode
a continuation if rc is different than -ERESTART AFAICT.
Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |