Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programmatically get the amount of memory currently available from C/C++ code?

In my middleware software layer I am receiving a lot of crashes due with the message,

page allocation failure. order:10, mode:0xd1

As I understand the crash can occur due to number of reasons, running out of dynamic memory for further allocations or Memory fragmentation.

The backtrace which follows the message is not relevant beause it comes through a third party driver module, Most likely the problem is with that driver but Unfortunately, I can neither get any debug information from that nor the source code. I would like to profile my source code using some programatic function calls so as to rule out the possibility of the two scenarios I mentioned above.

I cannot use valgrind because ARM is not yet fully supported by Valgrind.

[Update:] Adding the stacktrace, as @caf's answer suggests there can be some valuable information in it.

Application: page allocation failure. order:10, mode:0xd1
Backtrace:                                                  
[<c00297d0>] (dump_backtrace+0x0/0x114) from [<c02812b8>] (dump_stack+0x18/0x1c)
 r7:0000000a r6:000000d1 r5:00000000 r4:00000000                                
[<c02812a0>] (dump_stack+0x0/0x1c) from [<c00716e4>] (__alloc_pages_nodemask+0x49c/0x4fc)
[<c0071248>] (__alloc_pages_nodemask+0x0/0x4fc) from [<c007175c>] (__get_free_pages+0x18/0x44)
[<c0071744>] (__get_free_pages+0x0/0x44) from [<bf021790>] (tsif_request_rx_buffer+0x74/0xf4 [tsif_data])
[<bf02171c>] (tsif_request_rx_buffer+0x0/0xf4 [tsif_data]) from [<bf021bd8>] (tsif_data_ioctl+0x17c/0x9d4 [tsif_data])
 r7:be9e8604 r6:c0045319 r5:c3793400 r4:00000007
[<bf021a5c>] (tsif_data_ioctl+0x0/0x9d4 [tsif_data]) from [<c00a1c30>] (vfs_ioctl+0x78/0x94)
[<c00a1bb8>] (vfs_ioctl+0x0/0x94) from [<c00a22e0>] (do_vfs_ioctl+0x594/0x5f0)
 r7:c2067e80 r6:00000021 r5:c2067e80 r4:00000021
[<c00a1d4c>] (do_vfs_ioctl+0x0/0x5f0) from [<c00a237c>] (sys_ioctl+0x40/0x64)
[<c00a233c>] (sys_ioctl+0x0/0x64) from [<c0025ec0>] (ret_fast_syscall+0x0/0x28)
 r7:00000036 r6:00144220 r5:00139030 r4:008a47cc
Mem-info:
DMA per-cpu:
CPU    0: hi:   18, btch:   3 usd:   0
active_anon:4120 inactive_anon:134 isolated_anon:0
 active_file:79 inactive_file:3729 isolated_file:0
 unevictable:0 dirty:0 writeback:0 unstable:0 buffer:0
 free:4137 slab_reclaimable:198 slab_unreclaimable:894
 mapped:1707 shmem:64 pagetables:75 bounce:0
DMA free:16548kB min:1104kB low:1380kB high:1656kB active_anon:16480kB inactive_anon:536kB active_file:316kB inactive_file:14916kB unevictable:0kB isolated(o
lowmem_reserve[]: 0 0 0
DMA: 215*4kB 131*8kB 73*16kB 49*32kB 30*64kB 8*128kB 3*256kB 2*512kB 3*1024kB 2*2048kB 0*4096kB 0*8192kB 0*16384kB = 16548kB
3872 total pagecache pages
19200 pages of RAM
4209 free pages
4738 reserved pages
960 slab pages
1751 pages shared
0 pages swap cached

So the question is How can I programmatically get the amount of memory currently available from C/C++ code, the platform is Linux.

like image 904
Alok Save Avatar asked Jun 28 '11 06:06

Alok Save


1 Answers

The message you have shown indicates a failure to allocate memory for a kernel allocation, not a userspace allocation. It is a request for a 4MB (this is what order = 10 means) block of contiguous physical memory. This is a very large kmalloc() request, and it is not surprising that it fails (likely due to memory fragmentation rather than free memory).

You can find out how much free memory is available in /proc/meminfo, however a more detailed summary is available from the kernel log immediately after the backtrace - starting with the line "Mem-info".


Your backtrace shows that there is 16548kB of memory available, but the largest block is 2048kB (order = 9). So memory fragmentation is indeed your problem.

From reading the source to the tsif driver you appear to be using, it seems that the driver requests a kernel allocation with a size entirely controlled by userspace, invoked by the TSIF_REQ_RX_BUF ioctl() (this is a really bad design, especially given that it doesn't even try to report failures to userspace!). My suggestion is to reduce the size of the buffer you are requesting with this ioctl.

like image 146
caf Avatar answered Oct 20 '22 04:10

caf