|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2] xen/passthrough: Support a single iommu_domain per xen domain per SMMU
Hello Julien,
On 3/23/2015 5:53 PM, Julien Grall wrote:
> Hello Robert,
>
> On 23/03/2015 13:46, Robbie VanVossen wrote:
>> @@ -2569,7 +2570,9 @@ static int arm_smmu_assign_dev(struct domain *d, u8
>> devfn,
>> {
>> struct iommu_domain *domain;
>> struct arm_smmu_xen_domain *xen_domain;
>> - int ret;
>> + struct arm_smmu_device *smmu;
>> + int ret = 0;
>> + int existing_ctxt_fnd = 0;
>
> You can use a bool_t here.
>
Ok.
>>
>> xen_domain = domain_hvm_iommu(d)->arch.priv;
>>
>> @@ -2585,36 +2588,77 @@ static int arm_smmu_assign_dev(struct domain *d, u8
>> devfn,
>> return ret;
>> }
>>
>> + spin_lock(&xen_domain->lock);
>> +
>> /*
>> - * TODO: Share the context bank (i.e iommu_domain) when the device is
>> - * under the same SMMU as another device assigned to this domain.
>> - * Would it useful for PCI
>> + * Check to see if a context bank (iommu_domain) already exists for
>> + * this xen domain under the same SMMU
>> */
>> - domain = xzalloc(struct iommu_domain);
>> - if (!domain)
>> - return -ENOMEM;
>> + if (!list_empty(&xen_domain->contexts)) {
>> + smmu = find_smmu_for_device(dev);
>> + if (!smmu) {
>> + dev_err(dev, "cannot find SMMU\n");
>> + ret = -ENXIO;
>> + goto out;
>> + }
>>
>> - ret = arm_smmu_domain_init(domain);
>> - if (ret)
>> - goto err_dom_init;
>> + /*
>> + * Loop through the &xen_domain->contexts to locate a context
>> + * assigned to this SMMU
>> + */
>> + list_for_each_entry(domain, &xen_domain->contexts, list) {
>> + if(domain->priv->smmu == smmu)
>> + {
>
> Coding style. This should be
> if (domain->priv->smmu == smmu) {
>
Will fix.
>> + /*
>> + * We have found a context already associated
>> with the
>> + * same xen domain and SMMU
>> + */
>> + ret = arm_smmu_attach_dev(domain, dev);
>> + if (ret) {
>> + dev_err(dev,
>> + "cannot attach device to
>> already existing iommu_domain\n");
>
> We don't print an error message for new domain, I don't think this one
> is useful.
>
Will remove dev_err.
>> + goto out;
>> + }
>> + atomic_inc(&domain->ref);
>
> Introducing an helper to get the iommu_domain would simply the workflow.
>
> That would give smth like:
>
> domain = arm_smmu_get_domain(d, dev);
> if (!domain)
> {
> allocate domain
> Add to list dev
> }
>
> arm_smmu_attach_dev(domain, dev);
> atomic_inc(&domain->ref);
>
> out:
> if (failed && atomic == 0)
> destroy iommu_domain.
>
> The destroy iommu_domain could be shared with the one in deassign_dev.
>
But don't we need to handle the failure of attach_dev differently based on which
fails? If the attach_dev fails on a new iommu_domain, then the iommu_domain
should be destroyed. If it fails on a preexisting iommu_domain that is already
attached to another device, then you don't want to destroy the iommu_domain.
>> +
>> + existing_ctxt_fnd = 1;
>> + break;
>> + }
>> + }
>> + }
>>
>> - domain->priv->cfg.domain = d;
>> + if(!existing_ctxt_fnd){
>>
>> - ret = arm_smmu_attach_dev(domain, dev);
>> - if (ret)
>> - goto err_attach_dev;
>> + domain = xzalloc(struct iommu_domain);
>> + if (!domain) {
>> + ret = -ENOMEM;
>> + goto out;
>> + }
>>
>> - spin_lock(&xen_domain->lock);
>> - /* Chain the new context to the domain */
>> - list_add(&domain->list, &xen_domain->contexts);
>> - spin_unlock(&xen_domain->lock);
>> + ret = arm_smmu_domain_init(domain);
>> + if (ret)
>> + goto err_dom_init;
>>
>> - return 0;
>> + domain->priv->cfg.domain = d;
>> +
>> + ret = arm_smmu_attach_dev(domain, dev);
>> + if (ret)
>> + goto err_attach_dev;
>> + atomic_inc(&domain->ref);
>> +
>> + /* Chain the new context to the domain */
>> + list_add(&domain->list, &xen_domain->contexts);
>> +
>> + }
>> +
>> + goto out;
>>
>> err_attach_dev:
>> arm_smmu_domain_destroy(domain);
>> err_dom_init:
>> xfree(domain);
>> +out:
>> + spin_unlock(&xen_domain->lock);
>>
>> return ret;
>> }
>> @@ -2631,14 +2675,20 @@ static int arm_smmu_deassign_dev(struct domain *d,
>> struct device *dev)
>> return -ESRCH;
>> }
>>
>> + spin_lock(&xen_domain->lock);
>> +
>> arm_smmu_detach_dev(domain, dev);
>> + atomic_dec(&domain->ref);
>>
>> - spin_lock(&xen_domain->lock);
>> - list_del(&domain->list);
>> - spin_unlock(&xen_domain->lock);
>> + if (domain->ref.counter == 0)
>> + {
>
> Coding style:
>
> if (...) {
>
Will Fix
Thanks,
Robbie VanVossen
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |