Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1391808 > unrolled thread
| Started by | Muhammad Falak R Wani <falakreyaz@gmail.com> |
|---|---|
| First post | 2016-05-01 15:00 +0200 |
| Last post | 2016-05-03 15:10 +0200 |
| Articles | 9 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. Muhammad Falak R Wani <falakreyaz@gmail.com> - 2016-05-01 15:00 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. Christoph Hellwig <hch@infradead.org> - 2016-05-01 19:10 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2016-05-01 22:00 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2016-05-02 16:20 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2016-05-02 20:00 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. Christoph Hellwig <hch@infradead.org> - 2016-05-02 20:10 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2016-05-02 20:10 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. Christoph Hellwig <hch@infradead.org> - 2016-05-03 10:50 +0200
Re: [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2016-05-03 15:10 +0200
| From | Muhammad Falak R Wani <falakreyaz@gmail.com> |
|---|---|
| Date | 2016-05-01 15:00 +0200 |
| Subject | [PATCH 2/2] target: use RCU_INIT_POINTER() when NULLing. |
| Message-ID | <rtZ8C-1fy-7@gated-at.bofh.it> |
It is safe to use RCU_INIT_POINTER() to NULL, instead of rcu_assign_pointer(). This results in slightly smaller/faster code. Signed-off-by: Muhammad Falak R Wani <falakreyaz@gmail.com> --- drivers/target/target_core_tpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index ddf0460..7ae0f08 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -684,7 +684,7 @@ void core_tpg_remove_lun( spin_lock(&dev->se_port_lock); list_del(&lun->lun_dev_link); dev->export_count--; - rcu_assign_pointer(lun->lun_se_dev, NULL); + RCU_INIT_POINTER(lun->lun_se_dev, NULL); spin_unlock(&dev->se_port_lock); } if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) -- 1.9.1
[toc] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2016-05-01 19:10 +0200 |
| Message-ID | <ru32x-4A8-3@gated-at.bofh.it> |
| In reply to | #1391808 |
On Sun, May 01, 2016 at 06:22:01PM +0530, Muhammad Falak R Wani wrote: > It is safe to use RCU_INIT_POINTER() to NULL, instead of > rcu_assign_pointer(). > This results in slightly smaller/faster code. If this is indeed the case, rcu_assign_pointer should simply check for NULL using __builtin_constant_p and do the right thing transparently instead of burdening it on every user.
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-05-01 22:00 +0200 |
| Message-ID | <ru5H3-6Ma-5@gated-at.bofh.it> |
| In reply to | #1391852 |
On Sun, May 01, 2016 at 10:01:20AM -0700, Christoph Hellwig wrote:
> On Sun, May 01, 2016 at 06:22:01PM +0530, Muhammad Falak R Wani wrote:
> > It is safe to use RCU_INIT_POINTER() to NULL, instead of
> > rcu_assign_pointer().
> > This results in slightly smaller/faster code.
>
> If this is indeed the case, rcu_assign_pointer should simply check
> for NULL using __builtin_constant_p and do the right thing transparently
> instead of burdening it on every user.
Last time around, there was a compiler bug that prevented this from
working correctly. But it could well be time to look at it again.
How does the following (untested) patch look?
Thanx, Paul
------------------------------------------------------------------------
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c61b6b9506e7..3a4dbfe63c1a 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -650,7 +650,16 @@ static inline void rcu_preempt_sleep_check(void)
* please be careful when making changes to rcu_assign_pointer() and the
* other macros that it invokes.
*/
-#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
+#define rcu_assign_pointer(p, v) \
+({ \
+ typeof(v) _r_a_p__v = (v); \
+ \
+ if (__builtin_constant_p(v) && (_r_a_p__v) == NULL) \
+ WRITE_ONCE((p), (_r_a_p__v)); \
+ else \
+ smp_store_release(&p, RCU_INITIALIZER(_r_a_p__v)); \
+ _r_a_p__v; \
+})
/**
* rcu_access_pointer() - fetch RCU pointer with no dereferencing
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-05-02 16:20 +0200 |
| Message-ID | <rumRA-4OA-17@gated-at.bofh.it> |
| In reply to | #1391861 |
On Sun, May 01, 2016 at 12:53:13PM -0700, Paul E. McKenney wrote:
> On Sun, May 01, 2016 at 10:01:20AM -0700, Christoph Hellwig wrote:
> > On Sun, May 01, 2016 at 06:22:01PM +0530, Muhammad Falak R Wani wrote:
> > > It is safe to use RCU_INIT_POINTER() to NULL, instead of
> > > rcu_assign_pointer().
> > > This results in slightly smaller/faster code.
> >
> > If this is indeed the case, rcu_assign_pointer should simply check
> > for NULL using __builtin_constant_p and do the right thing transparently
> > instead of burdening it on every user.
>
> Last time around, there was a compiler bug that prevented this from
> working correctly. But it could well be time to look at it again.
> How does the following (untested) patch look?
Pretty bad, actually...
People use rcu_assign_pointer() for pointers to functions, which gets
interesting compiler warnings for some configurations. Please see below
for attempt #2.
Thanx, Paul
------------------------------------------------------------------------
commit f55c2ffb4e105fa0450fe495788765dffc4b752e
Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Date: Sun May 1 18:46:54 2016 -0700
rcu: No ordering for rcu_assign_pointer() of NULL
This commit does a compile-time check for rcu_assign_pointer() of NULL,
and uses WRITE_ONCE() rather than smp_store_release() in that case.
Reported-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c61b6b9506e7..9b8828c5a9c2 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -650,7 +650,16 @@ static inline void rcu_preempt_sleep_check(void)
* please be careful when making changes to rcu_assign_pointer() and the
* other macros that it invokes.
*/
-#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
+#define rcu_assign_pointer(p, v) \
+({ \
+ uintptr_t _r_a_p__v = (uintptr_t)(v); \
+ \
+ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \
+ WRITE_ONCE((p), (typeof(v))(_r_a_p__v)); \
+ else \
+ smp_store_release(&p, RCU_INITIALIZER((typeof(v))_r_a_p__v)); \
+ _r_a_p__v; \
+})
/**
* rcu_access_pointer() - fetch RCU pointer with no dereferencing
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-05-02 20:00 +0200 |
| Message-ID | <ruqiu-7Un-7@gated-at.bofh.it> |
| In reply to | #1392233 |
On Mon, May 02, 2016 at 07:10:23AM -0700, Paul E. McKenney wrote:
> On Sun, May 01, 2016 at 12:53:13PM -0700, Paul E. McKenney wrote:
> > On Sun, May 01, 2016 at 10:01:20AM -0700, Christoph Hellwig wrote:
> > > On Sun, May 01, 2016 at 06:22:01PM +0530, Muhammad Falak R Wani wrote:
> > > > It is safe to use RCU_INIT_POINTER() to NULL, instead of
> > > > rcu_assign_pointer().
> > > > This results in slightly smaller/faster code.
> > >
> > > If this is indeed the case, rcu_assign_pointer should simply check
> > > for NULL using __builtin_constant_p and do the right thing transparently
> > > instead of burdening it on every user.
> >
> > Last time around, there was a compiler bug that prevented this from
> > working correctly. But it could well be time to look at it again.
> > How does the following (untested) patch look?
>
> Pretty bad, actually...
>
> People use rcu_assign_pointer() for pointers to functions, which gets
> interesting compiler warnings for some configurations. Please see below
> for attempt #2.
Perhaps third time is the charm?
Thanx, Paul
------------------------------------------------------------------------
commit 72a616bf7f99b2ef4f211f73c6def7fa884d6ca4
Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Date: Sun May 1 18:46:54 2016 -0700
rcu: No ordering for rcu_assign_pointer() of NULL
This commit does a compile-time check for rcu_assign_pointer() of NULL,
and uses WRITE_ONCE() rather than smp_store_release() in that case.
Reported-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c61b6b9506e7..9be61e47badc 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -650,7 +650,16 @@ static inline void rcu_preempt_sleep_check(void)
* please be careful when making changes to rcu_assign_pointer() and the
* other macros that it invokes.
*/
-#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
+#define rcu_assign_pointer(p, v) \
+({ \
+ uintptr_t _r_a_p__v = (uintptr_t)(v); \
+ \
+ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \
+ WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \
+ else \
+ smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
+ _r_a_p__v; \
+})
/**
* rcu_access_pointer() - fetch RCU pointer with no dereferencing
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2016-05-02 20:10 +0200 |
| Message-ID | <ruqs9-8kk-1@gated-at.bofh.it> |
| In reply to | #1392418 |
On Mon, May 02, 2016 at 10:57:38AM -0700, Paul E. McKenney wrote:
> -#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
> +#define rcu_assign_pointer(p, v) \
> +({ \
> + uintptr_t _r_a_p__v = (uintptr_t)(v); \
> + \
> + if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \
> + WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \
> + else \
> + smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
> + _r_a_p__v; \
> +})
Can't we turn it into an inline (would need different calling
conventions for p, though).
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-05-02 20:10 +0200 |
| Message-ID | <ruqsa-8kk-13@gated-at.bofh.it> |
| In reply to | #1392421 |
On Mon, May 02, 2016 at 10:59:50AM -0700, Christoph Hellwig wrote:
> On Mon, May 02, 2016 at 10:57:38AM -0700, Paul E. McKenney wrote:
> > -#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
> > +#define rcu_assign_pointer(p, v) \
> > +({ \
> > + uintptr_t _r_a_p__v = (uintptr_t)(v); \
> > + \
> > + if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \
> > + WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \
> > + else \
> > + smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
> > + _r_a_p__v; \
> > +})
>
> Can't we turn it into an inline (would need different calling
> conventions for p, though).
And for v. But how do I do that without C++ templates?
Also, does __builtin_constant_p() work reliably on a parameter?
Especially when the compiler decides not to do the inlining?
Thanx, Paul
[toc] | [prev] | [next] | [standalone]
| From | Christoph Hellwig <hch@infradead.org> |
|---|---|
| Date | 2016-05-03 10:50 +0200 |
| Message-ID | <ruEbL-4H5-7@gated-at.bofh.it> |
| In reply to | #1392426 |
On Mon, May 02, 2016 at 11:06:44AM -0700, Paul E. McKenney wrote: > And for v. But how do I do that without C++ templates? > > Also, does __builtin_constant_p() work reliably on a parameter? > Especially when the compiler decides not to do the inlining? Yeah, it's going to be a pain indeed, guess that's why it hasn't been done before..
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2016-05-03 15:10 +0200 |
| Message-ID | <ruIfp-nG-31@gated-at.bofh.it> |
| In reply to | #1393186 |
On Tue, May 03, 2016 at 01:45:20AM -0700, Christoph Hellwig wrote: > On Mon, May 02, 2016 at 11:06:44AM -0700, Paul E. McKenney wrote: > > And for v. But how do I do that without C++ templates? > > > > Also, does __builtin_constant_p() work reliably on a parameter? > > Especially when the compiler decides not to do the inlining? > > Yeah, it's going to be a pain indeed, guess that's why it hasn't been > done before.. Speaking of pain and things that haven't been done before, would you be interested in being in the first group to review an attempt to formalize memory-barriers.txt? Thanx, Paul
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web