2014-12-18 06:45:05 +03:00
/*
* f2fs IO tracer
*
* Copyright ( c ) 2014 Motorola Mobility
* Copyright ( c ) 2014 Jaegeuk Kim < jaegeuk @ kernel . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/fs.h>
# include <linux/f2fs_fs.h>
# include <linux/sched.h>
2015-01-08 01:09:48 +03:00
# include <linux/radix-tree.h>
2014-12-18 06:45:05 +03:00
# include "f2fs.h"
# include "trace.h"
2015-02-11 03:23:12 +03:00
static RADIX_TREE ( pids , GFP_ATOMIC ) ;
2015-01-08 22:38:38 +03:00
static spinlock_t pids_lock ;
2015-02-11 03:23:12 +03:00
static struct last_io_info last_io ;
2014-12-18 06:51:57 +03:00
static inline void __print_last_io ( void )
{
if ( ! last_io . len )
return ;
trace_printk ( " %3x:%3x %4x %-16s %2x %5x %12x %4x \n " ,
last_io . major , last_io . minor ,
last_io . pid , " ---------------- " ,
last_io . type ,
f2fs: trace old block address for CoWed page
This patch enables to trace old block address of CoWed page for better
debugging.
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f0, oldaddr = 0xfe8ab, newaddr = 0xfee90 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f8, oldaddr = 0xfe8b0, newaddr = 0xfee91 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4fa, oldaddr = 0xfe8ae, newaddr = 0xfee92 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x96, oldaddr = 0xf049b, newaddr = 0x2bbe rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x97, oldaddr = 0xf049c, newaddr = 0x2bbf rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x98, oldaddr = 0xf049d, newaddr = 0x2bc0 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x47, oldaddr = 0xffffffff, newaddr = 0xf2631 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x48, oldaddr = 0xffffffff, newaddr = 0xf2632 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x49, oldaddr = 0xffffffff, newaddr = 0xf2633 rw = WRITE, type = DATA
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-02-22 13:36:38 +03:00
last_io . fio . rw ,
last_io . fio . new_blkaddr ,
2014-12-18 06:51:57 +03:00
last_io . len ) ;
memset ( & last_io , 0 , sizeof ( last_io ) ) ;
}
static int __file_type ( struct inode * inode , pid_t pid )
{
if ( f2fs_is_atomic_file ( inode ) )
return __ATOMIC_FILE ;
else if ( f2fs_is_volatile_file ( inode ) )
return __VOLATILE_FILE ;
else if ( S_ISDIR ( inode - > i_mode ) )
return __DIR_FILE ;
else if ( inode - > i_ino = = F2FS_NODE_INO ( F2FS_I_SB ( inode ) ) )
return __NODE_FILE ;
else if ( inode - > i_ino = = F2FS_META_INO ( F2FS_I_SB ( inode ) ) )
return __META_FILE ;
else if ( pid )
return __NORMAL_FILE ;
else
return __MISC_FILE ;
}
2014-12-18 06:45:05 +03:00
void f2fs_trace_pid ( struct page * page )
{
2014-12-18 06:51:57 +03:00
struct inode * inode = page - > mapping - > host ;
pid_t pid = task_pid_nr ( current ) ;
void * p ;
page - > private = pid ;
2015-01-08 01:07:36 +03:00
if ( radix_tree_preload ( GFP_NOFS ) )
return ;
spin_lock ( & pids_lock ) ;
2014-12-18 06:51:57 +03:00
p = radix_tree_lookup ( & pids , pid ) ;
if ( p = = current )
2015-01-08 01:07:36 +03:00
goto out ;
2014-12-18 06:51:57 +03:00
if ( p )
radix_tree_delete ( & pids , pid ) ;
f2fs_radix_tree_insert ( & pids , pid , current ) ;
trace_printk ( " %3x:%3x %4x %-16s \n " ,
MAJOR ( inode - > i_sb - > s_dev ) , MINOR ( inode - > i_sb - > s_dev ) ,
pid , current - > comm ) ;
2015-01-08 01:07:36 +03:00
out :
spin_unlock ( & pids_lock ) ;
radix_tree_preload_end ( ) ;
2014-12-18 06:45:05 +03:00
}
2015-04-24 00:38:15 +03:00
void f2fs_trace_ios ( struct f2fs_io_info * fio , int flush )
2014-12-18 06:45:05 +03:00
{
2014-12-18 06:51:57 +03:00
struct inode * inode ;
pid_t pid ;
int major , minor ;
if ( flush ) {
__print_last_io ( ) ;
return ;
}
2015-04-24 00:38:15 +03:00
inode = fio - > page - > mapping - > host ;
pid = page_private ( fio - > page ) ;
2014-12-18 06:51:57 +03:00
major = MAJOR ( inode - > i_sb - > s_dev ) ;
minor = MINOR ( inode - > i_sb - > s_dev ) ;
if ( last_io . major = = major & & last_io . minor = = minor & &
last_io . pid = = pid & &
last_io . type = = __file_type ( inode , pid ) & &
last_io . fio . rw = = fio - > rw & &
f2fs: trace old block address for CoWed page
This patch enables to trace old block address of CoWed page for better
debugging.
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f0, oldaddr = 0xfe8ab, newaddr = 0xfee90 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4f8, oldaddr = 0xfe8b0, newaddr = 0xfee91 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 1, page_index = 0x1d4fa, oldaddr = 0xfe8ae, newaddr = 0xfee92 rw = WRITE_SYNC, type = NODE
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x96, oldaddr = 0xf049b, newaddr = 0x2bbe rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x97, oldaddr = 0xf049c, newaddr = 0x2bbf rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 134824, page_index = 0x98, oldaddr = 0xf049d, newaddr = 0x2bc0 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x47, oldaddr = 0xffffffff, newaddr = 0xf2631 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x48, oldaddr = 0xffffffff, newaddr = 0xf2632 rw = WRITE, type = DATA
f2fs_submit_page_mbio: dev = (1,0), ino = 135260, page_index = 0x49, oldaddr = 0xffffffff, newaddr = 0xf2633 rw = WRITE, type = DATA
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
2016-02-22 13:36:38 +03:00
last_io . fio . new_blkaddr + last_io . len = =
fio - > new_blkaddr ) {
2014-12-18 06:51:57 +03:00
last_io . len + + ;
return ;
}
__print_last_io ( ) ;
last_io . major = major ;
last_io . minor = minor ;
last_io . pid = pid ;
last_io . type = __file_type ( inode , pid ) ;
last_io . fio = * fio ;
last_io . len = 1 ;
return ;
2014-12-18 06:45:05 +03:00
}
2015-01-08 01:07:36 +03:00
void f2fs_build_trace_ios ( void )
{
spin_lock_init ( & pids_lock ) ;
}
2015-01-08 01:09:48 +03:00
# define PIDVEC_SIZE 128
static unsigned int gang_lookup_pids ( pid_t * results , unsigned long first_index ,
unsigned int max_items )
{
struct radix_tree_iter iter ;
void * * slot ;
unsigned int ret = 0 ;
if ( unlikely ( ! max_items ) )
return 0 ;
radix_tree_for_each_slot ( slot , & pids , & iter , first_index ) {
results [ ret ] = iter . index ;
if ( + + ret = = PIDVEC_SIZE )
break ;
}
return ret ;
}
void f2fs_destroy_trace_ios ( void )
{
pid_t pid [ PIDVEC_SIZE ] ;
pid_t next_pid = 0 ;
unsigned int found ;
spin_lock ( & pids_lock ) ;
while ( ( found = gang_lookup_pids ( pid , next_pid , PIDVEC_SIZE ) ) ) {
unsigned idx ;
next_pid = pid [ found - 1 ] + 1 ;
for ( idx = 0 ; idx < found ; idx + + )
radix_tree_delete ( & pids , pid [ idx ] ) ;
}
spin_unlock ( & pids_lock ) ;
}