Re: crash-7.3.2 very long list iteration progressively increasing memory usage

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

 



On Tue, 2018-06-26 at 15:34 +0100, Jeremy Harris wrote:
> On 06/26/2018 03:29 PM, David Wysochanski wrote:
> > On Tue, 2018-06-26 at 09:21 -0400, Dave Anderson wrote:
> > > Yes, by default all list entries encountered are put in the built-in
> > > hash queue, specifically for the purpose of determining whether there
> > > are duplicate entries.  So if it's still running, it hasn't found any.
> > > 
> > > To avoid the use of the hashing feature, try entering "set hash off"
> > > before kicking off the command.  But of course if it finds any, it
> > > will loop forever.
> > > 
> > 
> > Ah ok yeah I forgot about the built-in list loop detection!
> 
> For a storage-less method of list loop-detection: run two walkers
> down the list, advancing two versus one elements.  If you ever
> match the same element location after starting, you have a loop.

I have a POC patch implementing this I'm testing.  Right now I don't
have a vmcore with a list loop in it so I cannot really test it much.

Keep in mind it may be a total non-starter and I don't really know if
it works yet.
From a594388975f31663c94c46c7b87f7a423ad17e49 Mon Sep 17 00:00:00 2001
From: Dave Wysochanski <dwysocha@xxxxxxxxxx>
Date: Wed, 27 Jun 2018 17:29:00 -0400
Subject: [PATCH] Add 'T' option to 'list' command to implement faster loop
 detection

The 'T' option of the 'list' command implements a version of the tortoise
and hare algorithm for loop detection.  The speed of the hare is set at
2 and if it ever passes the tortoise a loop is detected.  The tortoise
is the normal loop iteration.

All other functions in the 'do_list()' function should remain in tact.
This function is only implemented currently on the 'list' function by
adding a '-T' on the crash list command.

Signed-off-by: Dave Wysochanski <dwysocha@xxxxxxxxxx>
---
 defs.h  |  3 +++
 tools.c | 27 +++++++++++++++++++++++++--
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/defs.h b/defs.h
index 931be07..7019002 100644
--- a/defs.h
+++ b/defs.h
@@ -2490,6 +2490,9 @@ struct list_data {             /* generic structure used by do_list() to walk */
 #define CALLBACK_RETURN     (VERBOSE << 12)
 #define LIST_PARSE_MEMBER   (VERBOSE << 13)
 #define LIST_READ_MEMBER    (VERBOSE << 14)
+#define LIST_TORTOISE_HARE  (VERBOSE << 15)
+
+#define HARE_SPEED 2
 
 struct tree_data {
 	ulong flags;
diff --git a/tools.c b/tools.c
index 1a83643..ed46bf0 100644
--- a/tools.c
+++ b/tools.c
@@ -3266,9 +3266,14 @@ cmd_list(void)
 	BZERO(ld, sizeof(struct list_data));
 	struct_list_offset = 0;
 
-	while ((c = getopt(argcnt, args, "Hhrs:S:e:o:xdl:")) != EOF) {
+	while ((c = getopt(argcnt, args, "THhrs:S:e:o:xdl:")) != EOF) {
                 switch(c)
 		{
+		case 'T':
+			ld->flags |= LIST_TORTOISE_HARE;
+			ld->flags &= LIST_ALLOCATE;
+			break;
+
 		case 'H':
 			ld->flags |= LIST_HEAD_FORMAT;
 			ld->flags |= LIST_HEAD_POINTER;
@@ -3655,6 +3660,7 @@ int
 do_list(struct list_data *ld)
 {
 	ulong next, last, first, offset;
+	ulong hare, hare_idx;
 	ulong searchfor, readflag;
 	int i, count, others, close_hq_on_return;
 	unsigned int radix;
@@ -3776,7 +3782,8 @@ do_list(struct list_data *ld)
 			}
 		}
 
-                if (next && !hq_enter(next - ld->list_head_offset)) {
+                if (!(ld->flags & LIST_TORTOISE_HARE) &&
+		    next && !hq_enter(next - ld->list_head_offset)) {
 			if (ld->flags & 
 			    (RETURN_ON_DUPLICATE|RETURN_ON_LIST_ERROR)) {
                         	error(INFO, "\nduplicate list entry: %lx\n", 
@@ -3808,6 +3815,22 @@ do_list(struct list_data *ld)
 			return -1;
 		}
 
+		if (ld->flags & LIST_TORTOISE_HARE) {
+			hare = next;
+			for (hare_idx = 0; hare_idx < HARE_SPEED; hare_idx++) {
+				if (!readmem(hare + ld->member_offset, KVADDR, &hare,
+					     sizeof(void *), "list entry", readflag)) {
+					error(INFO, "\ninvalid list entry: %lx\n", hare);
+					return -1;
+				}
+				if (hare == next) {
+					error(INFO, "\nduplicate list entry: %lx\n",
+					      next);
+					return -1;
+				}
+			}
+		}
+
 		if (next == 0) {
 			if (ld->flags & LIST_HEAD_FORMAT) {
 				error(INFO, "\ninvalid list entry: 0\n");
-- 
1.8.3.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux