The intention was that cache code is re-entrant, so all cache entries should go through these states: 1. free 2. pending read 3. used The cache_add() function is used to move an entry from state 2 to 3, but since the caller did not know cache entry pointer, it had to search the pending list for a pending read for the given physical address. This is not needed if cache_alloc() returns this pointer. Signed-off-by: Petr Tesarik <ptesarik at suse.cz> --- cache.c | 26 ++++++-------------------- cache.h | 10 ++++++++-- makedumpfile.c | 8 +++++--- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/cache.c b/cache.c index 0dd957c..700ba0c 100644 --- a/cache.c +++ b/cache.c @@ -20,12 +20,6 @@ #include "cache.h" #include "print_info.h" -struct cache_entry { - unsigned long long paddr; - void *bufptr; - struct cache_entry *next, *prev; -}; - struct cache { struct cache_entry *head, *tail; }; @@ -98,38 +92,30 @@ cache_search(unsigned long long paddr) return NULL; /* cache miss */ } -void * +struct cache_entry * cache_alloc(unsigned long long paddr) { struct cache_entry *entry = NULL; if (avail) { entry = &pool[--avail]; - entry->paddr = paddr; add_entry(&pending, entry); } else if (pending.tail) { entry = pending.tail; - entry->paddr = paddr; } else if (used.tail) { entry = used.tail; remove_entry(&used, entry); - entry->paddr = paddr; add_entry(&pending, entry); } else return NULL; - return entry->bufptr; + entry->paddr = paddr; + return entry; } void -cache_add(unsigned long long paddr) +cache_add(struct cache_entry *entry) { - struct cache_entry *entry; - for (entry = pending.head; entry; entry = entry->next) { - if (entry->paddr == paddr) { - remove_entry(&pending, entry); - add_entry(&used, entry); - break; - } - } + remove_entry(&pending, entry); + add_entry(&used, entry); } diff --git a/cache.h b/cache.h index 4730e12..dab8eb9 100644 --- a/cache.h +++ b/cache.h @@ -19,9 +19,15 @@ #ifndef _CACHE_H #define _CACHE_H +struct cache_entry { + unsigned long long paddr; + void *bufptr; + struct cache_entry *next, *prev; +}; + int cache_init(void); void *cache_search(unsigned long long paddr); -void *cache_alloc(unsigned long long paddr); -void cache_add(unsigned long long paddr); +struct cache_entry *cache_alloc(unsigned long long paddr); +void cache_add(struct cache_entry *entry); #endif /* _CACHE_H */ diff --git a/makedumpfile.c b/makedumpfile.c index 74bc9db..828adeb 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -591,6 +591,7 @@ readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size) unsigned long long paddr, maddr = NOT_PADDR; unsigned long long pgaddr; void *pgbuf; + struct cache_entry *cached; next_page: switch (type_addr) { @@ -644,9 +645,10 @@ next_page: pgaddr = PAGEBASE(paddr); pgbuf = cache_search(pgaddr); if (!pgbuf) { - pgbuf = cache_alloc(pgaddr); - if (!pgbuf) + cached = cache_alloc(pgaddr); + if (!cached) goto error; + pgbuf = cached->bufptr; if (info->flag_refiltering) { if (!readpage_kdump_compressed(pgaddr, pgbuf)) @@ -658,7 +660,7 @@ next_page: if (!readpage_elf(pgaddr, pgbuf)) goto error; } - cache_add(pgaddr); + cache_add(cached); } memcpy(bufptr, pgbuf + PAGEOFFSET(paddr), read_size); -- 1.8.4.5