RE: clock_gettime() may return timestamps out of order

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sorry guys, but I can't make Outlook bottom-post. Hope you can live with it
this way...

> Rene: Would you be able to try the following?
> 1) report the values of data_addr and &vdso_data in
> arch_setup_additional_pages() (arch/mips/kernel/vdso.c)

arch_setup_additional_pages() seems to be invoked four times during start of our
application:
[   42.481858] data_addr = 77cad000, &vdso_data = 8051e000
[   51.031326] data_addr = 77b61000, &vdso_data = 8051e000
[   51.172457] data_addr = 77eaf000, &vdso_data = 8051e000
[   53.670570] data_addr = 77ec3000, &vdso_data = 8051e000

> 2) apply the (completely untested) patch below and see if it helps

It helped!!!! Well blind-coded :-)

> 3) report those two values with the patch applied to check it has 
> worked as expected

Looks like bits [13:12] are identical now. Nice!
[   19.990308] data_addr = 770da000, &vdso_data = 8051e000
[   28.519685] data_addr = 774c2000, &vdso_data = 8051e000
[   28.656196] data_addr = 77dd6000, &vdso_data = 8051e000
[   31.090116] data_addr = 77c20000, &vdso_data = 8051e000

Thanks a lot, James!
René

-----Original Message-----
From: Hauke Mehrtens [mailto:hauke@xxxxxxxxxx] 
Sent: 24. juni 2017 00:29
To: James Hogan <james.hogan@xxxxxxxxxx>
Cc: Rene Nielsen <rene.nielsen@xxxxxxxxxxxxx>; linux-mips@xxxxxxxxxxxxxx
Subject: Re: clock_gettime() may return timestamps out of order

On 06/23/2017 11:33 PM, James Hogan wrote:
> On Thu, Jun 22, 2017 at 09:32:33PM +0200, Hauke Mehrtens wrote:
>> On 06/21/2017 10:14 AM, Rene Nielsen wrote:
>>> Hi folks,
>>>
>>> Let me go straight into the problem:
>>> We have a multi-threaded application that runs on a MIPS 24KEc using glibc v.
>>> 2.24 under kernel v. 4.9.29 both compiled with gcc v. 6.3.0.
>>> Our 24KEc has a 4-way 32 KBytes dcache (and similar icache), so it's 
>>> prone to cache aliasing (don't know if this matters...).
>>>
>>> We want to be able to do stack backtraces from a signal handler in 
>>> case our application makes a glibc call that results in an assert(). 
>>> The stack backtracing is made within the signal handler with calls to _Unwind_Backtrace().
>>> With the default set of glibc compiler flags, we can't trace through 
>>> signal handlers. Not so long ago, we used uclibc rather than glibc, 
>>> and experienced the same problem, but we got it to work by enabling 
>>> the '-fasynchronous-unwind-tables' gcc flag during compilation of uclibc.
>>> Using the same flag during compilation of glibc causes unexpected 
>>> runtime
>>> problems:
>>>
>>> Many of the threads in our application call 
>>> clock_gettime(CLOCK_MONOTONIC) many times per second, so we greatly 
>>> appreciate the existence and utilization of the VDSO.
>>>
>>> Occassionally, however, clock_gettime(CLOCK_MONOTONIC) returns 
>>> timestamps out of order on the same thread. It's not that the 
>>> returned timestamps seem wrong (they are mostly off by some hundred 
>>> microseconds), but they simply appear out of order.
>>>
>>> Since glibc utilizes VDSO (and uclibc doesn't), my guess is that 
>>> there's something wrong in the interface between the two, but I can't figure out what.
>>> Other glibc calls seem OK (I don't know whether there's a problem 
>>> with the other VDSO function, gettimeofday(), though). If not 
>>> compiled with the infamous flag, we don't see this problem.
>>>
>>> I have tried with a single-threaded test-app, but haven't been able 
>>> to reproduce.
>>>
>>> Any help is highly appreciated. Don't hesitate to asking questions, if needed.
>>>
>>> Thank you very much in advance,
>>> Best regards,
>>> René Nielsen
>>
>>
>> Hi Rene
>>
>> I had a problem with the clock_gettime() call over VDSO on a MIPS BE 
>> 34Kc CPU, see this:
>> https://www.linux-mips.org/archives/linux-mips/2016-01/msg00727.html
>> It was sometimes off by 1 second.
>>
>> It is gone in the current version of LEDE (former OpenWrt), but when 
>> I used git bisect to find the place where it was fixed, I found a 
>> place which has nothing to do with MIPS internal or libc stuff.
>>
>> Makeing some pages uncached or flushing them help, but caused 
>> performance problems, I have never found the root cause of the problem.
> 
> Hauke: Did that platform have aliasing dcache too?

Yes my platform has an aliasing 32 KByte, 4-way associative dcache too.

> I notice that the mips_vdso_data is updated by update_vsyscall() via 
> kseg0, however userland will be accessing it via the mapping 1 page 
> below the VDSO.
> 
> If the kernel data happened to be placed such that the mips_vdso_data 
> in
> kseg0 and the user mapping had different page colours then you could 
> easily hit aliasing issues. A couple of well placed flushes or some 
> more careful placement of the VDSO data might well fix it, as could 
> some random patch changing the positioning of the data such that it 
> coincidentally lined up on the same colour.
> 
> Rene: Would you be able to try the following?
> 1) report the values of data_addr and &vdso_data in
> arch_setup_additional_pages() (arch/mips/kernel/vdso.c)
> 2) apply the (completely untested) patch below and see if it helps
> 3) report those two values with the patch applied to check it has 
> worked as expected
> 
> The patch unfortunately hacks arch_get_unmapped_area_common so that it 
> does the colour alignment on non-shared anonymous pages, as long as 
> non-zero pgoff is provided. Hopefully no userland code would try 
> mmap'ing anonymous memory with a file offset, and so it should be 
> harmless.
> 
> It doesn't look like we can just pass MAP_SHARED to avoid the hack as 
> then pgoff will get cleared by get_unmapped_area()).
> 
> Thanks
> James
> 
> diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 
> 093517e85a6c..4840b20a3756 100644
> --- a/arch/mips/kernel/vdso.c
> +++ b/arch/mips/kernel/vdso.c
> @@ -129,7 +129,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  	vvar_size = gic_size + PAGE_SIZE;
>  	size = vvar_size + image->size;
>  
> -	base = get_unmapped_area(NULL, 0, size, 0, 0);
> +	/*
> +	 * Hack to get the user mapping of the VDSO data page matching the cache
> +	 * colour of its kseg0 address.
> +	 */
> +	base = get_unmapped_area(NULL, 0, size,
> +			(virt_to_phys(&vdso_data) - gic_size) >> PAGE_SHIFT, 0);
>  	if (IS_ERR_VALUE(base)) {
>  		ret = base;
>  		goto out;
> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 
> 64dd8bdd92c3..872cf1fd1744 100644
> --- a/arch/mips/mm/mmap.c
> +++ b/arch/mips/mm/mmap.c
> @@ -81,7 +81,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
>  	}
>  
>  	do_color_align = 0;
> -	if (filp || (flags & MAP_SHARED))
> +	if (filp || (flags & MAP_SHARED) || pgoff)
>  		do_color_align = 1;
>  
>  	/* requesting a specific address */
> 






[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux