Commit 6feb9cf3 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: remove ghash.h

Remove dependency on ghash.h.  Remvoe ghash.h, too.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 77cb0870
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
*/ */
#include "linux/mm.h" #include "linux/mm.h"
#include "linux/ghash.h" #include "linux/rbtree.h"
#include "linux/slab.h" #include "linux/slab.h"
#include "linux/vmalloc.h" #include "linux/vmalloc.h"
#include "linux/bootmem.h" #include "linux/bootmem.h"
...@@ -19,36 +19,8 @@ ...@@ -19,36 +19,8 @@
#include "kern.h" #include "kern.h"
#include "init.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 phys_desc {
struct virtmem_ptrs virt_ptrs; struct rb_node rb;
int fd; int fd;
__u64 offset; __u64 offset;
void *virt; void *virt;
...@@ -56,21 +28,48 @@ struct phys_desc { ...@@ -56,21 +28,48 @@ struct phys_desc {
struct list_head list; 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; struct rb_node **n = find_rb(virt);
return(addr % PHYS_HASHSIZE);
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, static void insert_phys_mapping(struct phys_desc *desc)
virt_hash); {
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); LIST_HEAD(descriptor_mappings);
...@@ -127,7 +126,8 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) ...@@ -127,7 +126,8 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
return(-ENOMEM); return(-ENOMEM);
phys = __pa(virt); 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); panic("Address 0x%p is already substituted\n", virt);
err = -ENOMEM; err = -ENOMEM;
...@@ -136,13 +136,12 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) ...@@ -136,13 +136,12 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
goto out; goto out;
*desc = ((struct phys_desc) *desc = ((struct phys_desc)
{ .virt_ptrs = { NULL, NULL }, { .fd = fd,
.fd = fd,
.offset = offset, .offset = offset,
.virt = virt, .virt = virt,
.phys = __pa(virt), .phys = __pa(virt),
.list = LIST_HEAD_INIT(desc->list) }); .list = LIST_HEAD_INIT(desc->list) });
insert_virtmem_hash(&virtmem_hash, desc); insert_phys_mapping(desc);
list_add(&desc->list, &fd_maps->pages); list_add(&desc->list, &fd_maps->pages);
...@@ -151,7 +150,7 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) ...@@ -151,7 +150,7 @@ int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
if(!err) if(!err)
goto out; goto out;
remove_virtmem_hash(&virtmem_hash, desc); rb_erase(&desc->rb, &phys_mappings);
kfree(desc); kfree(desc);
out: out:
return(err); return(err);
...@@ -164,7 +163,7 @@ static void remove_mapping(struct phys_desc *desc) ...@@ -164,7 +163,7 @@ static void remove_mapping(struct phys_desc *desc)
void *virt = desc->virt; void *virt = desc->virt;
int err; int err;
remove_virtmem_hash(&virtmem_hash, desc); rb_erase(&desc->rb, &phys_mappings);
list_del(&desc->list); list_del(&desc->list);
kfree(desc); kfree(desc);
...@@ -179,7 +178,7 @@ int physmem_remove_mapping(void *virt) ...@@ -179,7 +178,7 @@ int physmem_remove_mapping(void *virt)
struct phys_desc *desc; struct phys_desc *desc;
virt = (void *) ((unsigned long) virt & PAGE_MASK); virt = (void *) ((unsigned long) virt & PAGE_MASK);
desc = find_virtmem_hash(&virtmem_hash, virt); desc = find_phys_mapping(virt);
if(desc == NULL) if(desc == NULL)
return(0); return(0);
...@@ -234,7 +233,9 @@ void arch_free_page(struct page *page, int order) ...@@ -234,7 +233,9 @@ void arch_free_page(struct page *page, int order)
int is_remapped(void *virt) 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 */ /* Changed during early boot */
...@@ -367,8 +368,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, ...@@ -367,8 +368,7 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,
int phys_mapping(unsigned long phys, __u64 *offset_out) int phys_mapping(unsigned long phys, __u64 *offset_out)
{ {
struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
__va(phys & PAGE_MASK));
int fd = -1; int fd = -1;
if(desc != NULL){ if(desc != NULL){
......
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment