1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2014 Motorola Mobility
6 * Copyright (c) 2014 Jaegeuk Kim <jaegeuk@kernel.org>
9 #include <linux/f2fs_fs.h>
10 #include <linux/sched.h>
11 #include <linux/radix-tree.h>
16 static RADIX_TREE(pids
, GFP_ATOMIC
);
17 static spinlock_t pids_lock
;
18 static struct last_io_info last_io
;
20 static inline void __print_last_io(void)
25 trace_printk("%3x:%3x %4x %-16s %2x %5x %5x %12x %4x\n",
26 last_io
.major
, last_io
.minor
,
27 last_io
.pid
, "----------------",
29 last_io
.fio
.op
, last_io
.fio
.op_flags
,
30 last_io
.fio
.new_blkaddr
,
32 memset(&last_io
, 0, sizeof(last_io
));
35 static int __file_type(struct inode
*inode
, pid_t pid
)
37 if (f2fs_is_atomic_file(inode
))
39 else if (f2fs_is_volatile_file(inode
))
40 return __VOLATILE_FILE
;
41 else if (S_ISDIR(inode
->i_mode
))
43 else if (inode
->i_ino
== F2FS_NODE_INO(F2FS_I_SB(inode
)))
45 else if (inode
->i_ino
== F2FS_META_INO(F2FS_I_SB(inode
)))
53 void f2fs_trace_pid(struct page
*page
)
55 struct inode
*inode
= page
->mapping
->host
;
56 pid_t pid
= task_pid_nr(current
);
59 set_page_private(page
, (unsigned long)pid
);
62 if (radix_tree_preload(GFP_NOFS
))
65 spin_lock(&pids_lock
);
66 p
= radix_tree_lookup(&pids
, pid
);
70 radix_tree_delete(&pids
, pid
);
72 if (radix_tree_insert(&pids
, pid
, current
)) {
73 spin_unlock(&pids_lock
);
74 radix_tree_preload_end();
79 trace_printk("%3x:%3x %4x %-16s\n",
80 MAJOR(inode
->i_sb
->s_dev
), MINOR(inode
->i_sb
->s_dev
),
83 spin_unlock(&pids_lock
);
84 radix_tree_preload_end();
87 void f2fs_trace_ios(struct f2fs_io_info
*fio
, int flush
)
98 inode
= fio
->page
->mapping
->host
;
99 pid
= page_private(fio
->page
);
101 major
= MAJOR(inode
->i_sb
->s_dev
);
102 minor
= MINOR(inode
->i_sb
->s_dev
);
104 if (last_io
.major
== major
&& last_io
.minor
== minor
&&
105 last_io
.pid
== pid
&&
106 last_io
.type
== __file_type(inode
, pid
) &&
107 last_io
.fio
.op
== fio
->op
&&
108 last_io
.fio
.op_flags
== fio
->op_flags
&&
109 last_io
.fio
.new_blkaddr
+ last_io
.len
==
117 last_io
.major
= major
;
118 last_io
.minor
= minor
;
120 last_io
.type
= __file_type(inode
, pid
);
126 void f2fs_build_trace_ios(void)
128 spin_lock_init(&pids_lock
);
131 #define PIDVEC_SIZE 128
132 static unsigned int gang_lookup_pids(pid_t
*results
, unsigned long first_index
,
133 unsigned int max_items
)
135 struct radix_tree_iter iter
;
137 unsigned int ret
= 0;
139 if (unlikely(!max_items
))
142 radix_tree_for_each_slot(slot
, &pids
, &iter
, first_index
) {
143 results
[ret
] = iter
.index
;
144 if (++ret
== max_items
)
150 void f2fs_destroy_trace_ios(void)
152 pid_t pid
[PIDVEC_SIZE
];
156 spin_lock(&pids_lock
);
157 while ((found
= gang_lookup_pids(pid
, next_pid
, PIDVEC_SIZE
))) {
160 next_pid
= pid
[found
- 1] + 1;
161 for (idx
= 0; idx
< found
; idx
++)
162 radix_tree_delete(&pids
, pid
[idx
]);
164 spin_unlock(&pids_lock
);