d1dc6f1bcf
Change frontswap single pointer to a singly linked list of frontswap implementations. Update Xen tmem implementation as register no longer returns anything. Frontswap only keeps track of a single implementation; any implementation that registers second (or later) will replace the previously registered implementation, and gets a pointer to the previous implementation that the new implementation is expected to pass all frontswap functions to if it can't handle the function itself. However that method doesn't really make much sense, as passing that work on to every implementation adds unnecessary work to implementations; instead, frontswap should simply keep a list of all registered implementations and try each implementation for any function. Most importantly, neither of the two currently existing frontswap implementations in the kernel actually do anything with any previous frontswap implementation that they replace when registering. This allows frontswap to successfully manage multiple implementations by keeping a list of them all. Signed-off-by: Dan Streetman <ddstreet@ieee.org> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: David Vrabel <david.vrabel@citrix.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
107 lines
2.7 KiB
C
107 lines
2.7 KiB
C
#ifndef _LINUX_FRONTSWAP_H
|
|
#define _LINUX_FRONTSWAP_H
|
|
|
|
#include <linux/swap.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/bitops.h>
|
|
|
|
struct frontswap_ops {
|
|
void (*init)(unsigned); /* this swap type was just swapon'ed */
|
|
int (*store)(unsigned, pgoff_t, struct page *); /* store a page */
|
|
int (*load)(unsigned, pgoff_t, struct page *); /* load a page */
|
|
void (*invalidate_page)(unsigned, pgoff_t); /* page no longer needed */
|
|
void (*invalidate_area)(unsigned); /* swap type just swapoff'ed */
|
|
struct frontswap_ops *next; /* private pointer to next ops */
|
|
};
|
|
|
|
extern bool frontswap_enabled;
|
|
extern void frontswap_register_ops(struct frontswap_ops *ops);
|
|
extern void frontswap_shrink(unsigned long);
|
|
extern unsigned long frontswap_curr_pages(void);
|
|
extern void frontswap_writethrough(bool);
|
|
#define FRONTSWAP_HAS_EXCLUSIVE_GETS
|
|
extern void frontswap_tmem_exclusive_gets(bool);
|
|
|
|
extern bool __frontswap_test(struct swap_info_struct *, pgoff_t);
|
|
extern void __frontswap_init(unsigned type, unsigned long *map);
|
|
extern int __frontswap_store(struct page *page);
|
|
extern int __frontswap_load(struct page *page);
|
|
extern void __frontswap_invalidate_page(unsigned, pgoff_t);
|
|
extern void __frontswap_invalidate_area(unsigned);
|
|
|
|
#ifdef CONFIG_FRONTSWAP
|
|
#define frontswap_enabled (1)
|
|
|
|
static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
|
|
{
|
|
return __frontswap_test(sis, offset);
|
|
}
|
|
|
|
static inline void frontswap_map_set(struct swap_info_struct *p,
|
|
unsigned long *map)
|
|
{
|
|
p->frontswap_map = map;
|
|
}
|
|
|
|
static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
|
|
{
|
|
return p->frontswap_map;
|
|
}
|
|
#else
|
|
/* all inline routines become no-ops and all externs are ignored */
|
|
|
|
#define frontswap_enabled (0)
|
|
|
|
static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline void frontswap_map_set(struct swap_info_struct *p,
|
|
unsigned long *map)
|
|
{
|
|
}
|
|
|
|
static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
|
|
{
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
static inline int frontswap_store(struct page *page)
|
|
{
|
|
int ret = -1;
|
|
|
|
if (frontswap_enabled)
|
|
ret = __frontswap_store(page);
|
|
return ret;
|
|
}
|
|
|
|
static inline int frontswap_load(struct page *page)
|
|
{
|
|
int ret = -1;
|
|
|
|
if (frontswap_enabled)
|
|
ret = __frontswap_load(page);
|
|
return ret;
|
|
}
|
|
|
|
static inline void frontswap_invalidate_page(unsigned type, pgoff_t offset)
|
|
{
|
|
if (frontswap_enabled)
|
|
__frontswap_invalidate_page(type, offset);
|
|
}
|
|
|
|
static inline void frontswap_invalidate_area(unsigned type)
|
|
{
|
|
if (frontswap_enabled)
|
|
__frontswap_invalidate_area(type);
|
|
}
|
|
|
|
static inline void frontswap_init(unsigned type, unsigned long *map)
|
|
{
|
|
if (frontswap_enabled)
|
|
__frontswap_init(type, map);
|
|
}
|
|
|
|
#endif /* _LINUX_FRONTSWAP_H */
|