RE: condvar wakeups

"Perez-Gonzalez, Inaky" <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
> From: Ingo Molnar [mailto:[email protected]]
> until someone can show some real degradation due to wakeup behavior i'll
> close this issue and wont pursue FUTEX_REQUEUE upstream, it seems to bring
> no benefits.

Hi Ingo - not related, except for a similar problem I found
when playing with it: Isn't vcache_callback screwing the page 
reference counts? 

My point is we update the page (as in the vcache callback code) but 
we ain't correctly accounting for it.

The futex_wait() call sets q->page and has a refcount on that q->page.
Now if we hit the callback, q->page is set to 'newpage', but we don't
hold a reference to it, so it might be paged out and then we are kind
of screwed. However, futex_wait() exit path will correctly remove the
reference to 'oldpage'.

Shouldn't this change to have vcache callback unpin() q->page, set the
new page, pin it (well, page_get()) and then, futex_wait() and futex_close()
both unpin (on exit) q->page? -third and fourth patch chunks-- 

--- futex.c	1 May 2003 20:11:20 -0000	1.1.1.1
+++ futex.c	5 May 2003 20:48:37 -0000
@@ -106,6 +106,13 @@
  *
  * Must be called with (and returns with) all futex-MM locks held.
  */
+static inline
+struct page *__pin_page_atomic (unsigned long addr)
+{
+	if (!PageReserved(page))
+		get_page(page);
+	return page;
+}
 static struct page *__pin_page(unsigned long addr)
 {
 	struct mm_struct *mm = current->mm;
@@ -116,11 +123,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:
@@ -208,7 +212,9 @@
 	spin_lock(&futex_lock);
 
 	if (!list_empty(&q->list)) {
+		unpin_page (q->page);
 		q->page = new_page;
+		__pin_page_atomic (q->page);
 		list_del(&q->list);
 		list_add_tail(&q->list, head);
 	}
@@ -310,7 +316,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.