Whamcloud - gitweb
LU-4423 lnet: use 64-bit time for selftest
[fs/lustre-release.git] / lnet / selftest / timer.c
index 7370f58..ff016e9 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 
 
 /*
- * Timers are implemented as a sorted queue of expiry times. The queue 
- * is slotted, with each slot holding timers which expire in a 
- * 2**STTIMER_MINPOLL (8) second period. The timers in each slot are 
+ * Timers are implemented as a sorted queue of expiry times. The queue
+ * is slotted, with each slot holding timers which expire in a
+ * 2**STTIMER_MINPOLL (8) second period. The timers in each slot are
  * sorted by increasing expiry time. The number of slots is 2**7 (128),
  * to cover a time period of 1024 seconds into the future before wrapping.
  */
-#define        STTIMER_MINPOLL        3   /* log2 min poll interval (8 s) */
-#define        STTIMER_SLOTTIME       (1 << STTIMER_MINPOLL)
-#define        STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))
-#define        STTIMER_NSLOTS         (1 << 7)
-#define        STTIMER_SLOT(t)        (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
+#define STTIMER_MINPOLL        3   /* log2 min poll interval (8 s) */
+#define STTIMER_SLOTTIME       (1 << STTIMER_MINPOLL)
+#define STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))
+#define STTIMER_NSLOTS        (1 << 7)
+#define STTIMER_SLOT(t)               (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
                                                     (STTIMER_NSLOTS - 1))])
 
-struct st_timer_data {
-        spinlock_t       stt_lock;
-        /* start time of the slot processed previously */
-        cfs_time_t       stt_prev_slot; 
-        struct list_head stt_hash[STTIMER_NSLOTS];
-        int              stt_shuttingdown;
-#ifdef __KERNEL__
-        cfs_waitq_t      stt_waitq;
-        int              stt_nthreads;
-#endif
+static struct st_timer_data {
+       spinlock_t              stt_lock;
+       /* start time of the slot processed previously */
+       cfs_time_t              stt_prev_slot;
+       struct list_head        stt_hash[STTIMER_NSLOTS];
+       int                     stt_shuttingdown;
+       wait_queue_head_t       stt_waitq;
+       int                     stt_nthreads;
 } stt_data;
 
 void
-stt_add_timer (stt_timer_t *timer)
+stt_add_timer(stt_timer_t *timer)
 {
-        struct list_head *pos;
+       struct list_head *pos;
 
-        spin_lock(&stt_data.stt_lock);
+       spin_lock(&stt_data.stt_lock);
 
-#ifdef __KERNEL__
-        LASSERT (stt_data.stt_nthreads > 0);
-#endif
-        LASSERT (!stt_data.stt_shuttingdown);
-        LASSERT (timer->stt_func != NULL);
-        LASSERT (list_empty(&timer->stt_list));
-        LASSERT (cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
+       LASSERT(timer->stt_func != NULL);
+       LASSERT(list_empty(&timer->stt_list));
+       LASSERT(timer->stt_expires > ktime_get_real_seconds());
 
-        /* a simple insertion sort */
-        list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) {
-                stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);
+       /* a simple insertion sort */
+       list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) {
+               stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);
 
-                if (cfs_time_aftereq(timer->stt_expires, old->stt_expires))
-                        break;
-        }
-        list_add(&timer->stt_list, pos);
+               if (timer->stt_expires >= old->stt_expires)
+                       break;
+       }
+       list_add(&timer->stt_list, pos);
 
-        spin_unlock(&stt_data.stt_lock);
+       spin_unlock(&stt_data.stt_lock);
 }
 
 /*
@@ -106,129 +98,110 @@ stt_add_timer (stt_timer_t *timer)
  * another CPU.
  */
 int
-stt_del_timer (stt_timer_t *timer)
+stt_del_timer(stt_timer_t *timer)
 {
-        int ret = 0;
+       int ret = 0;
 
-        spin_lock(&stt_data.stt_lock);
+       spin_lock(&stt_data.stt_lock);
 
-#ifdef __KERNEL__
-        LASSERT (stt_data.stt_nthreads > 0);
-#endif
-        LASSERT (!stt_data.stt_shuttingdown);
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
 
-        if (!list_empty(&timer->stt_list)) {
-                ret = 1;
-                list_del_init(&timer->stt_list);
-        }
+       if (!list_empty(&timer->stt_list)) {
+               ret = 1;
+               list_del_init(&timer->stt_list);
+       }
 
-        spin_unlock(&stt_data.stt_lock);
-        return ret;
+       spin_unlock(&stt_data.stt_lock);
+       return ret;
 }
 
 /* called with stt_data.stt_lock held */
-int
-stt_expire_list (struct list_head *slot, cfs_time_t now)
+static int
+stt_expire_list(struct list_head *slot, time64_t now)
 {
-        int          expired = 0;
-        stt_timer_t *timer;
+       int          expired = 0;
+       stt_timer_t *timer;
+
+       while (!list_empty(slot)) {
+               timer = list_entry(slot->next, stt_timer_t, stt_list);
 
-        while (!list_empty(slot)) {
-                timer = list_entry(slot->next, stt_timer_t, stt_list);
+               if (timer->stt_expires > now)
+                       break;
 
-                if (cfs_time_after(timer->stt_expires, now))
-                        break;
+               list_del_init(&timer->stt_list);
+               spin_unlock(&stt_data.stt_lock);
 
-                list_del_init(&timer->stt_list);
-                spin_unlock(&stt_data.stt_lock);
+               expired++;
+               (*timer->stt_func) (timer->stt_data);
 
-                expired++;
-                (*timer->stt_func) (timer->stt_data);
-                
-                spin_lock(&stt_data.stt_lock);
-        }
+               spin_lock(&stt_data.stt_lock);
+       }
 
-        return expired;
+       return expired;
 }
 
-int
-stt_check_timers (cfs_time_t *last)
+static int
+stt_check_timers(cfs_time_t *last)
 {
-        int        expired = 0;
-        cfs_time_t now;
+       int expired = 0;
+       time64_t now;
         cfs_time_t this_slot;
 
-        now = cfs_time_current_sec();
+       now = ktime_get_real_seconds();
         this_slot = now & STTIMER_SLOTTIMEMASK;
 
-        spin_lock(&stt_data.stt_lock);
+       spin_lock(&stt_data.stt_lock);
 
-        while (cfs_time_aftereq(this_slot, *last)) {
-                expired += stt_expire_list(STTIMER_SLOT(this_slot), now);
-                this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME);
-        }
+       while (cfs_time_aftereq(this_slot, *last)) {
+               expired += stt_expire_list(STTIMER_SLOT(this_slot), now);
+               this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME);
+       }
 
-        *last = now & STTIMER_SLOTTIMEMASK;
-        spin_unlock(&stt_data.stt_lock);
-        return expired;
+       *last = now & STTIMER_SLOTTIMEMASK;
+       spin_unlock(&stt_data.stt_lock);
+       return expired;
 }
 
-#ifdef __KERNEL__
 
-int
+static int
 stt_timer_main (void *arg)
 {
-        UNUSED(arg);
+        int rc = 0;
 
-        cfs_daemonize("st_timer");
         cfs_block_allsigs();
 
-        while (!stt_data.stt_shuttingdown) {
-                stt_check_timers(&stt_data.stt_prev_slot);
+       while (!stt_data.stt_shuttingdown) {
+               stt_check_timers(&stt_data.stt_prev_slot);
 
-                cfs_waitq_wait_event_timeout(stt_data.stt_waitq,
-                                   stt_data.stt_shuttingdown,
-                                   cfs_time_seconds(STTIMER_SLOTTIME));
-        }
+               rc = wait_event_timeout(stt_data.stt_waitq,
+                                       stt_data.stt_shuttingdown,
+                                       cfs_time_seconds(STTIMER_SLOTTIME));
+       }
 
-        spin_lock(&stt_data.stt_lock);
-        stt_data.stt_nthreads--;
-        spin_unlock(&stt_data.stt_lock);
-        return 0;
+       spin_lock(&stt_data.stt_lock);
+       stt_data.stt_nthreads--;
+       spin_unlock(&stt_data.stt_lock);
+       return rc;
 }
 
-int
+static int
 stt_start_timer_thread (void)
 {
-        long pid;
+       struct task_struct *task;
 
-        LASSERT (!stt_data.stt_shuttingdown);
+       LASSERT(!stt_data.stt_shuttingdown);
 
-        pid = cfs_kernel_thread(stt_timer_main, NULL, 0);
-        if (pid < 0)
-                return (int)pid;
+       task = kthread_run(stt_timer_main, NULL, "st_timer");
+       if (IS_ERR(task))
+               return PTR_ERR(task);
 
-        spin_lock(&stt_data.stt_lock);
-        stt_data.stt_nthreads++;
-        spin_unlock(&stt_data.stt_lock);
-        return 0;
+       spin_lock(&stt_data.stt_lock);
+       stt_data.stt_nthreads++;
+       spin_unlock(&stt_data.stt_lock);
+       return 0;
 }
 
-#else /* !__KERNEL__ */
-
-int
-stt_check_events (void)
-{
-        return stt_check_timers(&stt_data.stt_prev_slot);
-}
-
-int
-stt_poll_interval (void)
-{
-        return STTIMER_SLOTTIME;
-}
-
-#endif
 
 int
 stt_startup (void)
@@ -237,42 +210,37 @@ stt_startup (void)
         int i;
 
         stt_data.stt_shuttingdown = 0;
-        stt_data.stt_prev_slot = cfs_time_current_sec() & STTIMER_SLOTTIMEMASK;
+       stt_data.stt_prev_slot = ktime_get_real_seconds() & STTIMER_SLOTTIMEMASK;
 
-        spin_lock_init(&stt_data.stt_lock);
+       spin_lock_init(&stt_data.stt_lock);
         for (i = 0; i < STTIMER_NSLOTS; i++)
-                CFS_INIT_LIST_HEAD(&stt_data.stt_hash[i]);
+               INIT_LIST_HEAD(&stt_data.stt_hash[i]);
 
-#ifdef __KERNEL__
-        stt_data.stt_nthreads = 0;
-        cfs_waitq_init(&stt_data.stt_waitq);
-        rc = stt_start_timer_thread();
-        if (rc != 0)
-                CERROR ("Can't spawn timer thread: %d\n", rc);
-#endif
+       stt_data.stt_nthreads = 0;
+       init_waitqueue_head(&stt_data.stt_waitq);
+       rc = stt_start_timer_thread();
+       if (rc != 0)
+               CERROR ("Can't spawn timer thread: %d\n", rc);
 
         return rc;
 }
 
 void
-stt_shutdown (void)
+stt_shutdown(void)
 {
-        int i;
+       int i;
 
-        spin_lock(&stt_data.stt_lock);
+       spin_lock(&stt_data.stt_lock);
 
-        for (i = 0; i < STTIMER_NSLOTS; i++)
-                LASSERT (list_empty(&stt_data.stt_hash[i]));
+       for (i = 0; i < STTIMER_NSLOTS; i++)
+               LASSERT(list_empty(&stt_data.stt_hash[i]));
 
-        stt_data.stt_shuttingdown = 1;
+       stt_data.stt_shuttingdown = 1;
 
-#ifdef __KERNEL__
-        cfs_waitq_signal(&stt_data.stt_waitq);
-        lst_wait_until(stt_data.stt_nthreads == 0, stt_data.stt_lock,
-                       "waiting for %d threads to terminate\n",
-                       stt_data.stt_nthreads);
-#endif
+       wake_up(&stt_data.stt_waitq);
+       lst_wait_until(stt_data.stt_nthreads == 0, stt_data.stt_lock,
+                      "waiting for %d threads to terminate\n",
+                      stt_data.stt_nthreads);
 
-        spin_unlock(&stt_data.stt_lock);
-        return;
+       spin_unlock(&stt_data.stt_lock);
 }