Blob Blame History Raw
--- crash-7.0.2/memory.c.orig
+++ crash-7.0.2/memory.c
@@ -1,8 +1,8 @@
 /* memory.c - core analysis suite
  *
  * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2013 David Anderson
- * Copyright (C) 2002-2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2014 David Anderson
+ * Copyright (C) 2002-2014 Red Hat, Inc. All rights reserved.
  * Copyright (C) 2002 Silicon Graphics, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -4162,6 +4162,8 @@ get_task_mem_usage(ulong task, struct ta
 #define SLAB_FIRST_NODE        (ADDRESS_SPECIFIED << 22)
 #define CACHE_SET              (ADDRESS_SPECIFIED << 23)
 
+#define SLAB_BITFIELD          (ADDRESS_SPECIFIED << 25)
+
 #define GET_ALL \
 	(GET_SHARED_PAGES|GET_TOTALRAM_PAGES|GET_BUFFERS_PAGES|GET_SLAB_PAGES)
 
@@ -16312,6 +16314,10 @@ dump_kmem_cache_slub(struct meminfo *si)
 	si->cache_count = get_kmem_cache_list(&si->cache_list);
 	si->cache_buf = GETBUF(SIZE(kmem_cache));
 
+	if (VALID_MEMBER(page_objects) &&
+	    OFFSET(page_objects) == OFFSET(page_inuse))
+		si->flags |= SLAB_BITFIELD;
+
 	if (!si->reqname &&
 	     !(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES)))
 		fprintf(fp, "%s", kmem_cache_hdr);
@@ -16613,7 +16619,7 @@ static void
 do_slab_slub(struct meminfo *si, int verbose)
 {
 	physaddr_t paddr; 
-	ulong vaddr;
+	ulong vaddr, objects_vaddr;
 	ushort inuse, objects; 
 	ulong freelist, cpu_freelist, cpu_slab_ptr;
 	int i, cpu_slab, is_free, node;
@@ -16652,9 +16658,23 @@ do_slab_slub(struct meminfo *si, int ver
 	 *  is kept in the slab.
 	 */
 	if (VALID_MEMBER(page_objects)) {
-		if (!readmem(si->slab + OFFSET(page_objects), KVADDR, &objects,
+		objects_vaddr = si->slab + OFFSET(page_objects);
+		if (si->flags & SLAB_BITFIELD)
+			objects_vaddr += sizeof(ushort);
+		if (!readmem(objects_vaddr, KVADDR, &objects,
 		    sizeof(ushort), "page.objects", RETURN_ON_ERROR))
 			return;
+		/*
+		 *  Strip page.frozen bit.
+		 */
+		if (si->flags & SLAB_BITFIELD) {
+			if (__BYTE_ORDER == __LITTLE_ENDIAN) {
+				objects <<= 1;
+				objects >>= 1;
+			}
+			if (__BYTE_ORDER == __BIG_ENDIAN)
+				objects >>= 1;
+		}
 
 		if (CRASHDEBUG(1) && (objects != si->objects))
 			error(NOTE, "%s: slab: %lx oo objects: %ld "
@@ -16678,14 +16698,11 @@ do_slab_slub(struct meminfo *si, int ver
 			cpu_slab = i;
 			/*
 			 *  Later slub scheme uses the per-cpu freelist
-			 *  and keeps page->inuse maxed out, so count 
-			 *  the free objects by hand.
+			 *  so count the free objects by hand.
 			 */
 			if (cpu_freelist)
 				freelist = cpu_freelist;
-			if ((si->objects - inuse) == 0)
-				inuse = si->objects - 
-					count_free_objects(si, freelist);
+			inuse = si->objects - count_free_objects(si, freelist);
 			break;
 		}
 	}