Whamcloud - gitweb
LU-9019 osd-ldiskfs: migrate to 64 bit time 57/29857/10
authorJames Simmons <uja.ornl@yahoo.com>
Mon, 5 Feb 2018 17:14:51 +0000 (12:14 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 27 Feb 2018 03:42:31 +0000 (03:42 +0000)
Replace cfs_time_current_sec() to avoid the overflow issues in
2038 with ktime_get_real_seconds(). Besides changing struct
scrub_file sf_time_* fields to time64_t for usage with
ktime_get_real_seconds() the other fields can also be moved to
time64_t as well since we don't need precision better than one
second for the scrubbing code. The dr_* time fields in struct
osd_iobuf are jiffies which does get reporting with the histograms.
This was with the thinking that jiffies equal milliseconds which
is not always the case. Since we need better than one second
resolution move dr_* time fields to ktime. This way the value
passed to lprocfs_oh_tally_log() will always be in milliseconds.

Change-Id: Ibce7f7d9f972c8d3188271950f68dcda7663676f
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/29857
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/lustre_scrub.h
lustre/obdclass/scrub.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_io.c
lustre/osd-ldiskfs/osd_scrub.c
lustre/osd-ldiskfs/osd_scrub.h
lustre/osd-zfs/osd_index.c
lustre/osd-zfs/osd_io.c
lustre/osd-zfs/osd_scrub.c

index 4002ba6..3eba040 100644 (file)
@@ -46,8 +46,6 @@
 #define SCRUB_CHECKPOINT_INTERVAL      60
 #define SCRUB_WINDOW_SIZE              1024
 
-#define HALF_SEC                       msecs_to_jiffies(MSEC_PER_SEC >> 1)
-
 enum scrub_next_status {
        /* exit current loop and process next group */
        SCRUB_NEXT_BREAK        = 1,
@@ -202,13 +200,13 @@ struct scrub_file {
        __u16   sf_param;
 
        /* The time for the last OI scrub completed. */
-       __u64   sf_time_last_complete;
+       time64_t sf_time_last_complete;
 
-       /* The time for the latest OI scrub ran. */
-       __u64   sf_time_latest_start;
+       /* The ttime for the latest OI scrub ran. */
+       time64_t sf_time_latest_start;
 
        /* The time for the last OI scrub checkpoint. */
-       __u64   sf_time_last_checkpoint;
+       time64_t sf_time_last_checkpoint;
 
        /* The position for the latest OI scrub started from. */
        __u64   sf_pos_latest_start;
@@ -237,8 +235,11 @@ struct scrub_file {
        /* How many IGIF objects. */
        __u64   sf_items_igif;
 
-       /* How long the OI scrub has run. */
-       __u32   sf_run_time;
+       /* How long the OI scrub has run in seconds. Do NOT change
+        * to time64_t since this breaks backwards compatibility.
+        * It shouldn't take more than 136 years to complete :-)
+        */
+       time_t  sf_run_time;
 
        /* How many completed OI scrub ran on the device. */
        __u32   sf_success_count;
@@ -276,11 +277,11 @@ struct lustre_scrub {
 
        const char             *os_name;
 
-       /* The time for last checkpoint, jiffies */
-       cfs_time_t              os_time_last_checkpoint;
+       /* The time for last checkpoint, seconds */
+       time64_t                os_time_last_checkpoint;
 
-       /* The time for next checkpoint, jiffies */
-       cfs_time_t              os_time_next_checkpoint;
+       /* The time for next checkpoint, seconds */
+       time64_t                os_time_next_checkpoint;
 
        /* How many objects have been checked since last checkpoint. */
        __u64                   os_new_checked;
index 3ab8540..094f928 100644 (file)
@@ -238,9 +238,9 @@ log:
                CDEBUG(D_LFSCK, "%s: store scrub file: rc = %d\n",
                       scrub->os_name, rc);
 
-       scrub->os_time_last_checkpoint = cfs_time_current();
+       scrub->os_time_last_checkpoint = ktime_get_seconds();
        scrub->os_time_next_checkpoint = scrub->os_time_last_checkpoint +
-                               cfs_time_seconds(SCRUB_CHECKPOINT_INTERVAL);
+                                        SCRUB_CHECKPOINT_INTERVAL;
        return rc;
 }
 EXPORT_SYMBOL(scrub_file_store);
@@ -248,10 +248,10 @@ EXPORT_SYMBOL(scrub_file_store);
 int scrub_checkpoint(const struct lu_env *env, struct lustre_scrub *scrub)
 {
        struct scrub_file *sf = &scrub->os_file;
+       time64_t now = ktime_get_seconds();
        int rc;
 
-       if (likely(cfs_time_before(cfs_time_current(),
-                                  scrub->os_time_next_checkpoint) ||
+       if (likely(now < scrub->os_time_next_checkpoint ||
                   scrub->os_new_checked == 0))
                return 0;
 
@@ -262,9 +262,8 @@ int scrub_checkpoint(const struct lu_env *env, struct lustre_scrub *scrub)
        sf->sf_items_checked += scrub->os_new_checked;
        scrub->os_new_checked = 0;
        sf->sf_pos_last_checkpoint = scrub->os_pos_current;
-       sf->sf_time_last_checkpoint = cfs_time_current_sec();
-       sf->sf_run_time += cfs_duration_sec(cfs_time_current() + HALF_SEC -
-                                           scrub->os_time_last_checkpoint);
+       sf->sf_time_last_checkpoint = ktime_get_real_seconds();
+       sf->sf_run_time += now - scrub->os_time_last_checkpoint;
        rc = scrub_file_store(env, scrub);
        up_write(&scrub->os_rwsem);
 
@@ -390,11 +389,12 @@ static void scrub_bits_dump(struct seq_file *m, int bits, const char *names[],
        }
 }
 
-static void scrub_time_dump(struct seq_file *m, __u64 time, const char *prefix)
+static void scrub_time_dump(struct seq_file *m, time64_t time,
+                           const char *prefix)
 {
        if (time != 0)
                seq_printf(m, "%s: %llu seconds\n", prefix,
-                          cfs_time_current_sec() - time);
+                          ktime_get_real_seconds() - time);
        else
                seq_printf(m, "%s: N/A\n", prefix);
 }
@@ -410,8 +410,8 @@ static void scrub_pos_dump(struct seq_file *m, __u64 pos, const char *prefix)
 void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub)
 {
        struct scrub_file *sf = &scrub->os_file;
-       __u64 checked;
-       __u64 speed;
+       u64 checked;
+       s64 speed;
 
        down_read(&scrub->os_rwsem);
        seq_printf(m, "name: OI_scrub\n"
@@ -460,33 +460,40 @@ void scrub_dump(struct seq_file *m, struct lustre_scrub *scrub)
 
        speed = checked;
        if (thread_is_running(&scrub->os_thread)) {
-               cfs_duration_t duration = cfs_time_current() -
-                                         scrub->os_time_last_checkpoint;
-               __u64 new_checked = msecs_to_jiffies(scrub->os_new_checked *
-                                                    MSEC_PER_SEC);
-               __u32 rtime = sf->sf_run_time +
-                             cfs_duration_sec(duration + HALF_SEC);
-
+               s64 new_checked = scrub->os_new_checked;
+               time64_t duration;
+               time64_t rtime;
+
+               /* Since the time resolution is in seconds for new system
+                * or small devices it ismore likely that duration will be
+                * zero which will lead to inaccurate results.
+                */
+               duration = ktime_get_seconds() -
+                          scrub->os_time_last_checkpoint;
                if (duration != 0)
-                       do_div(new_checked, duration);
+                       new_checked = div_s64(new_checked, duration);
+
+               rtime = sf->sf_run_time + duration;
                if (rtime != 0)
-                       do_div(speed, rtime);
-               seq_printf(m, "run_time: %u seconds\n"
-                          "average_speed: %llu objects/sec\n"
-                          "real-time_speed: %llu objects/sec\n"
+                       speed = div_s64(speed, rtime);
+
+               seq_printf(m, "run_time: %lld seconds\n"
+                          "average_speed: %lld objects/sec\n"
+                          "real-time_speed: %lld objects/sec\n"
                           "current_position: %llu\n"
                           "scrub_in_prior: %s\n"
                           "scrub_full_speed: %s\n"
                           "partial_scan: %s\n",
-                          rtime, speed, new_checked, scrub->os_pos_current,
+                          rtime, speed, new_checked,
+                          scrub->os_pos_current,
                           scrub->os_in_prior ? "yes" : "no",
                           scrub->os_full_speed ? "yes" : "no",
                           scrub->os_partial_scan ? "yes" : "no");
        } else {
                if (sf->sf_run_time != 0)
-                       do_div(speed, sf->sf_run_time);
-               seq_printf(m, "run_time: %u seconds\n"
-                          "average_speed: %llu objects/sec\n"
+                       speed = div_s64(speed, sf->sf_run_time);
+               seq_printf(m, "run_time: %ld seconds\n"
+                          "average_speed: %lld objects/sec\n"
                           "real-time_speed: N/A\n"
                           "current_position: N/A\n",
                           sf->sf_run_time, speed);
index ad77d4d..18b9a58 100644 (file)
@@ -5229,9 +5229,8 @@ osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
                RETURN(0);
 
        if (dev->od_auto_scrub_interval == AS_NEVER ||
-           cfs_time_before(ktime_get_real_seconds(),
-                           scrub->os_file.sf_time_last_complete +
-                           dev->od_auto_scrub_interval))
+           ktime_get_real_seconds() <
+           scrub->os_file.sf_time_last_complete + dev->od_auto_scrub_interval)
                RETURN(0);
 
 again:
index 5d4c6f3..2e94edb 100644 (file)
@@ -518,8 +518,8 @@ struct osd_iobuf {
        struct page      **dr_pages;
        struct lu_buf      dr_bl_buf;
        sector_t          *dr_blocks;
-       unsigned long      dr_start_time;
-       unsigned long      dr_elapsed;  /* how long io took */
+       ktime_t            dr_start_time;
+       ktime_t            dr_elapsed;  /* how long io took */
        struct osd_device *dr_dev;
        unsigned int       dr_init_at;  /* the line iobuf was initialized */
 };
index c6c72a5..1d0303a 100644 (file)
@@ -73,7 +73,7 @@ static int __osd_init_iobuf(struct osd_device *d, struct osd_iobuf *iobuf,
        iobuf->dr_error = 0;
        iobuf->dr_dev = d;
        iobuf->dr_frags = 0;
-       iobuf->dr_elapsed = 0;
+       iobuf->dr_elapsed = ktime_set(0, 0);
        /* must be counted before, so assert */
        iobuf->dr_rw = rw;
        iobuf->dr_init_at = line;
@@ -132,8 +132,8 @@ void osd_fini_iobuf(struct osd_device *d, struct osd_iobuf *iobuf)
                 lprocfs_oh_tally(&d->od_brw_stats.
                                  hist[BRW_R_DIO_FRAGS+rw],
                                  iobuf->dr_frags);
-                lprocfs_oh_tally_log2(&d->od_brw_stats.hist[BRW_R_IO_TIME+rw],
-                                      iobuf->dr_elapsed);
+               lprocfs_oh_tally_log2(&d->od_brw_stats.hist[BRW_R_IO_TIME+rw],
+                                     ktime_to_ms(iobuf->dr_elapsed));
         }
 }
 
@@ -210,7 +210,9 @@ static void dio_complete_routine(struct bio *bio, int error)
         * call to OSD.
         */
        if (atomic_read(&iobuf->dr_numreqs) == 1) {
-               iobuf->dr_elapsed = jiffies - iobuf->dr_start_time;
+               ktime_t now = ktime_get();
+
+               iobuf->dr_elapsed = ktime_sub(now, iobuf->dr_start_time);
                iobuf->dr_elapsed_valid = 1;
        }
        if (atomic_dec_and_test(&iobuf->dr_numreqs))
@@ -293,8 +295,8 @@ static int osd_do_bio(struct osd_device *osd, struct inode *inode,
 
         LASSERT(iobuf->dr_npages == npages);
 
-        osd_brw_stats_update(osd, iobuf);
-        iobuf->dr_start_time = cfs_time_current();
+       osd_brw_stats_update(osd, iobuf);
+       iobuf->dr_start_time = ktime_get();
 
        blk_start_plug(&plug);
         for (page_idx = 0, block_idx = 0;
index 2ede42c..2619087 100644 (file)
@@ -564,8 +564,9 @@ static int osd_scrub_post(const struct lu_env *env, struct osd_device *dev,
        } else {
                sf->sf_status = SS_FAILED;
        }
-       sf->sf_run_time += cfs_duration_sec(cfs_time_current() + HALF_SEC -
-                                           scrub->os_time_last_checkpoint);
+       sf->sf_run_time += ktime_get_seconds() -
+                          scrub->os_time_last_checkpoint;
+
        rc = scrub_file_store(env, scrub);
        up_write(&scrub->os_rwsem);
 
index aae442f..a33135c 100644 (file)
@@ -68,7 +68,7 @@ struct osd_scrub {
        __u64                   os_lf_failed;
 
        __u64                   os_bad_oimap_count;
-       __u64                   os_bad_oimap_time;
+       time64_t                os_bad_oimap_time;
 };
 
 #endif /* _OSD_SCRUB_H */
index e069d6b..7d69754 100644 (file)
@@ -567,9 +567,9 @@ osd_consistency_check(const struct lu_env *env, struct osd_device *osd,
        } else if (osd->od_auto_scrub_interval == AS_NEVER) {
                RETURN(0);
        } else {
-               if (cfs_time_before(cfs_time_current_sec(),
-                                   scrub->os_file.sf_time_last_complete +
-                                   osd->od_auto_scrub_interval))
+               if (ktime_get_real_seconds() <
+                   scrub->os_file.sf_time_last_complete +
+                   osd->od_auto_scrub_interval)
                        RETURN(0);
        }
 
index 94c36de..d6a8d1f 100644 (file)
@@ -109,18 +109,17 @@ static void record_end_io(struct osd_device *osd, int rw,
 static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
                        struct lu_buf *buf, loff_t *pos)
 {
-       struct osd_object *obj  = osd_dt_obj(dt);
+       struct osd_object *obj = osd_dt_obj(dt);
        struct osd_device *osd = osd_obj2dev(obj);
-       uint64_t           old_size;
-       int                size = buf->lb_len;
-       int                rc;
-       unsigned long      start;
+       int size = buf->lb_len;
+       uint64_t old_size;
+       ktime_t start;
+       s64 delta_ms;
+       int rc;
 
        LASSERT(dt_object_exists(dt));
        LASSERT(obj->oo_dn);
 
-       start = cfs_time_current();
-
        read_lock(&obj->oo_attr_lock);
        old_size = obj->oo_attr.la_size;
        read_unlock(&obj->oo_attr_lock);
@@ -132,13 +131,14 @@ static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
                        size = old_size - *pos;
        }
 
+       start = ktime_get();
        record_start_io(osd, READ, 0);
 
        rc = osd_dmu_read(osd, obj->oo_dn, *pos, size, buf->lb_buf,
                          DMU_READ_PREFETCH);
 
-       record_end_io(osd, READ, cfs_time_current() - start, size,
-                     size >> PAGE_SHIFT);
+       delta_ms = ktime_ms_delta(ktime_get(), start);
+       record_end_io(osd, READ, delta_ms, size, size >> PAGE_SHIFT);
        if (rc == 0) {
                rc = size;
                *pos += size;
@@ -315,11 +315,12 @@ static int osd_bufs_get_read(const struct lu_env *env, struct osd_object *obj,
                             loff_t off, ssize_t len, struct niobuf_local *lnb)
 {
        struct osd_device *osd = osd_obj2dev(obj);
-       unsigned long      start = cfs_time_current();
-       int                rc, i, numbufs, npages = 0;
-       dmu_buf_t        **dbp;
-       ENTRY;
+       int rc, i, numbufs, npages = 0;
+       ktime_t start = ktime_get();
+       dmu_buf_t **dbp;
+       s64 delta_ms;
 
+       ENTRY;
        record_start_io(osd, READ, 0);
 
        /* grab buffers for read:
@@ -390,8 +391,8 @@ static int osd_bufs_get_read(const struct lu_env *env, struct osd_object *obj,
                dmu_buf_rele_array(dbp, numbufs, osd_0copy_tag);
        }
 
-       record_end_io(osd, READ, cfs_time_current() - start,
-                     npages * PAGE_SIZE, npages);
+       delta_ms = ktime_ms_delta(ktime_get(), start);
+       record_end_io(osd, READ, delta_ms, npages * PAGE_SIZE, npages);
 
        RETURN(npages);
 
index dd0eddd..58914ae 100644 (file)
@@ -332,7 +332,7 @@ static int osd_scrub_prep(const struct lu_env *env, struct osd_device *dev)
 
        scrub->os_pos_current = sf->sf_pos_latest_start;
        sf->sf_status = SS_SCANNING;
-       sf->sf_time_latest_start = cfs_time_current_sec();
+       sf->sf_time_latest_start = ktime_get_real_seconds();
        sf->sf_time_last_checkpoint = sf->sf_time_latest_start;
        sf->sf_pos_last_checkpoint = sf->sf_pos_latest_start - 1;
        rc = scrub_file_store(env, scrub);
@@ -367,7 +367,7 @@ static int osd_scrub_post(const struct lu_env *env, struct osd_device *dev,
                scrub->os_new_checked = 0;
                sf->sf_pos_last_checkpoint = scrub->os_pos_current;
        }
-       sf->sf_time_last_checkpoint = cfs_time_current_sec();
+       sf->sf_time_last_checkpoint = ktime_get_real_seconds();
        if (result > 0) {
                sf->sf_status = SS_COMPLETED;
                if (!(sf->sf_param & SP_DRYRUN)) {
@@ -385,8 +385,9 @@ static int osd_scrub_post(const struct lu_env *env, struct osd_device *dev,
        } else {
                sf->sf_status = SS_FAILED;
        }
-       sf->sf_run_time += cfs_duration_sec(cfs_time_current() + HALF_SEC -
-                                           scrub->os_time_last_checkpoint);
+       sf->sf_run_time += ktime_get_seconds() -
+                          scrub->os_time_last_checkpoint;
+
        rc = scrub_file_store(env, scrub);
        up_write(&scrub->os_rwsem);