From 4a327fcef90ba27150a3e8741441b68c605ae248 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Sat, 26 Mar 2016 05:33:09 -0300 Subject: Add TuxOnIce support adapted for the 4.5-gnu kernel version --- include/linux/bio.h | 2 ++ include/linux/blk_types.h | 5 ++-- include/linux/fs.h | 11 ++++++++ include/linux/fs_uuid.h | 19 +++++++++++++ include/linux/gfp.h | 6 ++-- include/linux/mm.h | 1 + include/linux/page-flags.h | 25 +++++++++++++++-- include/linux/shmem_fs.h | 5 ++-- include/linux/suspend.h | 68 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/swap.h | 7 +++++ include/linux/thread_info.h | 4 +-- include/linux/tuxonice.h | 48 ++++++++++++++++++++++++++++++++ 12 files changed, 191 insertions(+), 10 deletions(-) create mode 100644 include/linux/fs_uuid.h create mode 100644 include/linux/tuxonice.h (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 88bc64f00..b721a9d63 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -32,6 +32,8 @@ /* struct bio, bio_vec and BIO_* flags are defined in blk_types.h */ #include +extern int trap_non_toi_io; + #define BIO_DEBUG #ifdef BIO_DEBUG diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 86a38ea18..fee9e23a3 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -120,13 +120,14 @@ struct bio { #define BIO_QUIET 6 /* Make BIO Quiet */ #define BIO_CHAIN 7 /* chained bio, ->bi_remaining in effect */ #define BIO_REFFED 8 /* bio has elevated ->bi_cnt */ +#define BIO_TOI 9 /* bio is TuxOnIce submitted */ /* * Flags starting here get preserved by bio_reset() - this includes * BIO_POOL_IDX() */ -#define BIO_RESET_BITS 13 -#define BIO_OWNS_VEC 13 /* bio_free() should free bvec */ +#define BIO_RESET_BITS 14 +#define BIO_OWNS_VEC 14 /* bio_free() should free bvec */ /* * top 4 bits of bio flags indicate the pool this bio came from diff --git a/include/linux/fs.h b/include/linux/fs.h index ae6810021..cf958ec45 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1278,6 +1278,8 @@ struct mm_struct; #define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ #define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */ +extern struct list_head super_blocks; + /* sb->s_iflags */ #define SB_I_CGROUPWB 0x00000001 /* cgroup-aware writeback enabled */ #define SB_I_NOEXEC 0x00000002 /* Ignore executables on this fs */ @@ -1774,6 +1776,8 @@ struct super_operations { #else #define S_DAX 0 /* Make all the DAX code disappear */ #endif +#define S_ATOMIC_COPY 16384 /* Pages mapped with this inode need to be + atomically copied (gem) */ /* * Note that nosuid etc flags are inode-specific: setting some file-system @@ -2306,6 +2310,13 @@ extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); extern int fsync_bdev(struct block_device *); +extern int fsync_super(struct super_block *); +extern int fsync_no_super(struct block_device *); +#define FS_FREEZER_FUSE 1 +#define FS_FREEZER_NORMAL 2 +#define FS_FREEZER_ALL (FS_FREEZER_FUSE | FS_FREEZER_NORMAL) +void freeze_filesystems(int which); +void thaw_filesystems(int which); #ifdef CONFIG_FS_DAX extern bool blkdev_dax_capable(struct block_device *bdev); #else diff --git a/include/linux/fs_uuid.h b/include/linux/fs_uuid.h new file mode 100644 index 000000000..3234135b5 --- /dev/null +++ b/include/linux/fs_uuid.h @@ -0,0 +1,19 @@ +#include + +struct hd_struct; +struct block_device; + +struct fs_info { + char uuid[16]; + dev_t dev_t; + char *last_mount; + int last_mount_size; +}; + +int part_matches_fs_info(struct hd_struct *part, struct fs_info *seek); +dev_t blk_lookup_fs_info(struct fs_info *seek); +struct fs_info *fs_info_from_block_dev(struct block_device *bdev); +void free_fs_info(struct fs_info *fs_info); +int bdev_matches_key(struct block_device *bdev, const char *key); +struct block_device *next_bdev_of_type(struct block_device *last, + const char *key); diff --git a/include/linux/gfp.h b/include/linux/gfp.h index af1f2b24b..0b6edf722 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -35,7 +35,8 @@ struct vm_area_struct; #define ___GFP_DIRECT_RECLAIM 0x400000u #define ___GFP_OTHER_NODE 0x800000u #define ___GFP_WRITE 0x1000000u -#define ___GFP_KSWAPD_RECLAIM 0x2000000u +#define ___GFP_TOI_NOTRACK 0x2000000u +#define ___GFP_KSWAPD_RECLAIM 0x4000000u /* If the above are modified, __GFP_BITS_SHIFT may need updating */ /* @@ -153,6 +154,7 @@ struct vm_area_struct; #define __GFP_REPEAT ((__force gfp_t)___GFP_REPEAT) #define __GFP_NOFAIL ((__force gfp_t)___GFP_NOFAIL) #define __GFP_NORETRY ((__force gfp_t)___GFP_NORETRY) +#define __GFP_TOI_NOTRACK ((__force gfp_t)___GFP_TOI_NOTRACK) /* Allocator wants page untracked by TOI */ /* * Action modifiers @@ -186,7 +188,7 @@ struct vm_area_struct; #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* Room for N __GFP_FOO bits */ -#define __GFP_BITS_SHIFT 26 +#define __GFP_BITS_SHIFT 27 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* diff --git a/include/linux/mm.h b/include/linux/mm.h index 516e14944..ccc992c6a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2225,6 +2225,7 @@ int drop_caches_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); #endif +void drop_pagecache(void); void drop_slab(void); void drop_slab_node(int nid); diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 19724e6eb..2e7ecb771 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -101,6 +101,12 @@ enum pageflags { #ifdef CONFIG_MEMORY_FAILURE PG_hwpoison, /* hardware poisoned page. Don't touch */ #endif +#ifdef CONFIG_TOI_INCREMENTAL + PG_toi_untracked, /* Don't track dirtiness of this page - assume always dirty */ + PG_toi_ro, /* Page was made RO by TOI */ + PG_toi_cbw, /* Copy the page before it is written to */ + PG_toi_dirty, /* Page has been modified */ +#endif #if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT) PG_young, PG_idle, @@ -343,6 +349,17 @@ TESTSCFLAG(HWPoison, hwpoison, PF_ANY) PAGEFLAG_FALSE(HWPoison) #define __PG_HWPOISON 0 #endif +#ifdef CONFIG_TOI_INCREMENTAL +PAGEFLAG(TOI_RO, toi_ro) +PAGEFLAG(TOI_Dirty, toi_dirty) +PAGEFLAG(TOI_Untracked, toi_untracked) +PAGEFLAG(TOI_CBW, toi_cbw) +#else +PAGEFLAG_FALSE(TOI_RO) +PAGEFLAG_FALSE(TOI_Dirty) +PAGEFLAG_FALSE(TOI_Untracked) +PAGEFLAG_FALSE(TOI_CBW) +#endif #if defined(CONFIG_IDLE_PAGE_TRACKING) && defined(CONFIG_64BIT) TESTPAGEFLAG(Young, young, PF_ANY) @@ -665,8 +682,12 @@ static inline void ClearPageSlabPfmemalloc(struct page *page) * __PG_HWPOISON is exceptional because it needs to be kept beyond page's * alloc-free cycle to prevent from reusing the page. */ -#define PAGE_FLAGS_CHECK_AT_PREP \ - (((1 << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON) +#ifdef CONFIG_TOI_INCREMENTAL +#define PAGE_FLAGS_CHECK_AT_PREP (((1 << NR_PAGEFLAGS) - 1) & \ + ~((1 << PG_toi_dirty) | (1 << PG_toi_ro) | ~__PG_HWPOISON)) +#else +#define PAGE_FLAGS_CHECK_AT_PREP (((1 << NR_PAGEFLAGS) - 1) & ~__PG_HWPOISON) +#endif #define PAGE_FLAGS_PRIVATE \ (1 << PG_private | 1 << PG_private_2) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 4d4780c00..665cd8591 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -45,9 +45,10 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) extern int shmem_init(void); extern int shmem_fill_super(struct super_block *sb, void *data, int silent); extern struct file *shmem_file_setup(const char *name, - loff_t size, unsigned long flags); + loff_t size, unsigned long flags, + int atomic_copy); extern struct file *shmem_kernel_file_setup(const char *name, loff_t size, - unsigned long flags); + unsigned long flags, int atomic_copy); extern int shmem_zero_setup(struct vm_area_struct *); extern int shmem_lock(struct file *file, int lock, struct user_struct *user); extern bool shmem_mapping(struct address_space *mapping); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 8b6ec7ef0..0e527a70e 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -491,6 +491,74 @@ extern bool pm_print_times_enabled; #define pm_print_times_enabled (false) #endif +enum { + TOI_CAN_HIBERNATE, + TOI_CAN_RESUME, + TOI_RESUME_DEVICE_OK, + TOI_NORESUME_SPECIFIED, + TOI_SANITY_CHECK_PROMPT, + TOI_CONTINUE_REQ, + TOI_RESUMED_BEFORE, + TOI_BOOT_TIME, + TOI_NOW_RESUMING, + TOI_IGNORE_LOGLEVEL, + TOI_TRYING_TO_RESUME, + TOI_LOADING_ALT_IMAGE, + TOI_STOP_RESUME, + TOI_IO_STOPPED, + TOI_NOTIFIERS_PREPARE, + TOI_CLUSTER_MODE, + TOI_BOOT_KERNEL, + TOI_DEVICE_HOTPLUG_LOCKED, +}; + +#ifdef CONFIG_TOI + +/* Used in init dir files */ +extern unsigned long toi_state; +#define set_toi_state(bit) (set_bit(bit, &toi_state)) +#define clear_toi_state(bit) (clear_bit(bit, &toi_state)) +#define test_toi_state(bit) (test_bit(bit, &toi_state)) +extern int toi_running; + +#define test_action_state(bit) (test_bit(bit, &toi_bkd.toi_action)) +extern int try_tuxonice_hibernate(void); + +#else /* !CONFIG_TOI */ + +#define toi_state (0) +#define set_toi_state(bit) do { } while (0) +#define clear_toi_state(bit) do { } while (0) +#define test_toi_state(bit) (0) +#define toi_running (0) + +static inline int try_tuxonice_hibernate(void) { return 0; } +#define test_action_state(bit) (0) + +#endif /* CONFIG_TOI */ + +#ifdef CONFIG_HIBERNATION +#ifdef CONFIG_TOI +extern void try_tuxonice_resume(void); +#else +#define try_tuxonice_resume() do { } while (0) +#endif + +extern int resume_attempted; +extern int software_resume(void); + +static inline void check_resume_attempted(void) +{ + if (resume_attempted) + return; + + software_resume(); +} +#else +#define check_resume_attempted() do { } while (0) +#define resume_attempted (0) +#endif + #ifdef CONFIG_PM_AUTOSLEEP /* kernel/power/autosleep.c */ diff --git a/include/linux/swap.h b/include/linux/swap.h index d18b65c53..44324f10f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -288,6 +288,7 @@ static inline void workingset_node_shadows_dec(struct radix_tree_node *node) extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; extern unsigned long nr_free_buffer_pages(void); +extern unsigned long nr_unallocated_buffer_pages(void); extern unsigned long nr_free_pagecache_pages(void); /* Definition of global_page_state not available yet */ @@ -328,6 +329,8 @@ extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, struct zone *zone, unsigned long *nr_scanned); extern unsigned long shrink_all_memory(unsigned long nr_pages); +extern unsigned long shrink_memory_mask(unsigned long nr_to_reclaim, + gfp_t mask); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); extern unsigned long vm_total_pages; @@ -413,14 +416,18 @@ extern void swapcache_free(swp_entry_t); extern int free_swap_and_cache(swp_entry_t); extern int swap_type_of(dev_t, sector_t, struct block_device **); extern unsigned int count_swap_pages(int, int); +extern sector_t map_swap_entry(swp_entry_t entry, struct block_device **); extern sector_t map_swap_page(struct page *, struct block_device **); extern sector_t swapdev_block(int, pgoff_t); +extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int page_swapcount(struct page *); extern int swp_swapcount(swp_entry_t entry); extern struct swap_info_struct *page_swap_info(struct page *); extern int reuse_swap_page(struct page *); extern int try_to_free_swap(struct page *); struct backing_dev_info; +extern void get_swap_range_of_type(int type, swp_entry_t *start, + swp_entry_t *end, unsigned int limit); #else /* CONFIG_SWAP */ diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index b4c2a485b..c54e16a5d 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -56,10 +56,10 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ #ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | ___GFP_TOI_NOTRACK | \ __GFP_ZERO) #else -# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | ___GFP_TOI_NOTRACK) #endif /* diff --git a/include/linux/tuxonice.h b/include/linux/tuxonice.h new file mode 100644 index 000000000..67b05a750 --- /dev/null +++ b/include/linux/tuxonice.h @@ -0,0 +1,48 @@ +/* + * include/linux/tuxonice.h + * + * Copyright (C) 2015 Nigel Cunningham (nigel at tuxonice net) + * + * This file is released under the GPLv2. + */ + +#ifndef INCLUDE_LINUX_TUXONICE_H +#define INCLUDE_LINUX_TUXONICE_H +#ifdef CONFIG_TOI_INCREMENTAL +extern void toi_set_logbuf_untracked(void); +extern int toi_make_writable(pgd_t *pgd, unsigned long address); + +static inline int toi_incremental_support(void) +{ + return 1; +} + +/* Copy Before Write */ +struct toi_cbw { + unsigned long pfn; + void *virt; + struct toi_cbw *next; +}; + +struct toi_cbw_state { + bool active; /* Is a fault handler running? */ + bool enabled; /* Are we doing copy before write? */ + int size; /* The number of pages allocated */ + struct toi_cbw *first, *next, *last; /* Pointers to the data structure */ +}; + +#define CBWS_PER_PAGE (PAGE_SIZE / sizeof(struct toi_cbw)) +DECLARE_PER_CPU(struct toi_cbw_state, toi_cbw_states); +#else +#define toi_set_logbuf_untracked() do { } while(0) +static inline int toi_make_writable(pgd_t *pgd, unsigned long addr) +{ + return 0; +} + +static inline int toi_incremental_support(void) +{ + return 0; +} +#endif +#endif -- cgit v1.2.3-54-g00ecf