[PATCH v2 1/8] cache: get rid of search loop in cache_add()
Petr Tesarik
ptesarik at suse.cz
Fri Mar 6 00:23:47 PST 2015
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
More information about the kexec
mailing list