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

Re: [Xen-devel] [RFC PATCH 03/19] xen/arm: its: Port ITS driver to xen



Hi Julien,

On Fri, Mar 13, 2015 at 5:16 PM, Julien Grall <julien.grall@xxxxxxxxxx> wrote:
> Hello Vijay,
>
> On 02/03/2015 12:30, vijay.kilari@xxxxxxxxx wrote:
>>
>> @@ -228,10 +242,10 @@ static struct its_collection
>> *its_build_mapd_cmd(struct its_cmd_block *cmd,
>>                                                    struct its_cmd_desc
>> *desc)
>>   {
>>       unsigned long itt_addr;
>> -    u8 size = max(order_base_2(desc->its_mapd_cmd.dev->nr_ites), 1);
>> +    u8 size = max(fls(desc->its_mapd_cmd.dev->nr_ites) - 1, 1);
>
>
> You may want to give a look to get_count_order.
>
>>
>> -    itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
>> -    itt_addr = ALIGN(itt_addr, ITS_ITT_ALIGN);
>> +    itt_addr = __pa(desc->its_mapd_cmd.dev->itt);
>> +    itt_addr = ((itt_addr) + (ITS_ITT_ALIGN - 1)) & ~(ITS_ITT_ALIGN - 1);
>
>
> You can use ROUNDUP.
>
> [..]
>
>> @@ -343,17 +357,23 @@ static int its_queue_full(struct its_node *its)
>>   static struct its_cmd_block *its_allocate_entry(struct its_node *its)
>>   {
>>       struct its_cmd_block *cmd;
>> -    u32 count = 1000000;    /* 1s! */
>> +    bool_t timeout = 0;
>> +    s_time_t deadline = NOW() + MILLISECS(1000);
>>
>>       while (its_queue_full(its)) {
>> -        count--;
>> -        if (!count) {
>> -            pr_err_ratelimited("ITS queue not draining\n");
>> -            return NULL;
>> +       if ( NOW() > deadline )
>> +        {
>> +            timeout = 1;
>> +            break;
>>           }
>>           cpu_relax();
>>           udelay(1);
>>       }
>> +    if ( timeout )
>> +    {
>> +        its_err("ITS queue not draining\n");
>> +        return NULL;
>> +    }
>
>
> Why do you need to modify the loop? It looks like to me it will work Xen
> too.

I remember we used similar approach for GICv3.

>
>>   /*
>> - * irqchip functions - assumes MSI, mostly.
>> - */
>> -
>> -static void lpi_set_config(struct its_device *its_dev, u32 hwirq,
>> -               u32 id, int enable)
>> -{
>> -    u8 *cfg = page_address(gic_rdists->prop_page) + hwirq - 8192;
>> -
>> -    if (enable)
>> -        *cfg |= LPI_PROP_ENABLED;
>> -    else
>> -        *cfg &= ~LPI_PROP_ENABLED;
>> -
>> -    /*
>> -     * Make the above write visible to the redistributors.
>> -     * And yes, we're flushing exactly: One. Single. Byte.
>> -     * Humpf...
>> -     */
>> -    if (gic_rdists->flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING)
>> -        __flush_dcache_area(cfg, sizeof(*cfg));
>> -    else
>> -        dsb(ishst);
>> -    its_send_inv(its_dev, id);
>> -}
>> -
>> -static inline u16 its_msi_get_entry_nr(struct msi_desc *desc)
>> -{
>> -    return desc->msi_attrib.entry_nr;
>> -}
>> -
>> -static void its_mask_irq(struct irq_data *d)
>> -{
>> -    struct its_device *its_dev = irq_data_get_irq_handler_data(d);
>> -    u32 id;
>> -
>> -    /* If MSI, propagate the mask to the RC */
>> -    if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc) {
>> -        id = its_msi_get_entry_nr(d->msi_desc);
>> -        mask_msi_irq(d);
>> -    } else {
>> -        id = d->hwirq;
>> -    }
>> -
>> -    lpi_set_config(its_dev, d->hwirq, id, 0);
>> -}
>> -
>> -static void its_unmask_irq(struct irq_data *d)
>> -{
>> -    struct its_device *its_dev = irq_data_get_irq_handler_data(d);
>> -    u32 id;
>> -
>> -    /* If MSI, propagate the unmask to the RC */
>> -    if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc) {
>> -        id = its_msi_get_entry_nr(d->msi_desc);
>> -        unmask_msi_irq(d);
>> -    } else {
>> -        id = d->hwirq;
>> -    }
>> -
>> -    lpi_set_config(its_dev, d->hwirq, id, 1);
>> -}
>> -
>> -static void its_eoi_irq(struct irq_data *d)
>> -{
>> -    gic_write_eoir(d->hwirq);
>> -}
>> -
>> -static int its_set_affinity(struct irq_data *d, const struct cpumask
>> *mask_val,
>> -                            bool force)
>> -{
>> -    unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
>> -    struct its_device *its_dev = irq_data_get_irq_handler_data(d);
>> -    struct its_collection *target_col;
>> -    u32 id;
>> -
>> -    if (cpu >= nr_cpu_ids)
>> -        return -EINVAL;
>> -
>> -    target_col = &its_dev->its->collections[cpu];
>> -    if (IS_ENABLED(CONFIG_PCI_MSI) && d->msi_desc)
>> -        id = its_msi_get_entry_nr(d->msi_desc);
>> -    else
>> -        id = d->hwirq;
>> -    its_send_movi(its_dev, target_col, id);
>> -    its_dev->collection = target_col;
>> -
>> -    return IRQ_SET_MASK_OK;
>> -}
>> -
>> -static struct irq_chip its_irq_chip = {
>> -    .name            = "ITS",
>> -    .irq_mask        = its_mask_irq,
>> -    .irq_unmask        = its_unmask_irq,
>> -    .irq_eoi        = its_eoi_irq,
>> -    .irq_set_affinity    = its_set_affinity,
>> -};
>> -
>
>
> Most of those callbacks seems useful to me. Why did you drop them?

There is no irq_chip in xen. So thought of removing in completely and
adding as separate patch



>>
>> -
>> -
>> -static int its_msi_get_vec_count(struct pci_dev *pdev, struct msi_desc
>> *desc)
>> -{
>> -#ifdef CONFIG_PCI_MSI
>> -    if (desc->msi_attrib.is_msix)
>> -        return pci_msix_vec_count(pdev);
>> -    else
>> -        return pci_msi_vec_count(pdev);
>> -#else
>> -    return -EINVAL;
>> -#endif
>> -}
>> -
>> -int pci_requester_id(struct pci_dev *dev);
>> -static int its_msi_setup_irq(struct msi_chip *chip,
>> -                             struct pci_dev *pdev,
>> -                             struct msi_desc *desc)
>> -{
>> -    struct its_node *its = container_of(chip, struct its_node, msi_chip);
>> -    struct its_device *its_dev;
>> -    struct msi_msg msg;
>> -    unsigned int irq;
>> -    u64 addr;
>> -    int hwirq;
>> -    int err;
>> -    u32 dev_id = pci_requester_id(pdev);
>> -    u32 vec_nr;
>> -
>> -    its_dev = its_find_device(its, dev_id);
>> -    if (!its_dev) {
>> -        int nvec = its_msi_get_vec_count(pdev, desc);
>> -        if (WARN_ON(nvec <= 0))
>> -            return nvec;
>> -        its_dev = its_create_device(its, dev_id, nvec);
>> -    }
>> -    if (!its_dev)
>> -        return -ENOMEM;
>> -    vec_nr = its_msi_get_entry_nr(desc);
>> -    err = its_alloc_device_irq(its_dev, vec_nr, &hwirq, &irq);
>> -    if (err)
>> -        return err;
>> -
>> -    irq_set_msi_desc(irq, desc);
>> -    irq_set_handler_data(irq, its_dev);
>> -
>> -    addr = its->phys_base + GITS_TRANSLATER;
>> -
>> -    msg.address_lo        = (u32)addr;
>> -    msg.address_hi        = (u32)(addr >> 32);
>> -    msg.data        = vec_nr;
>> -
>> -    write_msi_msg(irq, &msg);
>> -    return 0;
>> -}
>> -
>> -static void its_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
>> -{
>> -    struct irq_data *d = irq_get_irq_data(irq);
>> -    struct its_device *its_dev = irq_data_get_irq_handler_data(d);
>> -
>> -    BUG_ON(d->hwirq < its_dev->lpi_base ||        /* OMG! */
>> -           d->hwirq > (its_dev->lpi_base + its_dev->nr_lpis));
>> -
>> -    /* Stop the delivery of interrupts */
>> -    its_send_discard(its_dev, its_msi_get_entry_nr(d->msi_desc));
>> -
>> -    /* Mark interrupt index as unused, and clear the mapping */
>> -    clear_bit(d->hwirq - its_dev->lpi_base, its_dev->lpi_map);
>> -    irq_dispose_mapping(irq);
>> -
>> -    /* If all interrupts have been freed, start mopping the floor */
>> -    if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) {
>> -        its_lpi_free(its_dev->lpi_map,
>> -                     its_dev->lpi_base,
>> -                     its_dev->nr_lpis);
>> -
>> -        /* Unmap device/itt */
>> -        its_send_mapd(its_dev, 0);
>> -        its_free_device(its_dev);
>> -    }
>> -}
>> -
>
>
> Those 2 functions seems useful for me. Why did you drop them?

These are callbacks registered for msi_chip in linux, Since we have removed
msi_chip from its_node structure, these functions are supposed to be removed.

Regards
Vijay

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