Bug 77712

Summary: [JSC] Range of cache flush is not guaranteed by Linux kernel
Product: WebKit Reporter: Hojong Han <hojong.han>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: barraclough, fpizlo, ggaren, hausmann, loki, msaboff, webkit.review.bot, zherczeg
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Linux   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch none

Description Hojong Han 2012-02-02 21:28:30 PST
Current MetaAllocator concept, always coalesces adjacent free spaces, doesn't meet memory management of Linux kernel.
In a certain case Linux kernel doesn't regard contiguous virtual memory areas as one but two.

Let's assume that mmap is called by MetaAllocator three times like below.

1. 8KB allocated from 0x41000000 to 0x41002000 by the 1st mmap call
2. 8KB allocated from 0x41004000 to 0x41006000 by the 2nd mmap call
3. 8KB allocated from 0x41002000 to 0x41004000 by the 3rd mmap call

These virtual memory areas(VMAs) above are contiguous from 0x41000000 to 0x41006000,
but the kernel merges only the third allocated 8KB with the first allocated 8KB although the second one is adjacent to the third.
Because newly allocated VMA can be coalesced with the previously allocated 
and it's not allowed between previously allocated VMAs which internally have different information about annoymous pages.

But current MetaAllocator is not considered on this kernel operation,
thereby it just coalesces adjacent spaces when those are freed.

This different mergence operation between MetaAllocator and Linux kernel finally causes the problem during cache flush.
MetaAllocator hands over coalesced free space that the kernel regards it just as parts of two separated VMAs.
The free space, coalesced by MetaAllocator, will be filled with JIT and cache flush will be run before the execution.
At that time the flush range of the coalesced space is not guaranteed by kernel.
It means inconsistency of data and instruction cache, and nobody knows what happens when this JIT code runs.

The bottom line is that routines, handling this kernel operation, is necessary in MetaAllocator.
Comment 1 Hojong Han 2012-03-08 22:07:38 PST
Created attachment 130982 [details]
Patch
Comment 2 WebKit Review Bot 2012-03-08 22:11:02 PST
Attachment 130982 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/JavaScriptCore/ChangeLog', u'Source..." exit_code: 1
Source/JavaScriptCore/jit/ExecutableAllocator.h:202:  Extra space before ( in function call  [whitespace/parens] [4]
Total errors found: 1 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 3 Andy Wingo 2012-03-09 03:30:39 PST
Comment on attachment 130982 [details]
Patch

Is size_t the right type to use for startPage and endPage?  It seems safer to use intptr_t or something.

Also it seems to me that you would be better off doing

  uintptr_t start = reinterpret_cast<uintptr_t>(code) & ~(pageSize() - 1);

and just adding pageSize() each round instead of doing the divide-and-multiply dance.  Dunno.

I'm not a reviewer, so please take these comments with a grain of salt.
Comment 4 Hojong Han 2012-03-09 04:14:04 PST
(In reply to comment #3)
> (From update of attachment 130982 [details])
> Is size_t the right type to use for startPage and endPage?  It seems safer to use intptr_t or something.
> 
> Also it seems to me that you would be better off doing
> 
>   uintptr_t start = reinterpret_cast<uintptr_t>(code) & ~(pageSize() - 1);
> 
> and just adding pageSize() each round instead of doing the divide-and-multiply dance.  Dunno.
> 
> I'm not a reviewer, so please take these comments with a grain of salt.

Thank you. It's really necessary salt for me.
I'm going to put it into new patch.
Comment 5 Geoffrey Garen 2012-03-09 12:48:48 PST
Phil, does this mean that munmap will eventually fail as well?
Comment 6 Filip Pizlo 2012-03-09 12:49:57 PST
(In reply to comment #5)
> Phil, does this mean that munmap will eventually fail as well?

Nope.  We munmap one page at a time.
Comment 7 Hojong Han 2012-03-11 18:05:59 PDT
Created attachment 131264 [details]
Patch
Comment 8 WebKit Review Bot 2012-03-11 18:07:51 PDT
Attachment 131264 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/JavaScriptCore/ChangeLog', u'Source..." exit_code: 1
Source/JavaScriptCore/jit/ExecutableAllocator.h:202:  Extra space before ( in function call  [whitespace/parens] [4]
Total errors found: 1 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 9 Hojong Han 2012-03-11 18:56:28 PDT
Created attachment 131268 [details]
Patch
Comment 10 WebKit Review Bot 2012-03-11 19:00:06 PDT
Attachment 131268 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/JavaScriptCore/ChangeLog', u'Source..." exit_code: 1
Source/JavaScriptCore/jit/ExecutableAllocator.h:202:  Extra space before ( in function call  [whitespace/parens] [4]
Total errors found: 1 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 11 Geoffrey Garen 2012-03-12 11:45:54 PDT
Comment on attachment 131268 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=131268&action=review

> Source/JavaScriptCore/jit/ExecutableAllocator.h:209
> +            current = next;

You can eliminate the "next" variable if you change this line to "current += pageSize()".

> Source/JavaScriptCore/jit/ExecutableAllocator.h:211
> +        } while (end >= current);

In C++, "end" traditionally means one-past-the-end. That's not the case here, so I don't think you should use the word "end".

I'd suggest "currentPage" and "lastPage" for variable names.
Comment 12 Hojong Han 2012-03-12 19:35:42 PDT
Created attachment 131496 [details]
Patch
Comment 13 WebKit Review Bot 2012-03-12 19:38:23 PDT
Attachment 131496 [details] did not pass style-queue:

Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/JavaScriptCore/ChangeLog', u'Source..." exit_code: 1
Source/JavaScriptCore/jit/ExecutableAllocator.h:201:  Extra space before ( in function call  [whitespace/parens] [4]
Total errors found: 1 in 2 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 14 Hojong Han 2012-03-12 23:59:02 PDT
(In reply to comment #11)
> (From update of attachment 131268 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=131268&action=review
> 
> > Source/JavaScriptCore/jit/ExecutableAllocator.h:209
> > +            current = next;
> 
> You can eliminate the "next" variable if you change this line to "current += pageSize()".
> 
> > Source/JavaScriptCore/jit/ExecutableAllocator.h:211
> > +        } while (end >= current);
> 
> In C++, "end" traditionally means one-past-the-end. That's not the case here, so I don't think you should use the word "end".
> 
> I'd suggest "currentPage" and "lastPage" for variable names.

Thanks for your kind comments. I reflect your advice.
Comment 15 Geoffrey Garen 2012-03-14 16:26:12 PDT
Comment on attachment 131496 [details]
Patch

r=me
Comment 16 WebKit Review Bot 2012-03-14 17:06:20 PDT
Comment on attachment 131496 [details]
Patch

Clearing flags on attachment: 131496

Committed r110792: <http://trac.webkit.org/changeset/110792>
Comment 17 WebKit Review Bot 2012-03-14 17:06:26 PDT
All reviewed patches have been landed.  Closing bug.