Closed
Bug 903420
Opened 13 years ago
Closed 13 years ago
jemalloc's stats_chunks lacks proper locking
Categories
(Core :: Memory Allocator, defect)
Core
Memory Allocator
Tracking
()
RESOLVED
FIXED
mozilla26
People
(Reporter: Yoric, Assigned: justin.lebar+bug)
References
Details
Attachments
(1 file, 1 obsolete file)
|
13.25 KB,
patch
|
glandium
:
review+
|
Details | Diff | Splinter Review |
STR:
- from tip 140824:05d3797276d3, apply patch attachment 787002 [details] [diff] [review]
- ./mach build toolkit
- ./mach xpcshell-test toolkit/components/telemetry/unit/test_TelemetryPing.js
| Assignee | ||
Comment 1•13 years ago
|
||
I just tested and as expected, this reproduces even without the patch from comment 0. You're off the hook, Yoric; this is all me. :)
Summary: memory/mozjemalloc/jemalloc.c:6767: Failed assertion: "stats->mapped >= stats->allocated + stats->waste + stats->page_cache + stats->bookkeeping" → memory/mozjemalloc/jemalloc.c:6767: Failed assertion: "stats->mapped >= stats->allocated + stats->waste + stats->page_cache + stats->bookkeeping" when running test_TelemetryPing.js in a debug+jemalloc build
| Assignee | ||
Comment 2•13 years ago
|
||
Interestingly this does not reproduce in a debugger.
| Assignee | ||
Comment 3•13 years ago
|
||
Huh, this was broken before we changed it, too. Thanks for finding this, Yoric!
Attachment #788369 -
Flags: review?(mh+mozilla)
| Assignee | ||
Comment 4•13 years ago
|
||
Actually, I am not so sure this is right...
| Assignee | ||
Comment 5•13 years ago
|
||
Comment on attachment 788369 [details] [diff] [review]
Patch, v1
Yeah, I was mislead by the comments.
There are comments which say that stats_chunks.curchunks is for large allocs only, but those are wrong afaict.
Attachment #788369 -
Flags: review?(mh+mozilla) → review-
| Assignee | ||
Comment 6•13 years ago
|
||
There are actually two race conditions here; one in jemalloc_stats, and one outside it.
chunk_alloc doesn't take any locks, and it reads/writes stats_chunks.curchunks.
chunk_alloc is called by both huge_alloc, which holds the huge lock, and arena_run_alloc, which holds the arena lock.
So that's busted.
But then also, it's possible for allocations to happen during a call to jemalloc_stats, and we won't handle that correctly, either.
We need to fix the race in huge_alloc, but we may end up just taking out this assertion in jemalloc_stats; that one doesn't seem very problematic. And who knows whether these races are what's causing the test failure here; it happens so consistently, I have difficulty believing it's the case, but who knows.
| Assignee | ||
Comment 7•13 years ago
|
||
Whoa, and if we have MALLOC_VALIDATE defined, we touch an rbtree without holding the right locks.
| Assignee | ||
Comment 8•13 years ago
|
||
Wow, this keeps getting worse and worse.
MALLOC_VALIDATE is defined, but even worse, we don't hold the huge mutex while running chunk_alloc, which means that this rbtree is only synchronized when two allocs from the same arena race. (We only have one arena, so this happens when two non-huge allocs race.)
Group: core-security
| Assignee | ||
Comment 9•13 years ago
|
||
I don't see any reason why this isn't sg:crit, save that it might be hard to pull off because you're relying on threading effects.
Updated•13 years ago
|
Keywords: sec-critical
| Assignee | ||
Comment 11•13 years ago
|
||
Renaming this bug to cover the sec-sensitive race condition I found. I'll see if it makes sense to fix the stats race while I'm at it. Fixing the stats race may or may not fix the assertion that this bug was originally filed about.
One option we have here is to disable MALLOC_VALIDATE. I'll need to look into what the consequences of doing that will be if we pass in an invalid pointer. It may be the easiest, safest thing we can do; fixing this properly will require shuffling around and potentially acquiring more locks, which may have an effect on jemalloc's performance.
Summary: memory/mozjemalloc/jemalloc.c:6767: Failed assertion: "stats->mapped >= stats->allocated + stats->waste + stats->page_cache + stats->bookkeeping" when running test_TelemetryPing.js in a debug+jemalloc build → jemalloc's chunk_rtree rbtree lacks proper locking
| Assignee | ||
Comment 12•13 years ago
|
||
Oh, thank goodnesss, I'm wrong about the s-s race here.
malloc_rtree_set, which is the function called from chunk_alloc, does in fact acquire a lock; it's just hiding.
The stats are still racy afaict, but that isn't security-sensitive.
| Assignee | ||
Comment 13•13 years ago
|
||
Sorry for the false alarm, everyone. I'm pretty confident we can safely unprotect this.
Group: core-security
| Assignee | ||
Comment 14•13 years ago
|
||
This patch makes two fixes to jemalloc's memory reporters.
1) We were counting "dirty" pages in "waste", when we shouldn't have
been. This was causing the assertion at the end of jemalloc_stats
which checks that mapped memory is greater than committed memory to
fail.
2) Previously jemalloc_stats used stats_chunks.curchunks to measure the
number of mapped pages. This was problematic for two reasons.
a) stats_chunks.curchunks was not locked when it was modified in
chunk_{de}alloc(), so it could be garbage.
b) Even if it had been locked properly, it would have been possible
for an allocation to occur during a call to jemalloc_stats which
would cause the measured amount of allocated memory to exceed the
measured amount of mapped memory.
We fixed these issues by deleting stats_chunks entirely, and by
introducing huge_mapped, which measures the amount of memory mapped
by huge allocations (and is properly protected by huge_mtx).
We now measure the amount of mapped memory by adding huge_mapped and
each arena's mapped memory, and we do this in such a way that even if
an allocation occurs during our call to jemalloc_stats, we'll still
get a consistent result (where mapped >= committed).
Attachment #790453 -
Flags: review?(mh+mozilla)
| Assignee | ||
Updated•13 years ago
|
Attachment #788369 -
Attachment is obsolete: true
| Assignee | ||
Updated•13 years ago
|
Attachment #790453 -
Attachment description: Patch, v1 → Patch, v2
| Assignee | ||
Comment 15•13 years ago
|
||
If for some reason you want to keep stats_chunks, it is possible to touch it from inside the function which modifies the chunk rbtree (which already acquires its own locks). So we could keep it without any additional overhead, so long as MALLOC_VALIDATE is defined. But I think the approach here is cleaner.
| Assignee | ||
Comment 16•13 years ago
|
||
Note also that currently stats_chunks.nchunks isn't even written to except on Windows.
Comment 17•13 years ago
|
||
Comment on attachment 790453 [details] [diff] [review]
Patch, v2
Review of attachment 790453 [details] [diff] [review]:
-----------------------------------------------------------------
LGTM
Attachment #790453 -
Flags: review?(mh+mozilla) → review+
| Assignee | ||
Comment 18•13 years ago
|
||
| Assignee | ||
Comment 19•13 years ago
|
||
Note that this will affect explicit (I think it should decrease a bit).
Comment 20•13 years ago
|
||
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla26
You need to log in
before you can comment on or make changes to this bug.
Description
•