diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-09-08 11:24:16 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-09-08 11:24:16 -0300 |
commit | 376027f2a3888ef3dec73ee41f85d90e51162d78 (patch) | |
tree | ac9a9030d31cadc92fdc4145a3d9bf379064721f /include/linux | |
parent | e5fd91f1ef340da553f7a79da9540c3db711c937 (diff) |
Add TuxOnIce support
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/bio.h | 2 | ||||
-rw-r--r-- | include/linux/blk_types.h | 5 | ||||
-rw-r--r-- | include/linux/fs.h | 11 | ||||
-rw-r--r-- | include/linux/fs_uuid.h | 19 | ||||
-rw-r--r-- | include/linux/gfp.h | 4 | ||||
-rw-r--r-- | include/linux/mm.h | 1 | ||||
-rw-r--r-- | include/linux/page-flags.h | 25 | ||||
-rw-r--r-- | include/linux/shmem_fs.h | 5 | ||||
-rw-r--r-- | include/linux/suspend.h | 68 | ||||
-rw-r--r-- | include/linux/swap.h | 7 | ||||
-rw-r--r-- | include/linux/thread_info.h | 4 | ||||
-rw-r--r-- | include/linux/tuxonice.h | 48 |
12 files changed, 190 insertions, 9 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index 5e963a6d7..9f46b625d 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 <linux/blk_types.h> +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 7303b3405..74b4ec5f8 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -121,13 +121,14 @@ struct bio { #define BIO_SNAP_STABLE 7 /* bio data must be snapshotted during write */ #define BIO_CHAIN 8 /* chained bio, ->bi_remaining in effect */ #define BIO_REFFED 9 /* bio has elevated ->bi_cnt */ +#define BIO_TOI 10 /* 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 */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) diff --git a/include/linux/fs.h b/include/linux/fs.h index 84b783f27..8826cf0ff 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1258,6 +1258,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 */ @@ -1741,6 +1743,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 @@ -2269,6 +2273,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); extern struct super_block *blockdev_superblock; 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 <linux/device.h> + +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 ad35f300b..d332d6165 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -35,6 +35,7 @@ struct vm_area_struct; #define ___GFP_NO_KSWAPD 0x400000u #define ___GFP_OTHER_NODE 0x800000u #define ___GFP_WRITE 0x1000000u +#define ___GFP_TOI_NOTRACK 0x2000000u /* If the above are modified, __GFP_BITS_SHIFT may need updating */ /* @@ -94,6 +95,7 @@ struct vm_area_struct; #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD) #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */ #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) /* Allocator intends to dirty page */ +#define __GFP_TOI_NOTRACK ((__force gfp_t)___GFP_TOI_NOTRACK) /* Allocator wants page untracked by TOI */ /* * This may seem redundant, but it's a way of annotating false positives vs. @@ -101,7 +103,7 @@ struct vm_area_struct; */ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) -#define __GFP_BITS_SHIFT 25 /* Room for N __GFP_FOO bits */ +#define __GFP_BITS_SHIFT 26 /* Room for N __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ diff --git a/include/linux/mm.h b/include/linux/mm.h index bf6f117fc..ae930c67b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2137,6 +2137,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 41c93844f..bf858b220 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -109,6 +109,12 @@ enum pageflags { #ifdef CONFIG_TRANSPARENT_HUGEPAGE PG_compound_lock, #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 __NR_PAGEFLAGS, /* Filesystems */ @@ -288,6 +294,17 @@ TESTSCFLAG(HWPoison, hwpoison) 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 /* * On an anonymous page mapped into a user virtual memory area, @@ -642,8 +659,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 50777b5b1..6723fec71 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -48,9 +48,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 5efe743ce..9ae75219f 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -452,6 +452,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 38874729d..9cdd0be25 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -289,6 +289,7 @@ extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; extern unsigned long dirty_balance_reserve; 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; @@ -428,13 +431,17 @@ 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 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 ff307b548..b42ba9169 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -56,9 +56,9 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ #ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | ___GFP_TOI_NOTRACK | __GFP_ZERO) #else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL | __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 |