2019-06-04 11:11:15 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-04-10 03:09:27 +04:00
/*
* Frontswap frontend
*
* This code provides the generic " frontend " layer to call a matching
* " backend " driver implementation of frontswap . See
2018-03-21 22:22:47 +03:00
* Documentation / vm / frontswap . rst for more information .
2012-04-10 03:09:27 +04:00
*
* Copyright ( C ) 2009 - 2012 Oracle Corp . All rights reserved .
* Author : Dan Magenheimer
*/
# include <linux/mman.h>
# include <linux/swap.h>
# include <linux/swapops.h>
# include <linux/security.h>
# include <linux/module.h>
# include <linux/debugfs.h>
# include <linux/frontswap.h>
# include <linux/swapfile.h>
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
DEFINE_STATIC_KEY_FALSE ( frontswap_enabled_key ) ;
2012-04-10 03:09:27 +04:00
/*
2015-06-25 02:58:18 +03:00
* frontswap_ops are added by frontswap_register_ops , and provide the
* frontswap " backend " implementation functions . Multiple implementations
* may be registered , but implementations can never deregister . This
* is a simple singly - linked list of all registered implementations .
2012-04-10 03:09:27 +04:00
*/
2013-05-01 02:26:51 +04:00
static struct frontswap_ops * frontswap_ops __read_mostly ;
2012-04-10 03:09:27 +04:00
2015-06-25 02:58:18 +03:00
# define for_each_frontswap_ops(ops) \
for ( ( ops ) = frontswap_ops ; ( ops ) ; ( ops ) = ( ops ) - > next )
2012-04-10 03:09:27 +04:00
# ifdef CONFIG_DEBUG_FS
/*
* Counters available via / sys / kernel / debug / frontswap ( if debugfs is
* properly configured ) . These are for information only so are not protected
* against increment races .
*/
2012-05-15 19:32:15 +04:00
static u64 frontswap_loads ;
static u64 frontswap_succ_stores ;
static u64 frontswap_failed_stores ;
2012-04-10 03:09:27 +04:00
static u64 frontswap_invalidates ;
2021-05-05 04:40:12 +03:00
static inline void inc_frontswap_loads ( void )
{
2020-08-15 03:31:17 +03:00
data_race ( frontswap_loads + + ) ;
2012-04-10 03:09:27 +04:00
}
2021-05-05 04:40:12 +03:00
static inline void inc_frontswap_succ_stores ( void )
{
2020-08-15 03:31:17 +03:00
data_race ( frontswap_succ_stores + + ) ;
2012-04-10 03:09:27 +04:00
}
2021-05-05 04:40:12 +03:00
static inline void inc_frontswap_failed_stores ( void )
{
2020-08-15 03:31:17 +03:00
data_race ( frontswap_failed_stores + + ) ;
2012-04-10 03:09:27 +04:00
}
2021-05-05 04:40:12 +03:00
static inline void inc_frontswap_invalidates ( void )
{
2020-08-15 03:31:17 +03:00
data_race ( frontswap_invalidates + + ) ;
2012-04-10 03:09:27 +04:00
}
# else
2012-05-15 19:32:15 +04:00
static inline void inc_frontswap_loads ( void ) { }
static inline void inc_frontswap_succ_stores ( void ) { }
static inline void inc_frontswap_failed_stores ( void ) { }
2012-04-10 03:09:27 +04:00
static inline void inc_frontswap_invalidates ( void ) { }
# endif
2013-05-01 02:26:50 +04:00
/*
* Due to the asynchronous nature of the backends loading potentially
* _after_ the swap system has been activated , we have chokepoints
* on all frontswap functions to not call the backend until the backend
* has registered .
*
* This would not guards us against the user deciding to call swapoff right as
* we are calling the backend to initialize ( so swapon is in action ) .
2020-06-05 02:49:25 +03:00
* Fortunately for us , the swapon_mutex has been taken by the callee so we are
2013-05-01 02:26:50 +04:00
* OK . The other scenario where calls to frontswap_store ( called via
* swap_writepage ) is racing with frontswap_invalidate_area ( called via
* swapoff ) is again guarded by the swap subsystem .
*
* While no backend is registered all calls to frontswap_ [ store | load |
* invalidate_area | invalidate_page ] are ignored or fail .
*
* The time between the backend being registered and the swap file system
* calling the backend ( via the frontswap_ * functions ) is indeterminate as
2013-05-01 02:26:51 +04:00
* frontswap_ops is not atomic_t ( or a value guarded by a spinlock ) .
2013-05-01 02:26:50 +04:00
* That is OK as we are comfortable missing some of these calls to the newly
* registered backend .
*
* Obviously the opposite ( unloading the backend ) must be done after all
* the frontswap_ [ store | load | invalidate_area | invalidate_page ] start
2015-06-25 02:58:18 +03:00
* ignoring or failing the requests . However , there is currently no way
* to unload a backend once it is registered .
2013-05-01 02:26:50 +04:00
*/
2012-04-10 03:09:27 +04:00
/*
2015-06-25 02:58:18 +03:00
* Register operations for frontswap
2012-04-10 03:09:27 +04:00
*/
2015-06-25 02:58:18 +03:00
void frontswap_register_ops ( struct frontswap_ops * ops )
2012-04-10 03:09:27 +04:00
{
2015-06-25 02:58:18 +03:00
/*
* Setting frontswap_ops must happen after the ops - > init ( ) calls
* above ; cmpxchg implies smp_mb ( ) which will ensure the init is
* complete at this point .
*/
do {
ops - > next = frontswap_ops ;
} while ( cmpxchg ( & frontswap_ops , ops - > next , ops ) ! = ops - > next ) ;
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
static_branch_inc ( & frontswap_enabled_key ) ;
2012-04-10 03:09:27 +04:00
}
/*
* Called when a swap device is swapon ' d .
*/
2022-01-22 09:14:51 +03:00
void frontswap_init ( unsigned type , unsigned long * map )
2012-04-10 03:09:27 +04:00
{
struct swap_info_struct * sis = swap_info [ type ] ;
2015-06-25 02:58:18 +03:00
struct frontswap_ops * ops ;
2012-04-10 03:09:27 +04:00
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
VM_BUG_ON ( sis = = NULL ) ;
2013-05-01 02:26:54 +04:00
/*
* p - > frontswap is a bitmap that we MUST have to figure out which page
* has gone in frontswap . Without it there is no point of continuing .
*/
if ( WARN_ON ( ! map ) )
return ;
/*
* Irregardless of whether the frontswap backend has been loaded
* before this function or it will be later , we _MUST_ have the
* p - > frontswap set to something valid to work properly .
*/
frontswap_map_set ( sis , map ) ;
2015-06-25 02:58:18 +03:00
for_each_frontswap_ops ( ops )
ops - > init ( type ) ;
2012-04-10 03:09:27 +04:00
}
2022-01-22 09:15:01 +03:00
static bool __frontswap_test ( struct swap_info_struct * sis ,
2013-05-01 02:26:53 +04:00
pgoff_t offset )
{
2015-06-25 02:58:18 +03:00
if ( sis - > frontswap_map )
return test_bit ( offset , sis - > frontswap_map ) ;
return false ;
2013-05-01 02:26:53 +04:00
}
2015-06-25 02:58:18 +03:00
static inline void __frontswap_set ( struct swap_info_struct * sis ,
pgoff_t offset )
{
set_bit ( offset , sis - > frontswap_map ) ;
atomic_inc ( & sis - > frontswap_pages ) ;
}
2013-05-01 02:26:53 +04:00
static inline void __frontswap_clear ( struct swap_info_struct * sis ,
2015-06-25 02:58:18 +03:00
pgoff_t offset )
2012-06-10 14:51:07 +04:00
{
2013-05-01 02:26:53 +04:00
clear_bit ( offset , sis - > frontswap_map ) ;
2012-06-10 14:51:07 +04:00
atomic_dec ( & sis - > frontswap_pages ) ;
}
2012-04-10 03:09:27 +04:00
/*
2012-05-15 19:32:15 +04:00
* " Store " data from a page to frontswap and associate it with the page ' s
2012-04-10 03:09:27 +04:00
* swaptype and offset . Page must be locked and in the swap cache .
* If frontswap already contains a page with matching swaptype and
2012-06-16 16:37:48 +04:00
* offset , the frontswap implementation may either overwrite the data and
2012-04-10 03:09:27 +04:00
* return success or invalidate the page from frontswap and return failure .
*/
2012-05-15 19:32:15 +04:00
int __frontswap_store ( struct page * page )
2012-04-10 03:09:27 +04:00
{
2015-06-25 02:58:18 +03:00
int ret = - 1 ;
2012-04-10 03:09:27 +04:00
swp_entry_t entry = { . val = page_private ( page ) , } ;
int type = swp_type ( entry ) ;
struct swap_info_struct * sis = swap_info [ type ] ;
pgoff_t offset = swp_offset ( entry ) ;
2015-06-25 02:58:18 +03:00
struct frontswap_ops * ops ;
2012-04-10 03:09:27 +04:00
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
VM_BUG_ON ( ! frontswap_ops ) ;
VM_BUG_ON ( ! PageLocked ( page ) ) ;
VM_BUG_ON ( sis = = NULL ) ;
2015-06-25 02:58:18 +03:00
/*
* If a dup , we must remove the old page first ; we can ' t leave the
* old page no matter if the store of the new page succeeds or fails ,
* and we can ' t rely on the new page replacing the old page as we may
* not store to the same implementation that contains the old page .
*/
if ( __frontswap_test ( sis , offset ) ) {
__frontswap_clear ( sis , offset ) ;
for_each_frontswap_ops ( ops )
ops - > invalidate_page ( type , offset ) ;
}
/* Try to store in each implementation, until one succeeds. */
for_each_frontswap_ops ( ops ) {
ret = ops - > store ( type , offset , page ) ;
if ( ! ret ) /* successful store */
break ;
}
2012-04-10 03:09:27 +04:00
if ( ret = = 0 ) {
2015-06-25 02:58:18 +03:00
__frontswap_set ( sis , offset ) ;
2012-05-15 19:32:15 +04:00
inc_frontswap_succ_stores ( ) ;
2012-06-10 14:51:04 +04:00
} else {
2012-05-15 19:32:15 +04:00
inc_frontswap_failed_stores ( ) ;
2012-06-10 14:51:00 +04:00
}
2022-01-22 09:14:38 +03:00
2012-04-10 03:09:27 +04:00
return ret ;
}
/*
* " Get " data from frontswap associated with swaptype and offset that were
* specified when the data was put to frontswap and use it to fill the
* specified page with data . Page must be locked and in the swap cache .
*/
2012-05-15 19:32:15 +04:00
int __frontswap_load ( struct page * page )
2012-04-10 03:09:27 +04:00
{
int ret = - 1 ;
swp_entry_t entry = { . val = page_private ( page ) , } ;
int type = swp_type ( entry ) ;
struct swap_info_struct * sis = swap_info [ type ] ;
pgoff_t offset = swp_offset ( entry ) ;
2015-06-25 02:58:18 +03:00
struct frontswap_ops * ops ;
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
VM_BUG_ON ( ! frontswap_ops ) ;
VM_BUG_ON ( ! PageLocked ( page ) ) ;
VM_BUG_ON ( sis = = NULL ) ;
2012-04-10 03:09:27 +04:00
2015-06-25 02:58:18 +03:00
if ( ! __frontswap_test ( sis , offset ) )
return - 1 ;
/* Try loading from each implementation, until one succeeds. */
for_each_frontswap_ops ( ops ) {
ret = ops - > load ( type , offset , page ) ;
if ( ! ret ) /* successful load */
break ;
}
2022-01-22 09:14:41 +03:00
if ( ret = = 0 )
2012-05-15 19:32:15 +04:00
inc_frontswap_loads ( ) ;
2012-04-10 03:09:27 +04:00
return ret ;
}
/*
* Invalidate any data from frontswap associated with the specified swaptype
* and offset so that a subsequent " get " will fail .
*/
void __frontswap_invalidate_page ( unsigned type , pgoff_t offset )
{
struct swap_info_struct * sis = swap_info [ type ] ;
2015-06-25 02:58:18 +03:00
struct frontswap_ops * ops ;
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
VM_BUG_ON ( ! frontswap_ops ) ;
VM_BUG_ON ( sis = = NULL ) ;
2012-04-10 03:09:27 +04:00
2015-06-25 02:58:18 +03:00
if ( ! __frontswap_test ( sis , offset ) )
return ;
for_each_frontswap_ops ( ops )
ops - > invalidate_page ( type , offset ) ;
__frontswap_clear ( sis , offset ) ;
inc_frontswap_invalidates ( ) ;
2012-04-10 03:09:27 +04:00
}
/*
* Invalidate all data from frontswap associated with all offsets for the
* specified swaptype .
*/
void __frontswap_invalidate_area ( unsigned type )
{
struct swap_info_struct * sis = swap_info [ type ] ;
2015-06-25 02:58:18 +03:00
struct frontswap_ops * ops ;
2012-04-10 03:09:27 +04:00
mm, frontswap: convert frontswap_enabled to static key
I have noticed that frontswap.h first declares "frontswap_enabled" as
extern bool variable, and then overrides it with "#define
frontswap_enabled (1)" for CONFIG_FRONTSWAP=Y or (0) when disabled. The
bool variable isn't actually instantiated anywhere.
This all looks like an unfinished attempt to make frontswap_enabled
reflect whether a backend is instantiated. But in the current state,
all frontswap hooks call unconditionally into frontswap.c just to check
if frontswap_ops is non-NULL. This should at least be checked inline,
but we can further eliminate the overhead when CONFIG_FRONTSWAP is
enabled and no backend registered, using a static key that is initially
disabled, and gets enabled only upon first backend registration.
Thus, checks for "frontswap_enabled" are replaced with
"frontswap_enabled()" wrapping the static key check. There are two
exceptions:
- xen's selfballoon_process() was testing frontswap_enabled in code guarded
by #ifdef CONFIG_FRONTSWAP, which was effectively always true when reachable.
The patch just removes this check. Using frontswap_enabled() does not sound
correct here, as this can be true even without xen's own backend being
registered.
- in SYSCALL_DEFINE2(swapon), change the check to IS_ENABLED(CONFIG_FRONTSWAP)
as it seems the bitmap allocation cannot currently be postponed until a
backend is registered. This means that frontswap will still have some
memory overhead by being configured, but without a backend.
After the patch, we can expect that some functions in frontswap.c are
called only when frontswap_ops is non-NULL. Change the checks there to
VM_BUG_ONs. While at it, convert other BUG_ONs to VM_BUG_ONs as
frontswap has been stable for some time.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/1463152235-9717-1-git-send-email-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-07-27 01:24:42 +03:00
VM_BUG_ON ( ! frontswap_ops ) ;
VM_BUG_ON ( sis = = NULL ) ;
2015-06-25 02:58:18 +03:00
if ( sis - > frontswap_map = = NULL )
return ;
for_each_frontswap_ops ( ops )
ops - > invalidate_area ( type ) ;
atomic_set ( & sis - > frontswap_pages , 0 ) ;
bitmap_zero ( sis - > frontswap_map , sis - > max ) ;
2012-04-10 03:09:27 +04:00
}
static int __init init_frontswap ( void )
{
# ifdef CONFIG_DEBUG_FS
struct dentry * root = debugfs_create_dir ( " frontswap " , NULL ) ;
if ( root = = NULL )
return - ENXIO ;
2018-06-15 01:27:58 +03:00
debugfs_create_u64 ( " loads " , 0444 , root , & frontswap_loads ) ;
debugfs_create_u64 ( " succ_stores " , 0444 , root , & frontswap_succ_stores ) ;
debugfs_create_u64 ( " failed_stores " , 0444 , root ,
& frontswap_failed_stores ) ;
debugfs_create_u64 ( " invalidates " , 0444 , root , & frontswap_invalidates ) ;
2012-04-10 03:09:27 +04:00
# endif
return 0 ;
}
module_init ( init_frontswap ) ;