[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

RE: condvar wakeups

> From: Ingo Molnar [mailto:mingo elte hu]
> 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
+++ 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 @@
 	if (!list_empty(&q->list)) {
+		unpin_page (q->page);
 		q->page = new_page;
+		__pin_page_atomic (q->page);
 		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)

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]