Hello Dave, These two patches are used to improve the performance of "kmem -s [address]". Current code need to search all kmem_caches twice. It is a waste of time. With my patch, the address is sent to "dump_kmem_cache" function to make the second search be restricted to the kmem_cache found in the first search. It means the second search is neglected. I have implemented the improvement for three types of kmem_cache. The search for "slub" does not waste that much time as its peers, so I did not modify the code related to "slub". Additionally, I only get the environment to test my first patch, so the second patch has not been tested. Here is the statistic of my test on RHEL6.2 x86_64, the vmcore used for testing has about 150000 kmem_caches commands in file: 1. only 'quit' origin code : about 36s with patch : about 36s 2. 1 time of searching the 100000th kmem_cache origin code : about 59s with patch : about 39s 3. 100 times of searching the 100000th kmem_cache origin code : about 38min30s with patch : about 5min p.s. If I create a kmem_cache called "list", a little confusion may happen when using "kmem -s list". I am wondering is it necessary to introduce an another option replacing list to avoid such collision. -- -- Regards Qiao Nuohan
diff --git a/memory.c b/memory.c index 95eefc9..2ec44ab 100755 --- a/memory.c +++ b/memory.c @@ -4091,6 +4091,7 @@ cmd_kmem(void) error(FATAL, "only one kmem_cache reference is allowed\n"); meminfo.reqname = p1; + meminfo.cache = value[i]; if ((i+1) == spec_addr) { /* done? */ if (meminfo.calls++) fprintf(fp, "\n"); @@ -7589,15 +7590,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 +7613,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 +8732,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->cache) { + 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))) {
diff --git a/memory.c b/memory.c index 2ec44ab..27a5346 100755 --- a/memory.c +++ b/memory.c @@ -8303,7 +8303,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->cache) { + 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))) { @@ -8509,7 +8515,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->cache) { + 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))) {
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility