diff mbox

[v2] ARM: include: asm: use 'long long' instead of 'u64' within atomic.h

Message ID 5242498F.8060407@asianux.com (mailing list archive)
State New, archived
Headers show

Commit Message

Chen Gang Sept. 25, 2013, 2:25 a.m. UTC
atomic* value is signed value, and atomic* functions need also process
signed value (parameter value, and return value), so 32-bit arm need
use 'long long' instead of 'u64'.

After replacement, it will also fix a bug for atomic64_add_negative():
"u64 is never less than 0".

The modifications are:

  in vim, use "1,% s/\<u64\>/long long/g" command.
  remove '__aligned(8)' which is useless for 64-bit.
  be sure of 80 column limitation after replacement.


Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
 arch/arm/include/asm/atomic.h |   49 +++++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 24 deletions(-)

Comments

Will Deacon Sept. 25, 2013, 4:07 p.m. UTC | #1
On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
> atomic* value is signed value, and atomic* functions need also process
> signed value (parameter value, and return value), so 32-bit arm need
> use 'long long' instead of 'u64'.
> 
> After replacement, it will also fix a bug for atomic64_add_negative():
> "u64 is never less than 0".
> 
> The modifications are:
> 
>   in vim, use "1,% s/\<u64\>/long long/g" command.
>   remove '__aligned(8)' which is useless for 64-bit.
>   be sure of 80 column limitation after replacement.
> 
> 
> Signed-off-by: Chen Gang <gang.chen@asianux.com>

Looks better to me, thanks. While you're here, we could also replace the use
of `unsigned long' with `int' for the 32-bit atomics, then the whole header
is consistent with the generic types.

Will
Chen Gang Sept. 26, 2013, 2 a.m. UTC | #2
On 09/26/2013 12:07 AM, Will Deacon wrote:
> On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
>> atomic* value is signed value, and atomic* functions need also process
>> signed value (parameter value, and return value), so 32-bit arm need
>> use 'long long' instead of 'u64'.
>>
>> After replacement, it will also fix a bug for atomic64_add_negative():
>> "u64 is never less than 0".
>>
>> The modifications are:
>>
>>   in vim, use "1,% s/\<u64\>/long long/g" command.
>>   remove '__aligned(8)' which is useless for 64-bit.
>>   be sure of 80 column limitation after replacement.
>>
>>
>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
> 
> Looks better to me, thanks. While you're here, we could also replace the use
> of `unsigned long' with `int' for the 32-bit atomics, then the whole header
> is consistent with the generic types.
> 
> Will
> 
> 

Hmm... at least, it seems we can let "use 'int' for 32-bit atomics" in
another patch.


Firstly, this 'fix' is not belong to API, and either, it has no related
'standard' 'demo' in "asm-generic/" (it is architecture independent, so
no related inline assembly code).

After a random check, another 3 architectures (maybe more) are also may
using 'unsigned long': "arm64/include/asm/atomic.h",
"sh/include/asm/atomic-llsc.h", and "xtensa/include/asm/atomic.h".

And as far as I know, for a register related variable, 'unsigned long'
is also a common using way for both 32-bit and 64-bit (at least, it is a
simple way to prevent issues).


Thanks.
Will Deacon Sept. 26, 2013, 10:04 a.m. UTC | #3
On Thu, Sep 26, 2013 at 03:00:30AM +0100, Chen Gang wrote:
> On 09/26/2013 12:07 AM, Will Deacon wrote:
> > On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
> >> atomic* value is signed value, and atomic* functions need also process
> >> signed value (parameter value, and return value), so 32-bit arm need
> >> use 'long long' instead of 'u64'.
> >>
> >> After replacement, it will also fix a bug for atomic64_add_negative():
> >> "u64 is never less than 0".
> >>
> >> The modifications are:
> >>
> >>   in vim, use "1,% s/\<u64\>/long long/g" command.
> >>   remove '__aligned(8)' which is useless for 64-bit.
> >>   be sure of 80 column limitation after replacement.
> >>
> >>
> >> Signed-off-by: Chen Gang <gang.chen@asianux.com>
> > 
> > Looks better to me, thanks. While you're here, we could also replace the use
> > of `unsigned long' with `int' for the 32-bit atomics, then the whole header
> > is consistent with the generic types.
> > 
> > Will
> > 
> > 
> 
> Hmm... at least, it seems we can let "use 'int' for 32-bit atomics" in
> another patch.

Sure, it can be a follow-up to this one.

> Firstly, this 'fix' is not belong to API, and either, it has no related
> 'standard' 'demo' in "asm-generic/" (it is architecture independent, so
> no related inline assembly code).

I was simply going by the types of atomic_t and atomic64_t, which are both
constructed using signed types.

> After a random check, another 3 architectures (maybe more) are also may
> using 'unsigned long': "arm64/include/asm/atomic.h",
> "sh/include/asm/atomic-llsc.h", and "xtensa/include/asm/atomic.h".
> 
> And as far as I know, for a register related variable, 'unsigned long'
> is also a common using way for both 32-bit and 64-bit (at least, it is a
> simple way to prevent issues).

Maybe, but atomic_t is always 32-bit and atomic64_t is always 64-bit, so I
don't think unsigned long buys you anything with regards to sizing.

Will
Chen Gang Sept. 26, 2013, 11:03 a.m. UTC | #4
On 09/26/2013 06:04 PM, Will Deacon wrote:
> On Thu, Sep 26, 2013 at 03:00:30AM +0100, Chen Gang wrote:
>> On 09/26/2013 12:07 AM, Will Deacon wrote:
>>> On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
>>>> atomic* value is signed value, and atomic* functions need also process
>>>> signed value (parameter value, and return value), so 32-bit arm need
>>>> use 'long long' instead of 'u64'.
>>>>
>>>> After replacement, it will also fix a bug for atomic64_add_negative():
>>>> "u64 is never less than 0".
>>>>
>>>> The modifications are:
>>>>
>>>>   in vim, use "1,% s/\<u64\>/long long/g" command.
>>>>   remove '__aligned(8)' which is useless for 64-bit.
>>>>   be sure of 80 column limitation after replacement.
>>>>
>>>>
>>>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
>>>
>>> Looks better to me, thanks. While you're here, we could also replace the use
>>> of `unsigned long' with `int' for the 32-bit atomics, then the whole header
>>> is consistent with the generic types.
>>>
>>> Will
>>>
>>>
>>
>> Hmm... at least, it seems we can let "use 'int' for 32-bit atomics" in
>> another patch.
> 
> Sure, it can be a follow-up to this one.
> 

OK, if it is really a useful patch too, I will follow-up.


>> Firstly, this 'fix' is not belong to API, and either, it has no related
>> 'standard' 'demo' in "asm-generic/" (it is architecture independent, so
>> no related inline assembly code).
> 
> I was simply going by the types of atomic_t and atomic64_t, which are both
> constructed using signed types.
> 

So, it is not quite necessary (but still better) to let it 'consistent'
with 'generic' types (in fact, I feel, for a register related variable,
'unsigned long' is more 'generic' than 'int').

Since it is not belong to API, if some architectures have some reasons
(or excuse) to keep 'inconsistent' with 'generic' types, it is still
acceptable.


>> After a random check, another 3 architectures (maybe more) are also may
>> using 'unsigned long': "arm64/include/asm/atomic.h",
>> "sh/include/asm/atomic-llsc.h", and "xtensa/include/asm/atomic.h".
>>
>> And as far as I know, for a register related variable, 'unsigned long'
>> is also a common using way for both 32-bit and 64-bit (at least, it is a
>> simple way to prevent issues).
> 
> Maybe, but atomic_t is always 32-bit and atomic64_t is always 64-bit, so I
> don't think unsigned long buys you anything with regards to sizing.
> 

'unsigned long' can be used as a register related variable, it is always
32-bit under 32-bit machine, and always 64-bit under 64-bit machine.

So can use it for both arm and arm64, for arm, it can not cause issue,
and for arm64, it is also OK (if changed to 'int' under arm64, may cause
real issue).

So I feel, current arm/arm64 implementation for 'unsigned long' is well
done, not need additional improvement.

> Will
> 
> 

Thanks.
Will Deacon Sept. 27, 2013, 11:06 a.m. UTC | #5
On Thu, Sep 26, 2013 at 12:03:43PM +0100, Chen Gang wrote:
> On 09/26/2013 06:04 PM, Will Deacon wrote:
> > On Thu, Sep 26, 2013 at 03:00:30AM +0100, Chen Gang wrote:
> >> On 09/26/2013 12:07 AM, Will Deacon wrote:
> >>> On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
> >>>> atomic* value is signed value, and atomic* functions need also process
> >>>> signed value (parameter value, and return value), so 32-bit arm need
> >>>> use 'long long' instead of 'u64'.
> >>>>
> >>>> After replacement, it will also fix a bug for atomic64_add_negative():
> >>>> "u64 is never less than 0".
> >>>>
> >>>> The modifications are:
> >>>>
> >>>>   in vim, use "1,% s/\<u64\>/long long/g" command.
> >>>>   remove '__aligned(8)' which is useless for 64-bit.
> >>>>   be sure of 80 column limitation after replacement.
> >>>>
> >>>>
> >>>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
> >>>
> >>> Looks better to me, thanks. While you're here, we could also replace the use
> >>> of `unsigned long' with `int' for the 32-bit atomics, then the whole header
> >>> is consistent with the generic types.
> >>>
> >>> Will
> >>>
> >>>
> >>
> >> Hmm... at least, it seems we can let "use 'int' for 32-bit atomics" in
> >> another patch.
> > 
> > Sure, it can be a follow-up to this one.
> > 
> 
> OK, if it is really a useful patch too, I will follow-up.

It's a cosmetic change to bring the signedness of our 32-bit atomics in-line
with your proposal for 64-bit atomics.

> 'unsigned long' can be used as a register related variable, it is always
> 32-bit under 32-bit machine, and always 64-bit under 64-bit machine.

Not necessarily (c.f. ILP32).

> So can use it for both arm and arm64, for arm, it can not cause issue,
> and for arm64, it is also OK (if changed to 'int' under arm64, may cause
> real issue).

arm and arm64 have different instructions sets. There's no way the inline
assembly used to implement the atomic operations can be made portable
between them.

Will
Chen Gang Sept. 27, 2013, 11:36 a.m. UTC | #6
On 09/27/2013 07:06 PM, Will Deacon wrote:
> On Thu, Sep 26, 2013 at 12:03:43PM +0100, Chen Gang wrote:
>> On 09/26/2013 06:04 PM, Will Deacon wrote:
>>> On Thu, Sep 26, 2013 at 03:00:30AM +0100, Chen Gang wrote:
>>>> On 09/26/2013 12:07 AM, Will Deacon wrote:
>>>>> On Wed, Sep 25, 2013 at 03:25:19AM +0100, Chen Gang wrote:
>>>>>> atomic* value is signed value, and atomic* functions need also process
>>>>>> signed value (parameter value, and return value), so 32-bit arm need
>>>>>> use 'long long' instead of 'u64'.
>>>>>>
>>>>>> After replacement, it will also fix a bug for atomic64_add_negative():
>>>>>> "u64 is never less than 0".
>>>>>>
>>>>>> The modifications are:
>>>>>>
>>>>>>   in vim, use "1,% s/\<u64\>/long long/g" command.
>>>>>>   remove '__aligned(8)' which is useless for 64-bit.
>>>>>>   be sure of 80 column limitation after replacement.
>>>>>>
>>>>>>
>>>>>> Signed-off-by: Chen Gang <gang.chen@asianux.com>
>>>>>
>>>>> Looks better to me, thanks. While you're here, we could also replace the use
>>>>> of `unsigned long' with `int' for the 32-bit atomics, then the whole header
>>>>> is consistent with the generic types.
>>>>>
>>>>> Will
>>>>>
>>>>>
>>>>
>>>> Hmm... at least, it seems we can let "use 'int' for 32-bit atomics" in
>>>> another patch.
>>>
>>> Sure, it can be a follow-up to this one.
>>>
>>
>> OK, if it is really a useful patch too, I will follow-up.
> 
> It's a cosmetic change to bring the signedness of our 32-bit atomics in-line
> with your proposal for 64-bit atomics.
> 
>> 'unsigned long' can be used as a register related variable, it is always
>> 32-bit under 32-bit machine, and always 64-bit under 64-bit machine.
> 
> Not necessarily (c.f. ILP32).
> 
>> So can use it for both arm and arm64, for arm, it can not cause issue,
>> and for arm64, it is also OK (if changed to 'int' under arm64, may cause
>> real issue).
> 
> arm and arm64 have different instructions sets. There's no way the inline
> assembly used to implement the atomic operations can be made portable
> between them.
> 


Hmm... if you like, I will send a follow-up patch for it, the reason is:

It is belong to internal implementation, not belong to API, so if it is
harmless, better to follow related maintainers' 'hobby' or 'tastes', it
will let the related code more clearer.  :-)


I will wait 1-2 days to let another reviewers check, if no reply, I will
send 2 patches for it. (if you already applied the "u64 -> long long"
patch, please let me know, and I will send one patch enough).


> Will
> 
> 

Thanks.
Chen Gang Sept. 29, 2013, 3:43 a.m. UTC | #7
It contents 2 patches:

Patch 1: use 'long long' instead of 'u64' for within atomic.h.

Patch 2: use 'int' instead of 'unsigned long' for normal register
variables within atomic.h


Signed-off-by: Chen Gang <gang.chen@asianux.com>
---
 arch/arm/include/asm/atomic.h |   77
+++++++++++++++++++++--------------------
 1 files changed, 39 insertions(+), 38 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index da1c77d..a715ac0 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -238,15 +238,15 @@  static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 
 #ifndef CONFIG_GENERIC_ATOMIC64
 typedef struct {
-	u64 __aligned(8) counter;
+	long long counter;
 } atomic64_t;
 
 #define ATOMIC64_INIT(i) { (i) }
 
 #ifdef CONFIG_ARM_LPAE
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-	u64 result;
+	long long result;
 
 	__asm__ __volatile__("@ atomic64_read\n"
 "	ldrd	%0, %H0, [%1]"
@@ -257,7 +257,7 @@  static inline u64 atomic64_read(const atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
 	__asm__ __volatile__("@ atomic64_set\n"
 "	strd	%2, %H2, [%1]"
@@ -266,9 +266,9 @@  static inline void atomic64_set(atomic64_t *v, u64 i)
 	);
 }
 #else
-static inline u64 atomic64_read(const atomic64_t *v)
+static inline long long atomic64_read(const atomic64_t *v)
 {
-	u64 result;
+	long long result;
 
 	__asm__ __volatile__("@ atomic64_read\n"
 "	ldrexd	%0, %H0, [%1]"
@@ -279,9 +279,9 @@  static inline u64 atomic64_read(const atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_set(atomic64_t *v, u64 i)
+static inline void atomic64_set(atomic64_t *v, long long i)
 {
-	u64 tmp;
+	long long tmp;
 
 	__asm__ __volatile__("@ atomic64_set\n"
 "1:	ldrexd	%0, %H0, [%2]\n"
@@ -294,9 +294,9 @@  static inline void atomic64_set(atomic64_t *v, u64 i)
 }
 #endif
 
-static inline void atomic64_add(u64 i, atomic64_t *v)
+static inline void atomic64_add(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_add\n"
@@ -311,9 +311,9 @@  static inline void atomic64_add(u64 i, atomic64_t *v)
 	: "cc");
 }
 
-static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -334,9 +334,9 @@  static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
 	return result;
 }
 
-static inline void atomic64_sub(u64 i, atomic64_t *v)
+static inline void atomic64_sub(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	__asm__ __volatile__("@ atomic64_sub\n"
@@ -351,9 +351,9 @@  static inline void atomic64_sub(u64 i, atomic64_t *v)
 	: "cc");
 }
 
-static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+static inline long long atomic64_sub_return(long long i, atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -374,9 +374,10 @@  static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
 	return result;
 }
 
-static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+					long long new)
 {
-	u64 oldval;
+	long long oldval;
 	unsigned long res;
 
 	smp_mb();
@@ -398,9 +399,9 @@  static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
 	return oldval;
 }
 
-static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -419,9 +420,9 @@  static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
 	return result;
 }
 
-static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
 {
-	u64 result;
+	long long result;
 	unsigned long tmp;
 
 	smp_mb();
@@ -445,9 +446,9 @@  static inline u64 atomic64_dec_if_positive(atomic64_t *v)
 	return result;
 }
 
-static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
-	u64 val;
+	long long val;
 	unsigned long tmp;
 	int ret = 1;