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 struct mutex 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
);
61 if (radix_tree_preload(GFP_NOFS
))
64 mutex_lock(&pids_lock
);
65 p
= radix_tree_lookup(&pids
, pid
);
69 radix_tree_delete(&pids
, pid
);
71 f2fs_radix_tree_insert(&pids
, pid
, current
);
73 trace_printk("%3x:%3x %4x %-16s\n",
74 MAJOR(inode
->i_sb
->s_dev
), MINOR(inode
->i_sb
->s_dev
),
77 mutex_unlock(&pids_lock
);
78 radix_tree_preload_end();
81 void f2fs_trace_ios(struct f2fs_io_info
*fio
, int flush
)
92 inode
= fio
->page
->mapping
->host
;
93 pid
= page_private(fio
->page
);
95 major
= MAJOR(inode
->i_sb
->s_dev
);
96 minor
= MINOR(inode
->i_sb
->s_dev
);
98 if (last_io
.major
== major
&& last_io
.minor
== minor
&&
100 last_io
.type
== __file_type(inode
, pid
) &&
101 last_io
.fio
.op
== fio
->op
&&
102 last_io
.fio
.op_flags
== fio
->op_flags
&&
103 last_io
.fio
.new_blkaddr
+ last_io
.len
==
111 last_io
.major
= major
;
112 last_io
.minor
= minor
;
114 last_io
.type
= __file_type(inode
, pid
);
120 void f2fs_build_trace_ios(void)
122 mutex_init(&pids_lock
);
125 #define PIDVEC_SIZE 128
126 static unsigned int gang_lookup_pids(pid_t
*results
, unsigned long first_index
,
127 unsigned int max_items
)
129 struct radix_tree_iter iter
;
131 unsigned int ret
= 0;
133 if (unlikely(!max_items
))
136 radix_tree_for_each_slot(slot
, &pids
, &iter
, first_index
) {
137 results
[ret
] = iter
.index
;
138 if (++ret
== max_items
)
144 void f2fs_destroy_trace_ios(void)
146 pid_t pid
[PIDVEC_SIZE
];
150 mutex_lock(&pids_lock
);
151 while ((found
= gang_lookup_pids(pid
, next_pid
, PIDVEC_SIZE
))) {
154 next_pid
= pid
[found
- 1] + 1;
155 for (idx
= 0; idx
< found
; idx
++)
156 radix_tree_delete(&pids
, pid
[idx
]);
158 mutex_unlock(&pids_lock
);