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

Re: [Xen-devel] [PATCH v3 for-next 1/3] x86/physdev: factor out the code to allocate and map a pirq



On Tue, May 30, 2017 at 03:16:51AM -0600, Jan Beulich wrote:
> >>> On 17.05.17 at 17:15, <roger.pau@xxxxxxxxxx> wrote:
> > --- a/xen/arch/x86/irq.c
> > +++ b/xen/arch/x86/irq.c
> > @@ -2537,3 +2537,162 @@ bool_t hvm_domain_use_pirq(const struct domain *d, 
> > const struct pirq *pirq)
> >      return is_hvm_domain(d) && pirq &&
> >             pirq->arch.hvm.emuirq != IRQ_UNBOUND; 
> >  }
> > +
> > +static int allocate_pirq(struct domain *d, int pirq, int irq, int type,
> > +                         int *nr)
> > +{
> > +    int current_pirq;
> > +
> > +    ASSERT(spin_is_locked(&d->event_lock));
> > +    current_pirq = domain_irq_to_pirq(d, irq);
> > +    if ( pirq < 0 )
> > +    {
> > +        if ( current_pirq )
> > +        {
> > +            dprintk(XENLOG_G_ERR, "dom%d: %d:%d already mapped to %d\n",
> > +                    d->domain_id, irq, pirq, current_pirq);
> 
> Instead of "irq" the old code did pass "*index", i.e. a Dom0 kernel
> specified value (which is going to be more useful, as any problem
> here will need to be diagnosed in the Dom0 kernel). The two
> values are identical only if, in the GSI case,
> domain_pirq_to_irq(current->domain, *index) in
> allocate_and_map_gsi_pirq() returned a negative value.

I guess I can propagate index into this function, I haven't done that
because it's only used by the error message, but not the code itself.

When I used the physdev hypoercalls in the past I think I was always
setting index == GSI IIRC.

> > +            if ( current_pirq < 0 )
> > +                return -EBUSY;
> > +        }
> > +        else if ( type == MAP_PIRQ_TYPE_MULTI_MSI )
> > +        {
> > +            if ( *nr <= 0 || *nr > 32 )
> > +                return -EDOM;
> > +            else if ( *nr != 1 && !iommu_intremap )
> > +                return -EOPNOTSUPP;
> > +            else
> 
> Pointless "else" (twice).

Done (and re-indented the section below).

> > +            {
> > +                while ( *nr & (*nr - 1) )
> > +                    *nr += *nr & -*nr;
> > +                pirq = get_free_pirqs(d, *nr);
> > +                if ( pirq < 0 )
> > +                {
> > +                    while ( (*nr >>= 1) > 1 )
> > +                        if ( get_free_pirqs(d, *nr) > 0 )
> > +                            break;
> > +                    dprintk(XENLOG_G_ERR, "dom%d: no block of %d free 
> > pirqs\n",
> > +                            d->domain_id, *nr << 1);
> > +                }
> > +            }
> > +        }
> > +        else
> > +        {
> > +            pirq = get_free_pirq(d, type);
> > +            if ( pirq < 0 )
> > +                dprintk(XENLOG_G_ERR, "dom%d: no free pirq\n", 
> > d->domain_id);
> > +        }
> > +    }
> > +    else if ( current_pirq && pirq != current_pirq )
> > +    {
> > +        dprintk(XENLOG_G_ERR, "dom%d: irq %d already mapped to pirq %d\n",
> > +                d->domain_id, irq, current_pirq);
> > +        pirq = -EEXIST;
> 
> "return -EEXIST" please, to match the direct returns you use further
> up.

Ack.

> > +    }
> > +
> > +    return pirq;
> > +}
> > +
> > +int allocate_and_map_gsi_pirq(struct domain *d, int *index, int *pirq_p)
> 
> Neither here nor in the MSI sibling you ever write to *index, so
> there's no need for the parameter to have pointer type.

Done

> > +{
> > +    int irq, pirq, ret;
> > +
> > +    if ( *index < 0 || *index >= nr_irqs_gsi )
> > +    {
> > +        dprintk(XENLOG_G_ERR, "dom%d: map invalid irq %d\n", d->domain_id,
> > +                *index);
> > +        return -EINVAL;
> > +    }
> > +
> > +    irq = domain_pirq_to_irq(current->domain, *index);
> > +    if ( irq <= 0 )
> > +    {
> > +        if ( is_hardware_domain(current->domain) )
> > +            irq = *index;
> > +        else
> > +        {
> > +            dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
> > +                    d->domain_id);
> > +            return -EINVAL;
> > +        }
> > +    }
> > +
> > +    /* Verify or get pirq. */
> > +    spin_lock(&d->event_lock);
> > +    pirq = allocate_pirq(d, *pirq_p, irq, MAP_PIRQ_TYPE_GSI, 0);
> 
> The last parameter of allocate_pirq() is a pointer, so you really
> mean NULL here.
>
> > +    if ( pirq < 0 )
> > +    {
> > +        ret = pirq;
> > +        goto done;
> > +    }
> > +
> > +    ret = map_domain_pirq(d, pirq, irq, MAP_PIRQ_TYPE_GSI, NULL);
> > +    if ( ret == 0 )
> > +        *pirq_p = pirq;
> > +
> > + done:
> > +    spin_unlock(&d->event_lock);
> > +    return ret;
> > +}
> 
> Blank line before final return statement please.

Fixed both of the above.

> > +int allocate_and_map_msi_pirq(struct domain *d, int *index, int *pirq_p,
> > +                              int type, struct msi_info *msi)
> > +{
> > +    int irq, pirq, ret;
> > +
> > +    switch ( type )
> > +    {
> > +    case MAP_PIRQ_TYPE_MSI:
> > +        if ( !msi->table_base )
> > +            msi->entry_nr = 1;
> > +        irq = *index;
> > +        if ( irq == -1 )
> > +    case MAP_PIRQ_TYPE_MULTI_MSI:
> > +            irq = create_irq(NUMA_NO_NODE);
> > +
> > +        if ( irq < nr_irqs_gsi || irq >= nr_irqs )
> > +        {
> > +            dprintk(XENLOG_G_ERR, "dom%d: can't create irq for msi!\n",
> > +                    d->domain_id);
> > +            return -EINVAL;
> > +        }
> > +
> > +        msi->irq = irq;
> > +        break;
> > +
> > +    default:
> > +        dprintk(XENLOG_G_ERR, "dom%d: wrong pirq type %x\n",
> > +                d->domain_id, type);
> > +        return -EINVAL;
> 
> This really should be an ASSERT_UNREACHABLE() (with the return
> statement kept).

Fixed.

> > +    }
> > +
> > +    msi->irq = irq;
> > +
> > +    pcidevs_lock();
> > +    /* Verify or get pirq. */
> > +    spin_lock(&d->event_lock);
> > +    pirq = allocate_pirq(d, *pirq_p, irq, type, &msi->entry_nr);
> > +    if ( pirq < 0 )
> > +    {
> > +        ret = pirq;
> > +        goto done;
> > +    }
> > +
> > +    ret = map_domain_pirq(d, pirq, irq, type, msi);
> > +    if ( ret == 0 )
> > +        *pirq_p = pirq;
> > +
> > + done:
> > +    spin_unlock(&d->event_lock);
> > +    pcidevs_unlock();
> > +    if ( ret != 0 )
> > +        switch ( type )
> > +        {
> > +        case MAP_PIRQ_TYPE_MSI:
> > +            if ( *index == -1 )
> > +        case MAP_PIRQ_TYPE_MULTI_MSI:
> > +                destroy_irq(irq);
> > +            break;
> > +        }
> > +    return ret;
> > +}
> > +
> 
> Please don't end a file with a blank line.

Fixed, and I've also added a new line before the return statement.

> > diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
> > index eec4a41231..e99fd9a35f 100644
> > --- a/xen/arch/x86/physdev.c
> > +++ b/xen/arch/x86/physdev.c
> > @@ -92,8 +92,7 @@ int physdev_map_pirq(domid_t domid, int type, int *index, 
> > int *pirq_p,
> >                       struct msi_info *msi)
> >  {
> >      struct domain *d = current->domain;
> > -    int pirq, irq, ret = 0;
> > -    void *map_data = NULL;
> > +    int ret;
> >  
> >      if ( domid == DOMID_SELF && is_hvm_domain(d) && has_pirq(d) )
> >      {
> > @@ -119,135 +118,22 @@ int physdev_map_pirq(domid_t domid, int type, int 
> > *index, int *pirq_p,
> >      switch ( type )
> >      {
> >      case MAP_PIRQ_TYPE_GSI:
> > -        if ( *index < 0 || *index >= nr_irqs_gsi )
> > -        {
> > -            dprintk(XENLOG_G_ERR, "dom%d: map invalid irq %d\n",
> > -                    d->domain_id, *index);
> > -            ret = -EINVAL;
> > -            goto free_domain;
> > -        }
> > -
> > -        irq = domain_pirq_to_irq(current->domain, *index);
> > -        if ( irq <= 0 )
> > -        {
> > -            if ( is_hardware_domain(current->domain) )
> > -                irq = *index;
> > -            else {
> > -                dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect 
> > irq!\n",
> > -                        d->domain_id);
> > -                ret = -EINVAL;
> > -                goto free_domain;
> > -            }
> > -        }
> > +        ret = allocate_and_map_gsi_pirq(d, index, pirq_p);
> >          break;
> > -
> >      case MAP_PIRQ_TYPE_MSI:
> 
> Please don't delete the blank lines between case blocks, even if
> the blocks are much smaller now.

Fixed (and the one below).

Roger.

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

 


Rackspace

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