iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* tegra alloc_pdir
@ 2012-06-26 18:15 Chris Wright
       [not found] ` <20120626181555.GW15796-JyIX8gxvWYPr2PDY2+4mTGD2FQJk+8+b@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Wright @ 2012-06-26 18:15 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA

This looks buggy to me:

drivers/iommu/tegra-smmu.c::smmu_iommu_domain_init()

  spin_lock_irqsave(&tmp->lock, flags);   <-- lock held, interrupts off
  alloc_pdir(as = tmp)
    devm_kzalloc(..., GFP_KERNEL);        <-- potentially sleeping allocation
    ...
    alloc_page(..., GFP_KERNEL | __GFP_DMA);   <-- same here

thanks,
-chris

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: tegra alloc_pdir
       [not found] ` <20120626181555.GW15796-JyIX8gxvWYPr2PDY2+4mTGD2FQJk+8+b@public.gmane.org>
@ 2012-06-27  9:46   ` Hiroshi Doyu
       [not found]     ` <20120627.124628.673793050413876363.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-06-27  9:46 UTC (permalink / raw)
  To: chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

Hi Chris,

Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org> wrote @ Tue, 26 Jun 2012 20:15:55 +0200:

> This looks buggy to me:
> 
> drivers/iommu/tegra-smmu.c::smmu_iommu_domain_init()
> 
>   spin_lock_irqsave(&tmp->lock, flags);   <-- lock held, interrupts off
>   alloc_pdir(as = tmp)
>     devm_kzalloc(..., GFP_KERNEL);        <-- potentially sleeping allocation
>     ...
>     alloc_page(..., GFP_KERNEL | __GFP_DMA);   <-- same here

Right. I totally agree. Thank you for pointing this out.

The fix patch follows.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]     ` <20120627.124628.673793050413876363.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-27  9:54       ` Hiroshi DOYU
       [not found]         ` <1340790841-23349-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi DOYU @ 2012-06-27  9:54 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA

allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
held. memory allocations in it have to be atomic/unsleepable.

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
---
 drivers/iommu/tegra-smmu.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ecd6790..3f3d09d 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as)
 		return 0;
 
 	as->pte_count = devm_kzalloc(smmu->dev,
-		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
+		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC);
 	if (!as->pte_count) {
 		dev_err(smmu->dev,
 			"failed to allocate smmu_device PTE cunters\n");
 		return -ENOMEM;
 	}
-	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
+	as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA);
 	if (!as->pdir_page) {
 		dev_err(smmu->dev,
 			"failed to allocate smmu_device page directory\n");
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]         ` <1340790841-23349-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-27 15:57           ` Chris Wright
  2012-06-27 16:59           ` Stephen Warren
  2012-07-02  9:57           ` [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation Joerg Roedel
  2 siblings, 0 replies; 19+ messages in thread
From: Chris Wright @ 2012-06-27 15:57 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA

* Hiroshi DOYU (hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org) wrote:
> allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> held. memory allocations in it have to be atomic/unsleepable.
> 
> Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>

Acked-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]         ` <1340790841-23349-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2012-06-27 15:57           ` Chris Wright
@ 2012-06-27 16:59           ` Stephen Warren
       [not found]             ` <4FEB3C04.6040606-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-07-02  9:57           ` [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation Joerg Roedel
  2 siblings, 1 reply; 19+ messages in thread
From: Stephen Warren @ 2012-06-27 16:59 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On 06/27/2012 03:54 AM, Hiroshi DOYU wrote:
> allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> held. memory allocations in it have to be atomic/unsleepable.

Presumably this will cause allocation failures in situations with heavy
memory pressure, rather than triggering swapping. Is it normal for IOMMU
drivers to work that way? If so, I'm fine with it. Otherwise, can the
allocations be performed before the spinlock is taken?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]             ` <4FEB3C04.6040606-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-06-28 10:42               ` Hiroshi Doyu
       [not found]                 ` <20120628134202.2102f715496a3b980b43f3b0-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-06-28 10:42 UTC (permalink / raw)
  To: Stephen Warren, Chris Wright
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org

On Wed, 27 Jun 2012 18:59:48 +0200
Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:

> On 06/27/2012 03:54 AM, Hiroshi DOYU wrote:
> > allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> > held. memory allocations in it have to be atomic/unsleepable.
> 
> Presumably this will cause allocation failures in situations with heavy
> memory pressure, rather than triggering swapping. Is it normal for IOMMU
> drivers to work that way? If so, I'm fine with it. Otherwise, can the
> allocations be performed before the spinlock is taken?

There are some requirement for atomic allocation from DMA mapping API,
but it's not normla for IOMMU, especiall not for
iommu_domain_alloc(). It has already used GFP_KERNEL and then, calls
->iommu_domain_init() in it.

The update patch v2 follows.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                 ` <20120628134202.2102f715496a3b980b43f3b0-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-28 10:51                   ` Hiroshi DOYU
       [not found]                     ` <1340880707-6934-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi DOYU @ 2012-06-28 10:51 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Chris Wright, Stephen Warren

alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
held. memory allocations in alloc_pdir() had to be
atomic/unsleepable. Instead of converting into atomic allocation, this
patch once releases a lock, do the allocation, hold the lock again and
then see if it's raced or not in order to avoid introducing mutex.

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
Cc: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
Cc: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
---
 drivers/iommu/tegra-smmu.c |   49 +++++++++++++++++++++++++++++--------------
 1 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ecd6790..ec656ec 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -539,31 +539,42 @@ static inline void put_signature(struct smmu_as *as,
 /*
  * Caller must lock/unlock as
  */
-static int alloc_pdir(struct smmu_as *as)
+static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
 {
 	unsigned long *pdir;
-	int pdn;
+	int pdn, err = 0;
 	u32 val;
 	struct smmu_device *smmu = as->smmu;
+	struct page *page;
+	unsigned int *cnt;
 
 	if (as->pdir_page)
 		return 0;
 
-	as->pte_count = devm_kzalloc(smmu->dev,
-		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
-	if (!as->pte_count) {
-		dev_err(smmu->dev,
-			"failed to allocate smmu_device PTE cunters\n");
-		return -ENOMEM;
+	/*
+	 * do the allocation outside the as lock
+	 */
+	spin_unlock_irqrestore(&as->lock, *flags);
+	cnt = devm_kzalloc(smmu->dev,
+			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
+	page = alloc_page(GFP_KERNEL | __GFP_DMA);
+	spin_lock_irqsave(&as->lock, *flags);
+
+	if (as->pdir_page) {
+		/* We raced, free the redundant */
+		err = -ENODEV;
+		goto err_out;
 	}
-	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
-	if (!as->pdir_page) {
-		dev_err(smmu->dev,
-			"failed to allocate smmu_device page directory\n");
-		devm_kfree(smmu->dev, as->pte_count);
-		as->pte_count = NULL;
-		return -ENOMEM;
+
+	if (!page || !cnt) {
+		dev_err(smmu->dev, "failed to allocate at %s\n", __func__);
+		err = -ENOMEM;
+		goto err_out;
 	}
+
+	as->pdir_page = page;
+	as->pte_count = cnt;
+
 	SetPageReserved(as->pdir_page);
 	pdir = page_address(as->pdir_page);
 
@@ -580,6 +591,12 @@ static int alloc_pdir(struct smmu_as *as)
 	FLUSH_SMMU_REGS(as->smmu);
 
 	return 0;
+
+err_out:
+	devm_kfree(smmu->dev, cnt);
+	if (page)
+		__free_page(page);
+	return err;
 }
 
 static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova)
@@ -791,7 +808,7 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
 	return -ENODEV;
 
 found:
-	if (alloc_pdir(as) < 0)
+	if (alloc_pdir(as, &flags) < 0)
 		goto err_alloc_pdir;
 
 	spin_lock(&smmu->lock);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                     ` <1340880707-6934-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-28 16:57                       ` Stephen Warren
       [not found]                         ` <4FEC8CEE.1000401-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Warren @ 2012-06-28 16:57 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Chris Wright

On 06/28/2012 04:51 AM, Hiroshi DOYU wrote:
> alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
> held. memory allocations in alloc_pdir() had to be
> atomic/unsleepable. Instead of converting into atomic allocation, this
> patch once releases a lock, do the allocation, hold the lock again and
> then see if it's raced or not in order to avoid introducing mutex.

> ---

You'd typically want to include a brief description of what changed from
v1->v2 here, as a hint to reviewers re: what to concentrate on.

> +static int alloc_pdir(struct smmu_as *as, unsigned long *flags)

> +	spin_unlock_irqrestore(&as->lock, *flags);
> +	cnt = devm_kzalloc(smmu->dev,
> +			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> +	page = alloc_page(GFP_KERNEL | __GFP_DMA);
> +	spin_lock_irqsave(&as->lock, *flags);
> +
> +	if (as->pdir_page) {
> +		/* We raced, free the redundant */
> +		err = -ENODEV;
> +		goto err_out;
>  	}

Is that really an error; it just means that something else allocated the
same pdir already. Since the top of the function does:

 	if (as->pdir_page)
 		return 0;

I'd expect to s/err = -ENODEV/err = 0/ inside that if condition that I
quoted above, but still of cause "goto err_out" to free the now unneeded
allocations.

Aside from that, I think this looks reasonable.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                         ` <4FEC8CEE.1000401-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-06-28 18:35                           ` Hiroshi Doyu
       [not found]                             ` <20120628.213554.1189327754979133382.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-06-28 18:35 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org

Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote @ Thu, 28 Jun 2012 18:57:18 +0200:

> On 06/28/2012 04:51 AM, Hiroshi DOYU wrote:
> > alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
> > held. memory allocations in alloc_pdir() had to be
> > atomic/unsleepable. Instead of converting into atomic allocation, this
> > patch once releases a lock, do the allocation, hold the lock again and
> > then see if it's raced or not in order to avoid introducing mutex.
> 
> > ---
> 
> You'd typically want to include a brief description of what changed from
> v1->v2 here, as a hint to reviewers re: what to concentrate on.

Ok, I'll.

> > +static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
> 
> > +	spin_unlock_irqrestore(&as->lock, *flags);
> > +	cnt = devm_kzalloc(smmu->dev,
> > +			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> > +	page = alloc_page(GFP_KERNEL | __GFP_DMA);
> > +	spin_lock_irqsave(&as->lock, *flags);
> > +
> > +	if (as->pdir_page) {
> > +		/* We raced, free the redundant */
> > +		err = -ENODEV;
> > +		goto err_out;
> >  	}
> 
> Is that really an error; it just means that something else allocated the
> same pdir already. Since the top of the function does:
> 
>  	if (as->pdir_page)
>  		return 0;
> 
> I'd expect to s/err = -ENODEV/err = 0/ inside that if condition that I
> quoted above, but still of cause "goto err_out" to free the now unneeded
> allocations.
> 
> Aside from that, I think this looks reasonable.

I think that, in the case of race condition, the one which comes
later, should retry with the another ASID, which is incremented as
below. So I modified that the latter one returns with -EAGAIN, and try
with another ASID.

The complete patch follows this mail.

Changes:
	Modified drivers/iommu/tegra-smmu.c
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ec656ec..f2c18fa 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -562,7 +562,7 @@ static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
 
 	if (as->pdir_page) {
 		/* We raced, free the redundant */
-		err = -ENODEV;
+		err = -EAGAIN;
 		goto err_out;
 	}
 
@@ -799,8 +799,15 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
 
 		spin_lock_irqsave(&tmp->lock, flags);
 		if (!tmp->pdir_page) {
-			as = tmp;
-			goto found;
+			int err;
+
+			err = alloc_pdir(tmp, &flags);
+			if (!err) {
+				as = tmp;
+				goto found;
+			}
+			if (err == -EAGAIN)
+				continue;
 		}
 		spin_unlock_irqrestore(&tmp->lock, flags);
 	}
@@ -808,9 +815,6 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
 	return -ENODEV;
 
 found:
-	if (alloc_pdir(as, &flags) < 0)
-		goto err_alloc_pdir;
-
 	spin_lock(&smmu->lock);
 
 	/* Update PDIR register */
@@ -826,10 +830,6 @@ found:
 
 	dev_dbg(smmu->dev, "smmu_as@%p\n", as);
 	return 0;
-
-err_alloc_pdir:
-	spin_unlock_irqrestore(&as->lock, flags);
-	return -ENODEV;
 }
 
 static void smmu_iommu_domain_destroy(struct iommu_domain *domain)

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                             ` <20120628.213554.1189327754979133382.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-28 19:08                               ` Stephen Warren
       [not found]                                 ` <4FECAB9C.9040809-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Stephen Warren @ 2012-06-28 19:08 UTC (permalink / raw)
  To: Hiroshi Doyu
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org

On 06/28/2012 12:35 PM, Hiroshi Doyu wrote:
> Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote @ Thu, 28 Jun 2012 18:57:18 +0200:
>> On 06/28/2012 04:51 AM, Hiroshi DOYU wrote:
>>> alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
>>> held. memory allocations in alloc_pdir() had to be
>>> atomic/unsleepable. Instead of converting into atomic allocation, this
>>> patch once releases a lock, do the allocation, hold the lock again and
>>> then see if it's raced or not in order to avoid introducing mutex.

>>> +static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
>>
>>> +	spin_unlock_irqrestore(&as->lock, *flags);
>>> +	cnt = devm_kzalloc(smmu->dev,
>>> +			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
>>> +	page = alloc_page(GFP_KERNEL | __GFP_DMA);
>>> +	spin_lock_irqsave(&as->lock, *flags);
>>> +
>>> +	if (as->pdir_page) {
>>> +		/* We raced, free the redundant */
>>> +		err = -ENODEV;
>>> +		goto err_out;
>>>  	}
>>
>> Is that really an error; it just means that something else allocated the
>> same pdir already. Since the top of the function does:
>>
>>  	if (as->pdir_page)
>>  		return 0;
>>
>> I'd expect to s/err = -ENODEV/err = 0/ inside that if condition that I
>> quoted above, but still of cause "goto err_out" to free the now unneeded
>> allocations.
>>
>> Aside from that, I think this looks reasonable.
> 
> I think that, in the case of race condition, the one which comes
> later, should retry with the another ASID, which is incremented as
> below. So I modified that the latter one returns with -EAGAIN, and try
> with another ASID.
> 
> The complete patch follows this mail.

incremental rather than complete, right?

> 
> Changes:
> 	Modified drivers/iommu/tegra-smmu.c
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> index ec656ec..f2c18fa 100644
> --- a/drivers/iommu/tegra-smmu.c
> +++ b/drivers/iommu/tegra-smmu.c
> @@ -562,7 +562,7 @@ static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
>  
>  	if (as->pdir_page) {
>  		/* We raced, free the redundant */
> -		err = -ENODEV;
> +		err = -EAGAIN;
>  		goto err_out;
>  	}
>  
> @@ -799,8 +799,15 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
>  
>  		spin_lock_irqsave(&tmp->lock, flags);
>  		if (!tmp->pdir_page) {
> -			as = tmp;
> -			goto found;
> +			int err;
> +
> +			err = alloc_pdir(tmp, &flags);
> +			if (!err) {
> +				as = tmp;
> +				goto found;
> +			}
> +			if (err == -EAGAIN)
> +				continue;

That loop is going to continue anyway, since that code is right at the
end of the loop. Don't you want to replace that if block with:

if (err != -EAGAIN)
    goto err_alloc_pdir;

?

Also, the first thinig that alloc_pdir does is:

        if (as->pdir_page)
                return 0;

It seems that should be removed completely, right? Since having the
pdir_page already allocated is an error.

>  		}
>  		spin_unlock_irqrestore(&tmp->lock, flags);
>  	}
> @@ -808,9 +815,6 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
>  	return -ENODEV;
>  
>  found:
> -	if (alloc_pdir(as, &flags) < 0)
> -		goto err_alloc_pdir;
> -
>  	spin_lock(&smmu->lock);
>  
>  	/* Update PDIR register */
> @@ -826,10 +830,6 @@ found:
>  
>  	dev_dbg(smmu->dev, "smmu_as@%p\n", as);
>  	return 0;
> -
> -err_alloc_pdir:
> -	spin_unlock_irqrestore(&as->lock, flags);
> -	return -ENODEV;
>  }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                                 ` <4FECAB9C.9040809-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-06-28 19:19                                   ` Hiroshi Doyu
       [not found]                                     ` <20120628.221945.1306825810095951985.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-06-28 19:19 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org

Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote @ Thu, 28 Jun 2012 21:08:12 +0200:

> On 06/28/2012 12:35 PM, Hiroshi Doyu wrote:
> > Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote @ Thu, 28 Jun 2012 18:57:18 +0200:
> >> On 06/28/2012 04:51 AM, Hiroshi DOYU wrote:
> >>> alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
> >>> held. memory allocations in alloc_pdir() had to be
> >>> atomic/unsleepable. Instead of converting into atomic allocation, this
> >>> patch once releases a lock, do the allocation, hold the lock again and
> >>> then see if it's raced or not in order to avoid introducing mutex.
> 
> >>> +static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
> >>
> >>> +	spin_unlock_irqrestore(&as->lock, *flags);
> >>> +	cnt = devm_kzalloc(smmu->dev,
> >>> +			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> >>> +	page = alloc_page(GFP_KERNEL | __GFP_DMA);
> >>> +	spin_lock_irqsave(&as->lock, *flags);
> >>> +
> >>> +	if (as->pdir_page) {
> >>> +		/* We raced, free the redundant */
> >>> +		err = -ENODEV;
> >>> +		goto err_out;
> >>>  	}
> >>
> >> Is that really an error; it just means that something else allocated the
> >> same pdir already. Since the top of the function does:
> >>
> >>  	if (as->pdir_page)
> >>  		return 0;
> >>
> >> I'd expect to s/err = -ENODEV/err = 0/ inside that if condition that I
> >> quoted above, but still of cause "goto err_out" to free the now unneeded
> >> allocations.
> >>
> >> Aside from that, I think this looks reasonable.
> > 
> > I think that, in the case of race condition, the one which comes
> > later, should retry with the another ASID, which is incremented as
> > below. So I modified that the latter one returns with -EAGAIN, and try
> > with another ASID.
> > 
> > The complete patch follows this mail.
> 
> incremental rather than complete, right?

Actually I was working on it.

> > Changes:
> > 	Modified drivers/iommu/tegra-smmu.c
> > diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> > index ec656ec..f2c18fa 100644
> > --- a/drivers/iommu/tegra-smmu.c
> > +++ b/drivers/iommu/tegra-smmu.c
> > @@ -562,7 +562,7 @@ static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
> >  
> >  	if (as->pdir_page) {
> >  		/* We raced, free the redundant */
> > -		err = -ENODEV;
> > +		err = -EAGAIN;
> >  		goto err_out;
> >  	}
> >  
> > @@ -799,8 +799,15 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain)
> >  
> >  		spin_lock_irqsave(&tmp->lock, flags);
> >  		if (!tmp->pdir_page) {
> > -			as = tmp;
> > -			goto found;
> > +			int err;
> > +
> > +			err = alloc_pdir(tmp, &flags);
> > +			if (!err) {
> > +				as = tmp;
> > +				goto found;
> > +			}
> > +			if (err == -EAGAIN)
> > +				continue;
> 
> That loop is going to continue anyway, since that code is right at the
> end of the loop. Don't you want to replace that if block with:
> 
> if (err != -EAGAIN)
>     goto err_alloc_pdir;
> 
> ?

Yes, I also found. I'll send the update one tomorrow.

> Also, the first thinig that alloc_pdir does is:
> 
>         if (as->pdir_page)
>                 return 0;
> 
> It seems that should be removed completely, right? Since having the
> pdir_page already allocated is an error.

Yes. I thought that could be another patch. Same for the original code.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [v3 1/2] iommu/tegra: smmu: Remove unnecessary sanity check at alloc_pdir()
       [not found]                                     ` <20120628.221945.1306825810095951985.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-29  6:15                                       ` Hiroshi DOYU
       [not found]                                         ` <1340950527-16482-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi DOYU @ 2012-06-29  6:15 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi DOYU, Stephen Warren

alloc_pdir() is called with smmu->as[?].pdir_page == NULL. No need to
check pdir_page again inside alloc_pdir().

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
---
 drivers/iommu/tegra-smmu.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ecd6790..532c8a4 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -546,9 +546,6 @@ static int alloc_pdir(struct smmu_as *as)
 	u32 val;
 	struct smmu_device *smmu = as->smmu;
 
-	if (as->pdir_page)
-		return 0;
-
 	as->pte_count = devm_kzalloc(smmu->dev,
 		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
 	if (!as->pte_count) {
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [v3 2/2] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()
       [not found]                                         ` <1340950527-16482-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-06-29  6:15                                           ` Hiroshi DOYU
  2012-06-29 15:34                                           ` [v3 1/2] iommu/tegra: smmu: Remove unnecessary sanity check " Stephen Warren
  1 sibling, 0 replies; 19+ messages in thread
From: Hiroshi DOYU @ 2012-06-29  6:15 UTC (permalink / raw)
  To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Chris Wright, Stephen Warren

alloc_pdir() is called from smmu_iommu_domain_init() with spin_lock
held. memory allocations in alloc_pdir() had to be atomic. Instead of
converting into atomic allocation, this patch once releases a lock,
does the allocation, holds the lock again and then sees if it's raced
or not in order to avoid introducing mutex and preallocation.

Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
Cc: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
Cc: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
---
v3:
Added -EAGAIN in alloc_pdir when raced to retry.
---
 drivers/iommu/tegra-smmu.c |   77 +++++++++++++++++++++++++------------------
 1 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 532c8a4..dbba94c 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -539,28 +539,39 @@ static inline void put_signature(struct smmu_as *as,
 /*
  * Caller must lock/unlock as
  */
-static int alloc_pdir(struct smmu_as *as)
+static int alloc_pdir(struct smmu_as *as, unsigned long *flags)
 {
 	unsigned long *pdir;
-	int pdn;
+	int pdn, err = 0;
 	u32 val;
 	struct smmu_device *smmu = as->smmu;
+	struct page *page;
+	unsigned int *cnt;
 
-	as->pte_count = devm_kzalloc(smmu->dev,
-		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
-	if (!as->pte_count) {
-		dev_err(smmu->dev,
-			"failed to allocate smmu_device PTE cunters\n");
-		return -ENOMEM;
+	/*
+	 * do the allocation outside the as lock
+	 */
+	spin_unlock_irqrestore(&as->lock, *flags);
+	cnt = devm_kzalloc(smmu->dev,
+			   sizeof(cnt[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
+	page = alloc_page(GFP_KERNEL | __GFP_DMA);
+	spin_lock_irqsave(&as->lock, *flags);
+
+	if (as->pdir_page) {
+		/* We raced, free the redundant */
+		err = -EAGAIN;
+		goto err_out;
 	}
-	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
-	if (!as->pdir_page) {
-		dev_err(smmu->dev,
-			"failed to allocate smmu_device page directory\n");
-		devm_kfree(smmu->dev, as->pte_count);
-		as->pte_count = NULL;
-		return -ENOMEM;
+
+	if (!page || !cnt) {
+		dev_err(smmu->dev, "failed to allocate at %s\n", __func__);
+		err = -ENOMEM;
+		goto err_out;
 	}
+
+	as->pdir_page = page;
+	as->pte_count = cnt;
+
 	SetPageReserved(as->pdir_page);
 	pdir = page_address(as->pdir_page);
 
@@ -577,6 +588,12 @@ static int alloc_pdir(struct smmu_as *as)
 	FLUSH_SMMU_REGS(as->smmu);
 
 	return 0;
+
+err_out:
+	devm_kfree(smmu->dev, cnt);
+	if (page)
+		__free_page(page);
+	return err;
 }
 
 static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova)
@@ -768,29 +785,29 @@ out:
 
 static int smmu_iommu_domain_init(struct iommu_domain *domain)
 {
-	int i;
+	int i, err = -ENODEV;
 	unsigned long flags;
 	struct smmu_as *as;
 	struct smmu_device *smmu = smmu_handle;
 
 	/* Look for a free AS with lock held */
 	for  (i = 0; i < smmu->num_as; i++) {
-		struct smmu_as *tmp = &smmu->as[i];
-
-		spin_lock_irqsave(&tmp->lock, flags);
-		if (!tmp->pdir_page) {
-			as = tmp;
-			goto found;
+		as = &smmu->as[i];
+		spin_lock_irqsave(&as->lock, flags);
+		if (!as->pdir_page) {
+			err = alloc_pdir(as, &flags);
+			if (!err)
+				goto found;
 		}
-		spin_unlock_irqrestore(&tmp->lock, flags);
+		spin_unlock_irqrestore(&as->lock, flags);
+		if (err != -EAGAIN)
+			break;
 	}
-	dev_err(smmu->dev, "no free AS\n");
-	return -ENODEV;
+	if (i == smmu->num_as)
+		dev_err(smmu->dev,  "no free AS\n");
+	return err;
 
 found:
-	if (alloc_pdir(as) < 0)
-		goto err_alloc_pdir;
-
 	spin_lock(&smmu->lock);
 
 	/* Update PDIR register */
@@ -806,10 +823,6 @@ found:
 
 	dev_dbg(smmu->dev, "smmu_as@%p\n", as);
 	return 0;
-
-err_alloc_pdir:
-	spin_unlock_irqrestore(&as->lock, flags);
-	return -ENODEV;
 }
 
 static void smmu_iommu_domain_destroy(struct iommu_domain *domain)
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [v3 1/2] iommu/tegra: smmu: Remove unnecessary sanity check at alloc_pdir()
       [not found]                                         ` <1340950527-16482-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2012-06-29  6:15                                           ` [v3 2/2] iommu/tegra: smmu: Fix unsleepable memory allocation " Hiroshi DOYU
@ 2012-06-29 15:34                                           ` Stephen Warren
  1 sibling, 0 replies; 19+ messages in thread
From: Stephen Warren @ 2012-06-29 15:34 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA

On 06/29/2012 12:15 AM, Hiroshi DOYU wrote:
> alloc_pdir() is called with smmu->as[?].pdir_page == NULL. No need to
> check pdir_page again inside alloc_pdir().

Both patches,
Acked-by: Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]         ` <1340790841-23349-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2012-06-27 15:57           ` Chris Wright
  2012-06-27 16:59           ` Stephen Warren
@ 2012-07-02  9:57           ` Joerg Roedel
       [not found]             ` <20120702095747.GB2558-5C7GfCeVMHo@public.gmane.org>
  2 siblings, 1 reply; 19+ messages in thread
From: Joerg Roedel @ 2012-07-02  9:57 UTC (permalink / raw)
  To: Hiroshi DOYU
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Wed, Jun 27, 2012 at 12:54:01PM +0300, Hiroshi DOYU wrote:
> allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> held. memory allocations in it have to be atomic/unsleepable.
> 
> Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
> ---
>  drivers/iommu/tegra-smmu.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> index ecd6790..3f3d09d 100644
> --- a/drivers/iommu/tegra-smmu.c
> +++ b/drivers/iommu/tegra-smmu.c
> @@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as)
>  		return 0;
>  
>  	as->pte_count = devm_kzalloc(smmu->dev,
> -		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> +		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC);
>  	if (!as->pte_count) {
>  		dev_err(smmu->dev,
>  			"failed to allocate smmu_device PTE cunters\n");
>  		return -ENOMEM;
>  	}
> -	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
> +	as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA);
>  	if (!as->pdir_page) {
>  		dev_err(smmu->dev,
>  			"failed to allocate smmu_device page directory\n");

Okay, I queued this one for v3.5. It is small enough so that it counts
as a fix. The other two patches are 3.6 stuff.


	Joerg

-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]             ` <20120702095747.GB2558-5C7GfCeVMHo@public.gmane.org>
@ 2012-07-02 10:13               ` Hiroshi Doyu
       [not found]                 ` <20120702.131326.685361720133451299.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-07-02 10:13 UTC (permalink / raw)
  To: joerg.roedel-5C7GfCeVMHo@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

Hi Joerg,

Joerg Roedel <joerg.roedel-5C7GfCeVMHo@public.gmane.org> wrote @ Mon, 2 Jul 2012 11:57:47 +0200:

> On Wed, Jun 27, 2012 at 12:54:01PM +0300, Hiroshi DOYU wrote:
> > allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> > held. memory allocations in it have to be atomic/unsleepable.
> > 
> > Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
> > ---
> >  drivers/iommu/tegra-smmu.c |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> > index ecd6790..3f3d09d 100644
> > --- a/drivers/iommu/tegra-smmu.c
> > +++ b/drivers/iommu/tegra-smmu.c
> > @@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as)
> >  		return 0;
> >  
> >  	as->pte_count = devm_kzalloc(smmu->dev,
> > -		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> > +		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC);
> >  	if (!as->pte_count) {
> >  		dev_err(smmu->dev,
> >  			"failed to allocate smmu_device PTE cunters\n");
> >  		return -ENOMEM;
> >  	}
> > -	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
> > +	as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA);
> >  	if (!as->pdir_page) {
> >  		dev_err(smmu->dev,
> >  			"failed to allocate smmu_device page directory\n");
> 
> Okay, I queued this one for v3.5. It is small enough so that it counts
> as a fix. The other two patches are 3.6 stuff.

The other 2 patehs are the replacement of this one. They are
exclusive. Both of them are basically for the same fix.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]                 ` <20120702.131326.685361720133451299.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-07-02 10:19                   ` Hiroshi Doyu
       [not found]                     ` <20120702.131903.1053229523265080291.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Hiroshi Doyu @ 2012-07-02 10:19 UTC (permalink / raw)
  To: joerg.roedel-5C7GfCeVMHo@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote @ Mon, 2 Jul 2012 12:13:26 +0200:

> Hi Joerg,
> 
> Joerg Roedel <joerg.roedel-5C7GfCeVMHo@public.gmane.org> wrote @ Mon, 2 Jul 2012 11:57:47 +0200:
> 
> > On Wed, Jun 27, 2012 at 12:54:01PM +0300, Hiroshi DOYU wrote:
> > > allo_pdir() is called in smmu_iommu_domain_init() with spin_lock
> > > held. memory allocations in it have to be atomic/unsleepable.
> > > 
> > > Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > > Reported-by: Chris Wright <chrisw-69jw2NvuJkxg9hUCZPvPmw@public.gmane.org>
> > > ---
> > >  drivers/iommu/tegra-smmu.c |    4 ++--
> > >  1 files changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> > > index ecd6790..3f3d09d 100644
> > > --- a/drivers/iommu/tegra-smmu.c
> > > +++ b/drivers/iommu/tegra-smmu.c
> > > @@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as)
> > >  		return 0;
> > >  
> > >  	as->pte_count = devm_kzalloc(smmu->dev,
> > > -		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
> > > +		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC);
> > >  	if (!as->pte_count) {
> > >  		dev_err(smmu->dev,
> > >  			"failed to allocate smmu_device PTE cunters\n");
> > >  		return -ENOMEM;
> > >  	}
> > > -	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
> > > +	as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA);
> > >  	if (!as->pdir_page) {
> > >  		dev_err(smmu->dev,
> > >  			"failed to allocate smmu_device page directory\n");
> > 
> > Okay, I queued this one for v3.5. It is small enough so that it counts
> > as a fix. The other two patches are 3.6 stuff.
> 
> The other 2 patehs are the replacement of this one. They are
> exclusive. Both of them are basically for the same fix.

I might not get your point. If you plan to take the this(the original)
as immediate fix for v3.5  you need tok take the others for v3.6 after
*reverting* the original. This would also work.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]                     ` <20120702.131903.1053229523265080291.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-07-02 10:42                       ` joerg.roedel-5C7GfCeVMHo
       [not found]                         ` <20120702104231.GD2558-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 19+ messages in thread
From: joerg.roedel-5C7GfCeVMHo @ 2012-07-02 10:42 UTC (permalink / raw)
  To: Hiroshi Doyu
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On Mon, Jul 02, 2012 at 12:19:03PM +0200, Hiroshi Doyu wrote:
> Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote @ Mon, 2 Jul 2012 12:13:26 +0200:
> > The other 2 patehs are the replacement of this one. They are
> > exclusive. Both of them are basically for the same fix.
> 
> I might not get your point. If you plan to take the this(the original)
> as immediate fix for v3.5  you need tok take the others for v3.6 after
> *reverting* the original. This would also work.

Or you rebase the other two patches on-top of the first patch. Should
not be too difficult and you can also include the Ack from Steven while
at it :)


	Joerg

-- 
AMD Operating System Research Center

Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
       [not found]                         ` <20120702104231.GD2558-5C7GfCeVMHo@public.gmane.org>
@ 2012-07-02 11:14                           ` Hiroshi Doyu
  0 siblings, 0 replies; 19+ messages in thread
From: Hiroshi Doyu @ 2012-07-02 11:14 UTC (permalink / raw)
  To: joerg.roedel-5C7GfCeVMHo@public.gmane.org
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

"joerg.roedel-5C7GfCeVMHo@public.gmane.org" <joerg.roedel-5C7GfCeVMHo@public.gmane.org> wrote @ Mon, 2 Jul 2012 12:42:31 +0200:

> On Mon, Jul 02, 2012 at 12:19:03PM +0200, Hiroshi Doyu wrote:
> > Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote @ Mon, 2 Jul 2012 12:13:26 +0200:
> > > The other 2 patehs are the replacement of this one. They are
> > > exclusive. Both of them are basically for the same fix.
> > 
> > I might not get your point. If you plan to take the this(the original)
> > as immediate fix for v3.5  you need tok take the others for v3.6 after
> > *reverting* the original. This would also work.
> 
> Or you rebase the other two patches on-top of the first patch. Should
> not be too difficult and you can also include the Ack from Steven while
> at it :)

I'm sending the following patch again. The first one is for v3.5. The
rest goes to v3.6 as Joerg suggested.

  v3.5
	[1/1] iommu/tegra: smmu: Fix unsleepable memory allocation
  v3.6
	[1/3] Revert "iommu/tegra: smmu: Fix unsleepable memory allocation"
	[2/3] iommu/tegra: smmu: Remove unnecessary sanity check at alloc_pdir()
	[3/3] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir()

Is this OK?

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2012-07-02 11:14 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-26 18:15 tegra alloc_pdir Chris Wright
     [not found] ` <20120626181555.GW15796-JyIX8gxvWYPr2PDY2+4mTGD2FQJk+8+b@public.gmane.org>
2012-06-27  9:46   ` Hiroshi Doyu
     [not found]     ` <20120627.124628.673793050413876363.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-27  9:54       ` [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation Hiroshi DOYU
     [not found]         ` <1340790841-23349-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-27 15:57           ` Chris Wright
2012-06-27 16:59           ` Stephen Warren
     [not found]             ` <4FEB3C04.6040606-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-28 10:42               ` Hiroshi Doyu
     [not found]                 ` <20120628134202.2102f715496a3b980b43f3b0-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-28 10:51                   ` [v2 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation at alloc_pdir() Hiroshi DOYU
     [not found]                     ` <1340880707-6934-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-28 16:57                       ` Stephen Warren
     [not found]                         ` <4FEC8CEE.1000401-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-28 18:35                           ` Hiroshi Doyu
     [not found]                             ` <20120628.213554.1189327754979133382.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-28 19:08                               ` Stephen Warren
     [not found]                                 ` <4FECAB9C.9040809-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-06-28 19:19                                   ` Hiroshi Doyu
     [not found]                                     ` <20120628.221945.1306825810095951985.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-29  6:15                                       ` [v3 1/2] iommu/tegra: smmu: Remove unnecessary sanity check " Hiroshi DOYU
     [not found]                                         ` <1340950527-16482-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-06-29  6:15                                           ` [v3 2/2] iommu/tegra: smmu: Fix unsleepable memory allocation " Hiroshi DOYU
2012-06-29 15:34                                           ` [v3 1/2] iommu/tegra: smmu: Remove unnecessary sanity check " Stephen Warren
2012-07-02  9:57           ` [PATCH 1/1] iommu/tegra: smmu: Fix unsleepable memory allocation Joerg Roedel
     [not found]             ` <20120702095747.GB2558-5C7GfCeVMHo@public.gmane.org>
2012-07-02 10:13               ` Hiroshi Doyu
     [not found]                 ` <20120702.131326.685361720133451299.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-02 10:19                   ` Hiroshi Doyu
     [not found]                     ` <20120702.131903.1053229523265080291.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-02 10:42                       ` joerg.roedel-5C7GfCeVMHo
     [not found]                         ` <20120702104231.GD2558-5C7GfCeVMHo@public.gmane.org>
2012-07-02 11:14                           ` Hiroshi Doyu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).