Skip to content

Commit 04ed19c

Browse files
committed
Fix can't parser zram on kernel 6.11
1 parent 0b2555e commit 04ed19c

File tree

9 files changed

+219
-121
lines changed

9 files changed

+219
-121
lines changed

binder/binder.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ void Binder::print_binder_ref_olocked(ulong ref_addr) {
460460
void *binder_proc_buf = read_struct((ulong)node.proc,"binder_proc");
461461
if(binder_proc_buf == nullptr) return;
462462
ulong tsk_addr = ULONG(binder_proc_buf + field_offset(binder_proc,tsk));
463+
if (!is_kvaddr(tsk_addr)) {
464+
FREEBUF(binder_proc_buf);
465+
return;
466+
}
463467
int pid = UINT(binder_proc_buf + field_offset(binder_proc,pid));
464468
std::string task_name = read_cstring(tsk_addr + field_offset(task_struct,comm),16, "task_struct_comm");
465469
fprintf(fp, " binder_ref:%#lx id:%d desc:%d s:%d w:%d death:%#lx -> node_id:%d binder_proc:%#lx %s[%d]\n",ref_addr,

defs.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7532,13 +7532,19 @@ struct zspage {
75327532
unsigned int isolated : 3;
75337533
unsigned int magic : 8;
75347534
} v5_17;
7535-
struct {
7535+
struct {
75367536
unsigned int huge : 1;
75377537
unsigned int fullness : 4;
75387538
unsigned int class_id : 9;
75397539
unsigned int isolated : 5;
75407540
unsigned int magic : 8;
75417541
} v6_6;
7542+
struct {
7543+
unsigned int huge : 1;
7544+
unsigned int fullness : 4;
7545+
unsigned int class_id : 9;
7546+
unsigned int magic : 8;
7547+
} v6_12;
75427548
};
75437549
unsigned int inuse;
75447550
unsigned int freeobj;

memory/zram.cpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,21 +214,42 @@ void Zram::print_mem_pool(std::string zram_addr){
214214
<< std::left << std::setw(13) << "OBJ_ALLOCATED" << " "
215215
<< "OBJ_USED";
216216
fprintf(fp, "%s \n",oss_hd.str().c_str());
217-
217+
std::vector<std::string> class_stat_type = get_enumerator_list("class_stat_type");
218+
int CLASS_EMPTY = 0;
219+
int CLASS_ALMOST_EMPTY = 0;
220+
int CLASS_ALMOST_FULL = 0;
221+
int CLASS_FULL = 0;
222+
int OBJ_ALLOCATED = 0;
223+
int OBJ_USED = 0;
224+
if (class_stat_type.size() > 0){
225+
CLASS_EMPTY = read_enum_val("ZS_INUSE_RATIO_0");
226+
CLASS_ALMOST_EMPTY = read_enum_val("ZS_INUSE_RATIO_10");
227+
CLASS_ALMOST_FULL = read_enum_val("ZS_INUSE_RATIO_99");
228+
CLASS_FULL = read_enum_val("ZS_INUSE_RATIO_100");
229+
OBJ_ALLOCATED = read_enum_val("ZS_OBJS_ALLOCATED");
230+
OBJ_USED = read_enum_val("ZS_OBJS_INUSE");
231+
}else{
232+
CLASS_EMPTY = read_enum_val("CLASS_EMPTY");
233+
CLASS_ALMOST_EMPTY = read_enum_val("CLASS_ALMOST_EMPTY");
234+
CLASS_ALMOST_FULL = read_enum_val("CLASS_ALMOST_FULL");
235+
CLASS_FULL = read_enum_val("CLASS_FULL");
236+
OBJ_ALLOCATED = read_enum_val("OBJ_ALLOCATED");
237+
OBJ_USED = read_enum_val("OBJ_USED");
238+
}
218239
for (size_t i = 0; i < pool_ptr->class_list.size(); i++){
219240
std::shared_ptr<size_class> class_ptr = pool_ptr->class_list[i];
220241
std::ostringstream oss;
221-
oss << std::dec << std::setw(5) << std::setfill('0') << i << " "
242+
oss << "[" << std::dec << std::setw(5) << std::setfill('0') << i << "] "
222243
<< std::left << std::hex << std::setw(VADDR_PRLEN) << std::setfill(' ') << class_ptr->addr << " "
223-
<< std::left << std::dec << std::setw(5) << class_ptr->stats.objs[zs_stat_type::CLASS_EMPTY] << " "
224-
<< std::left << std::dec << std::setw(12) << class_ptr->stats.objs[zs_stat_type::CLASS_ALMOST_EMPTY] << " "
225-
<< std::left << std::dec << std::setw(12) << class_ptr->stats.objs[zs_stat_type::CLASS_ALMOST_FULL] << " "
226-
<< std::left << std::dec << std::setw(5) << class_ptr->stats.objs[zs_stat_type::CLASS_FULL] << " "
244+
<< std::left << std::dec << std::setw(5) << class_ptr->stats[CLASS_EMPTY] << " "
245+
<< std::left << std::dec << std::setw(12) << class_ptr->stats[CLASS_ALMOST_EMPTY] << " "
246+
<< std::left << std::dec << std::setw(12) << class_ptr->stats[CLASS_ALMOST_FULL] << " "
247+
<< std::left << std::dec << std::setw(5) << class_ptr->stats[CLASS_FULL] << " "
227248
<< std::left << std::dec << std::setw(12) << class_ptr->pages_per_zspage << " "
228249
<< std::left << std::dec << std::setw(12) << class_ptr->objs_per_zspage << " "
229250
<< std::left << std::dec << std::setw(9) << csize(class_ptr->size) << " "
230-
<< std::left << std::dec << std::setw(13) << class_ptr->stats.objs[zs_stat_type::OBJ_ALLOCATED] << " "
231-
<< std::left << std::dec << class_ptr->stats.objs[zs_stat_type::OBJ_USED];
251+
<< std::left << std::dec << std::setw(13) << class_ptr->stats[OBJ_ALLOCATED] << " "
252+
<< std::left << std::dec << class_ptr->stats[OBJ_USED];
232253
fprintf(fp, "%s \n",oss.str().c_str());
233254
}
234255
}
@@ -488,6 +509,10 @@ void Zram::print_zram_full_info(std::string zram_addr){
488509
}
489510

490511
void Zram::print_zrams(){
512+
if (zram_list.size() == 0){
513+
fprintf(fp, "Maybe not enable zram \n");
514+
return;
515+
}
491516
fprintf(fp, "========================================================================\n");
492517
for (const auto& zram_ptr : zram_list) {
493518
double ratio = (double)zram_ptr->stats.compr_data_size / (double)(zram_ptr->stats.pages_stored * page_size);

memory/zraminfo.cpp

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ void Zraminfo::init_offset(){
4040
field_init(zram,table);
4141
field_init(zram,mem_pool);
4242
field_init(zram,comp);
43+
field_init(zram,comps);
4344
field_init(zram,disk);
4445
field_init(zram,limit_pages);
4546
field_init(zram,stats);
4647
field_init(zram,disksize);
4748
field_init(zram,compressor);
49+
field_init(zram,comp_algs);
4850
field_init(zram,claim);
4951
struct_init(zram);
5052

@@ -71,6 +73,8 @@ void Zraminfo::init_offset(){
7173
field_init(zspage,huge);
7274
struct_init(zspage);
7375

76+
field_init(zs_size_stat,objs);
77+
7478
field_init(zram_stats,compr_data_size);
7579
field_init(zram_stats,num_reads);
7680
field_init(zram_stats,num_writes);
@@ -165,7 +169,9 @@ bool Zraminfo::get_zspage(ulong page,struct zspage* zp){
165169
return false;
166170
}
167171
if (field_offset(zspage, huge) != -1){
168-
if (THIS_KERNEL_VERSION >= LINUX(6, 6, 0)){
172+
if (THIS_KERNEL_VERSION >= LINUX(6, 12, 0)){
173+
zs_magic = zp->v6_12.magic;
174+
}else if (THIS_KERNEL_VERSION >= LINUX(6, 6, 0)){
169175
zs_magic = zp->v6_6.magic;
170176
}else{
171177
zs_magic = zp->v5_17.magic;
@@ -476,35 +482,46 @@ std::shared_ptr<size_class> Zraminfo::parser_size_class(ulong addr){
476482
class_ptr->pages_per_zspage = INT(class_buf + field_offset(size_class,pages_per_zspage));
477483
class_ptr->index = UINT(class_buf + field_offset(size_class,index));
478484
class_ptr->zspage_parser = false;
479-
// fprintf(fp, "\nsize_class(%lx) objs_per_zspage:%d size:%d\n", addr,class_ptr->objs_per_zspage,class_ptr->size);
480-
read_struct(addr + field_offset(size_class,stats),&class_ptr->stats,sizeof(struct zs_size_stat),"size_class_stats");
481485
FREEBUF(class_buf);
486+
// fprintf(fp, "\nsize_class(%lx) objs_per_zspage:%d size:%d\n", addr,class_ptr->objs_per_zspage,class_ptr->size);
487+
int stats_cnt = field_size(zs_size_stat,objs)/sizeof(unsigned long);
488+
ulong stats_addr = addr + field_offset(size_class,stats);
489+
for (size_t i = 0; i < stats_cnt; i++){
490+
class_ptr->stats.push_back(read_ulong(stats_addr + i * sizeof(unsigned long), "size_class_stats"));
491+
}
482492
return class_ptr;
483493
}
484494

485495
void Zraminfo::parser_zpage(std::shared_ptr<size_class> class_ptr){
486496
for (size_t i = 0; i < group_cnt; i++){
487497
ulong group_addr = class_ptr->addr + field_offset(size_class,fullness_list) + i * sizeof(struct kernel_list_head);
488498
int offset = field_offset(zspage,list);
489-
std::vector<ulong> zspage_list = for_each_list(group_addr,offset);
490-
for (const auto& zspage_addr : zspage_list) {
491-
class_ptr->fullness_list[i].push_back(parser_zpage(zspage_addr,class_ptr));
499+
std::vector<std::shared_ptr<zpage>> zspage_list;
500+
for (const auto& zspage_addr : for_each_list(group_addr,offset)) {
501+
zspage_list.push_back(parser_zpage(zspage_addr,class_ptr));
492502
}
503+
class_ptr->fullness_list.push_back(zspage_list);
493504
}
494505
class_ptr->zspage_parser = true;
495506
}
496507

497508
std::shared_ptr<zs_pool> Zraminfo::parser_mem_pool(ulong addr){
498-
if (!is_kvaddr(addr))return nullptr;
509+
if (!is_kvaddr(addr)){
510+
return nullptr;
511+
}
499512
void *pool_buf = read_struct(addr,"zs_pool");
500513
if(pool_buf == nullptr) return nullptr;
501514
std::shared_ptr<zs_pool> pool_ptr = std::make_shared<zs_pool>();
502515
pool_ptr->addr = addr;
503516
pool_ptr->name = read_cstring(ULONG(pool_buf + field_offset(zs_pool,name)),64,"pool_name");
504517
// fprintf(fp, "zs_pool(%lx) pool_name:%s\n", addr,pool_ptr->name.c_str());
505518
pool_ptr->pages_allocated = INT(pool_buf + field_offset(zs_pool,pages_allocated));
506-
pool_ptr->isolated_pages = INT(pool_buf + field_offset(zs_pool,isolated_pages));
507-
pool_ptr->destroying = BOOL(pool_buf + field_offset(zs_pool,destroying));
519+
if (field_offset(zs_pool,isolated_pages) != -1){
520+
pool_ptr->isolated_pages = INT(pool_buf + field_offset(zs_pool,isolated_pages));
521+
}
522+
if (field_offset(zs_pool,destroying) != -1){
523+
pool_ptr->destroying = BOOL(pool_buf + field_offset(zs_pool,destroying));
524+
}
508525
read_struct(addr + field_offset(zs_pool,stats),&pool_ptr->stats,sizeof(struct zs_pool_stats),"zs_pool_stats");
509526
int class_cnt = field_size(zs_pool,size_class)/sizeof(void *);
510527
for (size_t i = 0; i < class_cnt; i++){
@@ -517,34 +534,64 @@ std::shared_ptr<zs_pool> Zraminfo::parser_mem_pool(ulong addr){
517534
}
518535

519536
std::shared_ptr<zram> Zraminfo::parser_zram(ulong addr){
537+
if(debug)fprintf(fp, "zram:%lx \n",addr);
520538
void *zram_buf = read_struct(addr,"zram");
521539
if(zram_buf == nullptr) return nullptr;
540+
ulong pool_addr = ULONG(zram_buf + field_offset(zram,mem_pool));
541+
if (!is_kvaddr(pool_addr))return nullptr;
522542
std::shared_ptr<zram> zram_ptr = std::make_shared<zram>();
523543
zram_ptr->addr = addr;
524544
zram_ptr->table = ULONG(zram_buf + field_offset(zram,table));
525545
zram_ptr->mem_pool = parser_mem_pool(ULONG(zram_buf + field_offset(zram,mem_pool)));
526-
ulong zcomp_addr = ULONG(zram_buf + field_offset(zram,comp));
527-
ulong zcomp_name_addr = read_pointer(zcomp_addr + field_offset(zcomp,name),"zcomp_name_addr");
528-
zram_ptr->zcomp_name = read_cstring(zcomp_name_addr,64,"zcomp_name");
546+
if (field_offset(zram,comp) != -1){
547+
ulong zcomp_addr = ULONG(zram_buf + field_offset(zram,comp));
548+
if (is_kvaddr(zcomp_addr)){
549+
ulong zcomp_name_addr = read_pointer(zcomp_addr + field_offset(zcomp,name),"zcomp_name_addr");
550+
if (is_kvaddr(zcomp_name_addr)){
551+
zram_ptr->zcomp_name = read_cstring(zcomp_name_addr,64,"zcomp_name");
552+
}
553+
}
554+
}else if (field_offset(zram,comps) != -1){
555+
ulong zcomp_addr = ULONG(zram_buf + field_offset(zram,comps));
556+
if (is_kvaddr(zcomp_addr)){
557+
ulong zcomp_name_addr = read_pointer(zcomp_addr + field_offset(zcomp,name),"zcomp_name_addr");
558+
if (is_kvaddr(zcomp_name_addr)){
559+
zram_ptr->zcomp_name = read_cstring(zcomp_name_addr,64,"zcomp_name");
560+
}
561+
}
562+
}
529563
ulong disk_name_addr = ULONG(zram_buf + field_offset(zram,disk)) + field_offset(gendisk,disk_name);
530564
zram_ptr->disk_name = read_cstring(disk_name_addr,32,"disk_name");;
531565
// fprintf(fp, "disk_name:%s\n", zram_ptr->disk_name.c_str());
532-
char compressor_name[128];
533-
memcpy(&compressor_name,(void *)zram_buf + field_offset(zram,compressor),128);
534-
zram_ptr->compressor = extract_string(compressor_name);
535-
// std::cout << "compressor_name:" << zram_ptr->compressor << std::endl;
566+
if (field_offset(zram,compressor) != -1){
567+
char compressor_name[128];
568+
memcpy(&compressor_name,(void *)zram_buf + field_offset(zram,compressor),128);
569+
zram_ptr->compressor = extract_string(compressor_name);
570+
// std::cout << "compressor_name:" << zram_ptr->compressor << std::endl;
571+
}else if (field_offset(zram,comp_algs) != -1){
572+
ulong name_addr = ULONG(zram_buf + field_offset(zram,comp_algs));
573+
if (is_kvaddr(name_addr)){
574+
zram_ptr->compressor = read_cstring(name_addr, 64, "compressor name");
575+
}
576+
}
536577
zram_ptr->limit_pages = ULONG(zram_buf + field_offset(zram,limit_pages));
537578
zram_ptr->disksize = ULONGLONG(zram_buf + field_offset(zram,disksize));
538579
zram_ptr->claim = BOOL(zram_buf + field_offset(zram,claim));
539580
FREEBUF(zram_buf);
540581
void *stats_buf = read_struct(addr + field_offset(zram,stats),"zram_stats");
541582
if(stats_buf == nullptr) return nullptr;
542583
zram_ptr->stats.compr_data_size = ULONGLONG(stats_buf + field_offset(zram_stats,compr_data_size));
543-
zram_ptr->stats.num_reads = ULONGLONG(stats_buf + field_offset(zram_stats,num_reads));
544-
zram_ptr->stats.num_writes = ULONGLONG(stats_buf + field_offset(zram_stats,num_writes));
584+
if(field_offset(zram_stats,num_reads) != -1){
585+
zram_ptr->stats.num_reads = ULONGLONG(stats_buf + field_offset(zram_stats,num_reads));
586+
}
587+
if(field_offset(zram_stats,num_writes) != -1){
588+
zram_ptr->stats.num_writes = ULONGLONG(stats_buf + field_offset(zram_stats,num_writes));
589+
}
545590
zram_ptr->stats.failed_reads = ULONGLONG(stats_buf + field_offset(zram_stats,failed_reads));
546591
zram_ptr->stats.failed_writes = ULONGLONG(stats_buf + field_offset(zram_stats,failed_writes));
547-
zram_ptr->stats.invalid_io = ULONGLONG(stats_buf + field_offset(zram_stats,invalid_io));
592+
if(field_offset(zram_stats,invalid_io) != -1){
593+
zram_ptr->stats.invalid_io = ULONGLONG(stats_buf + field_offset(zram_stats,invalid_io));
594+
}
548595
zram_ptr->stats.notify_free = ULONGLONG(stats_buf + field_offset(zram_stats,notify_free));
549596
zram_ptr->stats.same_pages = ULONGLONG(stats_buf + field_offset(zram_stats,same_pages));
550597
zram_ptr->stats.huge_pages = ULONGLONG(stats_buf + field_offset(zram_stats,huge_pages));

memory/zraminfo.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ struct zs_pool_stats {
5656
atomic_long_t pages_compacted;
5757
};
5858

59-
struct zs_size_stat {
60-
unsigned long objs[6];
61-
};
62-
6359
struct zobj {
6460
int id;
6561
ulong start;
@@ -87,13 +83,13 @@ struct zpage {
8783

8884
struct size_class {
8985
ulong addr;
90-
std::vector<std::shared_ptr<zpage>> fullness_list[4];
86+
std::vector<std::vector<std::shared_ptr<zpage>>> fullness_list;
9187
bool zspage_parser;
9288
int size;
9389
int objs_per_zspage;
9490
int pages_per_zspage;
9591
unsigned int index;
96-
struct zs_size_stat stats;
92+
std::vector<ulong> stats;
9793
};
9894

9995
struct zs_pool {

pageowner/pageowner.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ void Pageowner::print_page_owner(std::string addr,int flags){
337337
if (flags == INPUT_PFN){
338338
pfn = number;
339339
}else if (flags == INPUT_PYHS){
340-
fprintf(fp, "hello \n");
341340
pfn = phy_to_pfn(number);
342341
}else if (flags == INPUT_PAGE){
343342
pfn = page_to_pfn(number);
@@ -691,8 +690,8 @@ void Pageowner::parser_all_pageowners(){
691690
try_get_symbol_data(TO_CONST_STRING("min_low_pfn"), sizeof(ulong), &min_low_pfn);
692691
}
693692
/* PAGE_EXT_OWNER{,_ALLOCATED} */
694-
enumerator_value(TO_CONST_STRING("PAGE_EXT_OWNER"), &PAGE_EXT_OWNER);
695-
enumerator_value(TO_CONST_STRING("PAGE_EXT_OWNER_ALLOCATED"), &PAGE_EXT_OWNER_ALLOCATED); /* 5.4 and later */
693+
PAGE_EXT_OWNER = read_enum_val("PAGE_EXT_OWNER");
694+
PAGE_EXT_OWNER_ALLOCATED = read_enum_val("PAGE_EXT_OWNER_ALLOCATED");
696695
// fprintf(fp, "min_low_pfn:%ld\n", min_low_pfn);
697696
// fprintf(fp, "max_pfn:%ld\n", max_pfn);
698697
for (size_t pfn = min_low_pfn; pfn < max_pfn; pfn++){

plugin.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,32 @@ int PaserPlugin::is_bigendian(void){
699699
return FALSE;
700700
}
701701

702+
std::vector<std::string> PaserPlugin::get_enumerator_list(const std::string &enum_name){
703+
std::vector<std::string> result;
704+
char buf[BUFSIZE];
705+
open_tmpfile();
706+
if (dump_enumerator_list(TO_CONST_STRING(enum_name.c_str()))){
707+
rewind(pc->tmpfile);
708+
while (fgets(buf, BUFSIZE, pc->tmpfile)){
709+
std::string line = buf;
710+
size_t pos = line.find('=');
711+
if (pos == std::string::npos) {
712+
continue;
713+
}else{
714+
std::string name = line.substr(0, pos - 1);
715+
size_t first = name.find_first_not_of(' ');
716+
size_t last = name.find_last_not_of(' ');
717+
if (first == std::string::npos || last == std::string::npos) {
718+
continue;
719+
}
720+
result.push_back(name.substr(first, (last - first + 1)));
721+
}
722+
}
723+
}
724+
close_tmpfile();
725+
return result;
726+
}
727+
702728
long PaserPlugin::read_enum_val(const std::string& enum_name){
703729
long enum_val = 0;
704730
enumerator_value(TO_CONST_STRING(enum_name.c_str()), &enum_val);

plugin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ class PaserPlugin {
163163
bool isNumber(const std::string& str);
164164
std::string extract_string(const char *input);
165165
int is_bigendian(void);
166-
long read_enum_val(const std::string& enum_name);
166+
std::vector<std::string> get_enumerator_list(const std::string &enum_name);
167+
long read_enum_val(const std::string &enum_name);
167168
std::map<std::string, ulong> read_enum_list(const std::string& enum_list_name);
168169
char get_printable(uint8_t d);
169170
std::string print_line(uint64_t addr, const std::vector<uint8_t>& data);

0 commit comments

Comments
 (0)