Page 1 of 1

Memory problem using pbuffers: EGL_BAD_ALLOC

Posted: Thu Oct 29, 2015 11:16 am
by jannewmarch
I am drawing into an off-screen VGImage using a pbuffer. The image is 2048 bytes x 2048 bytes, the maximum allowed on the RPi. The surface is an EGLSurface created using eglCreatePbufferFromClientBuffer. As a standalone program it works fine. However, when I load the same program as a .so module into the midi program TiMidity weird things happen. The program runs okay once. The next time and all successive times, creating the pbuffer gives an EGL_BAD_ALLOC error. Sometimes I can recover it by running other OpenVG programs, more generally I have to reboot the RPi.

I'm not expecting anyone to debug my code, rather asking if anyone else has had this type of error? When I quit the first run, I free the image, the pbuffer, the context and the surface, but it still seems like something is holding on to a piece of (corrupted?) memory.

I'm aware of the EGL spec and think I'm conforming to it: "Binding a buffer creates an additional reference to it, and implementations must respect outstanding references when destroying objects. For example, if a VGImage is bound to a pbuffer, destroying the image with vgDestroyImage will not free the underlying buffer, because it is still in use by EGL. However, following vgDestroyImage the buffer may only be referred to via the EGL pbuffer handle, since the OpenVG handle to that buffer no longer exists. Similarly, destroying the pbuffer with eglDestroySurface will not free the underlying buffer, because it is still in use by OpenVG . However, following eglDestroySurface the buffer may only be referred to via the OpenVG VGImage handle, since the EGL pbuffer handle no longer exists. "

Re: Memory problem using pbuffers: EGL_BAD_ALLOC

Posted: Sun Nov 08, 2015 1:16 am
by jannewmarch
Solved - not enough garbage collection.
I'm using 64M GPU memory, so the problem showed up early. I was assuming that memory used during an application would be reclaimed by the O/S, as usually happens with ordinary applications. That isn't the case with the GPU: memory allocated must be explicitly de-allocated or it is still marked as being in use. See the GPU memory use by

Code: Select all

/opt/vc/lib /opt/vc/bin/vcdbg reloc
(See e.g. viewtopic.php?f=70&t=48177). For OpenVG, you need to destroy contexts, surfaces and displays and release threads, as well as destroy paths, images, paints, etc.

The first code below shows GPU memory use with garbage collection (41M free), the second shows it without (33M free)
With explicit garbage collection:

Code: Select all

Relocatable heap version 4 found at 0x3b000000
total space allocated is 44M, with 44M relocatable, 0 legacy and 0 offline
0 legacy blocks of size 2359296

free list at 0x3d886760
41M free memory in 2 free block(s)
largest free block is 25M bytes

0x3b000000: free 16M
[2632] 0x3bfc6700: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3bfc6720, d0rual) 'ILCS VC buffer pool'
[ 718] 0x3bfc6940: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3bfc6960, d0rual) 'ILCS VC buffer pool'
0x3bfc6b80: free 25M
[   3] 0x3d886780: used 3.5M (refcount 1 lock count 8, size  3618816, align 4096, data 0x3d887000, d1rual) 'ARM FB'
[   2] 0x3dbfafa0: used  16K (refcount 1 lock count 0, size    16384, align   32, data 0x3dbfafc0, d0ruAl) 'audioplus_tmp_buf'
[   1] 0x3dbfefe0: used 4.0K (refcount 1 lock count 0, size        0, align 4096, data 0x3dbff000, d1rual) 'camera fast alloc arena'
small allocs not requested
With no garbage collection:

Code: Select all

Relocatable heap version 4 found at 0x3b000000
total space allocated is 44M, with 42M relocatable, 2.3M legacy and 0 offline
1 legacy blocks of size 2359296

free list at 0x3d7858a0
33M free memory in 11 free block(s)
largest free block is 24M bytes

0x3b000000: legacy block 2.3M
0x3b240000: free 1.5M
[2297] 0x3b3c9ca0: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b3c9d00, D1ruAl) 'khrn_hw_bin_mem'
0x3b3e1dc0: free 3.3K
[2124] 0x3b3e2ae0: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b3e2b00, D1ruAl) 'khrn_hw_bin_mem'
0x3b3fac00: free 608
[ 882] 0x3b3fae60: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b3faf00, D1ruAl) 'khrn_hw_bin_mem'
0x3b412f80: free 5.6K
[1040] 0x3b414600: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b414700, D1ruAl) 'khrn_hw_bin_mem'
[2428] 0x3b42c720: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b42c800, D1ruAl) 'khrn_hw_bin_mem'
[ 270] 0x3b444840: used  96K (refcount 1 lock count 0, size    98304, align  256, data 0x3b444900, D1ruAl) 'khrn_hw_bin_mem'
[1765] 0x3b45c960: used 4.0M (refcount 1 lock count 0, size  4194304, align 4096, data 0x3b45d000, d1Rual) 'KHRN_IMAGE_T.storage'
0x3b85d980: free 958K
[2728] 0x3b94d060: used  384 (refcount 3 lock count 0, size      312, align    8, data 0x3b94d080, d1Rual) 'vg_shader_fd'
0x3b94d1e0: free 3.2K
[2036] 0x3b94dec0: used  128 (refcount 2 lock count 0, size       64, align    4, data 0x3b94dee0, D1Rual) 'vg_spath'
0x3b94df40: free 608
[2019] 0x3b94e1a0: used  992 (refcount 2 lock count 0, size      924, align    4, data 0x3b94e1c0, d0rual) 'VG_SERVER_STATE_T'
[ 786] 0x3b94e580: used 2.1K (refcount 1 lock count 0, size     2048, align    4, data 0x3b94e5a0, d0rual) 'KHRN_MAP_T.storage'
0x3b94edc0: free 1.0M
[2290] 0x3ba53cc0: used 568K (refcount 1 lock count 0, size   577696, align 4096, data 0x3ba54000, d1ruAl) 'video_decodeRIL:image pool'
[1059] 0x3bae1d80: used 568K (refcount 1 lock count 0, size   577696, align 4096, data 0x3bae2000, d1ruAl) 'video_decodeRIL:image pool'
[ 592] 0x3bb6fe40: used 568K (refcount 1 lock count 0, size   577696, align 4096, data 0x3bb70000, d1rual) 'video_decodeRIL:image pool'
[1501] 0x3bbfdf00: used 568K (refcount 1 lock count 0, size   577696, align 4096, data 0x3bbfe000, d1rual) 'video_decodeRIL:image pool'
0x3bc8bfc0: free 3.2M
[2632] 0x3bfc6700: used  576 (refcount 1 lock count 1, size      512, align    4, data 0x3bfc6720, d0rual) 'ILCS VC buffer pool'
[ 669] 0x3bfc6940: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3bfc6960, d0rual) 'ILCS VC buffer pool'
0x3bfc6b80: free 24M
[ 133] 0x3d7858c0: used   64 (refcount 1 lock count 0, size        0, align   32, data 0x3d7858e0, d3ruAl) 'khdispatch_readahead'
[2418] 0x3d785900: used 1.0M (refcount 1 lock count 0, size  1048576, align   32, data 0x3d785920, d3ruAl) 'khdispatch_workspace'
[ 203] 0x3d885940: used   96 (refcount 1 lock count 0, size       22, align    1, data 0x3d885960, d1rual) 'khrn_hw_null_render'
[1507] 0x3d8859a0: used  160 (refcount 1 lock count 0, size       96, align    4, data 0x3d8859c0, d0rual) 'KHRN_MAP_64_T.storage'
[ 698] 0x3d885a40: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3d885a60, d0rual) 'KHRN_MAP_T.storage'
[ 307] 0x3d885c80: used 1.1K (refcount 1 lock count 0, size     1024, align    4, data 0x3d885ca0, d0rual) 'KHRN_PID_MAP_T.storage'
[1269] 0x3d8860c0: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3d8860e0, d0rual) 'KHRN_MAP_T.storage'
[ 395] 0x3d886300: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3d886320, d0rual) 'KHRN_MAP_T.storage'
[ 718] 0x3d886540: used  576 (refcount 1 lock count 0, size      512, align    4, data 0x3d886560, d0rual) 'KHRN_MAP_T.storage'
[   3] 0x3d886780: used 3.5M (refcount 1 lock count 8, size  3618816, align 4096, data 0x3d887000, d1rual) 'ARM FB'
[   2] 0x3dbfafa0: used  16K (refcount 1 lock count 0, size    16384, align   32, data 0x3dbfafc0, d0ruAl) 'audioplus_tmp_buf'
[   1] 0x3dbfefe0: used 4.0K (refcount 1 lock count 0, size        0, align 4096, data 0x3dbff000, d1rual) 'camera fast alloc arena'
small allocs not requested

Re: Memory problem using pbuffers: EGL_BAD_ALLOC

Posted: Mon Dec 14, 2015 11:05 am
by blackshard83
Maybe you have also to call eglReleaseThread() and eglTerminate() over your display handle when the process is going to terminate. I found myself that eglTerminate() removes a lot of garbage, leaving the videocore memory heap as clean as it was before.
Don't forget to call eglInitialize() at the beginning too.

Re: Memory problem using pbuffers: EGL_BAD_ALLOC

Posted: Mon Dec 14, 2015 12:50 pm
by jamesh
Good programming practice to always free any memory you allocate, even if you expect the system to recover it on exit.