[dm-devel] [RFC][PATCH 1/10] I/O context inheritance

Hirokazu Takahashi taka at valinux.co.jp
Tue Apr 22 13:51:31 UTC 2008


Make every bio points the iocontext of the process which originally
generated an I/O request. 
 - Assign the iocontext of the current process to a bio when it is
   newly allocated.
 - Assign the iocontext which the source bio has to a newly allocated
   bio when it is duplicated.


Signed-off-by: Hirokazu Takahashi <taka at valinux.co.jp>


--- linux-2.6.25.bio0/include/linux/bio.h	2008-04-22 15:48:36.000000000 +0900
+++ linux-2.6.25/include/linux/bio.h	2008-04-22 15:49:42.000000000 +0900
@@ -114,6 +114,8 @@ struct bio {
 	void			*bi_private;
 
 	bio_destructor_t	*bi_destructor;	/* destructor */
+
+	struct io_context       *bi_io_context;
 };
 
 /*
--- linux-2.6.25.bio0/include/linux/iocontext.h	2008-04-22 15:48:36.000000000 +0900
+++ linux-2.6.25/include/linux/iocontext.h	2008-04-22 15:49:42.000000000 +0900
@@ -85,7 +85,7 @@ struct io_context {
 	void *ioc_data;
 };
 
-static inline struct io_context *ioc_task_link(struct io_context *ioc)
+static inline struct io_context *ioc_object_link(struct io_context *ioc)
 {
 	/*
 	 * if ref count is zero, don't allow sharing (ioc is going away, it's
@@ -99,4 +99,6 @@ static inline struct io_context *ioc_tas
 	return NULL;
 }
 
+#define ioc_task_link(ioc)	ioc_object_link(ioc)
+
 #endif
--- linux-2.6.25.bio0/fs/bio.c	2008-04-22 15:48:31.000000000 +0900
+++ linux-2.6.25/fs/bio.c	2008-04-22 15:49:42.000000000 +0900
@@ -107,8 +107,16 @@ static inline struct bio_vec *bvec_alloc
 	return bvl;
 }
 
+static inline void put_bio_context(struct bio *bio)
+{
+	if (bio->bi_io_context)
+		put_io_context(bio->bi_io_context);
+}
+
 void bio_free(struct bio *bio, struct bio_set *bio_set)
 {
+	put_bio_context(bio);
+
 	if (bio->bi_io_vec) {
 		const int pool_idx = BIO_POOL_IDX(bio);
 
@@ -177,10 +185,29 @@ out:
 
 struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
 {
-	struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
+	struct bio *bio;
+	struct io_context *ioc;
 
-	if (bio)
+	/*
+	 * Set the io_context of the current process here since this newly
+	 * created bio may be passed to a I/O scheduler through another
+	 * kernel thread in half of the process that originate this bio.
+	 * get_io_context function should called here so it can be blocked
+	 * in it.
+	 * Todo: when the current is an aio kernel thread, the io_context
+	 *       of the original process should be set instead of that of
+	 *       the thread.
+	 */
+	ioc = get_io_context(gfp_mask, -1);
+	if (!ioc)
+		return NULL;
+
+	bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
+	if (bio) {
 		bio->bi_destructor = bio_fs_destructor;
+		bio->bi_io_context = ioc;
+	} else
+		put_io_context(ioc);
 
 	return bio;
 }
@@ -262,6 +289,7 @@ void __bio_clone(struct bio *bio, struct
 	bio->bi_vcnt = bio_src->bi_vcnt;
 	bio->bi_size = bio_src->bi_size;
 	bio->bi_idx = bio_src->bi_idx;
+	bio->bi_io_context = ioc_object_link(bio_src->bi_io_context);
 }
 
 /**




More information about the dm-devel mailing list