Thursday, June 28, 2012

Calculating tmpfs Swap Usage


Calculating tmpfs Swap Usage

This surprisingly seems to be undocumented; I say "surprisingly" because any system using POSIX shared memory or tmpfs filesystems will have skewed "free" output if any of that memory is swapped out.
Unlike SYSV shared memory (visible with ipcs -u), POSIX shared memory doesn't have a documented record of the number of resident/swap pages. Luckily, nr_shmem in /proc/vmstat, in testing and from what I can gather from the page reclaim code in mm/filemap.c, reports only the number of resident shared memory pages. This makes calculating shared swap usage trivial:
#size of all files in /dev/shmem in KB; you should do this for each tmpfs filesystem
ALL_POSIX_SHMEM=$(( $(ls -l /dev/shm/ | awk '{sum+=$5} END {print sum}') / 1024 ))
#resident shared memory pages in KB
RESIDENT_POSIX_SHMEM=$(( $(awk '/nr_shmem/ {print $2}' /proc/vmstat) * $(getconf PAGE_SIZE) / 1024 ))
#shared POSIX memory in swap?
SWAPPED_POSIX_SHMEM=$(( ALL_POSIX_SHMEM - RESIDENT_POSIX_SHMEM ))
SWAPPED_POSIX_PERCENT=$(echo "scale=2; $SWAPPED_POSIX_SHMEM / $ALL_POSIX_SHMEM * 100" | bc)
echo "Swapped POSIX Shared Memory: ${SWAPPED_POSIX_SHMEM}K, $(( SWAPPED_POSIX_SHMEM / 1024 ))M, ${SWAPPED_POSIX_PERCENT}%"

Implications

What does this mean? It means that we can get a more accurate portrayal of what is really available in physical memory, right now (for brevity, some of this is borrowed, yet again, from Jon Miller). This assumes that the above script has already been run:
#total memory
TOTAL_MEMORY_K=$(awk '/^(MemTotal):/{ print $2 }' /proc/meminfo)
#SYSV resident shared memory
RESIDENT_SYSV_SHMEM=$(( $(ipcs -u | awk '/pages resident/ {print $3}') * $(getconf PAGE_SIZE) / 1024))
#free memory minus POSIX/SYSV resident shared memory
FREE_MEMORY_K=$(( $(awk '/^(MemFree|Buffers|Cached):/{ t += $2 } END { print t }' /proc/meminfo) - RESIDENT_POSIX_SHMEM - RESIDENT_SYSV_SHMEM))
USED_MEMORY_K=$(( TOTAL_MEMORY_K - FREE_MEMORY_K ))
echo "${USED_MEMORY_K}K / ${TOTAL_MEMORY_K}K used (${FREE_MEMORY_K}K available)"

No comments:

Post a Comment