@@ -16,47 +16,60 @@ EXPORT_SYMBOL(_shared_alloc_tag);
16
16
DEFINE_STATIC_KEY_MAYBE (CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT ,
17
17
mem_alloc_profiling_key );
18
18
19
+ struct allocinfo_private {
20
+ struct codetag_iterator iter ;
21
+ bool print_header ;
22
+ };
23
+
19
24
static void * allocinfo_start (struct seq_file * m , loff_t * pos )
20
25
{
21
- struct codetag_iterator * iter ;
26
+ struct allocinfo_private * priv ;
22
27
struct codetag * ct ;
23
28
loff_t node = * pos ;
24
29
25
- iter = kzalloc (sizeof (* iter ), GFP_KERNEL );
26
- m -> private = iter ;
27
- if (!iter )
30
+ priv = kzalloc (sizeof (* priv ), GFP_KERNEL );
31
+ m -> private = priv ;
32
+ if (!priv )
28
33
return NULL ;
29
34
35
+ priv -> print_header = (node == 0 );
30
36
codetag_lock_module_list (alloc_tag_cttype , true);
31
- * iter = codetag_get_ct_iter (alloc_tag_cttype );
32
- while ((ct = codetag_next_ct (iter )) != NULL && node )
37
+ priv -> iter = codetag_get_ct_iter (alloc_tag_cttype );
38
+ while ((ct = codetag_next_ct (& priv -> iter )) != NULL && node )
33
39
node -- ;
34
40
35
- return ct ? iter : NULL ;
41
+ return ct ? priv : NULL ;
36
42
}
37
43
38
44
static void * allocinfo_next (struct seq_file * m , void * arg , loff_t * pos )
39
45
{
40
- struct codetag_iterator * iter = (struct codetag_iterator * )arg ;
41
- struct codetag * ct = codetag_next_ct (iter );
46
+ struct allocinfo_private * priv = (struct allocinfo_private * )arg ;
47
+ struct codetag * ct = codetag_next_ct (& priv -> iter );
42
48
43
49
(* pos )++ ;
44
50
if (!ct )
45
51
return NULL ;
46
52
47
- return iter ;
53
+ return priv ;
48
54
}
49
55
50
56
static void allocinfo_stop (struct seq_file * m , void * arg )
51
57
{
52
- struct codetag_iterator * iter = (struct codetag_iterator * )m -> private ;
58
+ struct allocinfo_private * priv = (struct allocinfo_private * )m -> private ;
53
59
54
- if (iter ) {
60
+ if (priv ) {
55
61
codetag_lock_module_list (alloc_tag_cttype , false);
56
- kfree (iter );
62
+ kfree (priv );
57
63
}
58
64
}
59
65
66
+ static void print_allocinfo_header (struct seq_buf * buf )
67
+ {
68
+ /* Output format version, so we can change it. */
69
+ seq_buf_printf (buf , "allocinfo - version: 1.0\n" );
70
+ seq_buf_printf (buf , "# <size> <calls> <tag info>\n" );
71
+ }
72
+
60
73
static void alloc_tag_to_text (struct seq_buf * out , struct codetag * ct )
61
74
{
62
75
struct alloc_tag * tag = ct_to_alloc_tag (ct );
@@ -71,13 +84,17 @@ static void alloc_tag_to_text(struct seq_buf *out, struct codetag *ct)
71
84
72
85
static int allocinfo_show (struct seq_file * m , void * arg )
73
86
{
74
- struct codetag_iterator * iter = (struct codetag_iterator * )arg ;
87
+ struct allocinfo_private * priv = (struct allocinfo_private * )arg ;
75
88
char * bufp ;
76
89
size_t n = seq_get_buf (m , & bufp );
77
90
struct seq_buf buf ;
78
91
79
92
seq_buf_init (& buf , bufp , n );
80
- alloc_tag_to_text (& buf , iter -> ct );
93
+ if (priv -> print_header ) {
94
+ print_allocinfo_header (& buf );
95
+ priv -> print_header = false;
96
+ }
97
+ alloc_tag_to_text (& buf , priv -> iter .ct );
81
98
seq_commit (m , seq_buf_used (& buf ));
82
99
return 0 ;
83
100
}
0 commit comments