|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |