diff mbox series

[v2,2/3] xen: make include/xen/unaligned.h usable on all architectures

Message ID 20231206071039.24435-3-jgross@suse.com (mailing list archive)
State Superseded
Headers show
Series xen: have a more generic unaligned.h header | expand

Commit Message

Jürgen Groß Dec. 6, 2023, 7:10 a.m. UTC
Instead of defining get_unaligned() and put_unaligned() in a way that
is only supporting architectures allowing unaligned accesses, use the
same approach as the Linux kernel and let the compiler do the
decision how to generate the code for probably unaligned data accesses.

Update include/xen/unaligned.h from include/asm-generic/unaligned.h of
the Linux kernel.

The generated code has been checked to be the same on x86.

Modify the Linux variant to not use underscore prefixed identifiers,
avoid unneeded parentheses and drop the 24-bit accessors.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 803f4e1eab7a
Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2:
- drop 24-bit accessors (Jan Beulich)
- avoid underscore prefixed identifiers (Jan Beulich)
- drop unneeded parentheses (Jan Beulich)
---
 xen/include/xen/unaligned.h | 77 ++++++++++++++++++++-----------------
 1 file changed, 42 insertions(+), 35 deletions(-)

Comments

Jan Beulich Dec. 6, 2023, 8:46 a.m. UTC | #1
On 06.12.2023 08:10, Juergen Gross wrote:
> Instead of defining get_unaligned() and put_unaligned() in a way that
> is only supporting architectures allowing unaligned accesses, use the
> same approach as the Linux kernel and let the compiler do the
> decision how to generate the code for probably unaligned data accesses.
> 
> Update include/xen/unaligned.h from include/asm-generic/unaligned.h of
> the Linux kernel.
> 
> The generated code has been checked to be the same on x86.
> 
> Modify the Linux variant to not use underscore prefixed identifiers,
> avoid unneeded parentheses and drop the 24-bit accessors.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 803f4e1eab7a
> Signed-off-by: Juergen Gross <jgross@suse.com>

Acked-by: Jan Beulich <jbeulich@suse.com>

Nevertheless ...

> @@ -15,67 +7,82 @@
>  #include <asm/byteorder.h>
>  #endif
>  
> -#define get_unaligned(p) (*(p))
> -#define put_unaligned(val, p) (*(p) = (val))
> +/*
> + * This is the most generic implementation of unaligned accesses
> + * and should work almost anywhere.
> + */
> +
> +#define get_unaligned_t_(type, ptr) ({					\

..., do we need the trailing underscores here in addition to the already
sufficiently clear _t suffixes? (Leaving aside that ..._t generally is to
denote types, not macros or functions.)

Jan
Jürgen Groß Dec. 6, 2023, 10:02 a.m. UTC | #2
On 06.12.23 09:46, Jan Beulich wrote:
> On 06.12.2023 08:10, Juergen Gross wrote:
>> Instead of defining get_unaligned() and put_unaligned() in a way that
>> is only supporting architectures allowing unaligned accesses, use the
>> same approach as the Linux kernel and let the compiler do the
>> decision how to generate the code for probably unaligned data accesses.
>>
>> Update include/xen/unaligned.h from include/asm-generic/unaligned.h of
>> the Linux kernel.
>>
>> The generated code has been checked to be the same on x86.
>>
>> Modify the Linux variant to not use underscore prefixed identifiers,
>> avoid unneeded parentheses and drop the 24-bit accessors.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 803f4e1eab7a
>> Signed-off-by: Juergen Gross <jgross@suse.com>
> 
> Acked-by: Jan Beulich <jbeulich@suse.com>
> 
> Nevertheless ...
> 
>> @@ -15,67 +7,82 @@
>>   #include <asm/byteorder.h>
>>   #endif
>>   
>> -#define get_unaligned(p) (*(p))
>> -#define put_unaligned(val, p) (*(p) = (val))
>> +/*
>> + * This is the most generic implementation of unaligned accesses
>> + * and should work almost anywhere.
>> + */
>> +
>> +#define get_unaligned_t_(type, ptr) ({					\
> 
> ..., do we need the trailing underscores here in addition to the already
> sufficiently clear _t suffixes? (Leaving aside that ..._t generally is to
> denote types, not macros or functions.)

Maybe we should just name it get_unaligned_type()?


Juergen
Andrew Cooper Dec. 6, 2023, 10:52 a.m. UTC | #3
On 06/12/2023 8:46 am, Jan Beulich wrote:
> On 06.12.2023 08:10, Juergen Gross wrote:
>> Instead of defining get_unaligned() and put_unaligned() in a way that
>> is only supporting architectures allowing unaligned accesses, use the
>> same approach as the Linux kernel and let the compiler do the
>> decision how to generate the code for probably unaligned data accesses.
>>
>> Update include/xen/unaligned.h from include/asm-generic/unaligned.h of
>> the Linux kernel.
>>
>> The generated code has been checked to be the same on x86.
>>
>> Modify the Linux variant to not use underscore prefixed identifiers,
>> avoid unneeded parentheses and drop the 24-bit accessors.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 803f4e1eab7a
>> Signed-off-by: Juergen Gross <jgross@suse.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
>
> Nevertheless ...
>
>> @@ -15,67 +7,82 @@
>>  #include <asm/byteorder.h>
>>  #endif
>>  
>> -#define get_unaligned(p) (*(p))
>> -#define put_unaligned(val, p) (*(p) = (val))
>> +/*
>> + * This is the most generic implementation of unaligned accesses
>> + * and should work almost anywhere.
>> + */
>> +
>> +#define get_unaligned_t_(type, ptr) ({					\
> ..., do we need the trailing underscores here in addition to the already
> sufficiently clear _t suffixes? (Leaving aside that ..._t generally is to
> denote types, not macros or functions.)

_t is fine.  It's what we use for {min,max}_t() and friends too.

~Andrew
Andrew Cooper Dec. 6, 2023, 10:59 a.m. UTC | #4
On 06/12/2023 7:10 am, Juergen Gross wrote:
> diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
> index 0a2b16d05d..0ceb06a2bb 100644
> --- a/xen/include/xen/unaligned.h
> +++ b/xen/include/xen/unaligned.h
> @@ -1,12 +1,4 @@
>
> -static inline uint16_t get_unaligned_be16(const void *p)
> +static inline u16 get_unaligned_le16(const void *p)

I've done some cleanup for you.

You swapped away from using stdint types, and shuffled the order of
functions, which made the diff basically illegible.

https://xenbits.xen.org/gitweb/?p=people/andrewcoop/xen.git;a=commitdiff;h=1d448a845ee4ad74cab76563b3a2552b10953186
is a much shorter diff.

~Andrew
Jan Beulich Dec. 6, 2023, 11:02 a.m. UTC | #5
On 06.12.2023 11:02, Juergen Gross wrote:
> On 06.12.23 09:46, Jan Beulich wrote:
>> On 06.12.2023 08:10, Juergen Gross wrote:
>>> @@ -15,67 +7,82 @@
>>>   #include <asm/byteorder.h>
>>>   #endif
>>>   
>>> -#define get_unaligned(p) (*(p))
>>> -#define put_unaligned(val, p) (*(p) = (val))
>>> +/*
>>> + * This is the most generic implementation of unaligned accesses
>>> + * and should work almost anywhere.
>>> + */
>>> +
>>> +#define get_unaligned_t_(type, ptr) ({					\
>>
>> ..., do we need the trailing underscores here in addition to the already
>> sufficiently clear _t suffixes? (Leaving aside that ..._t generally is to
>> denote types, not macros or functions.)
> 
> Maybe we should just name it get_unaligned_type()?

I wouldn't mind, but Andrew mentioning min_t() / max_t() suggests the
present naming might be okay, too. (Still those two macros signal
something quite different with their _t suffixes.)

Jan
Andrew Cooper Dec. 6, 2023, 11:33 a.m. UTC | #6
On 06/12/2023 10:59 am, Andrew Cooper wrote:
> On 06/12/2023 7:10 am, Juergen Gross wrote:
>> diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
>> index 0a2b16d05d..0ceb06a2bb 100644
>> --- a/xen/include/xen/unaligned.h
>> +++ b/xen/include/xen/unaligned.h
>> @@ -1,12 +1,4 @@
>>
>> -static inline uint16_t get_unaligned_be16(const void *p)
>> +static inline u16 get_unaligned_le16(const void *p)
> I've done some cleanup for you.
>
> You swapped away from using stdint types, and shuffled the order of
> functions, which made the diff basically illegible.
>
> https://xenbits.xen.org/gitweb/?p=people/andrewcoop/xen.git;a=commitdiff;h=1d448a845ee4ad74cab76563b3a2552b10953186
> is a much shorter diff.

Oh, and the Origin link ought to be

https://git.kernel.org/torvalds/c/803f4e1eab7a8938ba3a3c30dd4eb5e9eeef5e63

which is shorter and also lets people on the web view it.

~Andrew
Jürgen Groß Dec. 6, 2023, 11:40 a.m. UTC | #7
On 06.12.23 11:59, Andrew Cooper wrote:
> On 06/12/2023 7:10 am, Juergen Gross wrote:
>> diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
>> index 0a2b16d05d..0ceb06a2bb 100644
>> --- a/xen/include/xen/unaligned.h
>> +++ b/xen/include/xen/unaligned.h
>> @@ -1,12 +1,4 @@
>>
>> -static inline uint16_t get_unaligned_be16(const void *p)
>> +static inline u16 get_unaligned_le16(const void *p)
> 
> I've done some cleanup for you.
> 
> You swapped away from using stdint types, and shuffled the order of
> functions, which made the diff basically illegible.
> 
> https://xenbits.xen.org/gitweb/?p=people/andrewcoop/xen.git;a=commitdiff;h=1d448a845ee4ad74cab76563b3a2552b10953186
> is a much shorter diff.

Works for me.


Juergen
Jürgen Groß Dec. 6, 2023, 11:43 a.m. UTC | #8
On 06.12.23 12:33, Andrew Cooper wrote:
> On 06/12/2023 10:59 am, Andrew Cooper wrote:
>> On 06/12/2023 7:10 am, Juergen Gross wrote:
>>> diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
>>> index 0a2b16d05d..0ceb06a2bb 100644
>>> --- a/xen/include/xen/unaligned.h
>>> +++ b/xen/include/xen/unaligned.h
>>> @@ -1,12 +1,4 @@
>>>
>>> -static inline uint16_t get_unaligned_be16(const void *p)
>>> +static inline u16 get_unaligned_le16(const void *p)
>> I've done some cleanup for you.
>>
>> You swapped away from using stdint types, and shuffled the order of
>> functions, which made the diff basically illegible.
>>
>> https://xenbits.xen.org/gitweb/?p=people/andrewcoop/xen.git;a=commitdiff;h=1d448a845ee4ad74cab76563b3a2552b10953186
>> is a much shorter diff.
> 
> Oh, and the Origin link ought to be
> 
> https://git.kernel.org/torvalds/c/803f4e1eab7a8938ba3a3c30dd4eb5e9eeef5e63
> 
> which is shorter and also lets people on the web view it.

Then we should update docs/process/sending-patches.pandoc to reflect that
possibility to reference a commit (I wouldn't like that change, though).


Juergen
diff mbox series

Patch

diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
index 0a2b16d05d..0ceb06a2bb 100644
--- a/xen/include/xen/unaligned.h
+++ b/xen/include/xen/unaligned.h
@@ -1,12 +1,4 @@ 
-/*
- * This header can be used by architectures where unaligned accesses work
- * without faulting, and at least reasonably efficiently.  Other architectures
- * will need to have a custom asm/unaligned.h.
- */
-#ifndef __ASM_UNALIGNED_H__
-#error "xen/unaligned.h should not be included directly - include asm/unaligned.h instead"
-#endif
-
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __XEN_UNALIGNED_H__
 #define __XEN_UNALIGNED_H__
 
@@ -15,67 +7,82 @@ 
 #include <asm/byteorder.h>
 #endif
 
-#define get_unaligned(p) (*(p))
-#define put_unaligned(val, p) (*(p) = (val))
+/*
+ * This is the most generic implementation of unaligned accesses
+ * and should work almost anywhere.
+ */
+
+#define get_unaligned_t_(type, ptr) ({					\
+	const struct { type x; } __packed *ptr_ = (typeof(ptr_))(ptr);	\
+	ptr_->x;							\
+})
+
+#define put_unaligned_t_(type, val, ptr) do {				\
+	struct { type x; } __packed *ptr_ = (typeof(ptr_))(ptr);	\
+	ptr_->x = val;							\
+} while (0)
+
+#define get_unaligned(ptr)	get_unaligned_t_(typeof(*(ptr)), ptr)
+#define put_unaligned(val, ptr) put_unaligned_t_(typeof(*(ptr)), val, ptr)
 
-static inline uint16_t get_unaligned_be16(const void *p)
+static inline u16 get_unaligned_le16(const void *p)
 {
-	return be16_to_cpup(p);
+	return le16_to_cpu(get_unaligned_t_(__le16, p));
 }
 
-static inline void put_unaligned_be16(uint16_t val, void *p)
+static inline u32 get_unaligned_le32(const void *p)
 {
-	*(__force __be16*)p = cpu_to_be16(val);
+	return le32_to_cpu(get_unaligned_t_(__le32, p));
 }
 
-static inline uint32_t get_unaligned_be32(const void *p)
+static inline u64 get_unaligned_le64(const void *p)
 {
-	return be32_to_cpup(p);
+	return le64_to_cpu(get_unaligned_t_(__le64, p));
 }
 
-static inline void put_unaligned_be32(uint32_t val, void *p)
+static inline void put_unaligned_le16(u16 val, void *p)
 {
-	*(__force __be32*)p = cpu_to_be32(val);
+	put_unaligned_t_(__le16, cpu_to_le16(val), p);
 }
 
-static inline uint64_t get_unaligned_be64(const void *p)
+static inline void put_unaligned_le32(u32 val, void *p)
 {
-	return be64_to_cpup(p);
+	put_unaligned_t_(__le32, cpu_to_le32(val), p);
 }
 
-static inline void put_unaligned_be64(uint64_t val, void *p)
+static inline void put_unaligned_le64(u64 val, void *p)
 {
-	*(__force __be64*)p = cpu_to_be64(val);
+	put_unaligned_t_(__le64, cpu_to_le64(val), p);
 }
 
-static inline uint16_t get_unaligned_le16(const void *p)
+static inline u16 get_unaligned_be16(const void *p)
 {
-	return le16_to_cpup(p);
+	return be16_to_cpu(get_unaligned_t_(__be16, p));
 }
 
-static inline void put_unaligned_le16(uint16_t val, void *p)
+static inline u32 get_unaligned_be32(const void *p)
 {
-	*(__force __le16*)p = cpu_to_le16(val);
+	return be32_to_cpu(get_unaligned_t_(__be32, p));
 }
 
-static inline uint32_t get_unaligned_le32(const void *p)
+static inline u64 get_unaligned_be64(const void *p)
 {
-	return le32_to_cpup(p);
+	return be64_to_cpu(get_unaligned_t_(__be64, p));
 }
 
-static inline void put_unaligned_le32(uint32_t val, void *p)
+static inline void put_unaligned_be16(u16 val, void *p)
 {
-	*(__force __le32*)p = cpu_to_le32(val);
+	put_unaligned_t_(__be16, cpu_to_be16(val), p);
 }
 
-static inline uint64_t get_unaligned_le64(const void *p)
+static inline void put_unaligned_be32(u32 val, void *p)
 {
-	return le64_to_cpup(p);
+	put_unaligned_t_(__be32, cpu_to_be32(val), p);
 }
 
-static inline void put_unaligned_le64(uint64_t val, void *p)
+static inline void put_unaligned_be64(u64 val, void *p)
 {
-	*(__force __le64*)p = cpu_to_le64(val);
+	put_unaligned_t_(__be64, cpu_to_be64(val), p);
 }
 
 #endif /* __XEN_UNALIGNED_H__ */