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

Re: [Xen-devel] [PATCH] adjust a few RCU domain locking calls


  • To: Jan Beulich <JBeulich@xxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxx>
  • From: Keir Fraser <keir.xen@xxxxxxxxx>
  • Date: Fri, 07 Sep 2012 15:47:40 +0100
  • Delivery-date: Fri, 07 Sep 2012 14:48:09 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>
  • Thread-index: Ac2NB7qwu+5lcvA5BUOYr9XmKfdcDg==
  • Thread-topic: [Xen-devel] [PATCH] adjust a few RCU domain locking calls

On 07/09/2012 13:56, "Jan Beulich" <JBeulich@xxxxxxxx> wrote:

> x86's do_physdev_op() had a case where the locking was entirely
> superfluous. Its physdev_map_pirq() further had a case where the lock
> was being obtained too early, needlessly complicating early exit paths.
> 
> Grant table code had two open coded instances of
> rcu_lock_target_domain_by_id(), and a third code section could be
> consolidated by using the newly introduced helper function.
> 
> The memory hypercall code had two more instances of open coding
> rcu_lock_target_domain_by_id(), but note that here this is not just
> cleanup, but also fixes an error return path in memory_exchange() to
> actually return an error.
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

Acked-by: Keir Fraser <keir@xxxxxxx>

> --- a/xen/arch/x86/physdev.c
> +++ b/xen/arch/x86/physdev.c
> @@ -90,14 +90,10 @@ static int physdev_hvm_map_pirq(
>  int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p,
>                       struct msi_info *msi)
>  {
> -    struct domain *d;
> +    struct domain *d = current->domain;
>      int pirq, irq, ret = 0;
>      void *map_data = NULL;
>  
> -    ret = rcu_lock_target_domain_by_id(domid, &d);
> -    if ( ret )
> -        return ret;
> -
>      if ( domid == DOMID_SELF && is_hvm_domain(d) )
>      {
>          /*
> @@ -105,14 +101,15 @@ int physdev_map_pirq(domid_t domid, int
>           * calls back into itself and deadlocks on hvm_domain.irq_lock.
>           */
>          if ( !is_hvm_pv_evtchn_domain(d) )
> -        {
> -            ret = -EINVAL;
> -            goto free_domain;
> -        }
> -        ret = physdev_hvm_map_pirq(d, type, index, pirq_p);
> -        goto free_domain;
> +            return -EINVAL;
> +
> +        return physdev_hvm_map_pirq(d, type, index, pirq_p);
>      }
>  
> +    ret = rcu_lock_target_domain_by_id(domid, &d);
> +    if ( ret )
> +        return ret;
> +
>      if ( !IS_PRIV_FOR(current->domain, d) )
>      {
>          ret = -EPERM;
> @@ -696,13 +693,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
>      }
>      case PHYSDEVOP_get_free_pirq: {
>          struct physdev_get_free_pirq out;
> -        struct domain *d;
> +        struct domain *d = v->domain;
>  
>          ret = -EFAULT;
>          if ( copy_from_guest(&out, arg, 1) != 0 )
>              break;
>  
> -        d = rcu_lock_current_domain();
>          spin_lock(&d->event_lock);
>  
>          ret = get_free_pirq(d, out.type);
> @@ -717,7 +713,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
>          }
>  
>          spin_unlock(&d->event_lock);
> -        rcu_unlock_domain(d);
>  
>          if ( ret >= 0 )
>          {
> --- a/xen/common/grant_table.c
> +++ b/xen/common/grant_table.c
> @@ -24,7 +24,7 @@
>   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>   */
>  
> -#include <xen/config.h>
> +#include <xen/err.h>
>  #include <xen/iocap.h>
>  #include <xen/lib.h>
>  #include <xen/sched.h>
> @@ -195,6 +195,30 @@ double_gt_unlock(struct grant_table *lgt
>          spin_unlock(&rgt->lock);
>  }
>  
> +static struct domain *gt_lock_target_domain_by_id(domid_t dom)
> +{
> +    struct domain *d;
> +    int rc = GNTST_general_error;
> +
> +    switch ( rcu_lock_target_domain_by_id(dom, &d) )
> +    {
> +    case 0:
> +        return d;
> +
> +    case -ESRCH:
> +        gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
> +        rc = GNTST_bad_domain;
> +        break;
> +
> +    case -EPERM:
> +        rc = GNTST_permission_denied;
> +        break;
> +    }
> +
> +    ASSERT(rc < 0 && -rc <= MAX_ERRNO);
> +    return ERR_PTR(rc);
> +}
> +
>  static inline int
>  __get_maptrack_handle(
>      struct grant_table *t)
> @@ -1261,7 +1285,6 @@ gnttab_setup_table(
>      struct grant_table *gt;
>      int            i;
>      unsigned long  gmfn;
> -    domid_t        dom;
>  
>      if ( count != 1 )
>          return -EINVAL;
> @@ -1281,25 +1304,11 @@ gnttab_setup_table(
>          goto out1;
>      }
>  
> -    dom = op.dom;
> -    if ( dom == DOMID_SELF )
> +    d = gt_lock_target_domain_by_id(op.dom);
> +    if ( IS_ERR(d) )
>      {
> -        d = rcu_lock_current_domain();
> -    }
> -    else
> -    {
> -        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
> -        {
> -            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
> -            op.status = GNTST_bad_domain;
> -            goto out1;
> -        }
> -
> -        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
> -        {
> -            op.status = GNTST_permission_denied;
> -            goto out2;
> -        }
> +        op.status = PTR_ERR(d);
> +        goto out1;
>      }
>  
>      if ( xsm_grant_setup(current->domain, d) )
> @@ -1352,7 +1361,6 @@ gnttab_query_size(
>  {
>      struct gnttab_query_size op;
>      struct domain *d;
> -    domid_t        dom;
>      int rc;
>  
>      if ( count != 1 )
> @@ -1364,25 +1372,11 @@ gnttab_query_size(
>          return -EFAULT;
>      }
>  
> -    dom = op.dom;
> -    if ( dom == DOMID_SELF )
> -    {
> -        d = rcu_lock_current_domain();
> -    }
> -    else
> +    d = gt_lock_target_domain_by_id(op.dom);
> +    if ( IS_ERR(d) )
>      {
> -        if ( unlikely((d = rcu_lock_domain_by_id(dom)) == NULL) )
> -        {
> -            gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom);
> -            op.status = GNTST_bad_domain;
> -            goto query_out;
> -        }
> -
> -        if ( unlikely(!IS_PRIV_FOR(current->domain, d)) )
> -        {
> -            op.status = GNTST_permission_denied;
> -            goto query_out_unlock;
> -        }
> +        op.status = PTR_ERR(d);
> +        goto query_out;
>      }
>  
>      rc = xsm_grant_query_size(current->domain, d);
> @@ -2240,15 +2234,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDL
>          return -EFAULT;
>      }
>  
> -    rc = rcu_lock_target_domain_by_id(op.dom, &d);
> -    if ( rc < 0 )
> +    d = gt_lock_target_domain_by_id(op.dom);
> +    if ( IS_ERR(d) )
>      {
> -        if ( rc == -ESRCH )
> -            op.status = GNTST_bad_domain;
> -        else if ( rc == -EPERM )
> -            op.status = GNTST_permission_denied;
> -        else
> -            op.status = GNTST_general_error;
> +        op.status = PTR_ERR(d);
>          goto out1;
>      }
>      rc = xsm_grant_setup(current->domain, d);
> --- a/xen/common/memory.c
> +++ b/xen/common/memory.c
> @@ -329,22 +329,9 @@ static long memory_exchange(XEN_GUEST_HA
>          out_chunk_order = exch.in.extent_order - exch.out.extent_order;
>      }
>  
> -    if ( likely(exch.in.domid == DOMID_SELF) )
> -    {
> -        d = rcu_lock_current_domain();
> -    }
> -    else
> -    {
> -        if ( (d = rcu_lock_domain_by_id(exch.in.domid)) == NULL )
> -            goto fail_early;
> -
> -        if ( !IS_PRIV_FOR(current->domain, d) )
> -        {
> -            rcu_unlock_domain(d);
> -            rc = -EPERM;
> -            goto fail_early;
> -        }
> -    }
> +    rc = rcu_lock_target_domain_by_id(exch.in.domid, &d);
> +    if ( rc )
> +        goto fail_early;
>  
>      memflags |= MEMF_bits(domain_clamp_alloc_bitsize(
>          d,
> @@ -583,20 +570,8 @@ long do_memory_op(unsigned long cmd, XEN
>               && (reservation.mem_flags & XENMEMF_populate_on_demand) )
>              args.memflags |= MEMF_populate_on_demand;
>  
> -        if ( likely(reservation.domid == DOMID_SELF) )
> -        {
> -            d = rcu_lock_current_domain();
> -        }
> -        else
> -        {
> -            if ( (d = rcu_lock_domain_by_id(reservation.domid)) == NULL )
> -                return start_extent;
> -            if ( !IS_PRIV_FOR(current->domain, d) )
> -            {
> -                rcu_unlock_domain(d);
> -                return start_extent;
> -            }
> -        }
> +        if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) )
> +            return start_extent;
>          args.domain = d;
>  
>          rc = xsm_memory_adjust_reservation(current->domain, d);
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel



_______________________________________________
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®.