All of lore.kernel.org
 help / color / mirror / Atom feed
* [uml-devel] parallel I/O
@ 2008-09-12 13:40 Nicolas Boullis
  2008-09-15  8:59 ` Nicolas Boullis
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Boullis @ 2008-09-12 13:40 UTC (permalink / raw)
  To: user-mode-linux-devel

Hi,

I've been using uml on production servers for months, and have been
quite happy with it, except for I/O performance.

I was using the user-mode-linux package from Debian Etch, based on
2.6.18, and compiled with CONFIG_BLK_DEV_UBD_SYNC. Disabling this option
of course helps performance, but I feel that it's somewhat unsafe if the
host crashes... Moreover, I don't think it helps read performance.

As far as I can see, if one wants both safety and performance, the I/O
must not be serialized. So I decided to give it a try.

The first step was to run a per-device I/O thread. This improves
slightly the performance with several UBD devices: I/O on one device do
not block I/O on another device. Moreover, that helps to implement
parallelized I/O.

Then I managed to run several parallel threads per device. As far as I
am concernced, that much improves the performance. But currently, my
code is more a dirty proof-of-concept than a clean patch.

Would you be interested by my work?


Cheers,

Nicolas Boullis
École Centrale Paris

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [uml-devel] parallel I/O
  2008-09-12 13:40 [uml-devel] parallel I/O Nicolas Boullis
@ 2008-09-15  8:59 ` Nicolas Boullis
  2008-10-02 13:34   ` Nicolas Boullis
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Boullis @ 2008-09-15  8:59 UTC (permalink / raw)
  To: user-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 223 bytes --]

Hi,

For what it's worth, here is my quick-n-dirty proof-of-concept patch
that enables parallel I/O. Note that it is based on 2.6.24.

If people are interested, I can try to make a clean patch out of it.


Cheers,

Nicolas

[-- Attachment #2: uml_parallel_io.patch --]
[-- Type: text/x-patch, Size: 6580 bytes --]

--- linux-source-2.6.24/arch/um/drivers/ubd_kern.c.orig	2008-09-15 10:55:51.000000000 +0200
+++ linux-source-2.6.24/arch/um/drivers/ubd_kern.c	2008-09-12 15:13:24.000000000 +0200
@@ -65,7 +65,7 @@
 	unsigned long length;
 	char *buffer;
 	int sectorsize;
-	unsigned long sector_mask;
+	unsigned long sector_mask[8];
 	unsigned long long cow_offset;
 	unsigned long bitmap_words[2];
 	int error;
@@ -172,6 +172,9 @@
 	struct scatterlist sg[MAX_SG];
 	struct request *request;
 	int start_sg, end_sg;
+	int pipe_fd[2];
+	int io_pid;
+	unsigned long stack;
 };
 
 #define DEFAULT_COW { \
@@ -196,6 +199,9 @@
 	.request =		NULL, \
 	.start_sg =		0, \
 	.end_sg =		0, \
+	.pipe_fd =		{-1, -1}, \
+	.io_pid =		-1, \
+	.stack =		0, \
 }
 
 /* Protected by ubd_lock */
@@ -473,7 +479,7 @@
 static void do_ubd_request(struct request_queue * q);
 
 /* Only changed by ubd_init, which is an initcall. */
-int thread_fd = -1;
+int common_thread_fd = -1;
 
 static void ubd_end_request(struct request *req, int bytes, int uptodate)
 {
@@ -513,7 +519,7 @@
 	int n;
 
 	while(1){
-		n = os_read_file(thread_fd, &req,
+		n = os_read_file(common_thread_fd, &req,
 				 sizeof(struct io_thread_req *));
 		if(n != sizeof(req)){
 			if(n == -EAGAIN)
@@ -529,7 +535,7 @@
 			ubd_finish(rq, rq->hard_nr_sectors << 9);
 		kfree(req);
 	}
-	reactivate_fd(thread_fd, UBD_IRQ);
+	reactivate_fd(common_thread_fd, UBD_IRQ);
 
 	list_for_each_safe(list, next_ele, &restart){
 		ubd = container_of(list, struct ubd, restart);
@@ -565,6 +571,8 @@
 	return os_file_size(file, size_out);
 }
 
+extern pid_t waitpid(pid_t pid, int *status, int options);
+
 static void ubd_close_dev(struct ubd *ubd_dev)
 {
 	os_close_file(ubd_dev->fd);
@@ -576,6 +584,8 @@
 	ubd_dev->cow.bitmap = NULL;
 }
 
+int per_device_io_thread(void *arg);
+
 static int ubd_open_dev(struct ubd *ubd_dev)
 {
 	struct openflags flags;
@@ -636,6 +646,8 @@
 		if(err < 0) goto error;
 		ubd_dev->cow.fd = err;
 	}
+
+
 	return 0;
  error:
 	os_close_file(ubd_dev->fd);
@@ -938,7 +950,7 @@
 	}
 	stack = alloc_stack(0, 0);
 	io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
-				 &thread_fd);
+				 &common_thread_fd);
 	if(io_pid < 0){
 		printk(KERN_ERR
 		       "ubd : Failed to start I/O thread (errno = %d) - "
@@ -946,7 +958,7 @@
 		io_pid = -1;
 		return 0;
 	}
-	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
+	err = um_request_irq(UBD_IRQ, common_thread_fd, IRQ_READ, ubd_intr,
 			     IRQF_DISABLED, "ubd", ubd_devs);
 	if(err != 0)
 		printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
@@ -962,12 +974,23 @@
 	int err = 0;
 
 	if(ubd_dev->count == 0){
+		void *sp;
+
 		err = ubd_open_dev(ubd_dev);
 		if(err){
 			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
 			       disk->disk_name, ubd_dev->file, -err);
 			goto out;
 		}
+
+		pipe(ubd_dev->pipe_fd);
+		os_set_fd_block(ubd_dev->pipe_fd[1], 0);
+
+		ubd_dev->stack = alloc_stack(0, 0);
+		sp = (void *)(ubd_dev->stack + PAGE_SIZE - sizeof(void *));
+		ubd_dev->io_pid = clone(per_device_io_thread, sp, CLONE_VM, (void *)ubd_dev);
+
+		printk("Launched I/O thread.\n");
 	}
 	ubd_dev->count++;
 	set_disk_ro(disk, !ubd_dev->openflags.w);
@@ -987,12 +1010,21 @@
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ubd *ubd_dev = disk->private_data;
 
-	if(--ubd_dev->count == 0)
+	if(--ubd_dev->count == 0) {
+		printk("Trying to stop I/O thread.\n");
+		os_close_file(ubd_dev->pipe_fd[1]);
+		ubd_dev->pipe_fd[1] = -1;
+		waitpid(ubd_dev->io_pid, NULL, __WCLONE);
+		ubd_dev->io_pid = -1;
+		free_stack(ubd_dev->stack, 0);
+		ubd_dev->stack = 0;
+
 		ubd_close_dev(ubd_dev);
+	}
 	return 0;
 }
 
-static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
+static void cowify_bitmap(__u64 io_offset, int length, unsigned long (*cow_mask)[],
 			  __u64 *cow_offset, unsigned long *bitmap,
 			  __u64 bitmap_offset, unsigned long *bitmap_words,
 			  __u64 bitmap_len)
@@ -1059,6 +1091,7 @@
 {
 	struct gendisk *disk = req->rq_disk;
 	struct ubd *ubd_dev = disk->private_data;
+	int i;
 
 	io_req->req = req;
 	io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
@@ -1068,7 +1101,8 @@
 	io_req->offset = offset;
 	io_req->length = len;
 	io_req->error = 0;
-	io_req->sector_mask = 0;
+	for (i = 0; i < 8; i++)
+		io_req->sector_mask[i] = 0;
 
 	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
 	io_req->offsets[0] = 0;
@@ -1120,7 +1154,7 @@
 					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
-			n = os_write_file(thread_fd, &io_req,
+			n = os_write_file(dev->pipe_fd[1], &io_req,
 					  sizeof(struct io_thread_req *));
 			if(n != sizeof(struct io_thread_req *)){
 				if(n != -EAGAIN)
@@ -1482,3 +1516,86 @@
 
 	return 0;
 }
+
+extern int open(const char *pathname, int flags);
+extern int dup2(int oldfd, int newfd);
+
+void reopen(int fd)
+{
+	char name[64];
+	int tmp_fd;
+
+	sprintf(name, "/proc/self/fd/%d", fd);
+	tmp_fd = open(name, O_RDWR | O_SYNC);
+	os_close_file(fd);
+	dup2(tmp_fd, fd);
+}
+
+int io_subthread(void *arg)
+{
+	struct ubd *ubd_dev = (struct ubd *)arg;
+	struct io_thread_req *req;
+	int n;
+
+	if (ubd_dev->fd >= 0)
+		reopen(ubd_dev->fd);
+
+	if (ubd_dev->cow.fd >= 0)
+		reopen(ubd_dev->cow.fd);
+
+	while(1){
+		n = os_read_file(ubd_dev->pipe_fd[0], &req,
+				 sizeof(struct io_thread_req *));
+		if(n != sizeof(struct io_thread_req *)){
+			if(n < 0)
+				printk("io_subthread - read failed, fd = %d, "
+				       "err = %d\n", ubd_dev->pipe_fd[0], -n);
+			else if (n == 0)
+				break;
+			else {
+				printk("io_subthread - short read, fd = %d, "
+				       "length = %d\n", ubd_dev->pipe_fd[0], n);
+			}
+			continue;
+		}
+		io_count++;
+		do_io(req);
+		n = os_write_file(kernel_fd, &req,
+				  sizeof(struct io_thread_req *));
+		if(n != sizeof(struct io_thread_req *))
+			printk("io_subthread - write failed, fd = %d, err = %d\n",
+			       kernel_fd, -n);
+	}
+
+	ubd_close_dev(ubd_dev);
+
+	return 0;
+}
+
+int per_device_io_thread(void *arg)
+{
+	struct ubd *ubd_dev = (struct ubd *)arg;
+	unsigned long stack[16];
+	int i;
+
+	printk("I/O thread has started.\n");
+
+	ignore_sigwinch_sig();
+
+	os_close_file(ubd_dev->pipe_fd[1]);
+
+	for (i = 0; i < 16; i++) {
+		void *sp;
+		stack[i] = alloc_stack(0, 0);
+		sp = (void *)(stack[i] + PAGE_SIZE - sizeof(void *));
+		clone(io_subthread, sp, CLONE_VM, (void *)ubd_dev);
+	}
+
+	while (waitpid(-1, NULL, __WCLONE) != -1);
+	for (i = 0; i < 16; i++)
+		free_stack(stack[i], 0);
+
+	printk("I/O thread has finished.\n");
+
+	return 0;
+}

[-- Attachment #3: Type: text/plain, Size: 363 bytes --]

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

[-- Attachment #4: Type: text/plain, Size: 194 bytes --]

_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [uml-devel] parallel I/O
  2008-09-15  8:59 ` Nicolas Boullis
@ 2008-10-02 13:34   ` Nicolas Boullis
  2008-10-04  4:28     ` Jeff Dike
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Boullis @ 2008-10-02 13:34 UTC (permalink / raw)
  To: user-mode-linux-devel

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

Hi,

I wrote:
> 
> For what it's worth, here is my quick-n-dirty proof-of-concept patch
> that enables parallel I/O. Note that it is based on 2.6.24.
> 
> If people are interested, I can try to make a clean patch out of it.

For what it's worth, I fixed a few bugs in my patch. Here is the new
patch. It's still "quick'n'dirty", but it works better, and works for me.


Cheers,

Nicolas

[-- Attachment #2: uml_parallel_io.patch --]
[-- Type: text/x-patch, Size: 6731 bytes --]

--- linux-source-2.6.24/arch/um/drivers/ubd_kern.c.orig	2008-09-12 10:28:52.000000000 +0200
+++ linux-source-2.6.24/arch/um/drivers/ubd_kern.c	2008-10-02 15:07:43.000000000 +0200
@@ -65,7 +65,7 @@
 	unsigned long length;
 	char *buffer;
 	int sectorsize;
-	unsigned long sector_mask;
+	unsigned long sector_mask[8];
 	unsigned long long cow_offset;
 	unsigned long bitmap_words[2];
 	int error;
@@ -172,6 +172,9 @@
 	struct scatterlist sg[MAX_SG];
 	struct request *request;
 	int start_sg, end_sg;
+	int pipe_fd[2];
+	int io_pid;
+	unsigned long stacks[17];
 };
 
 #define DEFAULT_COW { \
@@ -196,6 +199,9 @@
 	.request =		NULL, \
 	.start_sg =		0, \
 	.end_sg =		0, \
+	.pipe_fd =		{-1, -1}, \
+	.io_pid =		-1, \
+	.stacks =		{ [0 ... 16] = 0 }, \
 }
 
 /* Protected by ubd_lock */
@@ -473,7 +479,7 @@
 static void do_ubd_request(struct request_queue * q);
 
 /* Only changed by ubd_init, which is an initcall. */
-int thread_fd = -1;
+int common_thread_fd = -1;
 
 static void ubd_end_request(struct request *req, int bytes, int uptodate)
 {
@@ -513,7 +519,7 @@
 	int n;
 
 	while(1){
-		n = os_read_file(thread_fd, &req,
+		n = os_read_file(common_thread_fd, &req,
 				 sizeof(struct io_thread_req *));
 		if(n != sizeof(req)){
 			if(n == -EAGAIN)
@@ -529,7 +535,7 @@
 			ubd_finish(rq, rq->hard_nr_sectors << 9);
 		kfree(req);
 	}
-	reactivate_fd(thread_fd, UBD_IRQ);
+	reactivate_fd(common_thread_fd, UBD_IRQ);
 
 	list_for_each_safe(list, next_ele, &restart){
 		ubd = container_of(list, struct ubd, restart);
@@ -565,6 +571,8 @@
 	return os_file_size(file, size_out);
 }
 
+extern pid_t waitpid(pid_t pid, int *status, int options);
+
 static void ubd_close_dev(struct ubd *ubd_dev)
 {
 	os_close_file(ubd_dev->fd);
@@ -576,6 +584,8 @@
 	ubd_dev->cow.bitmap = NULL;
 }
 
+int per_device_io_thread(void *arg);
+
 static int ubd_open_dev(struct ubd *ubd_dev)
 {
 	struct openflags flags;
@@ -636,6 +646,8 @@
 		if(err < 0) goto error;
 		ubd_dev->cow.fd = err;
 	}
+
+
 	return 0;
  error:
 	os_close_file(ubd_dev->fd);
@@ -938,7 +950,7 @@
 	}
 	stack = alloc_stack(0, 0);
 	io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
-				 &thread_fd);
+				 &common_thread_fd);
 	if(io_pid < 0){
 		printk(KERN_ERR
 		       "ubd : Failed to start I/O thread (errno = %d) - "
@@ -946,7 +958,7 @@
 		io_pid = -1;
 		return 0;
 	}
-	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
+	err = um_request_irq(UBD_IRQ, common_thread_fd, IRQ_READ, ubd_intr,
 			     IRQF_DISABLED, "ubd", ubd_devs);
 	if(err != 0)
 		printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
@@ -962,12 +974,27 @@
 	int err = 0;
 
 	if(ubd_dev->count == 0){
+		void *sp;
+		int i;
+
 		err = ubd_open_dev(ubd_dev);
 		if(err){
 			printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
 			       disk->disk_name, ubd_dev->file, -err);
 			goto out;
 		}
+
+		pipe(ubd_dev->pipe_fd);
+
+		for (i = 0; i <= 16; i++)
+			ubd_dev->stacks[i] = alloc_stack(0, 0);
+		sp = (void *)(ubd_dev->stacks[0] + PAGE_SIZE - sizeof(void *));
+		ubd_dev->io_pid = clone(per_device_io_thread, sp, CLONE_VM, (void *)ubd_dev);
+		os_close_file(ubd_dev->pipe_fd[0]);
+		os_set_exec_close(ubd_dev->pipe_fd[1], 1);
+		os_set_fd_block(ubd_dev->pipe_fd[1], 0);
+
+		printk("Launched I/O thread for %s.\n", disk->disk_name);
 	}
 	ubd_dev->count++;
 	set_disk_ro(disk, !ubd_dev->openflags.w);
@@ -987,12 +1014,26 @@
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct ubd *ubd_dev = disk->private_data;
 
-	if(--ubd_dev->count == 0)
+	if(--ubd_dev->count == 0) {
+		int i;
+		printk("Trying to stop I/O thread for %s... ", disk->disk_name);
+		os_close_file(ubd_dev->pipe_fd[1]);
+		waitpid(ubd_dev->io_pid, NULL, __WCLONE);
+		printk("done.\n");
+		ubd_dev->pipe_fd[0] = -1;
+		ubd_dev->pipe_fd[1] = -1;
+		ubd_dev->io_pid = -1;
+		for (i = 0; i <= 16; i++) {
+			free_stack(ubd_dev->stacks[i], 0);
+			ubd_dev->stacks[i] = 0;
+		}
+
 		ubd_close_dev(ubd_dev);
+	}
 	return 0;
 }
 
-static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
+static void cowify_bitmap(__u64 io_offset, int length, unsigned long (*cow_mask)[],
 			  __u64 *cow_offset, unsigned long *bitmap,
 			  __u64 bitmap_offset, unsigned long *bitmap_words,
 			  __u64 bitmap_len)
@@ -1059,6 +1100,7 @@
 {
 	struct gendisk *disk = req->rq_disk;
 	struct ubd *ubd_dev = disk->private_data;
+	int i;
 
 	io_req->req = req;
 	io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
@@ -1068,7 +1110,8 @@
 	io_req->offset = offset;
 	io_req->length = len;
 	io_req->error = 0;
-	io_req->sector_mask = 0;
+	for (i = 0; i < 8; i++)
+		io_req->sector_mask[i] = 0;
 
 	io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
 	io_req->offsets[0] = 0;
@@ -1120,7 +1163,7 @@
 					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
-			n = os_write_file(thread_fd, &io_req,
+			n = os_write_file(dev->pipe_fd[1], &io_req,
 					  sizeof(struct io_thread_req *));
 			if(n != sizeof(struct io_thread_req *)){
 				if(n != -EAGAIN)
@@ -1482,3 +1525,79 @@
 
 	return 0;
 }
+
+extern int open(const char *pathname, int flags);
+extern int dup2(int oldfd, int newfd);
+
+void reopen(int fd)
+{
+	char name[64];
+	int tmp_fd;
+
+	sprintf(name, "/proc/self/fd/%d", fd);
+	tmp_fd = open(name, O_RDWR | O_SYNC);
+	os_close_file(fd);
+	dup2(tmp_fd, fd);
+	os_close_file(tmp_fd);
+}
+
+int io_subthread(void *arg)
+{
+	struct ubd *ubd_dev = (struct ubd *)arg;
+	struct io_thread_req *req;
+	int n;
+
+	if (ubd_dev->fd >= 0)
+		reopen(ubd_dev->fd);
+
+	if (ubd_dev->cow.fd >= 0)
+		reopen(ubd_dev->cow.fd);
+
+	while(1){
+		n = os_read_file(ubd_dev->pipe_fd[0], &req,
+				 sizeof(struct io_thread_req *));
+		if(n != sizeof(struct io_thread_req *)){
+			if(n < 0)
+				printk("io_subthread - read failed, fd = %d, "
+				       "err = %d\n", ubd_dev->pipe_fd[0], -n);
+			else if (n == 0)
+				break;
+			else {
+				printk("io_subthread - short read, fd = %d, "
+				       "length = %d\n", ubd_dev->pipe_fd[0], n);
+			}
+			continue;
+		}
+		io_count++;
+		do_io(req);
+		n = os_write_file(kernel_fd, &req,
+				  sizeof(struct io_thread_req *));
+		if(n != sizeof(struct io_thread_req *))
+			printk("io_subthread - write failed, fd = %d, err = %d\n",
+			       kernel_fd, -n);
+	}
+
+	ubd_close_dev(ubd_dev);
+
+	return 0;
+}
+
+int per_device_io_thread(void *arg)
+{
+	struct ubd *ubd_dev = (struct ubd *)arg;
+	int i;
+
+	ignore_sigwinch_sig();
+
+	os_close_file(ubd_dev->pipe_fd[1]);
+
+	for (i = 0; i < 16; i++) {
+		void *sp;
+		sp = (void *)(ubd_dev->stacks[i+1] + PAGE_SIZE - sizeof(void *));
+		clone(io_subthread, sp, CLONE_VM, (void *)ubd_dev);
+	}
+
+	while (waitpid(-1, NULL, __WCLONE) != -1);
+
+	return 0;
+}

[-- Attachment #3: Type: text/plain, Size: 363 bytes --]

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

[-- Attachment #4: Type: text/plain, Size: 194 bytes --]

_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [uml-devel] parallel I/O
  2008-10-02 13:34   ` Nicolas Boullis
@ 2008-10-04  4:28     ` Jeff Dike
  2008-10-04 16:37       ` Nicolas Boullis
  0 siblings, 1 reply; 6+ messages in thread
From: Jeff Dike @ 2008-10-04  4:28 UTC (permalink / raw)
  To: Nicolas Boullis; +Cc: user-mode-linux-devel

On Thu, Oct 02, 2008 at 03:34:27PM +0200, Nicolas Boullis wrote:
> I wrote:
> > 
> > For what it's worth, here is my quick-n-dirty proof-of-concept patch
> > that enables parallel I/O. Note that it is based on 2.6.24.
> > 
> > If people are interested, I can try to make a clean patch out of it.
> 
> For what it's worth, I fixed a few bugs in my patch. Here is the new
> patch. It's still "quick'n'dirty", but it works better, and works for me.

Sorry about the lack of responsiveness.

I've had such a patch for quite a while.  I never stuck it in mainline
because I couldn't find any common use cases where it made a noticable
difference.

Does your patch help noticably with anything reasonable common?

     	  	     Jeff

-- 
Work email - jdike at linux dot intel dot com

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [uml-devel] parallel I/O
  2008-10-04  4:28     ` Jeff Dike
@ 2008-10-04 16:37       ` Nicolas Boullis
  2008-10-06 13:28         ` Nicolas Boullis
  0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Boullis @ 2008-10-04 16:37 UTC (permalink / raw)
  To: Jeff Dike; +Cc: user-mode-linux-devel

Hello,

Quoting Jeff Dike <jdike@addtoit.com>:

> Sorry about the lack of responsiveness.

No problem, I'm glad to read you now.


> I've had such a patch for quite a while.  I never stuck it in mainline
> because I couldn't find any common use cases where it made a noticable
> difference.
>
> Does your patch help noticably with anything reasonable common?

It did help significantly for me.
On a reasonably new host, using as UBD devices logical volumes built  
on top of a FC SAN, building a 10GB ext3 filesystem took something  
like 50 seconds before my patch, and something like 3 seconds after  
it. (I can check the exact values if you wish.)
Note that this is using CONFIG_UBD_SYNC (or whatever it is called);  
without it it gets even faster (but I guess parallel I/O make no  
difference).

My feeling is that it might improve performance when reads and writes  
are performed simultaneously, but I have not made any try.

As for using CONFIG_UBD_SYNC, my feeling is that it's much safer if  
the host might crash (or experience power outages, or...): as far as I  
understand it, journaled filesystems need to know when data is  
actually secured on the discs.


Hope this helps,

Nicolas Boullis
Ecole Centrale Paris


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [uml-devel] parallel I/O
  2008-10-04 16:37       ` Nicolas Boullis
@ 2008-10-06 13:28         ` Nicolas Boullis
  0 siblings, 0 replies; 6+ messages in thread
From: Nicolas Boullis @ 2008-10-06 13:28 UTC (permalink / raw)
  To: Jeff Dike, user-mode-linux-devel

Hi,

Nicolas Boullis wrote:
> On a reasonably new host, using as UBD devices logical volumes built  
> on top of a FC SAN, building a 10GB ext3 filesystem took something  
> like 50 seconds before my patch, and something like 3 seconds after  
> it. (I can check the exact values if you wish.)

Hmmm... my memory was making thing much better than they really are.
It's around 38 seconds with 2.6.18 (before the "batch I/O requests"
change); it's several minutes with unpatched 2.6.24, and it's around 7
seconds with patched 2.6.24...

To be more honnest, my patch contains a part similar to Steve
VanDeBogart's "ubd does multiple io's when one will suffice" patch.
Using 2.6.24 with his patch but still serialized I/O, the time is around
23 seconds.

Hence, my patch (with 16 threads per device) make things around 3 times
faster.


Cheers,

Nicolas Boullis
École Centrale Paris

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-10-06 13:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-12 13:40 [uml-devel] parallel I/O Nicolas Boullis
2008-09-15  8:59 ` Nicolas Boullis
2008-10-02 13:34   ` Nicolas Boullis
2008-10-04  4:28     ` Jeff Dike
2008-10-04 16:37       ` Nicolas Boullis
2008-10-06 13:28         ` Nicolas Boullis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.