summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2013-11-16 19:39:05 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-11-20 18:33:39 -0500
commit84b073868b9d9e754ae48b828337633d1b386482 (patch)
tree8e67a8fd82c71ffbe5eeece1b254039b00f324b9 /arch/powerpc
parent9db8bcfd73d4a18c0b3428c30557ccce1171d0af (diff)
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@samba.org> Cc: stable@vger.kernel.org Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/time.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 192b051df97e..b3b144121cc9 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)
213 if (i == be64_to_cpu(vpa->dtl_idx)) 213 if (i == be64_to_cpu(vpa->dtl_idx))
214 return 0; 214 return 0;
215 while (i < be64_to_cpu(vpa->dtl_idx)) { 215 while (i < be64_to_cpu(vpa->dtl_idx)) {
216 if (dtl_consumer)
217 dtl_consumer(dtl, i);
218 dtb = be64_to_cpu(dtl->timebase); 216 dtb = be64_to_cpu(dtl->timebase);
219 tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + 217 tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
220 be32_to_cpu(dtl->ready_to_enqueue_time); 218 be32_to_cpu(dtl->ready_to_enqueue_time);
@@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
227 } 225 }
228 if (dtb > stop_tb) 226 if (dtb > stop_tb)
229 break; 227 break;
228 if (dtl_consumer)
229 dtl_consumer(dtl, i);
230 stolen += tb_delta; 230 stolen += tb_delta;
231 ++i; 231 ++i;
232 ++dtl; 232 ++dtl;