2008-12-23 13:37:01 +03:00
# include <linux/fault-inject.h>
2010-02-26 09:36:12 +03:00
# include <linux/slab.h>
2016-03-16 00:53:38 +03:00
# include <linux/mm.h>
# include "slab.h"
2008-12-23 13:37:01 +03:00
static struct {
struct fault_attr attr ;
2015-11-07 03:28:28 +03:00
bool ignore_gfp_reclaim ;
2015-09-27 01:04:07 +03:00
bool cache_filter ;
2008-12-23 13:37:01 +03:00
} failslab = {
. attr = FAULT_ATTR_INITIALIZER ,
2015-11-07 03:28:28 +03:00
. ignore_gfp_reclaim = true ,
2015-09-27 01:04:07 +03:00
. cache_filter = false ,
2008-12-23 13:37:01 +03:00
} ;
2016-03-16 00:53:38 +03:00
bool should_failslab ( struct kmem_cache * s , gfp_t gfpflags )
2008-12-23 13:37:01 +03:00
{
2016-03-16 00:53:38 +03:00
/* No fault-injection for bootstrap cache */
if ( unlikely ( s = = kmem_cache ) )
return false ;
2008-12-23 13:37:01 +03:00
if ( gfpflags & __GFP_NOFAIL )
return false ;
2015-11-07 03:28:28 +03:00
if ( failslab . ignore_gfp_reclaim & & ( gfpflags & __GFP_RECLAIM ) )
2008-12-23 13:37:01 +03:00
return false ;
2016-03-16 00:53:38 +03:00
if ( failslab . cache_filter & & ! ( s - > flags & SLAB_FAILSLAB ) )
2010-02-26 09:36:12 +03:00
return false ;
2016-03-16 00:53:38 +03:00
return should_fail ( & failslab . attr , s - > object_size ) ;
2008-12-23 13:37:01 +03:00
}
static int __init setup_failslab ( char * str )
{
return setup_fault_attr ( & failslab . attr , str ) ;
}
__setup ( " failslab= " , setup_failslab ) ;
# ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
static int __init failslab_debugfs_init ( void )
{
2011-08-04 03:21:01 +04:00
struct dentry * dir ;
2011-07-24 12:33:43 +04:00
umode_t mode = S_IFREG | S_IRUSR | S_IWUSR ;
2008-12-23 13:37:01 +03:00
2011-08-04 03:21:01 +04:00
dir = fault_create_debugfs_attr ( " failslab " , NULL , & failslab . attr ) ;
if ( IS_ERR ( dir ) )
return PTR_ERR ( dir ) ;
2008-12-23 13:37:01 +03:00
2011-08-04 03:21:01 +04:00
if ( ! debugfs_create_bool ( " ignore-gfp-wait " , mode , dir ,
2015-11-07 03:28:28 +03:00
& failslab . ignore_gfp_reclaim ) )
2011-07-27 03:09:02 +04:00
goto fail ;
2011-08-04 03:21:01 +04:00
if ( ! debugfs_create_bool ( " cache-filter " , mode , dir ,
2011-07-27 03:09:02 +04:00
& failslab . cache_filter ) )
goto fail ;
2010-02-26 09:36:12 +03:00
2011-07-27 03:09:02 +04:00
return 0 ;
fail :
2011-08-04 03:21:01 +04:00
debugfs_remove_recursive ( dir ) ;
2008-12-23 13:37:01 +03:00
2011-07-27 03:09:02 +04:00
return - ENOMEM ;
2008-12-23 13:37:01 +03:00
}
late_initcall ( failslab_debugfs_init ) ;
# endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */