zram.init 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #!/bin/sh /etc/rc.common
  2. START=15
  3. extra_command "compact" "Trigger compaction for all zram swap devices"
  4. extra_command "status" "Print out information & statistics about zram swap devices"
  5. ram_getsize()
  6. {
  7. local line
  8. while read line; do case "$line" in MemTotal:*) set $line; echo "$2"; break ;; esac; done </proc/meminfo
  9. }
  10. zram_getsize() # in megabytes
  11. {
  12. local zram_size="$( uci -q get system.@system[0].zram_size_mb )"
  13. local ram_size="$( ram_getsize )"
  14. if [ -z "$zram_size" ]; then
  15. # e.g. 6mb for 16mb-routers or 61mb for 128mb-routers
  16. echo $(( ram_size / 2048 ))
  17. else
  18. echo "$zram_size"
  19. fi
  20. }
  21. zram_dev()
  22. {
  23. local idx="$1"
  24. echo "/dev/zram${idx:-0}"
  25. }
  26. zram_reset()
  27. {
  28. local dev="$1"
  29. local message="$2"
  30. local proc_entry="/sys/block/$( basename "$dev" )/reset"
  31. logger -s -t zram_reset -p daemon.debug "$message via $proc_entry"
  32. echo "1" >"$proc_entry"
  33. }
  34. zram_getdev()
  35. {
  36. #get unallocated zram dev
  37. local zdev=$( zram_dev )
  38. if [ "$(mount | grep $zdev)" ]; then
  39. local idx=$(cat /sys/class/zram-control/hot_add)
  40. zdev="$( zram_dev $idx )"
  41. fi
  42. echo $zdev
  43. }
  44. zram_comp_algo()
  45. {
  46. local dev="$1"
  47. local zram_comp_algo="$( uci -q get system.@system[0].zram_comp_algo )"
  48. if [ -z "$zram_comp_algo" ]; then
  49. # default to lzo, which is always available
  50. zram_comp_algo="lzo"
  51. fi
  52. if [ $(grep -c "$zram_comp_algo" /sys/block/$( basename $dev )/comp_algorithm) -ne 0 ]; then
  53. logger -s -t zram_comp_algo -p daemon.debug "set compression algorithm '$zram_comp_algo' for zram '$dev'"
  54. echo $zram_comp_algo > "/sys/block/$( basename $dev )/comp_algorithm"
  55. else
  56. logger -s -t zram_comp_algo -p daemon.debug "compression algorithm '$zram_comp_algo' is not supported for '$dev'"
  57. fi
  58. }
  59. #print various stats info about zram swap device
  60. zram_stats()
  61. {
  62. local zdev="/sys/block/$( basename "$1" )"
  63. printf "\nGathering stats info for zram device \"$( basename "$1" )\"\n\n"
  64. printf "ZRAM\n----\n"
  65. printf "%-25s - %s\n" "Block device" $zdev
  66. awk '{ printf "%-25s - %d MiB\n", "Device size", $1/1024/1024 }' <$zdev/disksize
  67. printf "%-25s - %s\n" "Compression algo" "$(cat $zdev/comp_algorithm)"
  68. awk 'BEGIN { fmt = "%-25s - %.2f %s\n"
  69. fmt2 = "%-25s - %d\n"
  70. print "\nDATA\n----" }
  71. { printf fmt, "Original data size", $1/1024/1024, "MiB"
  72. printf fmt, "Compressed data size", $2/1024/1024, "MiB"
  73. printf fmt, "Compress ratio", $1/$2, ""
  74. print "\nMEMORY\n------"
  75. printf fmt, "Memory used, total", $3/1024/1024, "MiB"
  76. printf fmt, "Allocator overhead", ($3-$2)/1024/1024, "MiB"
  77. printf fmt, "Allocator efficiency", $2/$3*100, "%"
  78. printf fmt, "Maximum memory ever used", $5/1024/1024, "MiB"
  79. printf fmt, "Memory limit", $4/1024/1024, "MiB"
  80. print "\nPAGES\n-----"
  81. printf fmt2, "Same pages count", $6
  82. printf fmt2, "Pages compacted", $7 }' <$zdev/mm_stat
  83. awk '{ printf "%-25s - %d\n", "Free pages discarded", $4 }' <$zdev/io_stat
  84. }
  85. zram_compact()
  86. {
  87. # compact zram device (reduce memory allocation overhead)
  88. local zdev="/sys/block/$( basename "$1" )"
  89. local old_mem_used=$(awk '{print $3}' <$zdev/mm_stat)
  90. local old_overhead=$(awk '{print $3-$2}' <$zdev/mm_stat)
  91. echo 1 > $zdev/compact
  92. # If not running interactively, than just return
  93. [ -z "$PS1" ] && return 0
  94. echo ""
  95. echo "Compacting zram device $zdev"
  96. awk -v old_mem="$old_mem_used" -v ovr="$old_overhead" 'BEGIN { fmt = "%-25s - %.1f %s\n" }
  97. { printf fmt, "Memory usage reduced by ", (old_mem-$3)/1024/1024, "MiB"
  98. printf fmt, "Overhead reduced by", (ovr-($3-$2))/ovr*100, "%" }' <$zdev/mm_stat
  99. }
  100. start()
  101. {
  102. [ -e /proc/swaps ] || {
  103. logger -s -t zram_start -p daemon.crit "kernel doesn't support swap"
  104. return 1
  105. }
  106. if [ $( grep -cs zram /proc/swaps ) -ne 0 ]; then
  107. logger -s -t zram_start -p daemon.notice "zram swap is already mounted"
  108. return 1
  109. fi
  110. local zram_dev="$( zram_getdev )"
  111. [ -e "$zram_dev" ] || {
  112. logger -s -t zram_start -p daemon.crit "[ERROR] device '$zram_dev' not found"
  113. return 1
  114. }
  115. local zram_size="$( zram_getsize )"
  116. local zram_priority="$( uci -q get system.@system[0].zram_priority )"
  117. if [ -z "$zram_priority" ]; then
  118. zram_priority="100"
  119. fi
  120. logger -s -t zram_start -p daemon.debug "activating '$zram_dev' for swapping ($zram_size MiB)"
  121. zram_reset "$zram_dev" "enforcing defaults"
  122. zram_comp_algo "$zram_dev"
  123. echo $(( $zram_size * 1024 * 1024 )) >"/sys/block/$( basename "$zram_dev" )/disksize"
  124. busybox mkswap "$zram_dev"
  125. busybox swapon -d -p $zram_priority "$zram_dev"
  126. }
  127. stop()
  128. {
  129. local zram_dev
  130. for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
  131. logger -s -t zram_stop -p daemon.debug "deactivate swap $zram_dev"
  132. busybox swapoff "$zram_dev" && zram_reset "$zram_dev" "claiming memory back"
  133. local dev_index="$( echo $zram_dev | grep -o "[0-9]*$" )"
  134. if [ $dev_index -ne 0 ]; then
  135. logger -s -t zram_stop -p daemon.debug "removing zram $zram_dev"
  136. echo $dev_index > /sys/class/zram-control/hot_remove
  137. fi
  138. } done
  139. }
  140. # show memory stats for all zram swaps
  141. status()
  142. {
  143. for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
  144. zram_stats "$zram_dev"
  145. } done
  146. }
  147. # trigger compaction for all zram swaps
  148. compact()
  149. {
  150. for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
  151. zram_compact "$zram_dev"
  152. } done
  153. }