git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: 2.18.0 Regression: packing performance and effectiveness

From
Elijah Newren <newren@gmail.com>
Date
Jul 19, 2018, 23:11 UTC
Message-ID
<CABPp-BEo1Ar17uwX=ib8iVYosdwhTXhdMWvi7kgqDb3iPQoj5Q@mail.gmail.com>
In-Reply-To
<20180719182442.GA5796@duynguyen.home>
On Thu, Jul 19, 2018 at 11:24 AM, Duy Nguyen <pclouds@gmail.com> wrote:
Show 51 quoted lines
> On Thu, Jul 19, 2018 at 07:31:35PM +0200, Duy Nguyen wrote:
>> On Thu, Jul 19, 2018 at 01:23:58PM -0400, Jeff King wrote:
>> > On Thu, Jul 19, 2018 at 09:42:00AM -0700, Elijah Newren wrote:
>> >
>> > > Thanks for the quick turnaround.  Unfortunately, I have some bad news.
>> > > With this patch, I get the following:
>> > >
>> > > $ /usr/bin/time -f 'MaxRSS:%M Time:%e' git gc --aggressive
>> > > Enumerating objects: 4460703, done.
>> > > Counting objects: 100% (4460703/4460703), done.
>> > > Delta compression using up to 40 threads.
>> > > Compressing objects: 100% (3807140/3807140), done.
>> > > Writing objects: 100% (4460703/4460703), done.
>> > > Total 4460703 (delta 2831383), reused 1587071 (delta 0)
>> > > error: failed to unpack compressed delta at offset 183854150 from
>> > > .git/objects/pack/pack-30d4f0b0e5a03dc91a658a0586f4e74cdf4a94d6.pack
>> > > fatal: packed object 20ce811e53dabbb8ef9368c108cbbdfa65639c03 (stored
>> > > in .git/objects/pack/pack-30d4f0b0e5a03dc91a658a0586f4e74cdf4a94d6.pack)
>> > > is corrupt
>> > > error: failed to run prune
>> > > MaxRSS:40025196 Time:2531.52
>> >
>> > Looking at that output, my _guess_ is that we somehow end up with a
>> > bogus delta_size value and write out a truncated entry. But I couldn't
>> > reproduce the issue with smaller test cases.
>>
>> Could it be a race condition?
>
> I'm convinced my code is racy (between two writes). I created a broken
> pack once with 32 threads. Elijah please try again with this new
> patch. It should fix this (I only tried repack a few times so far but
> will continue)
>
> The race is this
>
> 1. Thread one sees a large delta size and NULL delta_size[] array,
>    allocates the new array and in the middle of copying old delta
>    sizes over.
>
> 2. Thread two wants to write a new (large) delta size. It sees that
>    delta_size[] is already allocated, it writes the correct size there
>    (and truncated one in object_entry->delta_size_)
>
> 3. Back to thread one, it now copies the truncated value in
>    delta_size_ from step 2 to delta_size[] array, overwriting the good
>    value that thread two wrote.
>
> There is also a potential read/write race where a read from
> pack_size[] happens when the array is not ready. But I don't think it
> can happen with current try_delta() code. I protect it anyway to be
> safe.
Looking at the output from Peff's instrumentation elsewhere in this
thread, I see a lot of lines like
   mismatched get: 32889efd307c7be376da9e3d45a78305f14ba73a = (, 28)
Does that mean it was reading the array when it wasn't ready?

Anyway, with your latest patch (which I'm labelling fix-v4), git gc --aggressive completes, git fsck likes the result, and the new table of stats on this repo becomes:

Version  Pack (MB)  MaxRSS(kB)  Time (s)
-------  ---------  ----------  --------
 2.17.0     5498     43513628    2494.85
 2.18.0    10531     40449596    4168.94
 fix-v1     5509     42509784    2480.74
 fiv-v2     5509     41644104    2468.25
 fiv-v4     5500     44400948    2761.74

So, the pack size is back to what is expected. The code takes about 10% longer and requires 2% more memory than git-2.17.0, but the pack size was the main issue.

However, it's interesting to also look at the effect on packing linux.git (on the same beefy hardware):

Version  Pack (MB)  MaxRSS(kB)  Time (s)
-------  ---------  ----------  --------
 2.17.0     1279     11382932      632.24
 2.18.0     1279     10817568      621.97
 fiv-v4     1279     11484168     1193.67

While the pack size is nice and small, the original memory savings added in 2.18.0 are gone and the performance is much worse. :-(

Previous: Jeff KingNext: Jeff King
Message 16 of 44 in “2.18.0 Regression: packing performance and effectiveness”
  1. Elijah NewrenJul 18, 2018
  2. fix-v1: revert "pack-objects: shrink delta_size field in struct object_entry"Elijah Newren, Jul 18, 2018
  3. fix-v2: make OE_DELTA_SIZE_BITS a bit biggerElijah Newren, Jul 18, 2018
  4. Duy NguyenJul 19, 2018
  5. Jeff KingJul 19, 2018
  6. Elijah NewrenJul 19, 2018
  7. Duy NguyenJul 19, 2018
  8. Jeff KingJul 19, 2018
  9. Duy NguyenJul 19, 2018
  10. Duy NguyenJul 19, 2018
  11. Elijah NewrenJul 19, 2018
  12. Jeff KingJul 19, 2018
  13. Duy NguyenJul 19, 2018
  14. Duy NguyenJul 19, 2018
  15. Jeff KingJul 19, 2018
  16. Elijah NewrenJul 19, 2018
  17. Jeff KingJul 20, 2018
  18. Jeff KingJul 20, 2018
  19. Duy NguyenJul 20, 2018
  20. Elijah NewrenJul 20, 2018
  21. Jeff KingJul 19, 2018
  22. Junio C HamanoJul 19, 2018
  23. Junio C HamanoJul 19, 2018
  24. pack-objects: fix performance issues on packing large deltasNguyễn Thái Ngọc Duy, Jul 20, 2018
  25. Jeff KingJul 20, 2018
  26. Duy NguyenJul 21, 2018
  27. Jeff KingJul 23, 2018
  28. Elijah NewrenJul 20, 2018
  29. Elijah NewrenJul 20, 2018
  30. Duy NguyenJul 21, 2018
  31. Duy NguyenJul 21, 2018
  32. Duy NguyenJul 21, 2018
  33. Elijah NewrenJul 21, 2018
  34. Duy NguyenJul 21, 2018
  35. Elijah NewrenJul 22, 2018
  36. Duy NguyenJul 22, 2018
  37. Elijah NewrenJul 23, 2018
  38. Duy NguyenJul 23, 2018
  39. pack-objects: fix performance issues on packing large deltasNguyễn Thái Ngọc Duy, Jul 22, 2018
  40. Junio C HamanoJul 23, 2018
  41. Duy NguyenJul 23, 2018
  42. Duy NguyenJul 23, 2018
  43. Jeff KingJul 23, 2018
  44. Johannes SixtJul 26, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.