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