[PATCH 2.5.69.bk9] Fix reference counts for pages (take 1) [was R E: condvar wakeups]

"Perez-Gonzalez, Inaky" <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
> From: Ingo Molnar [mailto:[email protected]]
> 
> On Wed, 14 May 2003, Perez-Gonzalez, Inaky wrote:
> 
> > Now you got me all lost; you mean the ones fixing the vcache callback
> > counts too? the ones I did for rtfutex that I don't need any more?
> 
> the one adding the __pin_page_atomic thing, fixing non-rt futexes.

This is the first take at it; I still didn't have time to test it
(0.37 building, slow) ... but I don't think I screwed up anything 
- Saurabh, would you mind torturing it a little bit in your x4 to 
make sure it is not leaking memory anywhere? Performance wise it 
should do nothing to the system ...

Thanks

diff -u linux/kernel/futex.c:1.1.1.1.2.4
linux/kernel/futex.c:1.1.1.1.2.2.2.3
--- linux/kernel/futex.c:1.1.1.1.2.4	Wed May 14 16:30:07 2003
+++ linux/kernel/futex.c	Wed May 14 17:09:48 2003
@@ -98,6 +98,13 @@
  *
  * Must be called with (and returns with) all futex-MM locks held.
  */
+static inline
+struct page *__pin_page_atomic (struct page *page)
+{
+	if (!PageReserved(page))
+		get_page(page);
+	return page;
+}
 static struct page *__pin_page(unsigned long addr)
 {
 	struct mm_struct *mm = current->mm;
@@ -108,11 +115,8 @@
 	 * Do a quick atomic lookup first - this is the fastpath.
 	 */
 	page = follow_page(mm, addr, 0);
-	if (likely(page != NULL)) {	
-		if (!PageReserved(page))
-			get_page(page);
-		return page;
-	}
+	if (likely(page != NULL))
+		__pin_page_atomic(page);
 
 	/*
 	 * No luck - need to fault in the page:
@@ -202,7 +206,9 @@
 	spin_lock(&futex_lock);
 
 	if (!list_empty(&q->list)) {
+		unpin_page(q->page);
 		q->page = new_page;
+		__pin_page_atomic(new_page);
 		list_del(&q->list);
 		list_add_tail(&q->list, head);
 	}
@@ -242,11 +248,13 @@
 		if (this->page == page1 && this->offset == offset1) {
 			list_del_init(i);
 			__detach_vcache(&this->vcache);
+			unpin_page(this->page);
 			if (++ret <= num) {
 				wake_up_all_sync(&this->waiters);
 				if (this->filp)
 					send_sigio(&this->filp->f_owner,
this->fd, POLL_IN);
 			} else {
+				__pin_page_atomic (page2);
 				list_add_tail(i, head2);
 				__attach_vcache(&this->vcache, uaddr2,
current->mm, futex_vcache_callback);
 				this->offset = offset2;
@@ -362,7 +370,7 @@
 	/* Were we woken up anyway? */
 	if (!unqueue_me(&q))
 		ret = 0;
-	unpin_page(page);
+	unpin_page(q.page);
 
 	return ret;
 }




Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.