Re: [PATCH] improve the performance of kmem -s [address]

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

 



At 2012-2-3 2:53, Dave Anderson wrote:


----- Original Message -----

That all being said, your patch does have merit -- presuming that
the meminfo.cache field *never* gets set elsewhere prior to entering
the dump_kmem_cache_xxx functions.  I haven't taken the time to
verify that -- did you absolutely verify that?

It looks OK to use "if (si->cache)" in those 3 locations -- but it
would be safer to create/set a unique meminfo->flags bit for this
feature.
Thanks for your comments.

A new flag called "CACHE_SET" is created to inform the dump_kmem_cache_xxx functions that "si->cache" has been set.

As you said in the previous mail, I agree that ~150000 individual slabs rarely exist in a real-life scenario. However, ~150000 individual slabs are used to illustrate the improvement clearly. Think about the situation that I install a big module with some kmem_caches. I need to check the state of each kmem_cache related to my module once some operations are done. So the times of execution of "kmem -s <addr>" may be even big. Time, obviouly, will be saved with my patch in such situation.

Dave

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




--
--
Regards
Qiao Nuohan
diff --git a/memory.c b/memory.c
index 333d6e1..7a4c3ce 100755
--- a/memory.c
+++ b/memory.c
@@ -8306,7 +8306,13 @@ dump_kmem_cache(struct meminfo *si)
 
 	si->addrlist = (ulong *)GETBUF((vt->kmem_max_c_num+1) * sizeof(ulong));
 	cnt = 0;
-	si->cache = cache_cache = symbol_value("cache_cache");
+	if (si->flags & CACHE_SET) {
+		readmem(si->cache+OFFSET(kmem_cache_s_c_nextp),
+			KVADDR, &cache_cache, sizeof(ulong),
+			"kmem_cache next", FAULT_ON_ERROR);
+	} else {
+		si->cache = cache_cache = symbol_value("cache_cache");
+	}
 
 	if (si->flags & ADDRESS_SPECIFIED) {
 	        if (!(p1 = vaddr_to_kmem_cache(si->spec_addr, kbuf, VERBOSE))) {
@@ -8512,7 +8518,13 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
 			GETBUF(vt->kmem_max_limit * sizeof(ulong)); 
 
 	cnt = 0;
-	si->cache = cache_cache = symbol_value("cache_cache");
+	if (si->flags & CACHE_SET) {
+		readmem(si->cache+OFFSET(kmem_cache_s_next), 
+			KVADDR, &cache_cache, sizeof(ulong),
+			"kmem_cache_s next", FAULT_ON_ERROR);
+	} else {
+		si->cache = cache_cache = symbol_value("cache_cache");
+	}
 
 	if (si->flags & ADDRESS_SPECIFIED) {
 	        if (!(p1 = vaddr_to_kmem_cache(si->spec_addr, kbuf, VERBOSE))) {
diff --git a/memory.c b/memory.c
index 95eefc9..333d6e1 100755
--- a/memory.c
+++ b/memory.c
@@ -3886,6 +3886,7 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
 #define GET_SLUB_OBJECTS       (ADDRESS_SPECIFIED << 20)
 #define VMLIST_VERIFY          (ADDRESS_SPECIFIED << 21)
 #define SLAB_FIRST_NODE        (ADDRESS_SPECIFIED << 22)
+#define CACHE_SET              (ADDRESS_SPECIFIED << 23)
 
 #define GET_ALL \
 	(GET_SHARED_PAGES|GET_TOTALRAM_PAGES|GET_BUFFERS_PAGES|GET_SLAB_PAGES)
@@ -4091,11 +4092,14 @@ cmd_kmem(void)
 					error(FATAL, 
 				  "only one kmem_cache reference is allowed\n");
 				meminfo.reqname = p1;
+				meminfo.cache = value[i];
+				meminfo.flags |= CACHE_SET;
                         	if ((i+1) == spec_addr) { /* done? */ 
 					if (meminfo.calls++)
 						fprintf(fp, "\n");
                         		vt->dump_kmem_cache(&meminfo);
 				}
+				meminfo.flags &= ~CACHE_SET;
 			} else {
                         	meminfo.spec_addr = value[i];
                         	meminfo.flags = ADDRESS_SPECIFIED;
@@ -7589,15 +7593,12 @@ is_kmem_cache_addr(ulong vaddr, char *kbuf)
 	cache_buf = GETBUF(SIZE(kmem_cache_s));
 
         do {
-	        readmem(cache, KVADDR, cache_buf, SIZE(kmem_cache_s),
-	        	"kmem_cache buffer", FAULT_ON_ERROR);
 
 		if (cache == vaddr) {
 	                if (vt->kmem_cache_namelen) {
-				BCOPY(cache_buf+name_offset, kbuf, 
-					vt->kmem_cache_namelen);
+				readmem(cache+name_offset, KVADDR, kbuf, vt->kmem_cache_namelen, "name array", FAULT_ON_ERROR);
 	                } else {
-				name = ULONG(cache_buf + name_offset);
+				readmem(cache+name_offset, KVADDR, &name, sizeof(name), "name", FAULT_ON_ERROR);
 	                        if (!read_string(name, kbuf, BUFSIZE-1)) {
 					if (vt->flags & 
 					  (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2))
@@ -7615,7 +7616,8 @@ is_kmem_cache_addr(ulong vaddr, char *kbuf)
 			return kbuf;
 		}
 
-		cache = ULONG(cache_buf + next_offset);
+		readmem(cache+next_offset, KVADDR, &cache, sizeof(long),
+			"kmem_cache_s next", FAULT_ON_ERROR);
 
 		if (vt->flags & (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2))
 			cache -= next_offset;
@@ -8733,9 +8735,15 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
 
 	cnt = 0;
 
-        get_symbol_data("cache_chain", sizeof(ulong), &si->cache);
-        si->cache -= OFFSET(kmem_cache_s_next);
-        cache_end = symbol_value("cache_chain");
+	if (si->flags & CACHE_SET) {
+		readmem(si->cache+OFFSET(kmem_cache_s_next), 
+			KVADDR, &cache_end, sizeof(ulong),
+			"kmem_cache_s next", FAULT_ON_ERROR);
+	} else {
+		get_symbol_data("cache_chain", sizeof(ulong), &si->cache);
+		si->cache -= OFFSET(kmem_cache_s_next);
+		cache_end = symbol_value("cache_chain");
+	}
 
 	if (si->flags & ADDRESS_SPECIFIED) {
 	        if (!(p1 = vaddr_to_kmem_cache(si->spec_addr, kbuf, VERBOSE))) {
--
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