linux-um archives
 help / color / mirror / Atom feed
* [uml-devel] [PATCH 01/11] uml: sigio code - reduce spinlock hold time
@ 2005-10-25 22:00 Paolo 'Blaisorblade' Giarrusso
  2005-10-25 22:01 ` [uml-devel] [PATCH 02/11] Uml: fix access_ok Paolo 'Blaisorblade' Giarrusso
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Paolo 'Blaisorblade' Giarrusso @ 2005-10-25 22:00 UTC (permalink / raw)
  To: Jeff Dike; +Cc: linux-kernel, user-mode-linux-devel

From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

In a previous patch I shifted an allocation to being atomic.

In this patch, a better but more intrusive solution is implemented, i.e. hold
the lock only when really needing it, especially not over pipe operations, nor
over the culprit allocation.

Additionally, while at it, add a missing kfree in the failure path, and make
sure that if we fail in forking, write_sigio_pid is -1 and not, say, -ENOMEM.

And fix whitespace, at least for things I was touching anyway.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
---

 arch/um/kernel/sigio_user.c |   84 ++++++++++++++++++++++++++++++-------------
 1 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -336,70 +336,104 @@ int ignore_sigio_fd(int fd)
 	return(err);
 }
 
-static int setup_initial_poll(int fd)
+static struct pollfd* setup_initial_poll(int fd)
 {
 	struct pollfd *p;
 
-	p = um_kmalloc_atomic(sizeof(struct pollfd));
-	if(p == NULL){
+	p = um_kmalloc(sizeof(struct pollfd));
+	if (p == NULL) {
 		printk("setup_initial_poll : failed to allocate poll\n");
-		return(-1);
+		return NULL;
 	}
 	*p = ((struct pollfd) { .fd  	= fd,
 				.events 	= POLLIN,
 				.revents 	= 0 });
-	current_poll = ((struct pollfds) { .poll 	= p,
-					   .used 	= 1,
-					   .size 	= 1 });
-	return(0);
+	return p;
 }
 
 void write_sigio_workaround(void)
 {
 	unsigned long stack;
+	struct pollfd *p;
 	int err;
+	int l_write_sigio_fds[2];
+	int l_sigio_private[2];
+	int l_write_sigio_pid;
 
+	/* We call this *tons* of times - and most ones we must just fail. */
 	sigio_lock();
-	if(write_sigio_pid != -1)
-		goto out;
+	l_write_sigio_pid = write_sigio_pid;
+	sigio_unlock();
+
+	if (l_write_sigio_pid != -1)
+		return;
 
-	err = os_pipe(write_sigio_fds, 1, 1);
+	err = os_pipe(l_write_sigio_fds, 1, 1);
 	if(err < 0){
 		printk("write_sigio_workaround - os_pipe 1 failed, "
 		       "err = %d\n", -err);
-		goto out;
+		return;
 	}
-	err = os_pipe(sigio_private, 1, 1);
+	err = os_pipe(l_sigio_private, 1, 1);
 	if(err < 0){
-		printk("write_sigio_workaround - os_pipe 2 failed, "
+		printk("write_sigio_workaround - os_pipe 1 failed, "
 		       "err = %d\n", -err);
 		goto out_close1;
 	}
-	if(setup_initial_poll(sigio_private[1]))
+
+	p = setup_initial_poll(l_sigio_private[1]);
+	if(!p)
 		goto out_close2;
 
-	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
+	sigio_lock();
+
+	/* Did we race? Don't try to optimize this, please, it's not so likely
+	 * to happen, and no more than once at the boot. */
+	if(write_sigio_pid != -1)
+		goto out_unlock;
+
+	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
 					    CLONE_FILES | CLONE_VM, &stack, 0);
 
-	if(write_sigio_pid < 0) goto out_close2;
+	if (write_sigio_pid < 0)
+		goto out_clear;
 
-	if(write_sigio_irq(write_sigio_fds[0])) 
+	if (write_sigio_irq(l_write_sigio_fds[0])) 
 		goto out_kill;
 
- out:
+	/* Success, finally. */
+	memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
+	memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
+
+	current_poll = ((struct pollfds) { .poll 	= p,
+					   .used 	= 1,
+					   .size 	= 1 });
+
 	sigio_unlock();
 	return;
 
  out_kill:
-	os_kill_process(write_sigio_pid, 1);
+	l_write_sigio_pid = write_sigio_pid;
+	write_sigio_pid = -1;
+	sigio_unlock();
+	/* Going to call waitpid, avoid holding the lock. */
+	os_kill_process(l_write_sigio_pid, 1);
+	goto out_free;
+
+ out_clear:
 	write_sigio_pid = -1;
+ out_unlock:
+	sigio_unlock();
+ out_free:
+	kfree(p);
  out_close2:
-	os_close_file(sigio_private[0]);
-	os_close_file(sigio_private[1]);
+	os_close_file(l_sigio_private[0]);
+	os_close_file(l_sigio_private[1]);
  out_close1:
-	os_close_file(write_sigio_fds[0]);
-	os_close_file(write_sigio_fds[1]);
-	sigio_unlock();
+	os_close_file(l_write_sigio_fds[0]);
+	os_close_file(l_write_sigio_fds[1]);
+	return;
+
 }
 
 int read_sigio_fd(int fd)



-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.
Get Certified Today * Register for a JBoss Training Course
Free Certification Exam for All Training Attendees Through End of 2005
Visit http://www.jboss.com/services/certification for more information
_______________________________________________
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] 11+ messages in thread

end of thread, other threads:[~2005-10-25 22:05 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-25 22:00 [uml-devel] [PATCH 01/11] uml: sigio code - reduce spinlock hold time Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 02/11] Uml: fix access_ok Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 03/11] uml: fix signal code x86-64 [for 2.6.15] Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 04/11] uml: fix SKAS0 assembly stubs - use proper constraints Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 05/11] uml: fix assembly stub for segv Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 06/11] uml: remove bogus WARN_ON, triggerable harmlessly on a page fault race Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:01 ` [uml-devel] [PATCH 07/11] uml: fix mcast network driver error handling Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:02 ` [uml-devel] [PATCH 08/11] uml console channels: remove console_write wrappers Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:02 ` [uml-devel] [PATCH 09/11] uml console channels: fix the API of console_write Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:02 ` [uml-devel] [PATCH 10/11] uml: avoid malloc to sleep in atomic sections Paolo 'Blaisorblade' Giarrusso
2005-10-25 22:03 ` [uml-devel] [PATCH 11/11] uml: micro fixups to arch Kconfig Paolo 'Blaisorblade' Giarrusso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox