Commit 9bbd9bb4 authored by Peng Tao's avatar Peng Tao Committed by Trond Myklebust

pnfs/flexfiles: protect ktime manipulation with mirror lock

It looks as if xchg() and cmpxchg() are not available for 64-bit integers on sparc32:

> New breakage seen in linux-next today:
>
> ERROR: "__xchg_called_with_bad_pointer" [fs/nfs/flexfilelayout/nfs_layout_flexfiles.ko] undefined!
> ERROR: "__cmpxchg_called_with_bad_pointer" [fs/nfs/flexfilelayout/nfs_layout_flexfiles.ko] undefined!
> make[2]: *** [__modpost] Error 1
> make[1]: *** [modules] Error 2

Given that mirror ktime manipulation is already under mirror->lock, let's make use of the fact.
Reported-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarPeng Tao <tao.peng@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 865a7ecb
...@@ -417,21 +417,9 @@ ff_layout_get_lseg_count(struct nfs4_ff_layout_segment *fls) ...@@ -417,21 +417,9 @@ ff_layout_get_lseg_count(struct nfs4_ff_layout_segment *fls)
static void static void
nfs4_ff_start_busy_timer(struct nfs4_ff_busy_timer *timer) nfs4_ff_start_busy_timer(struct nfs4_ff_busy_timer *timer)
{ {
ktime_t old, new; /* first IO request? */
if (atomic_inc_return(&timer->n_ops) == 1) {
/* timer->start_time = ktime_get();
* Note: careful here!
* If the counter is zero, then we must not increment it until after
* we've set the start_time.
* If we were instead to use atomic_inc_return(), then another
* request might come in, bump, and then call end_busy_timer()
* before we've set the timer->start_time.
*/
old = timer->start_time;
if (atomic_inc_not_zero(&timer->n_ops) == 0) {
new = ktime_get();
cmpxchg(&timer->start_time.tv64, old.tv64, new.tv64);
atomic_inc(&timer->n_ops);
} }
} }
...@@ -440,9 +428,12 @@ nfs4_ff_end_busy_timer(struct nfs4_ff_busy_timer *timer) ...@@ -440,9 +428,12 @@ nfs4_ff_end_busy_timer(struct nfs4_ff_busy_timer *timer)
{ {
ktime_t start, now; ktime_t start, now;
if (atomic_dec_return(&timer->n_ops) < 0)
WARN_ON_ONCE(1);
now = ktime_get(); now = ktime_get();
start.tv64 = xchg(&timer->start_time.tv64, now.tv64); start = timer->start_time;
atomic_dec(&timer->n_ops); timer->start_time = now;
return ktime_sub(now, start); return ktime_sub(now, start);
} }
...@@ -460,8 +451,10 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror, ...@@ -460,8 +451,10 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror,
ktime_t now = ktime_get(); ktime_t now = ktime_get();
nfs4_ff_start_busy_timer(&layoutstat->busy_timer); nfs4_ff_start_busy_timer(&layoutstat->busy_timer);
cmpxchg(&mirror->start_time.tv64, notime.tv64, now.tv64); if (ktime_equal(mirror->start_time, notime))
cmpxchg(&mirror->last_report_time.tv64, notime.tv64, now.tv64); mirror->start_time = now;
if (ktime_equal(mirror->last_report_time, notime))
mirror->last_report_time = now;
if (ktime_to_ms(ktime_sub(now, mirror->last_report_time)) >= if (ktime_to_ms(ktime_sub(now, mirror->last_report_time)) >=
FF_LAYOUTSTATS_REPORT_INTERVAL) { FF_LAYOUTSTATS_REPORT_INTERVAL) {
mirror->last_report_time = now; mirror->last_report_time = now;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment