]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
alarmtimer: Unregister wakeup source when module get fails
authorStephen Boyd <swboyd@chromium.org>
Thu, 9 Jan 2020 15:59:07 +0000 (07:59 -0800)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 15 Jan 2020 10:16:54 +0000 (11:16 +0100)
The alarmtimer_rtc_add_device() function creates a wakeup source and then
tries to grab a module reference. If that fails the function returns early
with an error code, but fails to remove the wakeup source.

Cleanup this exit path so there is no dangling wakeup source, which is
named 'alarmtime' left allocated which will conflict with another RTC
device that may be registered later.

Fixes: 51218298a25e ("alarmtimer: Ensure RTC module is not unloaded")
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20200109155910.907-2-swboyd@chromium.org
kernel/time/alarmtimer.c

index b51b36e533c4387bc1709a9b2747973793e8537d..9dc7a0913190cd846980f1d2a6cdd647a878fc1a 100644 (file)
@@ -91,6 +91,7 @@ static int alarmtimer_rtc_add_device(struct device *dev,
        unsigned long flags;
        struct rtc_device *rtc = to_rtc_device(dev);
        struct wakeup_source *__ws;
+       int ret = 0;
 
        if (rtcdev)
                return -EBUSY;
@@ -105,8 +106,8 @@ static int alarmtimer_rtc_add_device(struct device *dev,
        spin_lock_irqsave(&rtcdev_lock, flags);
        if (!rtcdev) {
                if (!try_module_get(rtc->owner)) {
-                       spin_unlock_irqrestore(&rtcdev_lock, flags);
-                       return -1;
+                       ret = -1;
+                       goto unlock;
                }
 
                rtcdev = rtc;
@@ -115,11 +116,12 @@ static int alarmtimer_rtc_add_device(struct device *dev,
                ws = __ws;
                __ws = NULL;
        }
+unlock:
        spin_unlock_irqrestore(&rtcdev_lock, flags);
 
        wakeup_source_unregister(__ws);
 
-       return 0;
+       return ret;
 }
 
 static inline void alarmtimer_rtc_timer_init(void)