[PATCH 2/3] locking: Get rid of ACCESS_ONCE()

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

 



>From 99b7e15342fda1591838efc068d2624457afd5b0 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@xxxxxxxxx>
Date: Mon, 19 Nov 2018 23:02:09 +0900
Subject: [PATCH 2/3] locking: Get rid of ACCESS_ONCE()

Also add READ_ONCE() and WRITE_ONCE() to racy accesses in
xchglock.c.

Signed-off-by: Akira Yokosawa <akiyks@xxxxxxxxx>
---
 CodeSamples/locking/xchglock.c | 10 +++++-----
 locking/locking.tex            | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/CodeSamples/locking/xchglock.c b/CodeSamples/locking/xchglock.c
index 5877920..a5e3403 100644
--- a/CodeSamples/locking/xchglock.c
+++ b/CodeSamples/locking/xchglock.c
@@ -28,7 +28,7 @@ typedef int xchglock_t;				//\lnlbl{typedef}
 void xchg_lock(xchglock_t *xp)			//\lnlbl{lock:b}
 {
 	while (xchg(xp, 1) == 1) {		//\lnlbl{lock:atmxchg}
-		while (*xp == 1)		//\lnlbl{lock:inner:b}
+		while (READ_ONCE(*xp) == 1)	//\lnlbl{lock:inner:b}
 			continue;		//\lnlbl{lock:inner:e}
 	}
 }						//\lnlbl{lock:e}
@@ -59,9 +59,9 @@ void *test_xchg_lock(void *arg)
 
 	run_on(me);
 	atomic_inc(&nthreadsrunning);
-	while (ACCESS_ONCE(goflag) == GOFLAG_INIT)
+	while (READ_ONCE(goflag) == GOFLAG_INIT)
 		poll(NULL, 0, 1);
-	while (ACCESS_ONCE(goflag) == GOFLAG_RUN) {
+	while (READ_ONCE(goflag) == GOFLAG_RUN) {
 		xchg_lock(&testlock);
 		if (owner != -1)
 			lockerr++;
@@ -86,11 +86,11 @@ int main(int argc, char *argv[])
 	smp_mb();
 	while (atomic_read(&nthreadsrunning) < nthreads)
 		poll(NULL, 0, 1);
-	goflag = GOFLAG_RUN;
+	WRITE_ONCE(goflag, GOFLAG_RUN);
 	smp_mb();
 	poll(NULL, 0, 10000);
 	smp_mb();
-	goflag = GOFLAG_STOP;
+	WRITE_ONCE(goflag, GOFLAG_STOP);
 	smp_mb();
 	wait_all_threads();
 	printf("lockacqs = %lu, lockerr = %lu\n", lockacqs, lockerr);
diff --git a/locking/locking.tex b/locking/locking.tex
index 92ed2f2..874fb3b 100644
--- a/locking/locking.tex
+++ b/locking/locking.tex
@@ -1463,7 +1463,7 @@ void force_quiescent_state(struct rcu_node *rnp_leaf)
 	struct rcu_node *rnp_old = NULL;
 
 	for (; rnp != NULL; rnp = rnp->parent) {	\lnlbl[loop:b]
-		ret = (ACCESS_ONCE(gp_flags)) ||	\lnlbl[flag_set]
+		ret = (READ_ONCE(gp_flags)) ||		\lnlbl[flag_set]
 		       !raw_spin_trylock(&rnp->fqslock);\lnlbl[trylock]
 		if (rnp_old != NULL)			\lnlbl[non_NULL]
 			raw_spin_unlock(&rnp_old->fqslock);\lnlbl[rel1]
@@ -1471,11 +1471,11 @@ void force_quiescent_state(struct rcu_node *rnp_leaf)
 			return;				\lnlbl[return]
 		rnp_old = rnp;				\lnlbl[save]
 	}						\lnlbl[loop:e]
-	if (!ACCESS_ONCE(gp_flags)) {			\lnlbl[flag_not_set]
-		ACCESS_ONCE(gp_flags) = 1;		\lnlbl[set_flag]
+	if (!READ_ONCE(gp_flags)) {			\lnlbl[flag_not_set]
+		WRITE_ONCE(gp_flags, 1);		\lnlbl[set_flag]
 		do_force_quiescent_state();		\lnlbl[invoke]
 		schedule_timeout_interruptible(HZ / 10);\lnlbl[wait]
-		ACCESS_ONCE(gp_flags) = 0;		\lnlbl[clr_flag]
+		WRITE_ONCE(gp_flags, 0);		\lnlbl[clr_flag]
 	}
 	raw_spin_unlock(&rnp_old->fqslock);		\lnlbl[rel2]
 }
@@ -1649,7 +1649,7 @@ the lock, thus marking it as having been released.
 \QuickQuizAnswer{
 	This can be a legitimate implementation, but only if
 	this store is preceded by a memory barrier and makes use
-	of \co{ACCESS_ONCE()}.
+	of \co{WRITE_ONCE()}.
 	The memory barrier is not required when the \co{xchg()}
 	operation is used because this operation implies a
 	full memory barrier due to the fact that it returns
-- 
2.7.4





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux