[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 2/2] gnttab: refactor locking for scalability



>>> On 10.02.15 at 13:51, <chegger@xxxxxxxxx> wrote:
> @@ -188,6 +191,28 @@ nr_active_grant_frames(struct grant_table *gt)
>      return num_act_frames_from_sha_frames(nr_grant_frames(gt));
>  }
>  
> +static inline struct active_grant_entry *
> +active_entry_acquire(struct grant_table *t, grant_ref_t e)
> +{
> +    struct active_grant_entry *act;
> +
> +    /* 
> +     * not perfect, but better than nothing for a debug build
> +     * sanity check
> +     */

Better, but still not matching ./CODING_STYLE.

> @@ -316,7 +317,10 @@ get_maptrack_handle(
>      return handle;
>  }
>  
> -/* Number of grant table entries. Caller must hold d's grant table lock. */
> +/* 
> + * Number of grant table entries. Caller must hold d's grant table
> + * read lock.
> + */
>  static unsigned int nr_grant_entries(struct grant_table *gt)

Doesn't this belong in patch 1?

> @@ -505,26 +509,23 @@ static int grant_map_exists(const struct domain *ld,
>                              unsigned long mfn,
>                              unsigned int *ref_count)
>  {
> -    const struct active_grant_entry *act;
> +    struct active_grant_entry *act;
>      unsigned int ref, max_iter;
>      
>      ASSERT(rw_is_locked(&rgt->lock));
>  
>      max_iter = min(*ref_count + (1 << GNTTABOP_CONTINUATION_ARG_SHIFT),
>                     nr_grant_entries(rgt));
> -    for ( ref = *ref_count; ref < max_iter; ref++ )
> +    for ( ref = *ref_count; ref < max_iter; active_entry_release(act), ref++ 
> )
>      {
> -        act = &active_entry(rgt, ref);
> +        act = active_entry_acquire(rgt, ref);
>  
> -        if ( !act->pin )
> -            continue;
> -
> -        if ( act->domid != ld->domain_id )
> -            continue;
> -
> -        if ( act->frame != mfn )
> +        if ( !act->pin ||
> +             act->domid != ld->domain_id ||
> +             act->frame != mfn )
>              continue;

I don't mind this consolidation, but it does grow the patch size
without real need.

>      for ( handle = 0; handle < lgt->maptrack_limit; handle++ )
>      {
> +        struct active_grant_entry *act;
> +
>          map = &maptrack_entry(lgt, handle);
>          if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ||
>               map->domid != rd->domain_id )
>              continue;
> -        if ( active_entry(rd->grant_table, map->ref).frame == mfn )
> +        act = &_active_entry(rd->grant_table, map->ref);
> +        if ( act->frame == mfn )
>              (map->flags & GNTMAP_readonly) ? (*rdc)++ : (*wrc)++;
>      }

Yet here I don't understand at all what the change is good for - the
only thing you appear to need to change is to insert an underscore.

> @@ -2601,9 +2637,17 @@ __gnttab_swap_grant_ref(grant_ref_t ref_a, grant_ref_t 
> ref_b)
>  {
>      struct domain *d = rcu_lock_current_domain();
>      struct grant_table *gt = d->grant_table;
> -    struct active_grant_entry *act;
> +    struct active_grant_entry *act_a = NULL;
> +    struct active_grant_entry *act_b = NULL;
>      s16 rc = GNTST_okay;
>  
> +    if ( ref_a == ref_b )
> +        /*
> +         * noop, so avoid acquiring the same active entry
> +         * twice which would case a deadlock.

cause

> @@ -2953,7 +3001,7 @@ grant_table_create(
>      struct domain *d)
>  {
>      struct grant_table *t;
> -    int                 i;
> +    int                 i, j;

unsigned int

> @@ -3195,9 +3244,12 @@ static void gnttab_usage_print(struct domain *rd)
>          uint16_t status;
>          uint64_t frame;
>  
> -        act = &active_entry(gt, ref);
> +        act = active_entry_acquire(gt, ref);

As (again in a different context) said recently, debug key handlers
would better use try-lock variants, skipping the respective printing
if the lock is being held.

And to come back to a remark on v3 and v4: Considering that you
drop double_maptrack_lock() here altogether, is patch 1 really
correct/sensible in introducing that function in place of
double_gt_lock()? Wouldn't the new functionality want the local
maptrack and the remote grant table locked in such cases? I.e.
isn't one of the locks taken at least pointless?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.