Skip to contentSkip to conversation

Updating Section Deferred Processing

PATCH In review Junchang Wang 2 participants 7 messages Jun 14, 2017

lore
Share & tools
lore
#0 lore raw

cover Updating Section Deferred Processing

Hi Paul,

Most of the following patches switch from ACCESS_ONCE to READ_ONCE/WRITE_ONCE in Section Deferred Processing. Please take a look.

Thanks,
--Jason

Junchang Wang (5):
hazptr: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
route_rcu: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
route_rcu: Remove redundant assignment statement to rep->re_freed
seqlocktorture: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
rcu_rcpls: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

 CodeSamples/defer/hazptr.h         |  8 ++++----
 CodeSamples/defer/hazptrtorture.h  |  6 +++---
 CodeSamples/defer/rcu_rcpls.c      |  6 +++---
 CodeSamples/defer/rcu_rcpls.h      |  2 +-
 CodeSamples/defer/rcutorture.h     |  2 +-
 CodeSamples/defer/route_rcu.c      |  5 ++---
 CodeSamples/defer/seqlocktorture.c |  8 ++++----
 appendix/toyrcu/toyrcu.tex         | 14 +++++++-------
 defer/rcuusage.tex                 |  4 ++--
 9 files changed, 27 insertions(+), 28 deletions(-)
Signature · 1 line
2.7.4
#1 lore raw

PATCH 1/5 hazptr: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

---
 CodeSamples/defer/hazptr.h        | 8 ++++----
 CodeSamples/defer/hazptrtorture.h | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)
CodeSamples/defer/hazptr.h +4 -4
index 391d281..48bec0e 100644
@@ -65,17 +65,17 @@ static inline void *hp_record(void **p, hazard_pointer *hp)
 	hazptr_head_t *tmp;
 
 	do {
-		tmp = ACCESS_ONCE(*p);
-		ACCESS_ONCE(hp->p) = tmp;
+		tmp = READ_ONCE(*p);
+		WRITE_ONCE(hp->p, tmp);
 		smp_mb();
-	} while (tmp != ACCESS_ONCE(*p));
+	} while (tmp != READ_ONCE(*p));
 	return tmp;
 }
 
 static inline void hp_clear(hazard_pointer *hp)
 {
 	smp_mb();
-	ACCESS_ONCE(hp->p) = NULL;
+	WRITE_ONCE(hp->p, NULL);
 }
 
 #define hazptr_clean_pointer(p) ((typeof(p))((unsigned long)(p) & ~0x1UL))
CodeSamples/defer/hazptrtorture.h +3 -3
index 9341765..2188ec1 100644
@@ -286,17 +286,17 @@ void *hazptr_update_stress_test(void *arg)
 		if (i >= HAZPTR_STRESS_PIPE_LEN)
 			i = 0;
 		p = &hazptr_stress_array[i];
-		if (ACCESS_ONCE(p->inuse)) {
+		if (READ_ONCE(p->inuse)) {
 			hazptr_stress_idx = i;
 			continue;
 		}
 		p->pipe_count = 0;
-		ACCESS_ONCE(p->inuse) = 1;
+		WRITE_ONCE(p->inuse, 1);
 		p->mbtest = 0;
 		smp_mb();
 		p->mbtest = 1;
 		smp_mb();
-		ACCESS_ONCE(hazptr_stress_current) =  p;
+		WRITE_ONCE(hazptr_stress_current, p);
 		hazptr_stress_idx = i;
 		for (i = 0; i < HAZPTR_STRESS_PIPE_LEN; i++)
 			if (!hazptr_stress_array[i].inuse) {
Signature · 1 line
2.7.4
#2 lore raw

PATCH 2/5 route_rcu: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

In reply to Junchang Wang
---
 CodeSamples/defer/route_rcu.c | 6 +++---
 defer/rcuusage.tex            | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)
CodeSamples/defer/route_rcu.c +3 -3
index 9ac7b25..7716fe8 100644
@@ -44,7 +44,7 @@ DEFINE_SPINLOCK(routelock);
 
 static void re_free(struct route_entry *rep)
 {
-	ACCESS_ONCE(rep->re_freed) = 1;
+	WRITE_ONCE(rep->re_freed, 1);
 	free(rep);
 }
 
@@ -60,7 +60,7 @@ unsigned long route_lookup(unsigned long addr)
 	cds_list_for_each_entry_rcu(rep, &route_list, re_next) {
 		if (rep->addr == addr) {
 			ret = rep->iface;
-			if (ACCESS_ONCE(rep->re_freed))
+			if (READ_ONCE(rep->re_freed))
 				abort();
 			rcu_read_unlock();
 			return ret;
@@ -93,7 +93,7 @@ static void route_cb(struct rcu_head *rhp)
 {
 	struct route_entry *rep = container_of(rhp, struct route_entry, rh);
 
-	ACCESS_ONCE(rep->re_freed) = 1;
+	WRITE_ONCE(rep->re_freed, 1);
 	re_free(rep);
 }
 
defer/rcuusage.tex +2 -2
index 0a37312..9a90a14 100644
@@ -64,7 +64,7 @@ Section~\ref{sec:defer:RCU Usage Summary} provides a summary.
 18                               re_next) {
 19     if (rep->addr == addr) {
 20       ret = rep->iface;
-21       if (ACCESS_ONCE(rep->re_freed))
+21       if (READ_ONCE(rep->re_freed))
 22         abort();
 23       rcu_read_unlock();
 24       return ret;
@@ -106,7 +106,7 @@ Section~\ref{sec:defer:RCU Usage Summary} provides a summary.
 20   struct route_entry *rep;
 21
 22   rep = container_of(rhp, struct route_entry, rh);
-23   ACCESS_ONCE(rep->re_freed) = 1;
+23   WRITE_ONCE(rep->re_freed, 1);
 24   free(rep);
 25 }
 26
Signature · 1 line
2.7.4
#3 lore raw

PATCH 3/5 route_rcu: Remove redundant assignment statement to rep->re_freed

In reply to Junchang Wang
---
 CodeSamples/defer/route_rcu.c | 1 -
 1 file changed, 1 deletion(-)
CodeSamples/defer/route_rcu.c +0 -1
index 7716fe8..1fd69ea 100644
@@ -93,7 +93,6 @@ static void route_cb(struct rcu_head *rhp)
 {
 	struct route_entry *rep = container_of(rhp, struct route_entry, rh);
 
-	WRITE_ONCE(rep->re_freed, 1);
 	re_free(rep);
 }
 
Signature · 1 line
2.7.4
#4 lore raw

PATCH 4/5 seqlocktorture: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

In reply to Junchang Wang
---
 CodeSamples/defer/seqlocktorture.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
CodeSamples/defer/seqlocktorture.c +4 -4
index fa0b69a..a345a5f 100644
@@ -78,9 +78,9 @@ void *seqlock_read_test(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) {
 		for (i = COUNT_READ_RUN; i > 0; i--) {
 			n_retries_local_cur = -1;
 			do {
@@ -115,9 +115,9 @@ void *seqlock_write_test(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) {
 		for (i = COUNT_UPDATE_RUN; i > 0; i--) {
 			write_seqlock(&test_seqlock);
 			for (j = 0; j < n_elems; j++)
Signature · 1 line
2.7.4
#5 lore raw

PATCH 5/5 rcu_rcpls: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

In reply to Junchang Wang
---
 CodeSamples/defer/rcu_rcpls.c  |  6 +++---
 CodeSamples/defer/rcu_rcpls.h  |  2 +-
 CodeSamples/defer/rcutorture.h |  2 +-
 appendix/toyrcu/toyrcu.tex     | 14 +++++++-------
 4 files changed, 12 insertions(+), 12 deletions(-)
CodeSamples/defer/rcu_rcpls.c +3 -3
index 8dbf624..3018ae9 100644
@@ -28,7 +28,7 @@ static void flip_counter_and_wait(int ctr)
 	int i;
 	int t;
 
-	ACCESS_ONCE(rcu_idx) = ctr + 1;
+	WRITE_ONCE(rcu_idx, ctr + 1);
 	i = ctr & 0x1;
 	smp_mb();
 	for_each_thread(t) {
@@ -46,10 +46,10 @@ void synchronize_rcu(void)
 	int oldctr;
 
 	smp_mb();
-	oldctr = ACCESS_ONCE(rcu_idx);
+	oldctr = READ_ONCE(rcu_idx);
 	smp_mb();
 	spin_lock(&rcu_gp_lock);
-	ctr = ACCESS_ONCE(rcu_idx);
+	ctr = READ_ONCE(rcu_idx);
 	if (ctr - oldctr >= 3) {
 
 		/*
CodeSamples/defer/rcu_rcpls.h +1 -1
index a9c7723..6825270 100644
@@ -47,7 +47,7 @@ static void rcu_read_lock(void)
 
 	n = __get_thread_var(rcu_nesting);
 	if (n == 0) {
-		i = ACCESS_ONCE(rcu_idx) & 0x1;
+		i = READ_ONCE(rcu_idx) & 0x1;
 		__get_thread_var(rcu_read_idx) = i;
 		__get_thread_var(rcu_refcnt)[i]++;
 	}
CodeSamples/defer/rcutorture.h +1 -1
index c5bc87e..ca03df9 100644
@@ -271,7 +271,7 @@ void *rcu_read_stress_test(void *arg)
 			n_mberror++;
 		rcu_read_lock_nest();
 		for (i = 0; i < 100; i++)
-			ACCESS_ONCE(garbage)++;
+			WRITE_ONCE(garbage, READ_ONCE(garbage) + 1);
 		rcu_read_unlock_nest();
 		pc = p->pipe_count;
 		rcu_read_unlock();
appendix/toyrcu/toyrcu.tex +7 -7
index b4882c3..5e74afa 100644
@@ -1003,7 +1003,7 @@ concurrent RCU updates.
   5
   6   n = __get_thread_var(rcu_nesting);
   7   if (n == 0) {
-  8     i = ACCESS_ONCE(rcu_idx) & 0x1;
+  8     i = READ_ONCE(rcu_idx) & 0x1;
   9     __get_thread_var(rcu_read_idx) = i;
  10     __get_thread_var(rcu_refcnt)[i]++;
  11   }
@@ -1044,7 +1044,7 @@ so that line~8 of
 Figure~\ref{fig:app:toyrcu:RCU Read-Side Using Per-Thread Reference-Count Pair and Shared Update}
 must mask off the low-order bit.
 We also switched from using \co{atomic_read()} and \co{atomic_set()}
-to using \co{ACCESS_ONCE()}.
+to using \co{READ_ONCE()}.
 The data is also quite similar, as shown in
 Figure~\ref{fig:app:toyrcu:RCU Read-Side Using Per-Thread Reference-Count Pair and Shared Update Data},
 with \co{rcu_idx} now being a \co{long} instead of an
@@ -1058,7 +1058,7 @@ with \co{rcu_idx} now being a \co{long} instead of an
   3   int i;
   4   int t;
   5
-  6   ACCESS_ONCE(rcu_idx) = ctr + 1;
+  6   WRITE_ONCE(rcu_idx, ctr + 1);
   7   i = ctr & 0x1;
   8   smp_mb();
   9   for_each_thread(t) {
@@ -1075,10 +1075,10 @@ with \co{rcu_idx} now being a \co{long} instead of an
  20   int oldctr;
  21
  22   smp_mb();
- 23   oldctr = ACCESS_ONCE(rcu_idx);
+ 23   oldctr = READ_ONCE(rcu_idx);
  24   smp_mb();
  25   spin_lock(&rcu_gp_lock);
- 26   ctr = ACCESS_ONCE(rcu_idx);
+ 26   ctr = READ_ONCE(rcu_idx);
  27   if (ctr - oldctr >= 3) {
  28     spin_unlock(&rcu_gp_lock);
  29     smp_mb();
@@ -1106,7 +1106,7 @@ These are similar to those in
 Figure~\ref{fig:app:toyrcu:RCU Update Using Per-Thread Reference-Count Pair}.
 The differences in \co{flip_counter_and_wait()} include:
 \begin{enumerate}
-\item	Line~6 uses \co{ACCESS_ONCE()} instead of \co{atomic_set()},
+\item	Line~6 uses \co{WRITE_ONCE()} instead of \co{atomic_set()},
 	and increments rather than complementing.
 \item	A new line~7 masks the counter down to its bottom bit.
 \end{enumerate}
@@ -1116,7 +1116,7 @@ The changes to \co{synchronize_rcu()} are more pervasive:
 \item	There is a new \co{oldctr} local variable that captures
 	the pre-lock-acquisition value of \co{rcu_idx} on
 	line~23.
-\item	Line~26 uses \co{ACCESS_ONCE()} instead of \co{atomic_read()}.
+\item	Line~26 uses \co{READ_ONCE()} instead of \co{atomic_read()}.
 \item	Lines~27-30 check to see if at least three counter flips were
 	performed by other threads while the lock was being acquired,
 	and, if so, releases the lock, does a memory barrier, and returns.
Signature · 1 line
2.7.4
#6 lore raw
In reply to Junchang Wang
Quoted 4 lines · Junchang Wang

Hi Paul,

Most of the following patches switch from ACCESS_ONCE to READ_ONCE/WRITE_ONCE in Section Deferred Processing. Please take a look.

Applied and pushed, thank you!

And good catch on the redundant assignment! ;-)

Thanx, Paul

Quoted 24 lines

Thanks,
--Jason

Junchang Wang (5):
hazptr: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
route_rcu: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
route_rcu: Remove redundant assignment statement to rep->re_freed
seqlocktorture: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()
rcu_rcpls: Switch from ACCESS_ONCE() to READ_ONCE()/WRITE_ONCE()

 CodeSamples/defer/hazptr.h         |  8 ++++----
 CodeSamples/defer/hazptrtorture.h  |  6 +++---
 CodeSamples/defer/rcu_rcpls.c      |  6 +++---
 CodeSamples/defer/rcu_rcpls.h      |  2 +-
 CodeSamples/defer/rcutorture.h     |  2 +-
 CodeSamples/defer/route_rcu.c      |  5 ++---
 CodeSamples/defer/seqlocktorture.c |  8 ++++----
 appendix/toyrcu/toyrcu.tex         | 14 +++++++-------
 defer/rcuusage.tex                 |  4 ++--
 9 files changed, 27 insertions(+), 28 deletions(-)
Signature · 1 line
2.7.4