linux – How to See the Amount of Memory Allocated as GEM Buffers

drmgraphicslinuxmemory

My /proc/meminfo shows about 500 MB is allocated as Shmem. I want to get more specific figures. I found an explanation here:

https://lists.kernelnewbies.org/pipermail/kernelnewbies/2013-July/008628.html

It includes tmpfs memory, SysV shared memory (from ipc/shm.c),
POSIX shared memory (under /dev/shm [which is a tmpfs]), and shared anonymous mappings
(from mmap of /dev/zero with MAP_SHARED: see call to shmem_zero_setup()
from drivers/char/mem.c): whatever allocates pages through mm/shmem.c.

2-> as per the developer comments NR_SHMEM included tmpfs and GEM
pages. what is GEM pages?

Ah yes, and the Graphics Execution Manager uses shmem for objects shared
with the GPU: see use of shmem_read_mapping_page*() in drivers/gpu/drm/.

I have about

  • 50MB in user-visible tmpfs, found with df -h -t tmpfs.
  • 40MB (10,000 pages of 4096 bytes) in sysvipc shared memory, found with ipcs -mu.

I would like to get some more positive accounting, for what uses the 500MB! Is there a way to show total GEM allocations? (Or any other likely contributor).

I expect I have some GEM allocations, since I am running a graphical desktop on intel graphics hardware. My kernel version is 4.18.16-200.fc28.x86_64 (Fedora Workstation 28).

Best Answer

These appear in process maps as “drm mm object” or “i915”. You can see this in /proc/<pid>/maps; given the PID of a process using GEM/DRM:

awk '/(drm mm object)|i915/ { hypidx = index($1, "-"); from = substr($1, 1, hypidx - 1); to = substr($1, hypidx + 1); sum += strtonum("0x" to) - strtonum("0x" from) } END { print sum }' /proc/${PID}/maps

will show the total size of the allocated GEM buffers. Calculating the total can be done by feeding in all maps which contain at least one occurrence of “drm mm object” or “i915”; as root:

find /proc -maxdepth 2 -name maps |
xargs grep -E -l "(drm mm object)|i915" |
xargs awk '/(drm mm object)|i915/ { hypidx = index($1, "-"); sum += strtonum("0x" substr($1, hypidx + 1)) - strtonum("0x" substr($1, 1, hypidx - 1)) } END { print sum }'

(-maxdepth 2 is necessary to avoid looking at thread maps). Some additional inode-based de-duplication might be necessary.