From 6a9f264ced00390b9e10055059e5e6470778a1e4 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 13 Jul 2006 15:24:25 +0300 Subject: [PATCH] IDLETIMER: We shouldn't sleep in the timer routine Currently, IDLETIMER timer routine calls kobject_uevent, which might sleep. Since we are in interrupt context, we now schedule a work when the timer expires. This calls sysfs_notify() for notifying userspace. Signed-off-by: Samuel Ortiz Signed-off-by: Juha Yrjola --- net/ipv4/netfilter/ipt_IDLETIMER.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/net/ipv4/netfilter/ipt_IDLETIMER.c b/net/ipv4/netfilter/ipt_IDLETIMER.c index 16839e3a15e..2ee9b8cbf83 100644 --- a/net/ipv4/netfilter/ipt_IDLETIMER.c +++ b/net/ipv4/netfilter/ipt_IDLETIMER.c @@ -43,6 +43,7 @@ struct utimer_t { char name[IFNAMSIZ]; struct list_head entry; struct timer_list timer; + struct work_struct work; }; static LIST_HEAD(active_utimer_head); @@ -58,23 +59,31 @@ static void utimer_delete(struct utimer_t *timer) kfree(timer); } -static void utimer_expired(unsigned long data) +static void utimer_work(void * data) { struct utimer_t *timer = (struct utimer_t *) data; struct net_device *netdev; - DEBUGP("Timer '%s' expired\n", timer->name); netdev = dev_get_by_name(timer->name); + if (netdev != NULL) { + sysfs_notify(&netdev->class_dev.kobj, NULL, + "idletimer"); + dev_put(netdev); + } +} + +static void utimer_expired(unsigned long data) +{ + struct utimer_t *timer = (struct utimer_t *) data; + + DEBUGP("Timer '%s' expired\n", timer->name); + spin_lock_bh(&list_lock); utimer_delete(timer); spin_unlock_bh(&list_lock); - if (netdev != NULL) { - kobject_uevent(&netdev->class_dev.kobj, - KOBJ_CHANGE); - dev_put(netdev); - } + schedule_work(&timer->work); } static struct utimer_t *utimer_create(const char *name) @@ -92,6 +101,8 @@ static struct utimer_t *utimer_create(const char *name) timer->timer.function = utimer_expired; timer->timer.data = (unsigned long) timer; + INIT_WORK(&timer->work, utimer_work, timer); + DEBUGP("Created timer '%s'\n", timer->name); return timer; -- 2.41.1