From: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]> From: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]>
Also, fix a bit of issues in activate_fd(). It's not up-to-date wrt comment vs. code. I had this patch in my queue since some time, because it fixes some spinlocks vs sleeps issues; please verify whether after your restructuring it is still needed (it applied before this restructuring). Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]> --- arch/um/kernel/irq.c | 26 +++++++++++++------------- 1 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 589c69a..a5da95f 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -124,7 +124,7 @@ int activate_fd(int irq, int fd, int typ if (err < 0) goto out; - new_fd = um_kmalloc(sizeof(*new_fd)); + new_fd = um_kmalloc_atomic(sizeof(*new_fd)); err = -ENOMEM; if (new_fd == NULL) goto out; @@ -145,15 +145,17 @@ int activate_fd(int irq, int fd, int typ /* Critical section - locked by a spinlock because this stuff can * be changed from interrupt handlers. The stuff above is done * outside the lock because it allocates memory. + * Also, we can be called with spinlocks held - see + * write_sigio_workaround->write_sigio_irq->um_request_irq->activate_fd. */ /* Actually, it only looks like it can be called from interrupt * context. The culprit is reactivate_fd, which calls * maybe_sigio_broken, which calls write_sigio_workaround, * which calls activate_fd. However, write_sigio_workaround should - * only be called once, at boot time. That would make it clear that - * this is called only from process context, and can be locked with - * a semaphore. + * only be called once, at boot time. + * However we can be still called (once) under spinlocks, so we need + * anyway a semaphore. */ spin_lock_irqsave(&irq_lock, flags); for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { @@ -182,21 +184,19 @@ int activate_fd(int irq, int fd, int typ * and tmp_fds is NULL or too small for new pollfds array. * Needed size is equal to n as minimum. * - * Here we have to drop the lock in order to call - * kmalloc, which might sleep. - * If something else came in and changed the pollfds array + * We don't drop the lock any more; when we dropped it, we + * needed to loop: + * "If something else came in and changed the pollfds array * so we will not be able to put new pollfd struct to pollfds - * then we free the buffer tmp_fds and try again. + * then we free the buffer tmp_fds and try again." + * Do we still need now? Keep on the safe side for now - BB. */ - spin_unlock_irqrestore(&irq_lock, flags); kfree(tmp_pfd); tmp_pfd = NULL; - tmp_pfd = um_kmalloc(n); + tmp_pfd = um_kmalloc_atomic(n); if (tmp_pfd == NULL) - goto out_kfree; - - spin_lock_irqsave(&irq_lock, flags); + goto out_unlock; } /*-------------*/ ------------------------------------------------------------------------- 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