Re: [PATCH v2] ARM: pl330: Fix a race condition

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

 



Hi Javi,

On 9 December 2011 17:28, Javi Merino <javi.merino@xxxxxxx> wrote:
>
>>>>> Javi, could you please check if you too get the memcpy failure with
>>>>> dmatest ?
>>>>
>> Ok, I think I've just reproduced it in my end with the kernel's dmatest
>> module.  After the first transaction it looks like the dma test wasn't
>> able to issue any more transactions.  I'll have a look at it tomorrow
>> and try to answer my own questions ;)
>
> The problem is that pl330_submit_req() always puts the request in buffer 0 if
> both buffers are free.
>
There should be nothing wrong in that.
It is but natural to prefer 0 if both 0 and 1 are available.

> If you submit a transaction, it finishes and there's nothing else to run,
> pl330_update() calls _start() but there is nothing to send.  This is all
> right.  Then, if another transaction is submitted, pl330_submit_req() will
> put it in buffer 0 again.  This time, the PC of the DMA is in the last
> instruction of buffer 0 (the DMAEND of the *previous* transaction that
> finished long ago) so _thrd_active() thinks that this buffer is active,
>
Many thanks for the in-depth analysis.

Though before the PC check, the IS_FREE() should return true since
pl330_update() does MARK_FREE()

Could you please check if the client's callback function called
successfully for the
first submitted transfer ?

Then we can decide upon one of the following 2 options (I *think*
either should fix the issue)

diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index 97912fa..f550d46 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -846,7 +846,7 @@ static inline bool _req_active(struct pl330_thread *thrd,
 	if (IS_FREE(req))
 		return false;

-	return (pc >= buf && pc <= buf + req->mc_len) ? true : false;
+	return (pc >= buf && pc < buf + req->mc_len) ? true : false;
 }

--OR--

diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index 97912fa..ad85a75 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -233,7 +233,7 @@
 			} while (0)

 /* If the _pl330_req is available to the client */
-#define IS_FREE(req)	(*((u8 *)((req)->mc_cpu)) == CMD_DMAEND)
+#define IS_FREE(req)	((req)->mc_len == 0)

 /* Use this _only_ to wait on transient states */
 #define UNTIL(t, s)	while (!(_state(t) & (s))) cpu_relax();


Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux