linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Suparna Bhattacharya <suparna@in.ibm.com>
To: linux-aio@kvack.org, akpm@osdl.org, drepper@redhat.com
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	jakub@redhat.com, mingo@elte.hu
Subject: [FSAIO][PATCH 6/8] Enable asynchronous wait page and lock page
Date: Thu, 28 Dec 2006 14:11:49 +0530	[thread overview]
Message-ID: <20061228084149.GF6971@in.ibm.com> (raw)
In-Reply-To: <20061228082308.GA4476@in.ibm.com>


Define low-level page wait and lock page routines which take a
wait queue entry pointer as an additional parameter and
return status (which may be non-zero when the wait queue
parameter signifies an asynchronous wait, typically during
AIO).

Synchronous IO waits become a special case where the wait
queue parameter is the running task's default io wait context.
Asynchronous IO waits happen when the wait queue parameter
is the io wait context of a kiocb. Code paths which choose to
execute synchronous or asynchronous behaviour depending on the
called context specify the current io wait context (which points
to sync or async context as the case may be) as the wait
parameter. 

Signed-off-by: Suparna Bhattacharya <suparna@in.ibm.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
---

 linux-2.6.20-rc1-root/include/linux/pagemap.h |   30 ++++++++++++++++++-------
 linux-2.6.20-rc1-root/include/linux/sched.h   |    1 
 linux-2.6.20-rc1-root/kernel/sched.c          |   14 +++++++++++
 linux-2.6.20-rc1-root/mm/filemap.c            |   31 +++++++++++++++-----------
 4 files changed, 55 insertions(+), 21 deletions(-)

diff -puN include/linux/pagemap.h~aio-wait-page include/linux/pagemap.h
--- linux-2.6.20-rc1/include/linux/pagemap.h~aio-wait-page	2006-12-21 08:46:02.000000000 +0530
+++ linux-2.6.20-rc1-root/include/linux/pagemap.h	2006-12-21 08:46:02.000000000 +0530
@@ -133,20 +133,24 @@ static inline pgoff_t linear_page_index(
 	return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 }
 
-extern void FASTCALL(lock_page_slow(struct page *page));
+extern int FASTCALL(__lock_page_slow(struct page *page, wait_queue_t *wait));
 extern void FASTCALL(__lock_page_nosync(struct page *page));
 extern void FASTCALL(unlock_page(struct page *page));
 
 /*
  * lock_page may only be called if we have the page's inode pinned.
  */
-static inline void lock_page(struct page *page)
+static inline int __lock_page(struct page *page, wait_queue_t *wait)
 {
 	might_sleep();
 	if (TestSetPageLocked(page))
-		lock_page_slow(page);
+		return __lock_page_slow(page, wait);
+	return 0;
 }
 
+#define lock_page(page)		__lock_page(page, &current->__wait.wait)
+#define lock_page_slow(page)	__lock_page_slow(page, &current->__wait.wait)
+
 /*
  * lock_page_nosync should only be used if we can't pin the page's inode.
  * Doesn't play quite so well with block device plugging.
@@ -162,7 +166,8 @@ static inline void lock_page_nosync(stru
  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
  * Never use this directly!
  */
-extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr));
+extern int FASTCALL(wait_on_page_bit(struct page *page, int bit_nr,
+			wait_queue_t *wait));
 
 /* 
  * Wait for a page to be unlocked.
@@ -171,21 +176,30 @@ extern void FASTCALL(wait_on_page_bit(st
  * ie with increased "page->count" so that the page won't
  * go away during the wait..
  */
-static inline void wait_on_page_locked(struct page *page)
+static inline int __wait_on_page_locked(struct page *page, wait_queue_t *wait)
 {
 	if (PageLocked(page))
-		wait_on_page_bit(page, PG_locked);
+		return wait_on_page_bit(page, PG_locked, wait);
+	return 0;
 }
 
+#define wait_on_page_locked(page) \
+	__wait_on_page_locked(page, &current->__wait.wait)
+
 /* 
  * Wait for a page to complete writeback
  */
-static inline void wait_on_page_writeback(struct page *page)
+static inline int __wait_on_page_writeback(struct page *page,
+					wait_queue_t *wait)
 {
 	if (PageWriteback(page))
-		wait_on_page_bit(page, PG_writeback);
+		return wait_on_page_bit(page, PG_writeback, wait);
+	return 0;
 }
 
+#define wait_on_page_writeback(page) \
+	__wait_on_page_writeback(page, &current->__wait.wait)
+
 extern void end_page_writeback(struct page *page);
 
 /*
diff -puN include/linux/sched.h~aio-wait-page include/linux/sched.h
--- linux-2.6.20-rc1/include/linux/sched.h~aio-wait-page	2006-12-21 08:46:02.000000000 +0530
+++ linux-2.6.20-rc1-root/include/linux/sched.h	2006-12-28 09:26:27.000000000 +0530
@@ -216,6 +216,7 @@ extern void show_stack(struct task_struc
 
 void io_schedule(void);
 long io_schedule_timeout(long timeout);
+int io_wait_schedule(wait_queue_t *wait);
 
 extern void cpu_init (void);
 extern void trap_init(void);
diff -puN kernel/sched.c~aio-wait-page kernel/sched.c
--- linux-2.6.20-rc1/kernel/sched.c~aio-wait-page	2006-12-21 08:46:02.000000000 +0530
+++ linux-2.6.20-rc1-root/kernel/sched.c	2006-12-21 08:46:02.000000000 +0530
@@ -4743,6 +4743,20 @@ long __sched io_schedule_timeout(long ti
 	return ret;
 }
 
+/*
+ * Sleep only if the wait context passed is not async,
+ * otherwise return so that a retry can be issued later.
+ */
+int __sched io_wait_schedule(wait_queue_t *wait)
+{
+	if (!is_sync_wait(wait))
+		return -EIOCBRETRY;
+	io_schedule();
+	return 0;
+}
+
+EXPORT_SYMBOL(io_wait_schedule);
+
 /**
  * sys_sched_get_priority_max - return maximum RT priority.
  * @policy: scheduling class.
diff -puN mm/filemap.c~aio-wait-page mm/filemap.c
--- linux-2.6.20-rc1/mm/filemap.c~aio-wait-page	2006-12-21 08:46:02.000000000 +0530
+++ linux-2.6.20-rc1-root/mm/filemap.c	2006-12-28 09:32:27.000000000 +0530
@@ -165,8 +165,7 @@ static int sync_page(void *word, wait_qu
 	mapping = page_mapping(page);
 	if (mapping && mapping->a_ops && mapping->a_ops->sync_page)
 		mapping->a_ops->sync_page(page);
-	io_schedule();
-	return 0;
+	return io_wait_schedule(wait);
 }
 
 /**
@@ -478,7 +477,7 @@ struct page *__page_cache_alloc(gfp_t gf
 EXPORT_SYMBOL(__page_cache_alloc);
 #endif
 
-static int __sleep_on_page_lock(void *word)
+static int __sleep_on_page_lock(void *word, wait_queue_t *wait)
 {
 	io_schedule();
 	return 0;
@@ -506,13 +505,17 @@ static inline void wake_up_page(struct p
 	__wake_up_bit(page_waitqueue(page), &page->flags, bit);
 }
 
-void fastcall wait_on_page_bit(struct page *page, int bit_nr)
+int fastcall wait_on_page_bit(struct page *page, int bit_nr,
+					wait_queue_t *wait)
 {
-	DEFINE_WAIT_BIT(wait, &page->flags, bit_nr);
-
-	if (test_bit(bit_nr, &page->flags))
-		__wait_on_bit(page_waitqueue(page), &wait, sync_page,
+	if (test_bit(bit_nr, &page->flags)) {
+		struct wait_bit_queue *wait_bit
+			= container_of(wait, struct wait_bit_queue, wait);
+		init_wait_bit_key(wait_bit, &page->flags, bit_nr);
+		return __wait_on_bit(page_waitqueue(page), wait_bit, sync_page,
 							TASK_UNINTERRUPTIBLE);
+	}
+	return 0;
 }
 EXPORT_SYMBOL(wait_on_page_bit);
 
@@ -556,7 +559,7 @@ void end_page_writeback(struct page *pag
 EXPORT_SYMBOL(end_page_writeback);
 
 /**
- * lock_page_slow - get a lock on the page, assuming we need to sleep to get it
+ * __lock_page_slow: get a lock on the page, assuming we need to wait to get it
  * @page: the page to lock
  *
  * Ugly. Running sync_page() in state TASK_UNINTERRUPTIBLE is scary.  If some
@@ -564,14 +567,16 @@ EXPORT_SYMBOL(end_page_writeback);
  * chances are that on the second loop, the block layer's plug list is empty,
  * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
  */
-void fastcall lock_page_slow(struct page *page)
+int fastcall __lock_page_slow(struct page *page, wait_queue_t *wait)
 {
-	DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
+	struct wait_bit_queue *wait_bit
+		= container_of(wait, struct wait_bit_queue, wait);
 
-	__wait_on_bit_lock(page_waitqueue(page), &wait, sync_page,
+	init_wait_bit_key(wait_bit, &page->flags, PG_locked);
+	return __wait_on_bit_lock(page_waitqueue(page), wait_bit, sync_page,
 							TASK_UNINTERRUPTIBLE);
 }
-EXPORT_SYMBOL(lock_page_slow);
+EXPORT_SYMBOL(__lock_page_slow);
 
 /*
  * Variant of lock_page that does not require the caller to hold a reference
_
-- 
Suparna Bhattacharya (suparna@in.ibm.com)
Linux Technology Center
IBM Software Lab, India


  parent reply	other threads:[~2006-12-28  8:37 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-27 15:38 [RFC] Heads up on a series of AIO patchsets Suparna Bhattacharya
2006-12-27 16:25 ` Christoph Hellwig
2006-12-27 16:55   ` Ingo Molnar
2006-12-27 17:18     ` Ingo Molnar
2006-12-28 11:41   ` Evgeniy Polyakov
2007-01-02 21:38     ` Dan Williams
2007-01-03 13:35       ` Evgeniy Polyakov
2006-12-28  8:23 ` [PATCHSET 1][PATCH 0/6] Filesystem AIO read/write Suparna Bhattacharya
2006-12-28  8:34   ` [FSAIO][PATCH 1/6] Add a wait queue parameter to the wait_bit action routine Suparna Bhattacharya
2006-12-28  8:46     ` Suparna Bhattacharya
2006-12-28  8:36   ` [FSAIO][PATCH 2/8] Rename __lock_page to lock_page_slow Suparna Bhattacharya
2006-12-28  8:39   ` [FSAIO][PATCH 3/8] Routines to initialize and test a wait bit key Suparna Bhattacharya
2006-12-28 22:42     ` Andrew Morton
2006-12-28  8:39   ` [FSAIO][PATCH 4/8] Add a default io wait bit field in task struct Suparna Bhattacharya
2006-12-28  8:40   ` [FSAIO][PATCH 5/8] Enable wait bit based filtered wakeups to work for AIO Suparna Bhattacharya
2006-12-28  8:41   ` Suparna Bhattacharya [this message]
2006-12-28 11:55     ` [FSAIO][PATCH 6/8] Enable asynchronous wait page and lock page Christoph Hellwig
2006-12-28 14:47       ` Suparna Bhattacharya
2007-01-02 14:26         ` Christoph Hellwig
2007-01-04  6:50           ` Nick Piggin
2006-12-28  8:42   ` [FSAIO][PATCH 7/8] Filesystem AIO read Suparna Bhattacharya
2006-12-28 11:57     ` Christoph Hellwig
2006-12-28 14:15       ` Christoph Hellwig
2006-12-28 15:18       ` Suparna Bhattacharya
2007-01-02 14:29         ` Christoph Hellwig
2006-12-28 16:22       ` Jan Engelhardt
2006-12-28 16:56         ` Randy Dunlap
2006-12-28  8:44   ` [FSAIO][PATCH 8/8] AIO O_SYNC filesystem write Suparna Bhattacharya
2006-12-28  9:52   ` [PATCHSET 1][PATCH 0/6] Filesystem AIO read/write Ingo Molnar
2006-12-28 22:53   ` Andrew Morton
2007-01-03 22:15   ` Andrew Morton
2007-01-04  4:56     ` Suparna Bhattacharya
2007-01-04  5:51       ` Nick Piggin
2007-01-04  6:26         ` Suparna Bhattacharya
2007-01-04  6:50           ` Nick Piggin
2007-01-04 11:24             ` Suparna Bhattacharya
2007-01-05  4:56               ` Nick Piggin
2007-01-04 17:02       ` Andrew Morton
2007-01-04 17:49         ` Jens Axboe
2007-01-05  6:28         ` Suparna Bhattacharya
2007-01-05  7:02           ` Jens Axboe
2007-01-05  8:08             ` Suparna Bhattacharya
2007-01-05  8:32               ` Jens Axboe
2007-01-10  5:44         ` Suparna Bhattacharya
2007-01-11  1:08           ` Andrew Morton
2007-01-11  3:13             ` Suparna Bhattacharya
2007-01-11  4:52               ` Andrew Morton
2007-01-02 23:56 ` [RFC] Heads up on a series of AIO patchsets Zach Brown
     [not found]   ` <6f703f960701021640y444bc537w549fd6d74f3e9529@mail.gmail.com>
     [not found]     ` <A85B8249-FC4E-4612-8B28-02BC680DC812@oracle.com>
2007-01-03  1:18       ` Kent Overstreet
2007-01-04 20:33         ` Pavel Machek
2007-01-03  5:03   ` Suparna Bhattacharya
2007-01-05  0:36     ` Zach Brown
2007-01-03  7:23 ` [PATCHSET 2][PATCH 1/1] Combining epoll and disk file AIO Suparna Bhattacharya
2007-01-04  9:27 ` [PATCHSET 3][PATCH 0/5][AIO] - AIO completion signal notification v4 Bharata B Rao
2007-01-04  9:30   ` [PATCHSET 3][PATCH 1/5][AIO] - Rework compat_sys_io_submit Bharata B Rao
2007-01-04  9:32   ` [PATCHSET 3][PATCH 2/5][AIO] - fix aio.h includes Bharata B Rao
2007-01-04  9:34   ` [PATCHSET 3][PATCH 3/5][AIO] - Make good_sigevent non-static Bharata B Rao
2007-01-04  9:38   ` [PATCHSET 3][PATCH 4/5][AIO] - AIO completion signal notification Bharata B Rao
2007-01-04  9:40   ` [PATCHSET 3][PATCH 5/5][AIO] - Add listio support Bharata B Rao
2007-01-05  5:32 ` [PATCHSET 4][PATCH 1/1] AIO fallback for pipes, sockets and pollable fds Suparna Bhattacharya

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=20061228084149.GF6971@in.ibm.com \
    --to=suparna@in.ibm.com \
    --cc=akpm@osdl.org \
    --cc=drepper@redhat.com \
    --cc=jakub@redhat.com \
    --cc=linux-aio@kvack.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).