From: Jeff Dike Remove dependency on ghash.h. Remvoe ghash.h, too. Signed-off-by: Andrew Morton --- 25-akpm/arch/um/kernel/physmem.c | 96 +++++++-------- 25-akpm/include/linux/ghash.h | 236 --------------------------------------- 2 files changed, 48 insertions(+), 284 deletions(-) diff -puN arch/um/kernel/physmem.c~uml-remove-ghash arch/um/kernel/physmem.c --- 25/arch/um/kernel/physmem.c~uml-remove-ghash Thu Sep 9 17:17:34 2004 +++ 25-akpm/arch/um/kernel/physmem.c Thu Sep 9 17:17:34 2004 @@ -4,7 +4,7 @@ */ #include "linux/mm.h" -#include "linux/ghash.h" +#include "linux/rbtree.h" #include "linux/slab.h" #include "linux/vmalloc.h" #include "linux/bootmem.h" @@ -19,36 +19,8 @@ #include "kern.h" #include "init.h" -#if 0 -static pgd_t physmem_pgd[PTRS_PER_PGD]; - -static struct phys_desc *lookup_mapping(void *addr) -{ - pgd = &physmem_pgd[pgd_index(addr)]; - if(pgd_none(pgd)) - return(NULL); - - pmd = pmd_offset(pgd, addr); - if(pmd_none(pmd)) - return(NULL); - - pte = pte_offset_kernel(pmd, addr); - return((struct phys_desc *) pte_val(pte)); -} - -static struct add_mapping(void *addr, struct phys_desc *new) -{ -} -#endif - -#define PHYS_HASHSIZE (8192) - -struct phys_desc; - -DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc); - struct phys_desc { - struct virtmem_ptrs virt_ptrs; + struct rb_node rb; int fd; __u64 offset; void *virt; @@ -56,21 +28,48 @@ struct phys_desc { struct list_head list; }; -struct virtmem_table virtmem_hash; +static struct rb_root phys_mappings = RB_ROOT; -static int virt_cmp(void *virt1, void *virt2) +static struct rb_node **find_rb(void *virt) { - return(virt1 != virt2); + struct rb_node **n = &phys_mappings.rb_node; + struct phys_desc *d; + + while(*n != NULL){ + d = rb_entry(n, struct phys_desc, rb); + if(d->virt == virt) + return(n); + + if(d->virt > virt) + n = &(*n)->rb_left; + else + n = &(*n)->rb_right; + } + + return(n); } -static int virt_hash(void *virt) +static struct phys_desc *find_phys_mapping(void *virt) { - unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT; - return(addr % PHYS_HASHSIZE); + struct rb_node **n = find_rb(virt); + + if(*n == NULL) + return(NULL); + + return(rb_entry(n, struct phys_desc, rb)); } -DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, - virt_hash); +static void insert_phys_mapping(struct phys_desc *desc) +{ + struct rb_node **n = find_rb(desc->virt); + + if(*n != NULL) + panic("Physical remapping for %p already present", + desc->virt); + + rb_link_node(&desc->rb, (*n)->rb_parent, n); + rb_insert_color(&desc->rb, &phys_mappings); +} LIST_HEAD(descriptor_mappings); @@ -127,7 +126,8 @@ int physmem_subst_mapping(void *virt, in return(-ENOMEM); phys = __pa(virt); - if(find_virtmem_hash(&virtmem_hash, virt) != NULL) + desc = find_phys_mapping(virt); + if(desc != NULL) panic("Address 0x%p is already substituted\n", virt); err = -ENOMEM; @@ -136,13 +136,12 @@ int physmem_subst_mapping(void *virt, in goto out; *desc = ((struct phys_desc) - { .virt_ptrs = { NULL, NULL }, - .fd = fd, + { .fd = fd, .offset = offset, .virt = virt, .phys = __pa(virt), .list = LIST_HEAD_INIT(desc->list) }); - insert_virtmem_hash(&virtmem_hash, desc); + insert_phys_mapping(desc); list_add(&desc->list, &fd_maps->pages); @@ -151,7 +150,7 @@ int physmem_subst_mapping(void *virt, in if(!err) goto out; - remove_virtmem_hash(&virtmem_hash, desc); + rb_erase(&desc->rb, &phys_mappings); kfree(desc); out: return(err); @@ -164,7 +163,7 @@ static void remove_mapping(struct phys_d void *virt = desc->virt; int err; - remove_virtmem_hash(&virtmem_hash, desc); + rb_erase(&desc->rb, &phys_mappings); list_del(&desc->list); kfree(desc); @@ -179,7 +178,7 @@ int physmem_remove_mapping(void *virt) struct phys_desc *desc; virt = (void *) ((unsigned long) virt & PAGE_MASK); - desc = find_virtmem_hash(&virtmem_hash, virt); + desc = find_phys_mapping(virt); if(desc == NULL) return(0); @@ -234,7 +233,9 @@ void arch_free_page(struct page *page, i int is_remapped(void *virt) { - return(find_virtmem_hash(&virtmem_hash, virt) != NULL); + struct phys_desc *desc = find_phys_mapping(virt); + + return(desc != NULL); } /* Changed during early boot */ @@ -367,8 +368,7 @@ void setup_physmem(unsigned long start, int phys_mapping(unsigned long phys, __u64 *offset_out) { - struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, - __va(phys & PAGE_MASK)); + struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK)); int fd = -1; if(desc != NULL){ diff -puN include/linux/ghash.h~uml-remove-ghash include/linux/ghash.h --- 25/include/linux/ghash.h~uml-remove-ghash Thu Sep 9 17:17:34 2004 +++ 25-akpm/include/linux/ghash.h Thu Sep 9 17:17:34 2004 @@ -1,236 +0,0 @@ -/* - * include/linux/ghash.h -- generic hashing with fuzzy retrieval - * - * (C) 1997 Thomas Schoebel-Theuer - * - * The algorithms implemented here seem to be a completely new invention, - * and I'll publish the fundamentals in a paper. - */ - -#ifndef _GHASH_H -#define _GHASH_H -/* HASHSIZE _must_ be a power of two!!! */ - - -#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \ -\ -struct NAME##_table {\ - TYPE * hashtable[HASHSIZE];\ - TYPE * sorted_list;\ - int nr_entries;\ -};\ -\ -struct NAME##_ptrs {\ - TYPE * next_hash;\ - TYPE * prev_hash;\ - TYPE * next_sorted;\ - TYPE * prev_sorted;\ -}; - -#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\ -\ -LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - int ix = HASHFN(elem->KEY);\ - TYPE ** base = &tbl->hashtable[ix];\ - TYPE * ptr = *base;\ - TYPE * prev = NULL;\ -\ - tbl->nr_entries++;\ - while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ - base = &ptr->PTRS.next_hash;\ - prev = ptr;\ - ptr = *base;\ - }\ - elem->PTRS.next_hash = ptr;\ - elem->PTRS.prev_hash = prev;\ - if(ptr) {\ - ptr->PTRS.prev_hash = elem;\ - }\ - *base = elem;\ -\ - ptr = prev;\ - if(!ptr) {\ - ptr = tbl->sorted_list;\ - prev = NULL;\ - } else {\ - prev = ptr->PTRS.prev_sorted;\ - }\ - while(ptr) {\ - TYPE * next = ptr->PTRS.next_hash;\ - if(next && KEYCMP(next->KEY, elem->KEY)) {\ - prev = ptr;\ - ptr = next;\ - } else if(KEYCMP(ptr->KEY, elem->KEY)) {\ - prev = ptr;\ - ptr = ptr->PTRS.next_sorted;\ - } else\ - break;\ - }\ - elem->PTRS.next_sorted = ptr;\ - elem->PTRS.prev_sorted = prev;\ - if(ptr) {\ - ptr->PTRS.prev_sorted = elem;\ - }\ - if(prev) {\ - prev->PTRS.next_sorted = elem;\ - } else {\ - tbl->sorted_list = elem;\ - }\ -}\ -\ -LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - TYPE * next = elem->PTRS.next_hash;\ - TYPE * prev = elem->PTRS.prev_hash;\ -\ - tbl->nr_entries--;\ - if(next)\ - next->PTRS.prev_hash = prev;\ - if(prev)\ - prev->PTRS.next_hash = next;\ - else {\ - int ix = HASHFN(elem->KEY);\ - tbl->hashtable[ix] = next;\ - }\ -\ - next = elem->PTRS.next_sorted;\ - prev = elem->PTRS.prev_sorted;\ - if(next)\ - next->PTRS.prev_sorted = prev;\ - if(prev)\ - prev->PTRS.next_sorted = next;\ - else\ - tbl->sorted_list = next;\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix = hashfn(pos);\ - TYPE * ptr = tbl->hashtable[ix];\ - while(ptr && KEYCMP(ptr->KEY, pos))\ - ptr = ptr->PTRS.next_hash;\ - if(ptr && !KEYEQ(ptr->KEY, pos))\ - ptr = NULL;\ - return ptr;\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix;\ - int offset;\ - TYPE * ptr;\ - TYPE * next;\ -\ - ptr = tbl->sorted_list;\ - if(!ptr || KEYCMP(pos, ptr->KEY))\ - return NULL;\ - ix = HASHFN(pos);\ - offset = HASHSIZE;\ - do {\ - offset >>= 1;\ - next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\ - if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\ - && KEYCMP(ptr->KEY, next->KEY))\ - ptr = next;\ - } while(offset);\ -\ - for(;;) {\ - next = ptr->PTRS.next_hash;\ - if(next) {\ - if(KEYCMP(next->KEY, pos)) {\ - ptr = next;\ - continue;\ - }\ - }\ - next = ptr->PTRS.next_sorted;\ - if(next && KEYCMP(next->KEY, pos)) {\ - ptr = next;\ - continue;\ - }\ - return ptr;\ - }\ - return NULL;\ -} - -/* LINKAGE - empty or "static", depending on whether you want the definitions to - * be public or not - * NAME - a string to stick in names to make this hash table type distinct from - * any others - * HASHSIZE - number of buckets - * TYPE - type of data contained in the buckets - must be a structure, one - * field is of type NAME_ptrs, another is the hash key - * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that - * field - * KEYTYPE - type of the key field within TYPE - * KEY - name of the key field within TYPE - * KEYCMP - pointer to function that compares KEYTYPEs to each other - the - * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, - * non-zero for not equal - * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE), - * it returns a number in the range 0 ... HASHSIZE - 1 - * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call - * DEF_HASH. - */ - -#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \ -\ -struct NAME##_table {\ - TYPE * hashtable[HASHSIZE];\ - int nr_entries;\ -};\ -\ -struct NAME##_ptrs {\ - TYPE * next_hash;\ - TYPE * prev_hash;\ -}; - -#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\ -\ -LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - int ix = HASHFN(elem->KEY);\ - TYPE ** base = &tbl->hashtable[ix];\ - TYPE * ptr = *base;\ - TYPE * prev = NULL;\ -\ - tbl->nr_entries++;\ - while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\ - base = &ptr->PTRS.next_hash;\ - prev = ptr;\ - ptr = *base;\ - }\ - elem->PTRS.next_hash = ptr;\ - elem->PTRS.prev_hash = prev;\ - if(ptr) {\ - ptr->PTRS.prev_hash = elem;\ - }\ - *base = elem;\ -}\ -\ -LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ -{\ - TYPE * next = elem->PTRS.next_hash;\ - TYPE * prev = elem->PTRS.prev_hash;\ -\ - tbl->nr_entries--;\ - if(next)\ - next->PTRS.prev_hash = prev;\ - if(prev)\ - prev->PTRS.next_hash = next;\ - else {\ - int ix = HASHFN(elem->KEY);\ - tbl->hashtable[ix] = next;\ - }\ -}\ -\ -LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ -{\ - int ix = HASHFN(pos);\ - TYPE * ptr = tbl->hashtable[ix];\ - while(ptr && KEYCMP(ptr->KEY, pos))\ - ptr = ptr->PTRS.next_hash;\ - return ptr;\ -} - -#endif _