[10/11] hugetlb: use radix trees instead of inodes

From: William Lee Irwin III (wli@holomorphy.com)
Date: Tue Nov 12 2002 - 03:28:54 EST


This patch, substitutes direct usage of radix trees for inodes, and
removes the reviled custom-allocated inodes.

 hugetlbpage.c | 80 ++++++++++++++++++++++++----------------------------------
 1 files changed, 34 insertions(+), 46 deletions(-)

diff -urpN htlb-2.5.47-9/arch/i386/mm/hugetlbpage.c htlb-2.5.47-10/arch/i386/mm/hugetlbpage.c
--- htlb-2.5.47-9/arch/i386/mm/hugetlbpage.c 2002-11-11 22:42:23.000000000 -0800
+++ htlb-2.5.47-10/arch/i386/mm/hugetlbpage.c 2002-11-11 23:10:20.000000000 -0800
@@ -30,7 +30,7 @@ static spinlock_t htlbpage_lock = SPIN_L
 #define MAX_ID 32
 
 struct hugetlb_key {
- struct inode *in;
+ struct radix_tree_root tree;
         int key;
         int busy;
         uid_t uid;
@@ -84,44 +84,28 @@ struct hugetlb_key *alloc_key(int key, u
                         else if (!(flag & IPC_CREAT))
                                 hugetlb_key = ERR_PTR(-ENOENT);
                         else {
- struct inode *inode;
- inode = kmalloc(sizeof(struct inode), GFP_ATOMIC);
- if (!inode)
- inode = ERR_PTR(-ENOMEM);
- else {
- int i;
- for (i = 0; i < MAX_ID; ++i)
- if (!htlbpagek[i].key)
- break;
- if (i == MAX_ID) {
- kfree(inode);
- hugetlb_key = ERR_PTR(-ENOMEM);
- } else {
- hugetlb_key = &htlbpagek[i];
- inode_init_once(inode);
- mark_key_busy(hugetlb_key);
- inode->i_mapping = &inode->i_data;
- inode->i_mapping->host = inode;
- inode->i_ino = (unsigned long)key;
- hugetlb_key->key = key;
- hugetlb_key->in = inode;
- inode->i_uid = current->fsuid;
- inode->i_gid = current->fsgid;
- inode->i_mode = prot;
- inode->i_size = len;
- hugetlb_key->uid = current->fsuid;
- hugetlb_key->gid = current->fsgid;
- hugetlb_key->mode = prot;
- hugetlb_key->size = len;
- *new = 1;
- }
+ int i;
+ for (i = 0; i < MAX_ID; ++i)
+ if (!htlbpagek[i].key)
+ break;
+ if (i == MAX_ID) {
+ hugetlb_key = ERR_PTR(-ENOMEM);
+ } else {
+ hugetlb_key = &htlbpagek[i];
+ mark_key_busy(hugetlb_key);
+ hugetlb_key->key = key;
+ INIT_RADIX_TREE(&hugetlb_key->tree, GFP_ATOMIC);
+ hugetlb_key->uid = current->fsuid;
+ hugetlb_key->gid = current->fsgid;
+ hugetlb_key->mode = prot;
+ hugetlb_key->size = len;
+ *new = 1;
                                 }
                         }
                 } else if (key_busy(hugetlb_key)) {
                         hugetlb_key = ERR_PTR(-EAGAIN);
                         spin_unlock(&htlbpage_lock);
                 } else if (check_size_prot(hugetlb_key, len, prot, flag) < 0) {
- kfree(hugetlb_key->in);
                         hugetlb_key->key = 0;
                         hugetlb_key = ERR_PTR(-EINVAL);
                 } else
@@ -132,18 +116,16 @@ struct hugetlb_key *alloc_key(int key, u
 
 static void release_key(struct hugetlb_key *key)
 {
- int i;
- struct inode *inode = (struct inode *)key;;
-
+ unsigned long index;
         spin_lock(&htlbpage_lock);
- for(i = 0;i < MAX_ID; ++i)
- if (htlbpagek[i].key != inode->i_ino)
+ for (index = 0; index < key->size; ++index) {
+ struct page *page = radix_tree_lookup(&key->tree, index);
+ if (!page)
                         continue;
-
- BUG_ON(i >= MAX_ID);
- htlbpagek[i].key = 0;
- htlbpagek[i].in = NULL;
- kfree(inode);
+ huge_page_release(page);
+ }
+ key->key = 0;
+ INIT_RADIX_TREE(&key->tree, GFP_ATOMIC);
         spin_unlock(&htlbpage_lock);
 }
 
@@ -381,12 +363,18 @@ static int check_size_prot(struct hugetl
 
 struct page *key_find_page(struct hugetlb_key *key, unsigned long index)
 {
- return find_get_page(key->in->i_mapping, index);
+ struct page *page = radix_tree_lookup(&key->tree, index);
+ if (page)
+ get_page(page);
+ return page;
 }
 
-void key_add_page(struct page *page, struct hugetlb_key *key, unsigned long index)
+int key_add_page(struct page *page, struct hugetlb_key *key, unsigned long index)
 {
- add_to_page_cache(page, key->in->i_mapping, index);
+ int error = radix_tree_insert(&key->tree, index, page);
+ if (!error)
+ get_page(page);
+ return error;
 }
 
 static int prefault_key(struct hugetlb_key *key, struct vm_area_struct *vma)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Nov 15 2002 - 22:00:25 EST