ocfs2: use 64bit variables to track heartbeat time
o2hb_elapsed_msecs computes the time taken for a disk heartbeat. 'struct timeval' variables are used to store start and end times. On 32-bit systems, the 'tv_sec' component of 'struct timeval' will overflow in year 2038 and beyond. This patch solves the overflow with the following: 1. Replace o2hb_elapsed_msecs using 'ktime_t' values to measure start and end time, and built-in function 'ktime_ms_delta' to compute the elapsed time. ktime_get_real() is used since the code prints out the wallclock time. 2. Changes format string to print time as a single 64-bit nanoseconds value ("%lld") instead of seconds and microseconds. This simplifies the code since converting ktime_t to that format would need expensive computation. However, the debug log string is less readable than the previous format. Signed-off-by: Tina Ruchandani <ruchandani.tina@gmail.com> Suggested by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ad69482122
commit
40476b8294
@ -36,7 +36,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
||||
#include <linux/ktime.h>
|
||||
#include "heartbeat.h"
|
||||
#include "tcp.h"
|
||||
#include "nodemanager.h"
|
||||
@ -1060,37 +1060,6 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Subtract b from a, storing the result in a. a *must* have a larger
|
||||
* value than b. */
|
||||
static void o2hb_tv_subtract(struct timeval *a,
|
||||
struct timeval *b)
|
||||
{
|
||||
/* just return 0 when a is after b */
|
||||
if (a->tv_sec < b->tv_sec ||
|
||||
(a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) {
|
||||
a->tv_sec = 0;
|
||||
a->tv_usec = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
a->tv_sec -= b->tv_sec;
|
||||
a->tv_usec -= b->tv_usec;
|
||||
while ( a->tv_usec < 0 ) {
|
||||
a->tv_sec--;
|
||||
a->tv_usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int o2hb_elapsed_msecs(struct timeval *start,
|
||||
struct timeval *end)
|
||||
{
|
||||
struct timeval res = *end;
|
||||
|
||||
o2hb_tv_subtract(&res, start);
|
||||
|
||||
return res.tv_sec * 1000 + res.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* we ride the region ref that the region dir holds. before the region
|
||||
* dir is removed and drops it ref it will wait to tear down this
|
||||
@ -1101,7 +1070,7 @@ static int o2hb_thread(void *data)
|
||||
int i, ret;
|
||||
struct o2hb_region *reg = data;
|
||||
struct o2hb_bio_wait_ctxt write_wc;
|
||||
struct timeval before_hb, after_hb;
|
||||
ktime_t before_hb, after_hb;
|
||||
unsigned int elapsed_msec;
|
||||
|
||||
mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread running\n");
|
||||
@ -1118,18 +1087,18 @@ static int o2hb_thread(void *data)
|
||||
* hr_timeout_ms between disk writes. On busy systems
|
||||
* this should result in a heartbeat which is less
|
||||
* likely to time itself out. */
|
||||
do_gettimeofday(&before_hb);
|
||||
before_hb = ktime_get_real();
|
||||
|
||||
ret = o2hb_do_disk_heartbeat(reg);
|
||||
|
||||
do_gettimeofday(&after_hb);
|
||||
elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
|
||||
after_hb = ktime_get_real();
|
||||
|
||||
elapsed_msec = (unsigned int)
|
||||
ktime_ms_delta(after_hb, before_hb);
|
||||
|
||||
mlog(ML_HEARTBEAT,
|
||||
"start = %lu.%lu, end = %lu.%lu, msec = %u, ret = %d\n",
|
||||
before_hb.tv_sec, (unsigned long) before_hb.tv_usec,
|
||||
after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
|
||||
elapsed_msec, ret);
|
||||
"start = %lld, end = %lld, msec = %u, ret = %d\n",
|
||||
before_hb.tv64, after_hb.tv64, elapsed_msec, ret);
|
||||
|
||||
if (!kthread_should_stop() &&
|
||||
elapsed_msec < reg->hr_timeout_ms) {
|
||||
|
Loading…
Reference in New Issue
Block a user