]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
IDLETIMER: We shouldn't sleep in the timer routine
authorSamuel Ortiz <samuel.ortiz@solidboot.com>
Thu, 13 Jul 2006 12:24:25 +0000 (15:24 +0300)
committerJuha Yrjola <juha.yrjola@solidboot.com>
Fri, 14 Jul 2006 12:21:26 +0000 (15:21 +0300)
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 <samuel.ortiz@solidboot.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
net/ipv4/netfilter/ipt_IDLETIMER.c

index 16839e3a15ee75e2810041d9fb7d78a51b51f01b..2ee9b8cbf833434b508cc4c4a00cc9be1435d6e9 100644 (file)
@@ -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;