From 80e7b3cc8927bbb55efcfd4e7b46d5674c692575 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Wed, 18 Jan 2006 17:42:56 -0800 Subject: [PATCH] --- yaml --- r: 18928 b: refs/heads/master c: 71c8d4c3aad3132765d30b05dce98bb8a9508f02 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/um/drivers/net_kern.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 185fbf7b7d6a..0b3f7ca5a74e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e56a78855a4f72fc658bfd21d08939dd6e09fa4c +refs/heads/master: 71c8d4c3aad3132765d30b05dce98bb8a9508f02 diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index f3442ce29a21..8ebb2241ad42 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -68,6 +68,11 @@ static int uml_net_rx(struct net_device *dev) return pkt_len; } +static void uml_dev_close(void* dev) +{ + dev_close( (struct net_device *) dev); +} + irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; @@ -80,15 +85,21 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) spin_lock(&lp->lock); while((err = uml_net_rx(dev)) > 0) ; if(err < 0) { + DECLARE_WORK(close_work, uml_dev_close, dev); printk(KERN_ERR "Device '%s' read returned %d, shutting it down\n", dev->name, err); - dev_close(dev); + /* dev_close can't be called in interrupt context, and takes + * again lp->lock. + * And dev_close() can be safely called multiple times on the + * same device, since it tests for (dev->flags & IFF_UP). So + * there's no harm in delaying the device shutdown. */ + schedule_work(&close_work); goto out; } reactivate_fd(lp->fd, UM_ETH_IRQ); - out: +out: spin_unlock(&lp->lock); return(IRQ_HANDLED); }