* [PATCH] UML - Fix 2.6.20 hang
@ 2007-02-15 17:07 ` Jeff Dike
0 siblings, 0 replies; 5+ messages in thread
From: Jeff Dike @ 2007-02-15 17:07 UTC (permalink / raw)
To: akpm, stable; +Cc: uml, user-mode-linux-devel, linux-kernel
A previous cleanup misused need_poll, which had a fairly broken
interface. It implemented a growable array, changing the used
elements count itself, but leaving it up to the caller to fill in the
actual elements, including the entire array if the array had to be
reallocated. This worked because the previous users were switching
between two such structures, and the elements were copied from the
inactive array to the active array after making sure the active array
had enough room.
maybe_sigio_broken was made to use need_poll, but it was operating on
a single array, so when the buffer was reallocated, the previous
contents were lost.
This patch makes need_poll implement more sane semantics. It merely
assures that the array is of the proper size and that the contents are
preserved. It is up to the caller to adjust the used elements count
and to ensure that the proper elements are resent.
This manifested itself as a hang in 2.6.20 as the uninitialized buffer
convinced UML that one of its own file descriptors didn't support
SIGIO and needed to be watched by poll in a separate thread. The
result was an interrupt flood as control traffic over this descriptor
sparked interrupts, which resulted in more control traffic, ad nauseum.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
--
arch/um/os-Linux/sigio.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
Index: linux-2.6.18-mm/arch/um/os-Linux/sigio.c
===================================================================
--- linux-2.6.18-mm.orig/arch/um/os-Linux/sigio.c 2007-02-08 16:48:00.000000000 -0500
+++ linux-2.6.18-mm/arch/um/os-Linux/sigio.c 2007-02-14 19:16:22.000000000 -0500
@@ -97,20 +97,22 @@ static int write_sigio_thread(void *unus
static int need_poll(struct pollfds *polls, int n)
{
- if(n <= polls->size){
- polls->used = n;
+ struct pollfd *new;
+
+ if(n <= polls->size)
return 0;
- }
- kfree(polls->poll);
- polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
- if(polls->poll == NULL){
+
+ new = um_kmalloc_atomic(n * sizeof(struct pollfd));
+ if(new == NULL){
printk("need_poll : failed to allocate new pollfds\n");
- polls->size = 0;
- polls->used = 0;
return -ENOMEM;
}
+
+ memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
+ kfree(polls->poll);
+
+ polls->poll = new;
polls->size = n;
- polls->used = n;
return 0;
}
@@ -171,15 +173,15 @@ int add_sigio_fd(int fd)
goto out;
}
- n = current_poll.used + 1;
- err = need_poll(&next_poll, n);
+ n = current_poll.used;
+ err = need_poll(&next_poll, n + 1);
if(err)
goto out;
- for(i = 0; i < current_poll.used; i++)
- next_poll.poll[i] = current_poll.poll[i];
-
- next_poll.poll[n - 1] = *p;
+ memcpy(next_poll.poll, current_poll.poll,
+ current_poll.used * sizeof(struct pollfd));
+ next_poll.poll[n] = *p;
+ next_poll.used = n + 1;
update_thread();
out:
sigio_unlock();
@@ -214,6 +216,7 @@ int ignore_sigio_fd(int fd)
if(p->fd != fd)
next_poll.poll[n++] = *p;
}
+ next_poll.used = current_poll.used - 1;
update_thread();
out:
@@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read
sigio_lock();
err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
- if(err){
- printk("maybe_sigio_broken - failed to add pollfd\n");
+ if(err)
goto out;
- }
+
all_sigio_fds.poll[all_sigio_fds.used++] =
((struct pollfd) { .fd = fd,
.events = read ? POLLIN : POLLOUT,
^ permalink raw reply [flat|nested] 5+ messages in thread
* [uml-devel] [PATCH] UML - Fix 2.6.20 hang
@ 2007-02-15 17:07 ` Jeff Dike
0 siblings, 0 replies; 5+ messages in thread
From: Jeff Dike @ 2007-02-15 17:07 UTC (permalink / raw)
To: akpm, stable; +Cc: uml, user-mode-linux-devel, linux-kernel
A previous cleanup misused need_poll, which had a fairly broken
interface. It implemented a growable array, changing the used
elements count itself, but leaving it up to the caller to fill in the
actual elements, including the entire array if the array had to be
reallocated. This worked because the previous users were switching
between two such structures, and the elements were copied from the
inactive array to the active array after making sure the active array
had enough room.
maybe_sigio_broken was made to use need_poll, but it was operating on
a single array, so when the buffer was reallocated, the previous
contents were lost.
This patch makes need_poll implement more sane semantics. It merely
assures that the array is of the proper size and that the contents are
preserved. It is up to the caller to adjust the used elements count
and to ensure that the proper elements are resent.
This manifested itself as a hang in 2.6.20 as the uninitialized buffer
convinced UML that one of its own file descriptors didn't support
SIGIO and needed to be watched by poll in a separate thread. The
result was an interrupt flood as control traffic over this descriptor
sparked interrupts, which resulted in more control traffic, ad nauseum.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
--
arch/um/os-Linux/sigio.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
Index: linux-2.6.18-mm/arch/um/os-Linux/sigio.c
===================================================================
--- linux-2.6.18-mm.orig/arch/um/os-Linux/sigio.c 2007-02-08 16:48:00.000000000 -0500
+++ linux-2.6.18-mm/arch/um/os-Linux/sigio.c 2007-02-14 19:16:22.000000000 -0500
@@ -97,20 +97,22 @@ static int write_sigio_thread(void *unus
static int need_poll(struct pollfds *polls, int n)
{
- if(n <= polls->size){
- polls->used = n;
+ struct pollfd *new;
+
+ if(n <= polls->size)
return 0;
- }
- kfree(polls->poll);
- polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
- if(polls->poll == NULL){
+
+ new = um_kmalloc_atomic(n * sizeof(struct pollfd));
+ if(new == NULL){
printk("need_poll : failed to allocate new pollfds\n");
- polls->size = 0;
- polls->used = 0;
return -ENOMEM;
}
+
+ memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
+ kfree(polls->poll);
+
+ polls->poll = new;
polls->size = n;
- polls->used = n;
return 0;
}
@@ -171,15 +173,15 @@ int add_sigio_fd(int fd)
goto out;
}
- n = current_poll.used + 1;
- err = need_poll(&next_poll, n);
+ n = current_poll.used;
+ err = need_poll(&next_poll, n + 1);
if(err)
goto out;
- for(i = 0; i < current_poll.used; i++)
- next_poll.poll[i] = current_poll.poll[i];
-
- next_poll.poll[n - 1] = *p;
+ memcpy(next_poll.poll, current_poll.poll,
+ current_poll.used * sizeof(struct pollfd));
+ next_poll.poll[n] = *p;
+ next_poll.used = n + 1;
update_thread();
out:
sigio_unlock();
@@ -214,6 +216,7 @@ int ignore_sigio_fd(int fd)
if(p->fd != fd)
next_poll.poll[n++] = *p;
}
+ next_poll.used = current_poll.used - 1;
update_thread();
out:
@@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read
sigio_lock();
err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
- if(err){
- printk("maybe_sigio_broken - failed to add pollfd\n");
+ if(err)
goto out;
- }
+
all_sigio_fds.poll[all_sigio_fds.used++] =
((struct pollfd) { .fd = fd,
.events = read ? POLLIN : POLLOUT,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
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] 5+ messages in thread
* Re: [uml-devel] [PATCH] UML - Fix 2.6.20 hang
2007-02-15 17:07 ` [uml-devel] " Jeff Dike
@ 2007-02-22 0:22 ` Blaisorblade
-1 siblings, 0 replies; 5+ messages in thread
From: Blaisorblade @ 2007-02-22 0:22 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: Jeff Dike, akpm, stable, uml, linux-kernel
On Thursday 15 February 2007 18:07, Jeff Dike wrote:
> Signed-off-by: Jeff Dike <jdike@addtoit.com>
[...]
> @@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read
>
> sigio_lock();
> err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
> - if(err){
> - printk("maybe_sigio_broken - failed to add pollfd\n");
> + if(err)
> goto out;
> - }
> +
> all_sigio_fds.poll[all_sigio_fds.used++] =
> ((struct pollfd) { .fd = fd,
> .events = read ? POLLIN : POLLOUT,
>
Was that removal wanted or it happened by mistake? That way, err is completely
lost.
--
Inform me of my mistakes, so I can add them to my list!
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Chiacchiera con i tuoi amici in tempo reale!
http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [uml-devel] [PATCH] UML - Fix 2.6.20 hang
@ 2007-02-22 0:22 ` Blaisorblade
0 siblings, 0 replies; 5+ messages in thread
From: Blaisorblade @ 2007-02-22 0:22 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: akpm, Jeff Dike, uml, stable, linux-kernel
On Thursday 15 February 2007 18:07, Jeff Dike wrote:
> Signed-off-by: Jeff Dike <jdike@addtoit.com>
[...]
> @@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read
>
> sigio_lock();
> err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
> - if(err){
> - printk("maybe_sigio_broken - failed to add pollfd\n");
> + if(err)
> goto out;
> - }
> +
> all_sigio_fds.poll[all_sigio_fds.used++] =
> ((struct pollfd) { .fd = fd,
> .events = read ? POLLIN : POLLOUT,
>
Was that removal wanted or it happened by mistake? That way, err is completely
lost.
--
Inform me of my mistakes, so I can add them to my list!
Paolo Giarrusso, aka Blaisorblade
http://www.user-mode-linux.org/~blaisorblade
Chiacchiera con i tuoi amici in tempo reale!
http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
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] 5+ messages in thread
* [PATCH] UML - Fix 2.6.20 hang
@ 2007-02-22 16:48 Jeff Dike
0 siblings, 0 replies; 5+ messages in thread
From: Jeff Dike @ 2007-02-22 16:48 UTC (permalink / raw)
To: stable, linux-kernel; +Cc: Blaisorblade, user-mode-linux-devel
[ I mistyped the -stable email in my original posting ]
A previous cleanup misused need_poll, which had a fairly broken
interface. It implemented a growable array, changing the used
elements count itself, but leaving it up to the caller to fill in the
actual elements, including the entire array if the array had to be
reallocated. This worked because the previous users were switching
between two such structures, and the elements were copied from the
inactive array to the active array after making sure the active array
had enough room.
maybe_sigio_broken was made to use need_poll, but it was operating on
a single array, so when the buffer was reallocated, the previous
contents were lost.
This patch makes need_poll implement more sane semantics. It merely
assures that the array is of the proper size and that the contents are
preserved. It is up to the caller to adjust the used elements count
and to ensure that the proper elements are resent.
This manifested itself as a hang in 2.6.20 as the uninitialized buffer
convinced UML that one of its own file descriptors didn't support
SIGIO and needed to be watched by poll in a separate thread. The
result was an interrupt flood as control traffic over this descriptor
sparked interrupts, which resulted in more control traffic, ad nauseum.
Signed-off-by: Jeff Dike <jdike@addtoit.com>
--
arch/um/os-Linux/sigio.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
Index: linux-2.6.18-mm/arch/um/os-Linux/sigio.c
===================================================================
--- linux-2.6.18-mm.orig/arch/um/os-Linux/sigio.c 2007-02-08 16:48:00.000000000 -0500
+++ linux-2.6.18-mm/arch/um/os-Linux/sigio.c 2007-02-14 19:16:22.000000000 -0500
@@ -97,20 +97,22 @@ static int write_sigio_thread(void *unus
static int need_poll(struct pollfds *polls, int n)
{
- if(n <= polls->size){
- polls->used = n;
+ struct pollfd *new;
+
+ if(n <= polls->size)
return 0;
- }
- kfree(polls->poll);
- polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
- if(polls->poll == NULL){
+
+ new = um_kmalloc_atomic(n * sizeof(struct pollfd));
+ if(new == NULL){
printk("need_poll : failed to allocate new pollfds\n");
- polls->size = 0;
- polls->used = 0;
return -ENOMEM;
}
+
+ memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
+ kfree(polls->poll);
+
+ polls->poll = new;
polls->size = n;
- polls->used = n;
return 0;
}
@@ -171,15 +173,15 @@ int add_sigio_fd(int fd)
goto out;
}
- n = current_poll.used + 1;
- err = need_poll(&next_poll, n);
+ n = current_poll.used;
+ err = need_poll(&next_poll, n + 1);
if(err)
goto out;
- for(i = 0; i < current_poll.used; i++)
- next_poll.poll[i] = current_poll.poll[i];
-
- next_poll.poll[n - 1] = *p;
+ memcpy(next_poll.poll, current_poll.poll,
+ current_poll.used * sizeof(struct pollfd));
+ next_poll.poll[n] = *p;
+ next_poll.used = n + 1;
update_thread();
out:
sigio_unlock();
@@ -214,6 +216,7 @@ int ignore_sigio_fd(int fd)
if(p->fd != fd)
next_poll.poll[n++] = *p;
}
+ next_poll.used = current_poll.used - 1;
update_thread();
out:
@@ -331,10 +334,9 @@ void maybe_sigio_broken(int fd, int read
sigio_lock();
err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
- if(err){
- printk("maybe_sigio_broken - failed to add pollfd\n");
+ if(err)
goto out;
- }
+
all_sigio_fds.poll[all_sigio_fds.used++] =
((struct pollfd) { .fd = fd,
.events = read ? POLLIN : POLLOUT,
--
Work email - jdike at linux dot intel dot com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-02-22 16:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-15 17:07 [PATCH] UML - Fix 2.6.20 hang Jeff Dike
2007-02-15 17:07 ` [uml-devel] " Jeff Dike
2007-02-22 0:22 ` Blaisorblade
2007-02-22 0:22 ` Blaisorblade
2007-02-22 16:48 Jeff Dike
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.