Re: ååï Re: [PATCH linux-next] net/dccp/timer.c: use 'u64' instead of 's64' to avoid compiler's warning

From: Chen Gang
Date: Thu May 22 2014 - 21:43:49 EST


On 05/23/2014 07:58 AM, çéæ wrote:
>
> ----- David Miller <davem@xxxxxxxxxxxxx> åéï
>> From: Chen Gang <gang.chen.5i5j@xxxxxxxxx>
>> Date: Wed, 21 May 2014 08:19:34 +0800
>>
>>> 'dccp_timestamp_seed' is initialized once by ktime_get_real() in
>>> dccp_timestamping_init(). It is always less than ktime_get_real()
>>> in dccp_timestamp().
>>>
>>> Then, ktime_us_delta() in dccp_timestamp() will always return positive
>>> number. So can use manual type cast to let compiler and do_div() know
>>> about it to avoid warning.
>>>
>>> The related warning (with allmodconfig under unicore32):
>>>
>>> CC [M] net/dccp/timer.o
>>> net/dccp/timer.c: In function âdccp_timestampâ:
>>> net/dccp/timer.c:285: warning: comparison of distinct pointer types lacks a cast
>>>
>>>
>>> Signed-off-by: Chen Gang <gang.chen.5i5j@xxxxxxxxx>
>>
>> Applied to net-next, thanks.
>>

Thank you for your work.

>> But that type check in include/asm-generic/div64.h is bogus, it should
>> be checking sizeof(X) == 8 rather than the type thing, it just wants to
>> make sure that the value is 64-bit regardless of it's signedness.
>>
>> The arch local implementations do not do this, and that's why very few
>> other people notice this warning.
>
> Arch-dependent codes implement it with unsigned long long type.
> And, every warning should not be ignored.
>

Yeah, we have to let do_div() no touch (especially for 32-bit machine,
which the highest bit is checked). The related code in
"include/asm-generic/div64.h":

23 #if BITS_PER_LONG == 64
24
25 # define do_div(n,base) ({ \
26 uint32_t __base = (base); \
27 uint32_t __rem; \
28 __rem = ((uint64_t)(n)) % __base; \
29 (n) = ((uint64_t)(n)) / __base; \
30 __rem; \
31 })
32
33 #elif BITS_PER_LONG == 32
34
35 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
36
37 /* The unnecessary pointer compare is there
38 * to check for type safety (n must be 64bit)
39 */
40 # define do_div(n,base) ({ \
41 uint32_t __base = (base); \
42 uint32_t __rem; \
43 (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
44 if (likely(((n) >> 32) == 0)) { \
45 __rem = (uint32_t)(n) % __base; \
46 (n) = (uint32_t)(n) / __base; \
47 } else \
48 __rem = __div64_32(&(n), __base); \
49 __rem; \
50 })


And for division operation, architectures are signed/unsigned
sensitive, e.g. div_u64() and div_s64(), they are different.


Thanks.
--
Chen Gang

Open, share, and attitude like air, water, and life which God blessed
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/