powerpc/pseries: Duplicate dtl entries sometimes sent to userspace

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:02 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=84b073868b9d9e754ae48b828337633d1b386482
Commit:     84b073868b9d9e754ae48b828337633d1b386482
Parent:     9db8bcfd73d4a18c0b3428c30557ccce1171d0af
Author:     Anton Blanchard <anton at samba.org>
AuthorDate: Sun Nov 17 11:39:05 2013 +1100
Committer:  Benjamin Herrenschmidt <benh at kernel.crashing.org>
CommitDate: Thu Nov 21 10:33:39 2013 +1100

    powerpc/pseries: Duplicate dtl entries sometimes sent to userspace
    
    When reading from the dispatch trace log (dtl) userspace interface, I
    sometimes see duplicate entries. One example:
    
    # hexdump -C dtl.out
    
    00000000  07 04 00 0c 00 00 48 44  00 00 00 00 00 00 00 00
    00000010  00 0c a0 b4 16 83 6d 68  00 00 00 00 00 00 00 00
    00000020  00 00 00 00 10 00 13 50  80 00 00 00 00 00 d0 32
    
    00000030  07 04 00 0c 00 00 48 44  00 00 00 00 00 00 00 00
    00000040  00 0c a0 b4 16 83 6d 68  00 00 00 00 00 00 00 00
    00000050  00 00 00 00 10 00 13 50  80 00 00 00 00 00 d0 32
    
    The problem is in scan_dispatch_log() where we call dtl_consumer()
    but bail out before incrementing the index.
    
    To fix this I moved dtl_consumer() after the timebase comparison.
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Cc: stable at vger.kernel.org
    Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 arch/powerpc/kernel/time.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 192b051..b3b1441 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -213,8 +213,6 @@ static u64 scan_dispatch_log(u64 stop_tb)
 	if (i == be64_to_cpu(vpa->dtl_idx))
 		return 0;
 	while (i < be64_to_cpu(vpa->dtl_idx)) {
-		if (dtl_consumer)
-			dtl_consumer(dtl, i);
 		dtb = be64_to_cpu(dtl->timebase);
 		tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
 			be32_to_cpu(dtl->ready_to_enqueue_time);
@@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
 		}
 		if (dtb > stop_tb)
 			break;
+		if (dtl_consumer)
+			dtl_consumer(dtl, i);
 		stolen += tb_delta;
 		++i;
 		++dtl;



More information about the linux-mtd-cvs mailing list