2024-02-21 06:18:51

by zhangfei

[permalink] [raw]
Subject: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain

The accelerator dev can provide multi-queue and bind to
the same domain in multi-thread for better performance,
and domain refcount takes care of it.

'commit 092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
removes the possibility, so fix it

Fixs: '092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
Signed-off-by: Zhangfei Gao <[email protected]>
---
drivers/iommu/iommu-sva.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index c3fc9201d0be..a95c8f3a5407 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -91,7 +91,7 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm
/* Search for an existing domain. */
list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next) {
ret = iommu_attach_device_pasid(domain, dev, iommu_mm->pasid);
- if (!ret) {
+ if (!ret || ret == -EBUSY) {
domain->users++;
goto out;
}
@@ -141,8 +141,8 @@ void iommu_sva_unbind_device(struct iommu_sva *handle)
struct device *dev = handle->dev;

mutex_lock(&iommu_sva_lock);
- iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
if (--domain->users == 0) {
+ iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
list_del(&domain->next);
iommu_domain_free(domain);
}
--
2.34.1



2024-02-21 07:11:20

by Tian, Kevin

[permalink] [raw]
Subject: RE: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain

> From: Zhangfei Gao <[email protected]>
> Sent: Wednesday, February 21, 2024 2:19 PM
>
> The accelerator dev can provide multi-queue and bind to
> the same domain in multi-thread for better performance,
> and domain refcount takes care of it.
>
> 'commit 092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> removes the possibility, so fix it
>
> Fixs: '092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> Signed-off-by: Zhangfei Gao <[email protected]>
> ---
> drivers/iommu/iommu-sva.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
> index c3fc9201d0be..a95c8f3a5407 100644
> --- a/drivers/iommu/iommu-sva.c
> +++ b/drivers/iommu/iommu-sva.c
> @@ -91,7 +91,7 @@ struct iommu_sva *iommu_sva_bind_device(struct
> device *dev, struct mm_struct *mm
> /* Search for an existing domain. */
> list_for_each_entry(domain, &mm->iommu_mm->sva_domains,
> next) {
> ret = iommu_attach_device_pasid(domain, dev, iommu_mm-
> >pasid);
> - if (!ret) {
> + if (!ret || ret == -EBUSY) {
> domain->users++;
> goto out;

-EBUSY is not a right indicator for reuse.

It may simply indicate that the pasid has been used for other purposes
e.g. attached to a domain different from what the caller expects here.

2024-02-21 07:57:40

by zhangfei

[permalink] [raw]
Subject: Re: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain

On Wed, 21 Feb 2024 at 15:09, Tian, Kevin <[email protected]> wrote:
>
> > From: Zhangfei Gao <[email protected]>
> > Sent: Wednesday, February 21, 2024 2:19 PM
> >
> > The accelerator dev can provide multi-queue and bind to
> > the same domain in multi-thread for better performance,
> > and domain refcount takes care of it.
> >
> > 'commit 092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> > removes the possibility, so fix it
> >
> > Fixs: '092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> > Signed-off-by: Zhangfei Gao <[email protected]>
> > ---
> > drivers/iommu/iommu-sva.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
> > index c3fc9201d0be..a95c8f3a5407 100644
> > --- a/drivers/iommu/iommu-sva.c
> > +++ b/drivers/iommu/iommu-sva.c
> > @@ -91,7 +91,7 @@ struct iommu_sva *iommu_sva_bind_device(struct
> > device *dev, struct mm_struct *mm
> > /* Search for an existing domain. */
> > list_for_each_entry(domain, &mm->iommu_mm->sva_domains,
> > next) {
> > ret = iommu_attach_device_pasid(domain, dev, iommu_mm-
> > >pasid);
> > - if (!ret) {
> > + if (!ret || ret == -EBUSY) {
> > domain->users++;
> > goto out;
>
> -EBUSY is not a right indicator for reuse.
>
> It may simply indicate that the pasid has been used for other purposes
> e.g. attached to a domain different from what the caller expects here.

Thanks Kevin.

How about this

diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index c3fc9201d0be..20b232c7675d 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -141,8 +141,8 @@ void iommu_sva_unbind_device(struct iommu_sva *handle)
struct device *dev = handle->dev;

mutex_lock(&iommu_sva_lock);
- iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
if (--domain->users == 0) {
+ iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
list_del(&domain->next);
iommu_domain_free(domain);
}

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d14413916f93..a16ade93db25 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3551,7 +3551,7 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
mutex_lock(&group->mutex);
curr = xa_cmpxchg(&group->pasid_array, pasid, NULL, domain, GFP_KERNEL);
if (curr) {
- ret = xa_err(curr) ? : -EBUSY;
+ ret = xa_err(curr) ? : 0;
goto out_unlock;
}

if pasid is already attached, does not treat as error,
and domain->user++ in iommu_sva_bind_device.

Thanks

2024-02-21 07:59:18

by Zhang, Tina

[permalink] [raw]
Subject: RE: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain

Hi,

> -----Original Message-----
> From: Zhangfei Gao <[email protected]>
> Sent: Wednesday, February 21, 2024 2:19 PM
> To: Joerg Roedel <[email protected]>; Will Deacon <[email protected]>; jean-
> philippe <[email protected]>; Jason Gunthorpe <[email protected]>;
> [email protected]; Zhang, Tina <[email protected]>
> Cc: [email protected]; [email protected]; Zhangfei Gao
> <[email protected]>
> Subject: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain
>
> The accelerator dev can provide multi-queue and bind to the same domain in
> multi-thread for better performance, and domain refcount takes care of it.
>
> 'commit 092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> removes the possibility, so fix it
>
> Fixs: '092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> Signed-off-by: Zhangfei Gao <[email protected]>
> ---
> drivers/iommu/iommu-sva.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c index
> c3fc9201d0be..a95c8f3a5407 100644
> --- a/drivers/iommu/iommu-sva.c
> +++ b/drivers/iommu/iommu-sva.c
> @@ -91,7 +91,7 @@ struct iommu_sva *iommu_sva_bind_device(struct
> device *dev, struct mm_struct *mm
> /* Search for an existing domain. */
> list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next)
> {
> ret = iommu_attach_device_pasid(domain, dev, iommu_mm-
> >pasid);
> - if (!ret) {
> + if (!ret || ret == -EBUSY) {
If rebinding is allowed, how could IOMMU core know if this invocation is intended (like the multi-thread case mentioned in the commit message) or is mistakenly invoked?

Thanks,
-Tina

> domain->users++;
> goto out;
> }
> @@ -141,8 +141,8 @@ void iommu_sva_unbind_device(struct iommu_sva
> *handle)
> struct device *dev = handle->dev;
>
> mutex_lock(&iommu_sva_lock);
> - iommu_detach_device_pasid(domain, dev, iommu_mm->pasid);
> if (--domain->users == 0) {
> + iommu_detach_device_pasid(domain, dev, iommu_mm-
> >pasid);
> list_del(&domain->next);
> iommu_domain_free(domain);
> }
> --
> 2.34.1


2024-02-21 08:43:13

by zhangfei

[permalink] [raw]
Subject: Re: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain

On Wed, 21 Feb 2024 at 15:59, Zhang, Tina <[email protected]> wrote:
>
> Hi,
>
> > -----Original Message-----
> > From: Zhangfei Gao <[email protected]>
> > Sent: Wednesday, February 21, 2024 2:19 PM
> > To: Joerg Roedel <[email protected]>; Will Deacon <[email protected]>; jean-
> > philippe <[email protected]>; Jason Gunthorpe <[email protected]>;
> > [email protected]; Zhang, Tina <[email protected]>
> > Cc: [email protected]; [email protected]; Zhangfei Gao
> > <[email protected]>
> > Subject: [PATCH] iommu: Fix iommu_sva_bind_device to the same domain
> >
> > The accelerator dev can provide multi-queue and bind to the same domain in
> > multi-thread for better performance, and domain refcount takes care of it.
> >
> > 'commit 092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> > removes the possibility, so fix it
> >
> > Fixs: '092edaddb660 ("iommu: Support mm PASID 1:n with sva domains")'
> > Signed-off-by: Zhangfei Gao <[email protected]>
> > ---
> > drivers/iommu/iommu-sva.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c index
> > c3fc9201d0be..a95c8f3a5407 100644
> > --- a/drivers/iommu/iommu-sva.c
> > +++ b/drivers/iommu/iommu-sva.c
> > @@ -91,7 +91,7 @@ struct iommu_sva *iommu_sva_bind_device(struct
> > device *dev, struct mm_struct *mm
> > /* Search for an existing domain. */
> > list_for_each_entry(domain, &mm->iommu_mm->sva_domains, next)
> > {
> > ret = iommu_attach_device_pasid(domain, dev, iommu_mm-
> > >pasid);
> > - if (!ret) {
> > + if (!ret || ret == -EBUSY) {
> If rebinding is allowed, how could IOMMU core know if this invocation is intended (like the multi-thread case mentioned in the commit message) or is mistakenly invoked?

I think it is the purpose of refcount, it should be no difference
whether same device or not.
Even different dev, IOMMU core can not make sure it is intended or
mistakenly invoked.

Add the limitation does not make sense.

Thanks