UML: fix missing non-blocking I/O, now DEBUG_SHIRQ works
PATCH 1/1 UML: fix missing non-blocking I/O, now DEBUG_SHIRQ works
*This message was transferred with a trial version of CommuniGate(r) Pro* DEBUG_SHIRQ generates spurious interrupts, triggering handlers such as mconsole_interrupt() or line_interrupt(). They expect data to be available to be read from their sockets/pipes, but in the case of spurious interrupts, the host didn't actually send anything, so UML hangs in read() and friends. Setting those fd's as O_NONBLOCK makes DEBUG_SHIRQ-enabled UML kernels boot and run correctly.
The patch was written and tested on Linux 2.6.22-rc2-mm1.
I have also included a couple of short/minor fixes for potential problems.
--- arch/um/drivers/chan_user.c | 6 ++++++ arch/um/drivers/mconsole_kern.c | 11 +++++------ arch/um/drivers/mconsole_user.c | 5 +++-- arch/um/drivers/ubd_user.c | 6 ++++++ arch/um/drivers/xterm.c | 7 +++++++ 5 files changed, 27 insertions(+), 8 deletions(-)
arch/um/drivers/chan_user.c +6 -0
@@ -170,6 +170,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) err = -EINVAL ; goto out_close; } + +if (os_set_fd_block (*fd_out,0 )) { +printk ("winch_tramp: failed to set thread_fd non-blocking.\n" ); + goto out_close; + } +return err ; out_close:
arch/um/drivers/mconsole_kern.c +5 -6
@@ -74,12 +74,11 @@ static DECLARE_WORK(mconsole_work, mc_work_proc);static irqreturn_t mconsole_interrupt (int irq,void *dev_id) { -/* long to avoid size mismatch warnings from gcc */ -long fd; +int fd;struct mconsole_entry *new;static struct mc_request req;/* that's OK */ - fd = (long ) dev_id; + fd = *((int *) dev_id);while (mconsole_get_request (fd, &req)){if (req.cmd->context ==MCONSOLE_INTR ) (*req.cmd->handler)(&req);
@@ -798,10 +797,10 @@ void mconsole_stack(struct mc_request *req)*/ static char *notify_socket =NULL ; +static int sock; +static int mconsole_init (void ) { -/* long to avoid size mismatch warnings from gcc */ -long sock;int err;char file[256 ];
@@ -818,7 +817,7 @@ static int mconsole_init(void) err =um_request_irq (MCONSOLE_IRQ , sock,IRQ_READ , mconsole_interrupt,IRQF_DISABLED |IRQF_SHARED |IRQF_SAMPLE_RANDOM , -"mconsole" , (void *)sock); +"mconsole" , &sock);if (err){printk ("Failed to get IRQ for management console\n" );return (1 );
arch/um/drivers/mconsole_user.c +3 -2
@@ -86,8 +86,9 @@ int mconsole_get_request(int fd, struct mc_request *req)int len; req->originlen =sizeof (req->origin); - req->len =recvfrom (fd, &req->request,sizeof (req->request),0 , - (struct sockaddr *) req->origin, &req->originlen); + req->len =recvfrom (fd, &req->request,sizeof (req->request), +MSG_DONTWAIT , (struct sockaddr *) req->origin, + &req->originlen);if (req->len <0 )return 0 ;
arch/um/drivers/ubd_user.c +6 -0
@@ -43,6 +43,12 @@ int start_io_thread(unsigned long sp, int *fd_out) kernel_fd = fds[0 ]; *fd_out = fds[1 ]; + err =os_set_fd_block (*fd_out,0 ); +if (err) { +printk ("start_io_thread - failed to set nonblocking I/O.\n" ); + goto out_close; + } + pid =clone (io_thread, (void *) sp,CLONE_FILES |CLONE_VM |SIGCHLD ,NULL );if (pid <0 ){
arch/um/drivers/xterm.c +7 -0
@@ -151,6 +151,13 @@ int xterm_open(int input, int output, int primary, void *d, goto out; } + err =os_set_fd_block (new,0 ); +if (err) { +printk ("xterm_open : failed to set xterm descriptor " +"non-blocking, err = %d\n" , -err); +return (err); + } +CATCH_EINTR (err =tcgetattr (new, &data->tt));if (err){ new = err;
*This message was transferred with a trial version of CommuniGate(r) Pro*
Quoted 1 line · Eduard-Gabriel Munteanu
The patch was written and tested on Linux 2.6.22-rc2-mm1.
Also tested on git. I forgot to tell you the diff is done against git (it was made on that -mm, diffed, applied to git and then git-diffed against HEAD).