All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rohit Seth <rseth@unix-os.sc.intel.com>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, akpm@digeo.com,
	torvalds@transmeta.com, rohit.seth@intel.com
Subject: hugetlb page patch for 2.5.48-bug fixes
Date: Thu, 21 Nov 2002 14:05:53 -0800	[thread overview]
Message-ID: <3DDD58C1.9020503@unix-os.sc.intel.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

Linus, Andrew,

Attached is the hugetlbpage patch for 2.5.48 containing following main 
changes:

1) Bug fixes (mainly in the unsuccessful attempts of hugepages).
2) Removal of Radix Tree field in key structure (as it is not needed).
3) Include the IPC_LOCK for permission to use hugepages.
4) Increment the key_counts during forks.

thanks,
rohit



[-- Attachment #2: patch2548.1121 --]
[-- Type: text/plain, Size: 7728 bytes --]

--- linux-2.5.48/include/linux/hugetlb.h	Sun Nov 17 20:29:45 2002
+++ linux-2.5.48.work//include/linux/hugetlb.h	Thu Nov 21 11:49:57 2002
@@ -4,7 +4,17 @@
 #ifdef CONFIG_HUGETLB_PAGE
 
 struct ctl_table;
-struct hugetlb_key;
+struct hugetlb_key {
+	struct page *root;
+	loff_t size;
+	atomic_t count;
+	spinlock_t lock;
+	int key;
+	int busy;
+	uid_t uid;
+	gid_t gid;
+	umode_t mode;
+};
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 {
--- linux-2.5.48/arch/i386/mm/hugetlbpage.c	Sun Nov 17 20:29:55 2002
+++ linux-2.5.48.work/arch/i386/mm/hugetlbpage.c	Thu Nov 21 12:12:18 2002
@@ -19,6 +19,8 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
+#include <linux/sysctl.h>
+
 static long    htlbpagemem;
 int     htlbpage_max;
 static long    htlbzone_pages;
@@ -29,18 +31,6 @@
 
 #define MAX_ID 	32
 
-struct hugetlb_key {
-	struct radix_tree_root tree;
-	atomic_t count;
-	spinlock_t lock;
-	int key;
-	int busy;
-	uid_t uid;
-	gid_t gid;
-	umode_t mode;
-	loff_t size;
-};
-
 static struct hugetlb_key htlbpagek[MAX_ID];
 
 static void mark_key_busy(struct hugetlb_key *hugetlb_key)
@@ -81,7 +71,7 @@
 		spin_lock(&htlbpage_lock);
 		hugetlb_key = find_key(key);
 		if (!hugetlb_key) {
-			if (!capable(CAP_SYS_ADMIN) || !in_group_p(0))
+			if (!capable(CAP_SYS_ADMIN) && !capable(CAP_IPC_LOCK) && !in_group_p(0))
 				hugetlb_key = ERR_PTR(-EPERM);
 			else if (!(flag & IPC_CREAT))
 				hugetlb_key = ERR_PTR(-ENOENT);
@@ -96,7 +86,7 @@
 					hugetlb_key = &htlbpagek[i];
 					mark_key_busy(hugetlb_key);
 					hugetlb_key->key = key;
-					INIT_RADIX_TREE(&hugetlb_key->tree, GFP_ATOMIC);
+					hugetlb_key->root = NULL;
 					hugetlb_key->uid = current->fsuid;
 					hugetlb_key->gid = current->fsgid;
 					hugetlb_key->mode = prot;
@@ -107,7 +97,6 @@
 			hugetlb_key = ERR_PTR(-EAGAIN);
 			spin_unlock(&htlbpage_lock);
 		} else if (check_size_prot(hugetlb_key, len, prot, flag) < 0) {
-			hugetlb_key->key = 0;
 			hugetlb_key = ERR_PTR(-EINVAL);
 		} 
 	} while (hugetlb_key == ERR_PTR(-EAGAIN));
@@ -120,7 +109,10 @@
 {
 	unsigned long index;
 	unsigned long max_idx;
+	struct page *page, *prev;
 
+	if (key == NULL)
+		return;
 	if (!atomic_dec_and_test(&key->count)) {
 		spin_lock(&htlbpage_lock);
 		clear_key_busy(key);
@@ -129,16 +121,19 @@
 	}
 
 	max_idx = (key->size >> HPAGE_SHIFT);
+	page = key->root;
 	for (index = 0; index < max_idx; ++index) {
-		struct page *page = radix_tree_lookup(&key->tree, index);
 		if (!page)
 			continue;
-		huge_page_release(page);
+		prev = page;
+		page = (struct page *)page->private;
+		prev->private = 0UL;
+		huge_page_release(prev);
 	}
 	spin_lock(&htlbpage_lock);
 	key->key = 0;
 	clear_key_busy(key);
-	INIT_RADIX_TREE(&key->tree, GFP_ATOMIC);
+	key->root = NULL;
 	spin_unlock(&htlbpage_lock);
 }
 
@@ -247,7 +242,7 @@
 		vma->vm_end = end;
 	}
 	spin_unlock(&mm->page_table_lock);
-      out_error1:
+out_error1:
 	return -1;
 }
 
@@ -259,7 +254,10 @@
 	struct page *ptepage;
 	unsigned long addr = vma->vm_start;
 	unsigned long end = vma->vm_end;
+	struct hugetlb_key *key = vma->vm_private_data;
 
+	if ( key )
+		atomic_inc(&key->count);
 	while (addr < end) {
 		dst_pte = huge_pte_alloc(dst, addr);
 		if (!dst_pte)
@@ -352,6 +350,8 @@
 	spin_unlock(&htlbpage_lock);
 	for (address = start; address < end; address += HPAGE_SIZE) {
 		pte = huge_pte_offset(mm, address);
+		if (pte_none(*pte))
+			continue;
 		page = pte_page(*pte);
 		huge_page_release(page);
 		pte_clear(pte);
@@ -381,25 +381,10 @@
 	return 0;
 }
 
-struct page *key_find_page(struct hugetlb_key *key, unsigned long index)
-{
-	struct page *page = radix_tree_lookup(&key->tree, index);
-	if (page)
-		get_page(page);
-	return page;
-}
-
-int key_add_page(struct page *page, struct hugetlb_key *key, unsigned long 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)
+static int prefault_key(struct hugetlb_key *key, struct vm_area_struct *vma, unsigned long *temp)
 {
 	struct mm_struct *mm = current->mm;
+	struct page *page, *prev;
 	unsigned long addr;
 	int ret = 0;
 
@@ -408,21 +393,18 @@
 
 	spin_lock(&mm->page_table_lock);
 	spin_lock(&key->lock);
+	prev = page = key->root;
 	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
 		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
 
 		if (!pte) {
+			spin_unlock(&key->lock);
 			ret = -ENOMEM;
 			goto out;
 		}
 		if (!pte_none(*pte))
 			continue;
 
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = key_find_page(key, idx);
 		if (!page) {
 			page = alloc_hugetlb_page();
 			if (!page) {
@@ -430,13 +412,20 @@
 				ret = -ENOMEM;
 				goto out;
 			}
-			key_add_page(page, key, idx);
+			if (key->root == NULL)
+				key->root = page;
+			else
+				prev->private = (unsigned long)page;
 		}
+		get_page(page);
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
+		prev = page;
+		page = (struct page *)page->private;
 	}
 	spin_unlock(&key->lock);
 out:
 	spin_unlock(&mm->page_table_lock);
+	*temp = addr;
 	return ret;
 }
 
@@ -446,6 +435,7 @@
 	struct vm_area_struct *vma;
 	struct hugetlb_key *hugetlb_key;
 	int retval = -ENOMEM;
+	unsigned long temp;
 
 	hugetlb_key = alloc_key(key, len, prot, flag );
 	spin_unlock(&htlbpage_lock);
@@ -455,17 +445,18 @@
 	addr = do_mmap_pgoff(NULL, addr, len, (unsigned long) prot,
 			MAP_NORESERVE|MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0);
 	if (IS_ERR((void *) addr))
-		goto out_release;
+		goto out;
 
 	vma = find_vma(mm, addr);
 	if (!vma) {
 		retval = -EINVAL;
-		goto out_release;
+		goto out;
 	}
 
-	retval = prefault_key(hugetlb_key, vma);
+	retval = prefault_key(hugetlb_key, vma, &temp);
+	addr = temp;
 	if (retval)
-		goto out;
+		goto out_release;
 
 	vma->vm_flags |= (VM_HUGETLB | VM_RESERVED);
 	vma->vm_ops = &hugetlb_vm_ops;
@@ -474,7 +465,7 @@
 	clear_key_busy(hugetlb_key);
 	spin_unlock(&htlbpage_lock);
 	return retval;
-out:
+out_release:
 	if (addr > vma->vm_start) {
 		unsigned long raddr;
 		raddr = vma->vm_end;
@@ -482,10 +473,8 @@
 		zap_hugepage_range(vma, vma->vm_start, vma->vm_end - vma->vm_start);
 		vma->vm_end = raddr;
 	}
-	spin_lock(&mm->page_table_lock);
 	do_munmap(mm, vma->vm_start, len);
-	spin_unlock(&mm->page_table_lock);
-out_release:
+out:
 	hugetlb_release_key(hugetlb_key);
 	return retval;
 }
@@ -533,10 +522,8 @@
 
 static int alloc_private_hugetlb_pages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
-	if (!capable(CAP_SYS_ADMIN)) {
-		if (!in_group_p(0))
-			return -EPERM;
-	}
+	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_IPC_LOCK) && !in_group_p(0))
+		return -EPERM;
 	addr = do_mmap_pgoff(NULL, addr, len, prot,
 			MAP_NORESERVE|MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, 0);
 	if (IS_ERR((void *) addr))
--- linux-2.5.48/arch/i386/kernel/sys_i386.c	Sun Nov 17 20:29:56 2002
+++ linux-2.5.48.work/arch/i386/kernel/sys_i386.c	Thu Nov 21 12:01:08 2002
@@ -294,17 +294,17 @@
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
-	struct hugetlb_key *key;
 	int retval;
 
-	vma = find_vma(current->mm, addr);
-	if (!vma || !(vma->vm_flags & VM_HUGETLB) || vma->vm_start != addr)
-		return -EINVAL;
 	down_write(&mm->mmap_sem);
-	key = (struct hugetlb_key *)vma->vm_private_data;
+	vma = find_vma(current->mm, addr);
+	if (!vma || !(vma->vm_flags & VM_HUGETLB) || vma->vm_start != addr) {
+		retval =  -EINVAL;
+		goto out;
+	}
 	retval = do_munmap(vma->vm_mm, addr, vma->vm_end - addr);
+out:
 	up_write(&mm->mmap_sem);
-	hugetlb_release_key(key);
 	return retval;
 }
 #else

             reply	other threads:[~2002-11-21 22:00 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-21 22:05 Rohit Seth [this message]
2002-11-21 23:51 ` hugetlb page patch for 2.5.48-bug fixes William Lee Irwin III
2002-11-21 23:51   ` William Lee Irwin III
  -- strict thread matches above, loose matches on Subject: below --
2002-11-22  1:54 Seth, Rohit
2002-11-22  1:54 ` Seth, Rohit
2002-11-22  2:04 ` William Lee Irwin III
2002-11-22  2:04   ` William Lee Irwin III
2002-11-22  3:23 Seth, Rohit
2002-11-22  3:23 ` Seth, Rohit
2002-11-24 14:44 ` Ed Tomlinson
2002-11-24 14:44   ` Ed Tomlinson
2002-11-24 14:49   ` William Lee Irwin III
2002-11-24 14:49     ` William Lee Irwin III
2002-11-24 15:01     ` Ed Tomlinson
2002-11-24 15:01       ` Ed Tomlinson
2002-11-24 15:00       ` William Lee Irwin III
2002-11-24 15:00         ` William Lee Irwin III

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3DDD58C1.9020503@unix-os.sc.intel.com \
    --to=rseth@unix-os.sc.intel.com \
    --cc=akpm@digeo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=rohit.seth@intel.com \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.