问题现象

【充放电测试】测试机经过智能长期充电,充电一晚上,预期结果:测试机能正常使用,系统界面流畅,实际结果:测试机卡顿严重,还会黑屏,概率1/10

【复现步骤】
1. 测试样机电量50%,保证有3天以上使⽤数据,查询smart_batt为0,⼿机连接WIFI adb。
2. 设置-更多设置-⽇期和时间,关闭“使⽤⽹络提供的时间”。
3. 修改电池温度为38度;
echo 38> sys/class/qcom-battery/fake_temp
4. 连接QC3.0充电器充电,调整时间为当天时间的23:59,时间⾃动过渡到第⼆天,调整时间为23:40,修改电池温度为40℃,再次修改电池温度为38℃,继续调整时间为23:59,时间⾃动过渡到第三天,循环执⾏7次,依次修改时间为23:42 23:44 23:46 23:48 23:50 (保证每次时间结算≥24h)每修改⼀次⽇期更改两次电池温度(40℃/38℃)并保证时间⾃然过渡到下⼀天,查询smart_batt是否为15,若不是15,停⽌测试
⾮MCA架构的QCOM adb shell cat /sys/class/qcom-battery/smart_batt
⾮MCA架构的MTK adb shell cat /sys/class/power_supply/battery/smart_batt
MCA架构:adb shell cat /sys/class/xm_power/charger/smart_charge/smart_batt
5. 运⾏charger test脚本,连接QC3.0充电器,充电一天

【预期结果】
系统界面使用流畅
【实际结果】
系统界面卡死,滑动不了,而且还会黑屏
【是否可恢复】/
【上版本是否存在】首个测试版本

问题分析

07-01 16:28:38.451  root 24482 24482 W RxCachedThreadS: page allocation failure: order:0, mode:0x8000c0a(GFP_NOIO|__GFP_HIGHMEM|__GFP_MOVABLE|__GFP_CMA), nodemask=(null),cpuset=foreground,mems_allowed=0
07-01 16:28:38.452  root 24482 24482 F         : CPU: 6 PID: 24482 Comm: RxCachedThreadS Tainted: G         C OE      6.1.118-android14-11-ga3b9c44908dd-ab13320413 #1
07-01 16:28:38.452  root 24482 24482 F Hardware name: Qualcomm Technologies, Inc. Spring QRD (DT)
07-01 16:28:38.452  root 24482 24482 F Call trace:  
07-01 16:28:38.452  root 24482 24482 F         : dump_backtrace+0xf4/0x118
07-01 16:28:38.452  root 24482 24482 F         : show_stack+0x18/0x24
07-01 16:28:38.452  root 24482 24482 F         : dump_stack_lvl+0x60/0x7c
07-01 16:28:38.452  root 24482 24482 F         : dump_stack+0x18/0x3c
07-01 16:28:38.452  root 24482 24482 F         : warn_alloc+0xf4/0x160
07-01 16:28:38.452  root 24482 24482 F         : __alloc_pages_slowpath+0x1080/0x11ac
07-01 16:28:38.452  root 24482 24482 F         : __alloc_pages+0x1f4/0x22c
07-01 16:28:38.452  root 24482 24482 F         : zs_malloc+0x18c/0x7dc [zsmalloc]
07-01 16:28:38.452  root 24482 24482 F         : zram_bvec_rw+0x29c/0xab4 [zram]
07-01 16:28:38.452  root 24482 24482 F         : zram_rw_page+0xac/0x170 [zram]
07-01 16:28:38.452  root 24482 24482 F         : bdev_write_page+0x84/0xd8
07-01 16:28:38.452  root 24482 24482 F         : __swap_writepage+0x60/0x570
07-01 16:28:38.452  root 24482 24482 F         : swap_writepage+0x50/0xa8
07-01 16:28:38.452  root 24482 24482 F         : shrink_folio_list+0x9f0/0x12a4
07-01 16:28:38.452  root 24482 24482 F         : shrink_lruvec+0x7c8/0xd90
07-01 16:28:38.452  root 24482 24482 F         : shrink_node+0x1e0/0x10e4
07-01 16:28:38.452  root 24482 24482 F         : do_try_to_free_pages+0x240/0x5b4
07-01 16:28:38.452  root 24482 24482 F         : try_to_free_pages+0x2dc/0x50c
07-01 16:28:38.452  root 24482 24482 F         : __alloc_pages_slowpath+0x5bc/0x11ac
07-01 16:28:38.452  root 24482 24482 F         : __alloc_pages+0x1f4/0x22c
07-01 16:28:38.452  root 24482 24482 F         : __folio_alloc+0x1c/0x4c
07-01 16:28:38.452  root 24482 24482 F         : do_swap_page+0x684/0xb50
07-01 16:28:38.452  root 24482 24482 F         : handle_mm_fault+0x55c/0x12c0
07-01 16:28:38.452  root 24482 24482 F         : do_page_fault+0x1fc/0x4ac
07-01 16:28:38.452  root 24482 24482 F         : do_translation_fault+0x38/0x54
07-01 16:28:38.452  root 24482 24482 F         : do_mem_abort+0x58/0x118
07-01 16:28:38.452  root 24482 24482 F         : el0_da+0x44/0xac
07-01 16:28:38.452  root 24482 24482 F         : el0t_64_sync_handler+0x98/0xb4
07-01 16:28:38.452  root 24482 24482 F         : el0t_64_sync+0x1a4/0x1a8
07-01 16:28:38.452  root 24482 24482 F Mem-Info:  
07-01 16:28:38.452  root 24482 24482 F active_anon: 21798 inactive_anon:42315 isolated_anon:11
07-01 16:28:38.452  root 24482 24482 F active_file: 39516 inactive_file:67556 isolated_file:32
07-01 16:28:38.452  root 24482 24482 F unevictable: 35855 dirty:148 writeback:2
07-01 16:28:38.452  root 24482 24482 F slab_reclaimable: 28839 slab_unreclaimable:363499
07-01 16:28:38.452  root 24482 24482 F mapped  : 88756 shmem:1257 pagetables:27811
07-01 16:28:38.452  root 24482 24482 F sec_pagetables: 0 bounce:0
07-01 16:28:38.452  root 24482 24482 F kernel_misc_reclaimable: 7296
07-01 16:28:38.452  root 24482 24482 F free    : 3125 free_pcp:811 free_cma:0
07-01 16:28:38.452  root 24482 24482 F         : Node 0 active_anon:87192kB inactive_anon:169260kB active_file:158064kB inactive_file:270224kB unevictable:143420kB isolated(anon):44kB isolated(file):128kB mapped:355024kB dirty:592kB writeback:8kB shmem:5028kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 0kB writeback_tmp:0kB kernel_stack:66688kB shadow_call_stack:16708kB pagetables:111244kB sec_pagetables:0kB all_unreclaimable? no
07-01 16:28:38.452  root 24482 24482 F Normal free: 12500kB boost:0kB min:8192kB low:29488kB high:50784kB reserved_highatomic:4096KB active_anon:87308kB inactive_anon:170424kB active_file:158312kB inactive_file:271528kB unevictable:143420kB writepending:600kB present:3702272kB managed:3549460kB mlocked:143416kB bounce:0kB free_pcp:3216kB local_pcp:604kB free_cma:0kB
07-01 16:28:38.452  root 24482 24482 F lowmem_reserve[]: 0 0 0 0
07-01 16:28:38.452  root 24482 24482 F Normal  : 440*4kB (UME) 663*8kB (UM) 129*16kB (UME) 51*32kB (U) 2*64kB (U) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 10888kB
07-01 16:28:38.452  root 24482 24482 F         : 148157 total pagecache pages
07-01 16:28:38.452  root 24482 24482 F         : 4550 pages in swap cache
07-01 16:28:38.452  root 24482 24482 F         : Free swap  = 2889848kB
07-01 16:28:38.452  root 24482 24482 F         : Total swap = 4194300kB
07-01 16:28:38.452  root 24482 24482 F         : 925568 pages RAM
07-01 16:28:38.452  root 24482 24482 F         : 0 pages HighMem/MovableOnly
07-01 16:28:38.452  root 24482 24482 F         : 38203 pages reserved
07-01 16:28:38.452  root 24482 24482 F         : 72704 pages cma reserved

看起来出现了内存不足的情况,order=0的都分配不出来了

meminfo分析

------ MEMORY INFO (/proc/meminfo) ------
MemTotal:        3549460 kB
MemFree:           15152 kB
MemAvailable:     428048 kB
Buffers:             996 kB
Cached:           462096 kB
SwapCached:        20632 kB
Active:           225224 kB
Inactive:         489588 kB
Active(anon):      80712 kB
Inactive(anon):   235040 kB
Active(file):     144512 kB
Inactive(file):   254548 kB
Unevictable:       60400 kB
Mlocked:           60396 kB
SwapTotal:       4194300 kB
SwapFree:        2793620 kB
Dirty:               784 kB
Writeback:             4 kB
AnonPages:        310780 kB
Mapped:           286224 kB
Shmem:              6472 kB
KReclaimable:     123596 kB
Slab:            1607996 kB
SReclaimable:     110876 kB
SUnreclaim:      1497120 kB
KernelStack:       73780 kB
ShadowCallStack:   18492 kB
PageTables:       115596 kB
SecPageTables:         0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     5969028 kB
Committed_AS:   160851552 kB
VmallocTotal:   259653632 kB
VmallocUsed:      201736 kB
VmallocChunk:          0 kB
Percpu:            10496 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
FileHugePages:         0 kB
FilePmdMapped:         0 kB
CmaTotal:         290816 kB
CmaFree:             132 kB

------ 0.001s was the duration of 'MEMORY INFO' ------

MemFree: 15152 kB 只剩下了15M

Slab: 1607996 kB

SReclaimable: 110876 kB

SUnreclaim: 1497120 kB

slab占用1.6G内存,其中1.49G的内存是无法被清掉的,可以断定发生了slab内存泄露问题

slabinfo分析

------ SLAB INFO (/proc/slabinfo) ------
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
zspage             70805 106507     56   73    1 : tunables    0    0    0 : slabdata   1459   1459      0
zs_handle         331478 575488      8  512    1 : tunables    0    0    0 : slabdata   1124   1124      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4    825    825    160   25    1 : tunables    0    0    0 : slabdata     33     33      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     75     75    160   25    1 : tunables    0    0    0 : slabdata      3      3      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     25     25    160   25    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    125    125    160   25    1 : tunables    0    0    0 : slabdata      5      5      0
dm_bufio_buffer-4     75     75    160   25    1 : tunables    0    0    0 : slabdata      3      3      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
bio-624              475    475    640   25    4 : tunables    0    0    0 : slabdata     19     19      0
bio-704              829    850    768   21    4 : tunables    0    0    0 : slabdata     42     42      0
dm_bufio_buffer-4    125    125    160   25    1 : tunables    0    0    0 : slabdata      5      5      0
dm_bufio_buffer-4     50     50    160   25    1 : tunables    0    0    0 : slabdata      2      2      0
dm_bufio_buffer-4     75     75    160   25    1 : tunables    0    0    0 : slabdata      3      3      0
f2fs_xattr_entry-254:53    312    312    208   39    2 : tunables    0    0    0 : slabdata      8      8      0
cam_req_mgr_timer      0      0     88   46    1 : tunables    0    0    0 : slabdata      0      0      0
adreno_dispatch_job   2048   2048     16  256    1 : tunables    0    0    0 : slabdata      8      8      0
kgsl_iommu_addr_entry   2832   2958     40  102    1 : tunables    0    0    0 : slabdata     29     29      0
kgsl_memobj_node     512    512     64   64    1 : tunables    0    0    0 : slabdata      8      8      0
kgsl_event           340    340    120   34    1 : tunables    0    0    0 : slabdata     10     10      0
kgsl_pool_page_entry   1938   2040     40  102    1 : tunables    0    0    0 : slabdata     20     20      0
cnss-pool-128k         2      2 131072    1   32 : tunables    0    0    0 : slabdata      2      2      0
cnss-pool-64k          7      7  65536    1   16 : tunables    0    0    0 : slabdata      7      7      0
cnss-pool-32k         16     16  32768    1    8 : tunables    0    0    0 : slabdata     16     16      0
cnss-pool-16k         29     29  16384    2    8 : tunables    0    0    0 : slabdata     15     15      0
cnss-pool-8k           4      4   8192    4    8 : tunables    0    0    0 : slabdata      1      1      0
IPA_RX_PKT_WRAPPER   1872   1872    104   39    1 : tunables    0    0    0 : slabdata     48     48      0
IPA_TX_PKT_WRAPPER    312    312    104   39    1 : tunables    0    0    0 : slabdata      8      8      0
IPA_RT_TBL           108    108    224   36    2 : tunables    0    0    0 : slabdata      3      3      0
IPA_HDR_PROC_CTX_OFFSET      0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
IPA_HDR_PROC_CTX       0      0     96   42    1 : tunables    0    0    0 : slabdata      0      0      0
IPA_FNR_STATS        256    256     16  256    1 : tunables    0    0    0 : slabdata      1      1      0
IPA_HDR_OFFSET       640    640     32  128    1 : tunables    0    0    0 : slabdata      5      5      0
IPA_HDR              172    172    352   23    2 : tunables    0    0    0 : slabdata      8      8      0
IPA_RT               102    102    240   34    2 : tunables    0    0    0 : slabdata      3      3      0
IPA_FLT               76     76    424   38    4 : tunables    0    0    0 : slabdata      2      2      0
IEEE-802.15.4-MAC      0      0    896   36    8 : tunables    0    0    0 : slabdata      0      0      0
IEEE-802.15.4-RAW      0      0    896   36    8 : tunables    0    0    0 : slabdata      0      0      0
lowpan-frags           0      0    200   20    1 : tunables    0    0    0 : slabdata      0      0      0
can_gw                 0      0    824   39    8 : tunables    0    0    0 : slabdata      0      0      0
can_receiver           0      0     80   51    1 : tunables    0    0    0 : slabdata      0      0      0
TIPC                 224    224   1152   28    8 : tunables    0    0    0 : slabdata      8      8      0
ext4_groupinfo_4k    117    117    208   39    2 : tunables    0    0    0 : slabdata      3      3      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4    100    100    160   25    1 : tunables    0    0    0 : slabdata      4      4      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4     75     75    160   25    1 : tunables    0    0    0 : slabdata      3      3      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4    775    875    160   25    1 : tunables    0    0    0 : slabdata     35     35      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4   1575   1575    160   25    1 : tunables    0    0    0 : slabdata     63     63      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4   1100   1100    160   25    1 : tunables    0    0    0 : slabdata     44     44      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4   1500   1500    160   25    1 : tunables    0    0    0 : slabdata     60     60      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4   1100   1100    160   25    1 : tunables    0    0    0 : slabdata     44     44      0
bio-372              144    144   3776    8    8 : tunables    0    0    0 : slabdata     18     18      0
bio-380              284    284   3840    8    8 : tunables    0    0    0 : slabdata     74     74      0
dm_verity_fec_buffers      8      8   4048    8    8 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer       26     26    152   26    1 : tunables    0    0    0 : slabdata      1      1      0
dm_bufio_buffer-4   1200   1200    160   25    1 : tunables    0    0    0 : slabdata     48     48      0
bio-200              512    640    256   32    2 : tunables    0    0    0 : slabdata     20     20      0
bio-280              800    800    320   25    2 : tunables    0    0    0 : slabdata     32     32      0
f2fs_xattr_entry-8:12    195    195    208   39    2 : tunables    0    0    0 : slabdata      5      5      0
scsi_sense_cache     416    416    128   32    1 : tunables    0    0    0 : slabdata     13     13      0
QIPCRTR              408    408    960   34    8 : tunables    0    0    0 : slabdata     12     12      0
fsverity_info        330    330    272   30    2 : tunables    0    0    0 : slabdata     11     11      0
fscrypt_info        2076   5010    136   30    1 : tunables    0    0    0 : slabdata    167    167      0
wakeup_irq_node_cache    128    128     32  128    1 : tunables    0    0    0 : slabdata      1      1      0
AF_VSOCK              68     68   1472   22    8 : tunables    0    0    0 : slabdata      4      4      0
bridge_fdb_cache       0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
nf-frags               0      0    200   20    1 : tunables    0    0    0 : slabdata      0      0      0
xfrm6_tunnel_spi       0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
ip6-frags              0      0    200   20    1 : tunables    0    0    0 : slabdata      0      0      0
fib6_nodes            96     96    128   32    1 : tunables    0    0    0 : slabdata      3      3      0
ip6_dst_cache        256    256    256   32    2 : tunables    0    0    0 : slabdata      8      8      0
ip6_mrt_cache          0      0    192   21    1 : tunables    0    0    0 : slabdata      0      0      0
PINGv6                 0      0   1344   24    8 : tunables    0    0    0 : slabdata      0      0      0
RAWv6                216    216   1344   24    8 : tunables    0    0    0 : slabdata      9      9      0
UDPLITEv6              0      0   1472   22    8 : tunables    0    0    0 : slabdata      0      0      0
UDPv6                176    176   1472   22    8 : tunables    0    0    0 : slabdata      8      8      0
tw_sock_TCPv6        232    232    280   29    2 : tunables    0    0    0 : slabdata      8      8      0
request_sock_TCPv6      0      0    328   24    2 : tunables    0    0    0 : slabdata      0      0      0
TCPv6                120    120   2560   12    8 : tunables    0    0    0 : slabdata     10     10      0
xt_hashlimit           0      0    120   34    1 : tunables    0    0    0 : slabdata      0      0      0
nf_conncount_rb        0      0     96   42    1 : tunables    0    0    0 : slabdata      0      0      0
nf_conncount_tuple      0      0     72   56    1 : tunables    0    0    0 : slabdata      0      0      0
nf_conntrack_expect      0      0    232   35    2 : tunables    0    0    0 : slabdata      0      0      0
nf_conntrack         325    425    320   25    2 : tunables    0    0    0 : slabdata     17     17      0
fq_flow_cache          0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
ashmem_range_cache    512    512     64   64    1 : tunables    0    0    0 : slabdata      8      8      0
ashmem_area_cache    286    286    312   26    2 : tunables    0    0    0 : slabdata     11     11      0
dm_snap_pending_exception      0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
dm_exception           0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
kcopyd_job             0      0   3384    9    8 : tunables    0    0    0 : slabdata      0      0      0
io                  1472   1472     64   64    1 : tunables    0    0    0 : slabdata     23     23      0
dm_uevent              0      0   2888   11    8 : tunables    0    0    0 : slabdata      0      0      0
wg_peer                0      0   1760   18    8 : tunables    0    0    0 : slabdata      0      0      0
allowedips_node        0      0     72   56    1 : tunables    0    0    0 : slabdata      0      0      0
sd_ext_cdb             0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
bio-160              504    504    192   21    1 : tunables    0    0    0 : slabdata     24     24      0
io_kiocb               0      0    256   32    2 : tunables    0    0    0 : slabdata      0      0      0
bfq_io_cq              0      0    232   35    2 : tunables    0    0    0 : slabdata      0      0      0
bfq_queue              0      0    568   28    4 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-256      0      0   4232    7    8 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-128      0      0   2184   15    8 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-64      0      0   1160   28    8 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-16      0      0    392   20    2 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-4       0      0    200   20    1 : tunables    0    0    0 : slabdata      0      0      0
erofs_pcluster-1    2314   2314    152   26    1 : tunables    0    0    0 : slabdata     89     89      0
erofs_inode         3312   4745    784   20    4 : tunables    0    0    0 : slabdata    238    238      0
f2fs_casefolded_name    256    256    256   32    2 : tunables    0    0    0 : slabdata      8      8      0
f2fs_dic_entry         0      0    232   35    2 : tunables    0    0    0 : slabdata      0      0      0
f2fs_cic_entry         0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
f2fs_bio_entry_slab   1360   1360     24  170    1 : tunables    0    0    0 : slabdata      8      8      0
f2fs_bio_iostat_ctx   2432   2816     32  128    1 : tunables    0    0    0 : slabdata     22     22      0
f2fs_bio_post_read_ctx    510    510     80   51    1 : tunables    0    0    0 : slabdata     10     10      0
f2fs_victim_entry      0      0     56   73    1 : tunables    0    0    0 : slabdata      0      0      0
f2fs_extent_node    1456   1456     72   56    1 : tunables    0    0    0 : slabdata     26     26      0
f2fs_extent_tree    3434   8648     88   46    1 : tunables    0    0    0 : slabdata    188    188      0
f2fs_fsync_inode_entry      0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
f2fs_inode_entry    1360   1360     24  170    1 : tunables    0    0    0 : slabdata      8      8      0
f2fs_ino_entry      3251   3910     24  170    1 : tunables    0    0    0 : slabdata     23     23      0
f2fs_revoke_entry   2176   2176     32  128    1 : tunables    0    0    0 : slabdata     17     17      0
f2fs_sit_entry_set   1700   1700     24  170    1 : tunables    0    0    0 : slabdata     10     10      0
f2fs_discard_cmd    5940   5940    112   36    1 : tunables    0    0    0 : slabdata    165    165      0
f2fs_discard_entry    920   1150     88   46    1 : tunables    0    0    0 : slabdata     25     25      0
f2fs_fsync_node_entry   2432   2944     32  128    1 : tunables    0    0    0 : slabdata     23     23      0
f2fs_nat_entry_set   1428   1428     40  102    1 : tunables    0    0    0 : slabdata     14     14      0
f2fs_free_nid       8330   8330     24  170    1 : tunables    0    0    0 : slabdata     49     49      0
f2fs_nat_entry      2304   2560     32  128    1 : tunables    0    0    0 : slabdata     20     20      0
f2fs_inode_cache    1728   4857   1360   24    8 : tunables    0    0    0 : slabdata    212    212      0
ovl_aio_req            0      0     64   64    1 : tunables    0    0    0 : slabdata      0      0      0
ovl_inode            958   1465    816   20    4 : tunables    0    0    0 : slabdata     74     74      0
fuse_bpf_aio_req       0      0     64   64    1 : tunables    0    0    0 : slabdata      0      0      0
fuse_request         208    208    152   26    1 : tunables    0    0    0 : slabdata      8      8      0
fuse_inode           471    576    960   34    8 : tunables    0    0    0 : slabdata     24     24      0
exfat_inode_cache      0      0    936   35    8 : tunables    0    0    0 : slabdata      0      0      0
exfat_cache            0      0     40  102    1 : tunables    0    0    0 : slabdata      0      0      0
fat_inode_cache      612    756    888   36    8 : tunables    0    0    0 : slabdata     21     21      0
fat_cache           1224   1224     40  102    1 : tunables    0    0    0 : slabdata     12     12      0
jbd2_transaction_s    256    256    256   32    2 : tunables    0    0    0 : slabdata      8      8      0
jbd2_inode           512    512     64   64    1 : tunables    0    0    0 : slabdata      8      8      0
jbd2_journal_handle    584    584     56   73    1 : tunables    0    0    0 : slabdata      8      8      0
jbd2_journal_head    272    272    120   34    1 : tunables    0    0    0 : slabdata      8      8      0
jbd2_revoke_table_s    256    256     16  256    1 : tunables    0    0    0 : slabdata      1      1      0
jbd2_revoke_record_s      0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
ext4_fc_dentry_update      0      0     96   42    1 : tunables    0    0    0 : slabdata      0      0      0
ext4_inode_cache     900   1176   1344   24    8 : tunables    0    0    0 : slabdata     49     49      0
ext4_free_data       584    584     56   73    1 : tunables    0    0    0 : slabdata      8      8      0
ext4_allocation_context    240    240    136   30    1 : tunables    0    0    0 : slabdata      8      8      0
ext4_prealloc_space    312    312    104   39    1 : tunables    0    0    0 : slabdata      8      8      0
ext4_system_zone     306    306     40  102    1 : tunables    0    0    0 : slabdata      3      3      0
ext4_io_end_vec     1024   1024     32  128    1 : tunables    0    0    0 : slabdata      8      8      0
ext4_io_end          512    512     64   64    1 : tunables    0    0    0 : slabdata      8      8      0
ext4_bio_post_read_ctx    128    128     64   64    1 : tunables    0    0    0 : slabdata      2      2      0
ext4_pending_reservation      0      0     32  128    1 : tunables    0    0    0 : slabdata      0      0      0
ext4_extent_status   2372   2754     40  102    1 : tunables    0    0    0 : slabdata     27     27      0
mbcache              584    584     56   73    1 : tunables    0    0    0 : slabdata      8      8      0
kioctx               150    150    640   25    4 : tunables    0    0    0 : slabdata      6      6      0
aio_kiocb            168    168    192   21    1 : tunables    0    0    0 : slabdata      8      8      0
userfaultfd_ctx_cache    256    256    256   32    2 : tunables    0    0    0 : slabdata      8      8      0
dio                    0      0    640   25    4 : tunables    0    0    0 : slabdata      0      0      0
fasync_cache           0      0     48   85    1 : tunables    0    0    0 : slabdata      0      0      0
audit_tree_mark        0      0     80   51    1 : tunables    0    0    0 : slabdata      0      0      0
posix_timers_cache    248    248    264   31    2 : tunables    0    0    0 : slabdata      8      8      0
UNIX-STREAM          491    491   1152   28    8 : tunables    0    0    0 : slabdata     22     22      0
UNIX                 920   1176   1152   28    8 : tunables    0    0    0 : slabdata     42     42      0
ip4-frags              0      0    216   37    2 : tunables    0    0    0 : slabdata      0      0      0
UDP-Lite               0      0   1280   25    8 : tunables    0    0    0 : slabdata      0      0      0
tcp_bind2_bucket     512    512     64   64    1 : tunables    0    0    0 : slabdata      8      8      0
tcp_bind_bucket      256    256    128   32    1 : tunables    0    0    0 : slabdata      8      8      0
inet_peer_cache      147    147    192   21    1 : tunables    0    0    0 : slabdata      7      7      0
xfrm_dst_cache         0      0    320   25    2 : tunables    0    0    0 : slabdata      0      0      0
xfrm_state             0      0    768   21    4 : tunables    0    0    0 : slabdata      0      0      0
ip_fib_trie          340    340     48   85    1 : tunables    0    0    0 : slabdata      4      4      0
ip_fib_alias         292    292     56   73    1 : tunables    0    0    0 : slabdata      4      4      0
ip_dst_cache         168    168    192   21    1 : tunables    0    0    0 : slabdata      8      8      0
PING                 126    126   1088   30    8 : tunables    0    0    0 : slabdata      6      6      0
RAW                  252    252   1152   28    8 : tunables    0    0    0 : slabdata      9      9      0
UDP                  362    390   1280   25    8 : tunables    0    0    0 : slabdata     20     20      0
tw_sock_TCP          232    232    280   29    2 : tunables    0    0    0 : slabdata      8      8      0
request_sock_TCP      24     24    328   24    2 : tunables    0    0    0 : slabdata      1      1      0
TCP                  105    105   2432   13    8 : tunables    0    0    0 : slabdata      9      9      0
dquot                603    832    256   32    2 : tunables    0    0    0 : slabdata     26     26      0
bio-288               50     50    320   25    2 : tunables    0    0    0 : slabdata      2      2      0
ep_head             2304   2304     16  256    1 : tunables    0    0    0 : slabdata      9      9      0
eventpoll_pwq       1773   2112     64   64    1 : tunables    0    0    0 : slabdata     33     33      0
eventpoll_epi       1742   1920    128   32    1 : tunables    0    0    0 : slabdata     60     60      0
inotify_inode_mark    408    408     80   51    1 : tunables    0    0    0 : slabdata      8      8      0
dax_cache             36     36    896   36    8 : tunables    0    0    0 : slabdata      1      1      0
sgpool-128            87     92   4096    8    8 : tunables    0    0    0 : slabdata     22     22      0
sgpool-64            164    164   2048   16    8 : tunables    0    0    0 : slabdata     12     12      0
sgpool-32            256    256   1024   32    8 : tunables    0    0    0 : slabdata      8      8      0
sgpool-16            256    256    512   32    4 : tunables    0    0    0 : slabdata      8      8      0
sgpool-8             288    288    256   32    2 : tunables    0    0    0 : slabdata      9      9      0
bio_crypt_ctx       2142   2448     40  102    1 : tunables    0    0    0 : slabdata     24     24      0
request_queue_srcu     38     38   1640   19    8 : tunables    0    0    0 : slabdata      2      2      0
request_queue        196    196   1160   28    8 : tunables    0    0    0 : slabdata      7      7      0
blkdev_ioc           468    468    104   39    1 : tunables    0    0    0 : slabdata     12     12      0
bio-224             2272   2272    256   32    2 : tunables    0    0    0 : slabdata     71     71      0
biovec-max          1493   1499   4096    8    8 : tunables    0    0    0 : slabdata    197    197      0
biovec-128           262    296   2048   16    8 : tunables    0    0    0 : slabdata     29     29      0
biovec-64            496    532   1024   32    8 : tunables    0    0    0 : slabdata     21     21      0
biovec-16            256    256    256   32    2 : tunables    0    0    0 : slabdata      8      8      0
damon_region           0      0     56   73    1 : tunables    0    0    0 : slabdata      0      0      0
khugepaged_mm_slot      0      0    112   36    1 : tunables    0    0    0 : slabdata      0      0      0
uid_cache            210    210    192   21    1 : tunables    0    0    0 : slabdata     10     10      0
iommu_iova          4928   4928     64   64    1 : tunables    0    0    0 : slabdata     77     77      0
dmaengine-unmap-2     64     64     64   64    1 : tunables    0    0    0 : slabdata      1      1      0
audit_buffer        1360   1360     24  170    1 : tunables    0    0    0 : slabdata      8      8      0
sock_inode_cache    1632   1872    896   36    8 : tunables    0    0    0 : slabdata     52     52      0
skbuff_ext_cache       0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
skbuff_fclone_cache    864    864    512   32    4 : tunables    0    0    0 : slabdata     27     27      0
skbuff_head_cache   5026   5600    256   32    2 : tunables    0    0    0 : slabdata    175    175      0
configfs_dir_cache    460    460     88   46    1 : tunables    0    0    0 : slabdata     10     10      0
file_lock_cache      481    481    216   37    2 : tunables    0    0    0 : slabdata     13     13      0
file_lock_ctx       1698   1971     56   73    1 : tunables    0    0    0 : slabdata     27     27      0
fsnotify_mark_connector   1024   1024     32  128    1 : tunables    0    0    0 : slabdata      8      8      0
buffer_head         1807   2067    104   39    1 : tunables    0    0    0 : slabdata     53     53      0
taskstats            312    312    416   39    4 : tunables    0    0    0 : slabdata      8      8      0
proc_dir_entry      2835   2835    192   21    1 : tunables    0    0    0 : slabdata    135    135      0
pde_opener           816    816     40  102    1 : tunables    0    0    0 : slabdata      8      8      0
proc_inode_cache     563    645    784   20    4 : tunables    0    0    0 : slabdata     36     36      0
seq_file             540    540    136   30    1 : tunables    0    0    0 : slabdata     18     18      0
sigqueue             408    408     80   51    1 : tunables    0    0    0 : slabdata      8      8      0
bdev_cache           289    289   1856   17    8 : tunables    0    0    0 : slabdata     17     17      0
shmem_inode_cache   2550   2740    848   38    8 : tunables    0    0    0 : slabdata     73     73      0
kernfs_iattrs_cache   6563   7084     88   46    1 : tunables    0    0    0 : slabdata    154    154      0
kernfs_node_cache 118639 119010    136   30    1 : tunables    0    0    0 : slabdata   3967   3967      0
mnt_cache           9451   9794    384   21    2 : tunables    0    0    0 : slabdata    469    469      0
filp               31197  34974    320   25    2 : tunables    0    0    0 : slabdata   1400   1400      0
inode_cache        42896  45563    712   23    4 : tunables    0    0    0 : slabdata   1981   1981      0
dentry             54909  73476    208   39    2 : tunables    0    0    0 : slabdata   1884   1884      0
names_cache          144    160   4096    8    8 : tunables    0    0    0 : slabdata     20     20      0
net_namespace          0      0   4160    7    8 : tunables    0    0    0 : slabdata      0      0      0
hashtab_node        5610   5610     24  170    1 : tunables    0    0    0 : slabdata     33     33      0
ebitmap_node       11520  11520     64   64    1 : tunables    0    0    0 : slabdata    180    180      0
avtab_extended_perms   1428   1428     40  102    1 : tunables    0    0    0 : slabdata     14     14      0
avtab_node         96050  96050     24  170    1 : tunables    0    0    0 : slabdata    565    565      0
avc_xperms_data     1024   1024     32  128    1 : tunables    0    0    0 : slabdata      8      8      0
avc_xperms_decision_node    680    680     48   85    1 : tunables    0    0    0 : slabdata      8      8      0
avc_xperms_node     2048   2336     56   73    1 : tunables    0    0    0 : slabdata     32     32      0
avc_node            1904   1960     72   56    1 : tunables    0    0    0 : slabdata     35     35      0
iint_cache             0      0    144   28    1 : tunables    0    0    0 : slabdata      0      0      0
lsm_inode_cache    53033  72781     56   73    1 : tunables    0    0    0 : slabdata    997    997      0
lsm_file_cache     31916  41216     16  256    1 : tunables    0    0    0 : slabdata    161    161      0
key_jar               96     96    256   32    2 : tunables    0    0    0 : slabdata      3      3      0
uts_namespace          0      0    432   37    4 : tunables    0    0    0 : slabdata      0      0      0
nsproxy              448    448     72   56    1 : tunables    0    0    0 : slabdata      8      8      0
vma_lock          236516 265280     64   64    1 : tunables    0    0    0 : slabdata   4145   4145      0
vm_area_struct    236383 254060    200   20    1 : tunables    0    0    0 : slabdata  12703  12703      0
fs_cache             640    640     64   64    1 : tunables    0    0    0 : slabdata     10     10      0
files_cache          460    460    704   23    4 : tunables    0    0    0 : slabdata     20     20      0
signal_cache        1152   1204   1152   28    8 : tunables    0    0    0 : slabdata     43     43      0
sighand_cache       1118   1170   2112   15    8 : tunables    0    0    0 : slabdata     78     78      0
task_struct         4522   4868   4800    6    8 : tunables    0    0    0 : slabdata    818    818      0
cred_jar            1914   2058    192   21    1 : tunables    0    0    0 : slabdata     98     98      0
anon_vma_chain    130305 148736     64   64    1 : tunables    0    0    0 : slabdata   2324   2324      0
anon_vma           78896  86816    128   32    1 : tunables    0    0    0 : slabdata   2713   2713      0
pid                 4990   6208    128   32    1 : tunables    0    0    0 : slabdata    194    194      0
perf_event           210    210   1072   30    8 : tunables    0    0    0 : slabdata      7      7      0
trace_event_file    3772   3772     88   46    1 : tunables    0    0    0 : slabdata     82     82      0
ftrace_event_field   6935   6935     56   73    1 : tunables    0    0    0 : slabdata     95     95      0
pool_workqueue       416    416    256   32    2 : tunables    0    0    0 : slabdata     13     13      0
maple_node         24466  38000    256   32    2 : tunables    0    0    0 : slabdata   1189   1189      0
radix_tree_node    38668  68950    584   28    4 : tunables    0    0    0 : slabdata   2464   2464      0
task_group            96     96    512   32    4 : tunables    0    0    0 : slabdata      3      3      0
mm_struct            471    484   1024   32    8 : tunables    0    0    0 : slabdata     16     16      0
vmap_area          16726  26432     64   64    1 : tunables    0    0    0 : slabdata    413    413      0
kmalloc-rcl-8k         0      0   8192    4    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-4k         0      0   4096    8    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-2k         0      0   2048   16    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-1k         0      0   1024   32    8 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-512        0      0    512   32    4 : tunables    0    0    0 : slabdata      0      0      0
kmalloc-rcl-256       96     96    256   32    2 : tunables    0    0    0 : slabdata      3      3      0
kmalloc-rcl-192      966    966    192   21    1 : tunables    0    0    0 : slabdata     46     46      0
kmalloc-rcl-128     1663   1696    128   32    1 : tunables    0    0    0 : slabdata     53     53      0
kmalloc-rcl-64      2618   3904     64   64    1 : tunables    0    0    0 : slabdata     61     61      0
kmalloc-8k           892    898   8192    4    8 : tunables    0    0    0 : slabdata    241    241      0
kmalloc-4k          4352   4361   4096    8    8 : tunables    0    0    0 : slabdata    546    546      0
kmalloc-2k          3858   4066   2048   16    8 : tunables    0    0    0 : slabdata    255    255      0
kmalloc-1k          8969   9444   1024   32    8 : tunables    0    0    0 : slabdata    296    296      0
kmalloc-512       216375 216760    512   32    4 : tunables    0    0    0 : slabdata  12698  12698      0
kmalloc-256         6091   6176    256   32    2 : tunables    0    0    0 : slabdata    193    193      0
kmalloc-192         9683  11340    192   21    1 : tunables    0    0    0 : slabdata    540    540      0
kmalloc-128       5880296 5881696    128   32    1 : tunables    0    0    0 : slabdata 183803 183803      0
kmalloc-64        5981765 5984128     64   64    1 : tunables    0    0    0 : slabdata  93502  93502      0
kmem_cache_node      704    704     64   64    1 : tunables    0    0    0 : slabdata     11     11      0
kmem_cache           512    512    256   32    2 : tunables    0    0    0 : slabdata     16     16      0

------ 0.007s was the duration of 'SLAB INFO' ------

很明显kmalloc-128和kmalloc-64的slab内存是有问题的。

Debug过程

针对slab内存泄露,且定位到泄露内存的类型是“kmalloc-xxx”,我们的debug方案有两个,一个是ftrace去抓调用栈,一个是slabtrace。

本次使用slabtrace debug。

使用如下的方案抓取日志:

抓取日志

打开slub_debug

  1. adb reboot bootloader

  2. fastboot oem bootargs set "slub_debug=FU,kmalloc-*"

  3. fastboot reboot

导入抓日志脚本

  1. adb root

  2. adb push slab_log.sh /vendor/bin/slab_log.sh

  3. adb shell "chmod +x /vendor/bin/slab_log.sh"

  4. adb shell

  5. cd /data

  6. nohup /vendor/bin/slab_log.sh &

  7. 关掉cmd,拔掉usb

检查日志功能记录是否开启

  1. 插上usb,打开cmd

  2. adb shell

  3. ps -ef |grep slab

要存在以下进程

spring:/sdcard/meminfo # ps -ef |grep slab

root 9205 1 0 15:25:57 ? 00:00:00 sh /vendor/bin/slab_log.sh
  1. cd /sdcard/meminfo

  2. ls -al

要存在以日期命名的文件夹以及一个slab_log.log

spring:/sdcard/meminfo # ls -al

total 22

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:24 20250321_152415

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:26 20250321_152558

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:27 20250321_152701

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:28 20250321_152804

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:29 20250321_152907

drwxrws--- 2 u0_a228 media_rw 3452 2025-03-21 15:30 20250321_153010

-rw-rw---- 1 u0_a228 media_rw 1819 2025-03-21 15:30 slab_log.log
  1. 查看日期文件夹内日志

需要满足7份日志都存在,且所有日志的大小均不为0

spring:/sdcard/meminfo/20250321_152415 # ls -al

total 84

-rw-rw---- 1 u0_a228 media_rw 47081 2025-03-21 15:24 dumpsys_meminfo.txt

-rw-rw---- 1 u0_a228 media_rw 7080 2025-03-21 15:24 kmalloc_128_alloc_trace.txt

-rw-rw---- 1 u0_a228 media_rw 7080 2025-03-21 15:24 kmalloc_128_free_trace.txt

-rw-rw---- 1 u0_a228 media_rw 7080 2025-03-21 15:24 kmalloc_64_alloc_trace.txt

-rw-rw---- 1 u0_a228 media_rw 7080 2025-03-21 15:24 kmalloc_64_free_trace.txt

-rw-rw---- 1 u0_a228 media_rw 1261 2025-03-21 15:24 meminfo.txt

-rw-rw---- 1 u0_a228 media_rw 31376 2025-03-21 15:24 slabinfo.txt

复现场景挂测

导出日志

adb pull /sdcard/meminfo

slabtrace分析

1812565 devm_iio_channel_get+0x38/0x78 waste=87003120/48 age=283/11881927/24259814 pid=10-32767 cpus=0-7

1812834 __fwnode_iio_channel_get_by_name+0x5c/0xec waste=72513360/40 age=214/11883549/24262706 pid=8-32767 cpus=0-7

kmalloc-64和kmalloc-128 alloc_trace最多的是上面这两个,指向很明确都是charger模块。

问题根因分析

static struct iio_channel **get_ext_channels(struct device *dev,
		 const char *const *channel_map, int size)
{
	int i, rc = 0;
	struct iio_channel **iio_ch_ext;

	iio_ch_ext = devm_kcalloc(dev, size, sizeof(*iio_ch_ext), GFP_KERNEL);
	if (!iio_ch_ext)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < size; i++) {
		iio_ch_ext[i] = devm_iio_channel_get(dev, channel_map[i]);

		if (IS_ERR(iio_ch_ext[i])) {
			rc = PTR_ERR(iio_ch_ext[i]);
			if (rc != -EPROBE_DEFER)
				dev_err(dev, "%s channel unavailable, %d\n",
						channel_map[i], rc);
			return ERR_PTR(rc);
		}
	}

	return iio_ch_ext;
}

devm_iio_channel_get 函数是get_ext_channel中调用的。__fwnode_iio_channel_get_by_namedevm_iio_channel_get 中调用

struct iio_channel *iio_channel_get(struct device *dev,
				    const char *channel_name)
{
	const char *name = dev ? dev_name(dev) : NULL;
	struct iio_channel *channel;

	if (dev) {
		channel = fwnode_iio_channel_get_by_name(dev_fwnode(dev),
							 channel_name);
		if (!IS_ERR(channel) || PTR_ERR(channel) != -ENODEV)
			return channel;
	}

	return iio_channel_get_sys(name, channel_name);
}

struct iio_channel *devm_iio_channel_get(struct device *dev,
					 const char *channel_name)
{
	struct iio_channel *channel;
	int ret;

	channel = iio_channel_get(dev, channel_name);
	if (IS_ERR(channel))
		return channel;

	ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel);
	if (ret)
		return ERR_PTR(ret);

	return channel;
}

所以两个函数归根结底都get_ext_channel 造成的。

下面分析这个函数的调用情况,发现有如下的异常

static ssize_t real_capacity_show(struct class *c,
				struct class_attribute *attr, char *ubuf)
{
	int rc;
	struct pl_data *chip = container_of(c, struct pl_data, qcom_batt_class);
	union power_supply_propval pval = {0, };

	chip->iio_chan_list_qg = get_ext_channels(chip->dev,
			smblib_qg_ext_iio_chan,
			ARRAY_SIZE(smblib_qg_ext_iio_chan));

	if (IS_ERR_OR_NULL(chip->iio_chan_list_qg))
		return -ENODEV;
    //...

}

比如这个show函数,我们可以看到每次调用show时,就会调用这个函数申请内存,但是从来没有释放!

再比如下面的函数

static ssize_t fastcharge_mode_show(struct class *c,
				struct class_attribute *attr, char *ubuf)
{
	int rc;
	struct pl_data *chip = container_of(c, struct pl_data,
			qcom_batt_class);
	union power_supply_propval pval = {0, };

	chip->iio_chan_list_qg = get_ext_channels(chip->dev,
			smblib_qg_ext_iio_chan,
			ARRAY_SIZE(smblib_qg_ext_iio_chan));

	if (IS_ERR_OR_NULL(chip->iio_chan_list_qg))
		return -ENODEV;

	rc = battery_read_iio_prop(chip, QG, SMB5_QG_FASTCHARGE_MODE, &pval.intval);
	if (rc < 0) {
		pr_err("Failed to get fastcharge mode rc=%d\n", rc);
	}

	return scnprintf(ubuf, PAGE_SIZE, "%d\n", pval.intval);
}

同样,每次调用show函数时,都会申请内存,但是从来没有释放过

解决方案

在申请内存前,先判断是否已经申请过。如果申请过,不在重复申请!

diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index a4ac543..3f75352 100755
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -920,13 +920,24 @@
 	int rc;
 	struct pl_data *chip = container_of(c, struct pl_data, qcom_batt_class);
 	union power_supply_propval pval = {0, };
+	struct iio_channel **iio_list = NULL;
 
-	chip->iio_chan_list_qg = get_ext_channels(chip->dev,
-			smblib_qg_ext_iio_chan,
-			ARRAY_SIZE(smblib_qg_ext_iio_chan));
+	if (!chip->iio_chan_list_qg) {
+		iio_list = get_ext_channels(chip->dev,
+				smblib_qg_ext_iio_chan,
+				ARRAY_SIZE(smblib_qg_ext_iio_chan));
 
-	if (IS_ERR_OR_NULL(chip->iio_chan_list_qg))
-		return -ENODEV;
+		if (IS_ERR(iio_list)) {
+			rc = PTR_ERR(iio_list);
+			if (rc != -EPROBE_DEFER) {
+				dev_err(chip->dev, "Failed to get channels, %d\n",
+					rc);
+				chip->iio_chan_list_qg = ERR_PTR(-EINVAL);
+			}
+			return rc;
+		}
+		chip->iio_chan_list_qg = iio_list;
+	}
 
 	rc = battery_read_iio_prop(chip, QG, SMB5_QG_REAL_CAPACITY, &pval.intval);
 	if (rc < 0) {
@@ -2277,13 +2288,17 @@
 	struct pl_data *chip = container_of(c, struct pl_data,
 			qcom_batt_class);
 	union power_supply_propval pval = {0, };
+	struct iio_channel **iio_list = NULL;
 
-	chip->iio_chan_list_qg = get_ext_channels(chip->dev,
-			smblib_qg_ext_iio_chan,
-			ARRAY_SIZE(smblib_qg_ext_iio_chan));
+	if (!chip->iio_chan_list_qg) {
+		iio_list = get_ext_channels(chip->dev,
+				smblib_qg_ext_iio_chan,
+				ARRAY_SIZE(smblib_qg_ext_iio_chan));
 
-	if (IS_ERR_OR_NULL(chip->iio_chan_list_qg))
-		return -ENODEV;
+		if (IS_ERR_OR_NULL(iio_list))
+			return -ENODEV;
+		chip->iio_chan_list_qg = iio_list;
+	}
 
 	rc = battery_read_iio_prop(chip, QG, SMB5_QG_FASTCHARGE_MODE, &pval.intval);
 	if (rc < 0) {
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index 1bb9cd2..95bd7b5 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -2272,18 +2272,20 @@
 	int rc;
 	bool enable = !!val;
 
-	iio_list = get_ext_channels(chg->dev,
-		smblib_qg_ext_iio_chan,
-		ARRAY_SIZE(smblib_qg_ext_iio_chan));
-	if (IS_ERR(iio_list)) {
-		rc = PTR_ERR(iio_list);
-		if (rc != -EPROBE_DEFER) {
-			dev_err(chg->dev, "Failed to get channels, %d\n", rc);
-			chg->iio_chan_list_qg = ERR_PTR(-EINVAL);
+	if (!chg->iio_chan_list_qg) {
+		iio_list = get_ext_channels(chg->dev,
+			smblib_qg_ext_iio_chan,
+			ARRAY_SIZE(smblib_qg_ext_iio_chan));
+		if (IS_ERR(iio_list)) {
+			rc = PTR_ERR(iio_list);
+			if (rc != -EPROBE_DEFER) {
+				dev_err(chg->dev, "Failed to get channels, %d\n", rc);
+				chg->iio_chan_list_qg = ERR_PTR(-EINVAL);
+			}
+			return rc;
 		}
-		return rc;
+		chg->iio_chan_list_qg = iio_list;
 	}
-	chg->iio_chan_list_qg = iio_list;
 
 	rc = smblib_write_iio_prop(chg, QG, SMB5_QG_FASTCHARGE_MODE, enable);
 	if (rc < 0) {
@@ -9033,20 +9035,22 @@
 						pl_update_work);
 	struct iio_channel **iio_list;
 
-	iio_list = get_ext_channels(chg->dev,
-		smblib_parallel_ext_iio_chan,
-		ARRAY_SIZE(smblib_parallel_ext_iio_chan));
-	if (IS_ERR(iio_list)) {
-		rc = PTR_ERR(iio_list);
-		if (rc != -EPROBE_DEFER) {
-			dev_err(chg->dev, "Failed to get channels, %d\n",
-				rc);
-			chg->iio_chan_list_smb_parallel = ERR_PTR(-EINVAL);
+	if (!chg->iio_chan_list_smb_parallel) {
+		iio_list = get_ext_channels(chg->dev,
+			smblib_parallel_ext_iio_chan,
+			ARRAY_SIZE(smblib_parallel_ext_iio_chan));
+		if (IS_ERR(iio_list)) {
+			rc = PTR_ERR(iio_list);
+			if (rc != -EPROBE_DEFER) {
+				dev_err(chg->dev, "Failed to get channels, %d\n",
+					rc);
+				chg->iio_chan_list_smb_parallel = ERR_PTR(-EINVAL);
+			}
+			return;
 		}
-		return;
-	}
 
-	chg->iio_chan_list_smb_parallel = iio_list;
+		chg->iio_chan_list_smb_parallel = iio_list;
+	}
 
 	if (chg->smb_temp_max == -EINVAL) {
 		rc = smblib_get_thermal_threshold(chg,