From 1b7634c644285b46c0cdeedd483f9420e1b1213b Mon Sep 17 00:00:00 2001
From: Laura Abbott <lauraa@codeaurora.org>
Date: Thu, 30 Jan 2014 10:24:51 -0800
Subject: [PATCH] linux-ramdump-parser-v2: Check for loops in workqueues

Workqueues may be modified at runtime which can leave them in an
inconsistent state in ram dumps. Check for infinite loops in
workqueue lists caused by this state.

Change-Id: If5d8ebe48a538ffae58a8ed485cd4a50b20d60bf
---
 linux-ramdump-parser-v2/parsers/workqueue.py | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/linux-ramdump-parser-v2/parsers/workqueue.py b/linux-ramdump-parser-v2/parsers/workqueue.py
index 4986299..183cb03 100644
--- a/linux-ramdump-parser-v2/parsers/workqueue.py
+++ b/linux-ramdump-parser-v2/parsers/workqueue.py
@@ -269,6 +269,7 @@ class Workqueues(RamParser):
                             break
 
             worker_pool = workqueue_i + pools_offset
+            seen = []
             # Need better way to ge the number of pools...
             for k in range(0, 2):
                 worker_pool_i = worker_pool + k * worker_pool_size
@@ -279,9 +280,11 @@ class Workqueues(RamParser):
                     worker_addr = next_entry - worker_entry_offset
                     worker_task_addr = ram_dump.read_word(
                         next_entry - worker_entry_offset + worker_task_offset)
-                    if worker_task_addr is None or worker_task_addr == 0:
+                    if worker_task_addr is None or worker_task_addr == 0 or worker_task_addr in seen:
                         break
 
+                    seen.append(worker_task_addr)
+
                     taskname = ram_dump.read_cstring(
                         (worker_task_addr + offset_comm), 16)
                     scheduled_addr = ram_dump.read_word(
@@ -420,13 +423,16 @@ class Workqueues(RamParser):
 
                 idle_list_addr = worker_pool_i + pool_idle_offset
                 next_entry = ram_dump.read_word(idle_list_addr)
+                seen = []
                 while True:
                     worker_addr = next_entry - worker_entry_offset
                     worker_task_addr = ram_dump.read_word(
                         next_entry - worker_entry_offset + worker_task_offset)
-                    if worker_task_addr is None or worker_task_addr == 0:
+                    if worker_task_addr is None or worker_task_addr == 0 or worker_task_addr in seen:
                         break
 
+                    seen.append(worker_task_addr)
+
                     taskname = ram_dump.read_cstring(
                         (worker_task_addr + offset_comm), 16)
                     scheduled_addr = ram_dump.read_word(
-- 
GitLab