diff mbox

[Xen-devel,for,4.6,03/13] xen: Introduce ACCESS_ONCE macro

Message ID 1418760534-18163-4-git-send-email-julien.grall@linaro.org
State Not Applicable, archived
Headers show

Commit Message

Julien Grall Dec. 16, 2014, 8:08 p.m. UTC
This macro can be used in drivers imported from Linux.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
CC: Ian Jackson <ian.jackson@eu.citrix.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Keir Fraser <keir@xen.org>
---
 xen/include/xen/compiler.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Julien Grall Dec. 17, 2014, 12:54 p.m. UTC | #1
Hi Jan,

On 17/12/14 10:05, Jan Beulich wrote:
>>>> On 16.12.14 at 21:08, <julien.grall@linaro.org> wrote:
>> --- a/xen/include/xen/compiler.h
>> +++ b/xen/include/xen/compiler.h
>> @@ -90,4 +90,18 @@
>>      __asm__ ("" : "=r"(__ptr) : "0"(ptr));      \
>>      (typeof(ptr)) (__ptr + (off)); })
>>  
>> +/*
>> + * Prevent the compiler from merging or refetching accesses.  The compiler
>> + * is also forbidden from reordering successive instances of ACCESS_ONCE(),
>> + * but only when the compiler is aware of some particular ordering.  One way
>> + * to make the compiler aware of ordering is to put the two invocations of
>> + * ACCESS_ONCE() in different C statements.
>> + *
>> + * This macro does absolutely -nothing- to prevent the CPU from reordering,
>> + * merging, or refetching absolutely anything at any time.  Its main intended
>> + * use is to mediate communication between process-level code and irq/NMI
>> + * handlers, all running on the same CPU.
>> + */
>> +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
> 
> Any reason not to simply use {read,write}_atomic() instead, which we
> already have?

To avoid modifying Linux drivers when it's not necessary and doesn't harm.

Regards,
Julien Grall Dec. 18, 2014, 3:58 p.m. UTC | #2
Hi Andrew Cooper,

On 17/12/2014 17:52, Andrew Cooper wrote:
> On 17/12/14 17:10, Jan Beulich wrote:
>>>>> Julien Grall <julien.grall@linaro.org> 12/17/14 1:55 PM >>>
>>> On 17/12/14 10:05, Jan Beulich wrote:
>>>>>> On 16.12.14 at 21:08, <julien.grall@linaro.org> wrote:
>>>>> +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
>>>> Any reason not to simply use {read,write}_atomic() instead, which we
>>>> already have?
>>> To avoid modifying Linux drivers when it's not necessary and doesn't harm.
>> I realize that's the motivation, but I also view it as problematic to have two
>> different constructs doing the same thing. Defining the new one in terms of
>> the existing ones doesn't seem possible (or else I would suggest that in
>> order for the connection to be obvious). We'll see what other maintainers
>> think...
>
> Personally, I find the semantics of ACCESS_ONCE() more intuitive than
> read/write_atomic(), and it is certainly more familiar to Linux developers.
>
> Furthermore, ACCESS_ONCE() doesn't force an mov instruction if the
> compiler can identify a better instruction to use.
>
> There are only a handful of user users of read/write_atomic().  It would
> not be hard to make a blanket switch, if we chose to go in that direction.

Do you mean replacing read/write_atomic() by

#define read_atomic(p) ACCESS_ONCE(p)
#define write_atomic(p, x) (ACCESS_ONCE(p) = x)

Regards,
Julien Grall Dec. 18, 2014, 3:58 p.m. UTC | #3
Hi Andrew,

On 17/12/2014 17:52, Andrew Cooper wrote:
> On 17/12/14 17:10, Jan Beulich wrote:
>>>>> Julien Grall <julien.grall@linaro.org> 12/17/14 1:55 PM >>>
>>> On 17/12/14 10:05, Jan Beulich wrote:
>>>>>> On 16.12.14 at 21:08, <julien.grall@linaro.org> wrote:
>>>>> +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
>>>> Any reason not to simply use {read,write}_atomic() instead, which we
>>>> already have?
>>> To avoid modifying Linux drivers when it's not necessary and doesn't harm.
>> I realize that's the motivation, but I also view it as problematic to have two
>> different constructs doing the same thing. Defining the new one in terms of
>> the existing ones doesn't seem possible (or else I would suggest that in
>> order for the connection to be obvious). We'll see what other maintainers
>> think...
>
> Personally, I find the semantics of ACCESS_ONCE() more intuitive than
> read/write_atomic(), and it is certainly more familiar to Linux developers.
>
> Furthermore, ACCESS_ONCE() doesn't force an mov instruction if the
> compiler can identify a better instruction to use.
>
> There are only a handful of user users of read/write_atomic().  It would
> not be hard to make a blanket switch, if we chose to go in that direction.

Do you mean replacing read/write_atomic() by

#define read_atomic(p) ACCESS_ONCE(p)
#define write_atomic(p, x) (ACCESS_ONCE(p) = x)

Regards,
Julien Grall Jan. 15, 2015, 1:39 p.m. UTC | #4
Hi,

On 17/12/14 17:52, Andrew Cooper wrote:
> On 17/12/14 17:10, Jan Beulich wrote:
>>>>> Julien Grall <julien.grall@linaro.org> 12/17/14 1:55 PM >>>
>>> On 17/12/14 10:05, Jan Beulich wrote:
>>>>>> On 16.12.14 at 21:08, <julien.grall@linaro.org> wrote:
>>>>> +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
>>>> Any reason not to simply use {read,write}_atomic() instead, which we
>>>> already have?
>>> To avoid modifying Linux drivers when it's not necessary and doesn't harm.
>> I realize that's the motivation, but I also view it as problematic to have two
>> different constructs doing the same thing. Defining the new one in terms of
>> the existing ones doesn't seem possible (or else I would suggest that in
>> order for the connection to be obvious). We'll see what other maintainers
>> think...
> 
> Personally, I find the semantics of ACCESS_ONCE() more intuitive than
> read/write_atomic(), and it is certainly more familiar to Linux developers.
> 
> Furthermore, ACCESS_ONCE() doesn't force an mov instruction if the
> compiler can identify a better instruction to use.
> 
> There are only a handful of user users of read/write_atomic().  It would
> not be hard to make a blanket switch, if we chose to go in that direction.

It seems the next version of Linux will start to replace ACCESS_ONCE by
READ_ONCE/WRITE_ONCE.

So I will drop this patch and declare ACCESS_ONCE in the SMMU driver. I
will keep it as long as Linux is still using ACCESS_ONCE in this driver.

Regards,
diff mbox

Patch

diff --git a/xen/include/xen/compiler.h b/xen/include/xen/compiler.h
index 4b3472d..57eb7a6 100644
--- a/xen/include/xen/compiler.h
+++ b/xen/include/xen/compiler.h
@@ -90,4 +90,18 @@ 
     __asm__ ("" : "=r"(__ptr) : "0"(ptr));      \
     (typeof(ptr)) (__ptr + (off)); })
 
+/*
+ * Prevent the compiler from merging or refetching accesses.  The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering.  One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.  Its main intended
+ * use is to mediate communication between process-level code and irq/NMI
+ * handlers, all running on the same CPU.
+ */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
 #endif /* __LINUX_COMPILER_H */