[PATCH] pnfs/flexfiles: protect ktime manipulation with mirror lock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
Signed-off-by: Peng Tao <tao.peng@xxxxxxxxxxxxxxx>
---
 fs/nfs/flexfilelayout/flexfilelayout.c | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index d3b3b62..85b4234 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -417,21 +417,9 @@ ff_layout_get_lseg_count(struct nfs4_ff_layout_segment *fls)
 static void
 nfs4_ff_start_busy_timer(struct nfs4_ff_busy_timer *timer)
 {
-	ktime_t old, new;
-
-	/*
-	 * 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);
+	/* first IO request? */
+	if (atomic_inc_return(&timer->n_ops) == 1) {
+		timer->start_time = ktime_get();
 	}
 }
 
@@ -440,9 +428,12 @@ nfs4_ff_end_busy_timer(struct nfs4_ff_busy_timer *timer)
 {
 	ktime_t start, now;
 
+	if (atomic_dec_return(&timer->n_ops) < 0)
+		WARN_ON_ONCE(1);
+
 	now = ktime_get();
-	start.tv64 = xchg(&timer->start_time.tv64, now.tv64);
-	atomic_dec(&timer->n_ops);
+	start = timer->start_time;
+	timer->start_time = now;
 	return ktime_sub(now, start);
 }
 
@@ -460,8 +451,10 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror,
 	ktime_t now = ktime_get();
 
 	nfs4_ff_start_busy_timer(&layoutstat->busy_timer);
-	cmpxchg(&mirror->start_time.tv64, notime.tv64, now.tv64);
-	cmpxchg(&mirror->last_report_time.tv64, notime.tv64, now.tv64);
+	if (ktime_equal(mirror->start_time, notime))
+		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)) >=
 			FF_LAYOUTSTATS_REPORT_INTERVAL) {
 		mirror->last_report_time = now;
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux