[yocto] liblzma: memory allocation failed

Peter Bergin peter at berginkonsult.se
Mon Sep 17 00:12:29 PDT 2018


Hi Randy,

On 2018-09-17 06:25, Randy MacLeod wrote:
> On 09/16/2018 04:40 PM, Peter Bergin wrote:
>> Hi,
>>
>> during the task do_package_write_rpm I get the error "liblzma: Memory 
>> allocation failed". It happens during packaging of binary RPM 
>> packages. The root cause seems to be the host environment that is 
>> used in our project. We run our builds on a big server with 32 cores 
>> and 256GB of physical RAM but each user has a limit of virtual memory 
>> usage to 32GB (ulimit -v). The packaging in rpm-native has been 
>> parallelized in the commit 
>> http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/meta/recipes-devtools/rpm?id=84e0bb8d936f1b9094c9d5a92825e9d22e1bc7e3. 
>> What seems to happen is that rpm-native put up 32 parallel tasks with 
>> '#pragma omp', each task is using liblzma that also put up 32 tasks for 
>
> #pragma omp
>
> Tha'ts OpenMP, right? I haven't played with that at all but
> it looks like you can limit the number of threads using an
> environment variable:
>    OMP_NUM_THREADS num
> https://www.openmp.org/wp-content/uploads/OpenMP3.0-SummarySpec.pdf
>
> Doing that would be a little ugly but for now at least, there doesn't
> seem to be that many packages using such a pragma.
>
> Does that work for your case?
>
Yes, it's OpenMP. I tried '#pragma omp parallel num_thread(4)' and it 
worked as a workaround. On the failing server the build succeeded. The 
problem is to get this as a generic solution based on the host settings 
because the #pragma is a compiler directive. But for sure we can make a 
bbappend on this to get it working on our host.

>> the compression work. The memory calculations in liblzma is based on 
>> the amount of physical RAM but as the user is limited by 'ulimit -v' 
>> we get into a OOM situation in liblzma.
>>
>> Here is the code snippet from rpm-native/build/pack.c where it happens:
>>
>>      #pragma omp parallel
>>      #pragma omp single
>>      // re-declaring task variable is necessary, or older gcc 
>> versions will produce code that segfaults
>>      for (struct binaryPackageTaskData *task = tasks; task != NULL; 
>> task = task->next) {
>>          if (task != tasks)
>>          #pragma omp task
>>          {
>>              task->result = packageBinary(spec, task->pkg, cookie, 
>> cheating, &(task->filename), buildTime, buildHost);
>>              rpmlog(RPMLOG_NOTICE, _("Finished binary package job, 
>> result %d, filename %s\n"), task->result, task->filename);
>>          }
>>      }
>>
>>
>> Steps to reproduce is to set 'ulimit -v' in your shell to, for 
>> example, 1/8 of the amount of physical RAM and then build for example 
>> glibc-locale. I have tested this with rocko. If the '#pragma omp' 
>> statements in code snippet above is removed the problem is solved. 
>> But that not good as the parallel processing speed up the process.
>>
>> Is the host environment used here with restricted virtual memory 
>> supported by Yocto? If it is, someone that have any suggestion for a 
>> solution on this issue?
>
>
> This is a little tricky.
>
> From bitbake's point of view, it's almost like you are building
> on a 32 core, 32 GB box and runing out of RAM/swap.
> Clearly we would not fix a build that OOMs in that case
> (it does seem odd that 32 GB isn't enough ...)
>
> Are you sure that there isn't something else going on?
> I have a 24 core machine with 64 GB RAM that never comes
> close to such a problem (so I haven't paid attention to RAM usage).
>
I'm pretty sure I have narrowed down the root cause to the restriction 
of virtual memory and that liblzma base its memory calculations on 
physical RAM.

To prove this I added a printout in rpm-native/rpmio/rpmio.c and the 
function lzopen_internal.

         uint64_t memory_usage = lzma_stream_encoder_mt_memusage(&mt_options);
	rpmlog(RPMLOG_NOTICE, "DBG: memory_usage %lu\n", memory_usage);


The value of memory_usage is the same regardless of which 'ulimit -v' 
value I set. On the host with 256GB of physical RAM and 32GB of virtual 
memory, memory_usage is ~5.1GB. On another host with 16GB of physical 
RAM I get memory_usage of ~660MB.

I guess you have not seen this kind of failure if you not have 
restricted virutal memory on your host. If you want to try to reproduce 
this set 'ulimit -v 8388608' (8GB) in your shell and then 'bitbake 
glibc-locale -c package_write_rpm -f'.

Best regards,
/Peter

>
> ../Randy
>
>>
>> Best regards,
>> /Peter
>>
>>
>>
>>
>
>



More information about the yocto mailing list