diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/helpers.c | 2 | ||||
-rw-r--r-- | kernel/power/power.h | 3 | ||||
-rw-r--r-- | kernel/power/tuxonice_bio.h | 2 | ||||
-rw-r--r-- | kernel/power/tuxonice_bio_chains.c | 17 | ||||
-rw-r--r-- | kernel/power/tuxonice_bio_core.c | 79 | ||||
-rw-r--r-- | kernel/power/tuxonice_highlevel.c | 7 | ||||
-rw-r--r-- | kernel/power/tuxonice_io.c | 28 | ||||
-rw-r--r-- | kernel/power/tuxonice_io.h | 2 | ||||
-rw-r--r-- | kernel/power/tuxonice_prepare_image.c | 15 | ||||
-rw-r--r-- | kernel/power/tuxonice_prepare_image.h | 2 |
10 files changed, 87 insertions, 70 deletions
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 4504ca661..50da680c4 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -166,7 +166,7 @@ static u64 bpf_get_current_comm(u64 r1, u64 size, u64 r3, u64 r4, u64 r5) if (!task) return -EINVAL; - memcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm))); + strlcpy(buf, task->comm, min_t(size_t, size, sizeof(task->comm))); return 0; } diff --git a/kernel/power/power.h b/kernel/power/power.h index 2577c6d01..bf4d922b2 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -81,6 +81,7 @@ static struct kobj_attribute _name##_attr = { \ .store = _name##_store, \ } +extern struct pbe *restore_pblist; #define power_attr_ro(_name) \ static struct kobj_attribute _name##_attr = { \ .attr = { \ @@ -90,8 +91,6 @@ static struct kobj_attribute _name##_attr = { \ .show = _name##_show, \ } -extern struct pbe *restore_pblist; - /* Preferred image size in bytes (default 500 MB) */ extern unsigned long image_size; /* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */ diff --git a/kernel/power/tuxonice_bio.h b/kernel/power/tuxonice_bio.h index 9d52a3b69..2f717f5c5 100644 --- a/kernel/power/tuxonice_bio.h +++ b/kernel/power/tuxonice_bio.h @@ -76,3 +76,5 @@ struct toi_bio_allocator_ops { void (*free_storage) (struct toi_bdev_info *); unsigned long (*free_unused_storage) (struct toi_bdev_info *, unsigned long used); }; + +extern int toi_bio_register_storage(void); diff --git a/kernel/power/tuxonice_bio_chains.c b/kernel/power/tuxonice_bio_chains.c index 086a5527d..11cd37f77 100644 --- a/kernel/power/tuxonice_bio_chains.c +++ b/kernel/power/tuxonice_bio_chains.c @@ -924,11 +924,14 @@ static int apply_header_reservation(void) return 0; } -static int toi_bio_register_storage(void) +int toi_bio_register_storage(void) { int result = 0; struct toi_module_ops *this_module; + toi_message(TOI_BIO, TOI_VERBOSE, 0, "toi_bio_allocate_storage: " + "Registering storage."); + list_for_each_entry(this_module, &toi_modules, module_list) { if (!this_module->enabled || this_module->type != BIO_ALLOCATOR_MODULE) @@ -962,16 +965,8 @@ int toi_bio_allocate_storage(unsigned long request) int no_free = 0; if (!chain) { - int result = toi_bio_register_storage(); - toi_message(TOI_BIO, TOI_VERBOSE, 0, "toi_bio_allocate_storage: " - "Registering storage."); - if (result) - return 0; - chain = prio_chain_head; - if (!chain) { - printk("TuxOnIce: No storage was registered.\n"); - return 0; - } + printk("TuxOnIce: No storage was registered.\n"); + return 0; } toi_message(TOI_BIO, TOI_VERBOSE, 0, "toi_bio_allocate_storage: " diff --git a/kernel/power/tuxonice_bio_core.c b/kernel/power/tuxonice_bio_core.c index 87aa4c96e..bc27662d7 100644 --- a/kernel/power/tuxonice_bio_core.c +++ b/kernel/power/tuxonice_bio_core.c @@ -565,7 +565,7 @@ void debug_broken_header(void) printk(KERN_DEBUG "Total used : %d (%ld pages).\n", total_header_bytes, DIV_ROUND_UP(total_header_bytes, PAGE_SIZE)); printk(KERN_DEBUG "Space needed now : %ld.\n", - get_header_storage_needed()); + get_header_storage_needed(0)); dump_block_chains(); abort_hibernate(TOI_HEADER_TOO_BIG, "Header reservation too small."); } @@ -1389,6 +1389,11 @@ static int toi_bio_initialise(int starting_cycle) if (result) return result; + result = toi_bio_register_storage(); + + if (result) + return result; + return get_signature_page(); } @@ -1875,47 +1880,47 @@ static struct toi_sysfs_data sysfs_params[] = { }; struct toi_module_ops toi_blockwriter_ops = { - .type = WRITER_MODULE, - .name = "block i/o", - .directory = "block_io", - .module = THIS_MODULE, - .memory_needed = toi_bio_memory_needed, - .print_debug_info = toi_bio_print_debug_stats, - .storage_needed = toi_bio_storage_needed, - .save_config_info = toi_bio_save_config_info, - .load_config_info = toi_bio_load_config_info, - .initialise = toi_bio_initialise, + .type = WRITER_MODULE, + .name = "block i/o", + .directory = "block_io", + .module = THIS_MODULE, + .memory_needed = toi_bio_memory_needed, + .print_debug_info = toi_bio_print_debug_stats, + .storage_needed = toi_bio_storage_needed, + .save_config_info = toi_bio_save_config_info, + .load_config_info = toi_bio_load_config_info, + .initialise = toi_bio_initialise, .cleanup = toi_bio_cleanup, - .post_atomic_restore = toi_bio_chains_post_atomic, + .post_atomic_restore = toi_bio_chains_post_atomic, .rw_init = toi_rw_init, - .rw_cleanup = toi_rw_cleanup, - .read_page = toi_bio_read_page, - .write_page = toi_bio_write_page, + .rw_cleanup = toi_rw_cleanup, + .read_page = toi_bio_read_page, + .write_page = toi_bio_write_page, .rw_header_chunk = toi_rw_header_chunk, - .rw_header_chunk_noreadahead = toi_rw_header_chunk_noreadahead, - .io_flusher = bio_io_flusher, - .update_throughput_throttle = update_throughput_throttle, - .finish_all_io = toi_finish_all_io, - - .noresume_reset = toi_bio_noresume_reset, - .storage_available = toi_bio_storage_available, - .storage_allocated = toi_bio_storage_allocated, - .reserve_header_space = toi_bio_reserve_header_space, - .allocate_storage = toi_bio_allocate_storage, + .rw_header_chunk_noreadahead = toi_rw_header_chunk_noreadahead, + .io_flusher = bio_io_flusher, + .update_throughput_throttle = update_throughput_throttle, + .finish_all_io = toi_finish_all_io, + + .noresume_reset = toi_bio_noresume_reset, + .storage_available = toi_bio_storage_available, + .storage_allocated = toi_bio_storage_allocated, + .reserve_header_space = toi_bio_reserve_header_space, + .allocate_storage = toi_bio_allocate_storage, .free_unused_storage = toi_bio_free_unused_storage, - .image_exists = toi_bio_image_exists, - .mark_resume_attempted = toi_bio_mark_resume_attempted, - .write_header_init = toi_bio_write_header_init, - .write_header_cleanup = toi_bio_write_header_cleanup, - .read_header_init = toi_bio_read_header_init, - .read_header_cleanup = toi_bio_read_header_cleanup, - .get_header_version = toi_bio_get_header_version, - .remove_image = toi_bio_remove_image, - .parse_sig_location = toi_bio_parse_sig_location, - - .sysfs_data = sysfs_params, - .num_sysfs_entries = sizeof(sysfs_params) / + .image_exists = toi_bio_image_exists, + .mark_resume_attempted = toi_bio_mark_resume_attempted, + .write_header_init = toi_bio_write_header_init, + .write_header_cleanup = toi_bio_write_header_cleanup, + .read_header_init = toi_bio_read_header_init, + .read_header_cleanup = toi_bio_read_header_cleanup, + .get_header_version = toi_bio_get_header_version, + .remove_image = toi_bio_remove_image, + .parse_sig_location = toi_bio_parse_sig_location, + + .sysfs_data = sysfs_params, + .num_sysfs_entries = sizeof(sysfs_params) / sizeof(struct toi_sysfs_data), }; diff --git a/kernel/power/tuxonice_highlevel.c b/kernel/power/tuxonice_highlevel.c index 16cf14cbc..1ef1f22b7 100644 --- a/kernel/power/tuxonice_highlevel.c +++ b/kernel/power/tuxonice_highlevel.c @@ -160,7 +160,8 @@ void toi_finish_anything(int hibernate_or_resume) set_cpus_allowed_ptr(current, cpu_all_mask); toi_alloc_print_debug_stats(); atomic_inc(&snapshot_device_available); - unlock_system_sleep(); + unlock_system_sleep(); + release_super_lock(); } set_fs(oldfs); @@ -185,7 +186,8 @@ int toi_start_anything(int hibernate_or_resume) toi_trace_index = 0; if (hibernate_or_resume) { - lock_system_sleep(); + take_super_lock(); + lock_system_sleep(); if (!atomic_add_unless(&snapshot_device_available, -1, 0)) goto snapshotdevice_unavailable; @@ -230,6 +232,7 @@ prehibernate_err: snapshotdevice_unavailable: if (hibernate_or_resume) mutex_unlock(&pm_mutex); + release_super_lock(); set_fs(oldfs); mutex_unlock(&tuxonice_in_use); return -EBUSY; diff --git a/kernel/power/tuxonice_io.c b/kernel/power/tuxonice_io.c index 3c62c2682..2db934350 100644 --- a/kernel/power/tuxonice_io.c +++ b/kernel/power/tuxonice_io.c @@ -1232,24 +1232,28 @@ static inline int save_fs_info(struct fs_info *fs, struct block_device *bdev) return (!fs || IS_ERR(fs) || !fs->last_mount_size) ? 0 : 1; } -int fs_info_space_needed(void) +int fs_info_space_needed(int reset) { - const struct super_block *sb; - int result = sizeof(int); + static int last_result = 0; + const struct super_block *sb; + int result = sizeof(int); + if (!last_result || reset) { list_for_each_entry(sb, &super_blocks, s_list) { - struct fs_info *fs; + struct fs_info *fs; - if (!sb->s_bdev) - continue; + if (!sb->s_bdev) + continue; - fs = fs_info_from_block_dev(sb->s_bdev); - if (save_fs_info(fs, sb->s_bdev)) - result += 16 + sizeof(dev_t) + sizeof(int) + - fs->last_mount_size; - free_fs_info(fs); + fs = fs_info_from_block_dev(sb->s_bdev); + if (save_fs_info(fs, sb->s_bdev)) + result += 16 + sizeof(dev_t) + sizeof(int) + + fs->last_mount_size; + free_fs_info(fs); } - return result; + last_result = result; + } + return result; } static int fs_info_num_to_save(void) diff --git a/kernel/power/tuxonice_io.h b/kernel/power/tuxonice_io.h index 683eab7a0..7d4d83f40 100644 --- a/kernel/power/tuxonice_io.h +++ b/kernel/power/tuxonice_io.h @@ -67,6 +67,6 @@ extern atomic_t toi_io_workers; extern wait_queue_head_t toi_io_queue_flusher; extern int toi_bio_queue_flusher_should_finish; -int fs_info_space_needed(void); +int fs_info_space_needed(int reset); extern int toi_max_workers; diff --git a/kernel/power/tuxonice_prepare_image.c b/kernel/power/tuxonice_prepare_image.c index a10d62080..df37cc805 100644 --- a/kernel/power/tuxonice_prepare_image.c +++ b/kernel/power/tuxonice_prepare_image.c @@ -428,13 +428,18 @@ static unsigned long main_storage_needed(int use_ecr, /* * Storage needed for the image header, in bytes until the return. + * + * fs_info_space_needed is saved in a static variable unless we + * explicitly want to reset the value (done at the start of a cycle) + * as it requires memory allocation that may result in a hang if we're + * also trying to free memory. */ -unsigned long get_header_storage_needed(void) +unsigned long get_header_storage_needed(int reset) { unsigned long bytes = sizeof(struct toi_header) + toi_header_storage_for_modules() + toi_pageflags_space_needed() + - fs_info_space_needed(); + fs_info_space_needed(0); return DIV_ROUND_UP(bytes, PAGE_SIZE); } @@ -858,7 +863,7 @@ static void update_image(int ps2_recalc) toiActiveAllocator->storage_allocated(); /* Need more header because more storage allocated? */ - header_storage_needed = get_header_storage_needed(); + header_storage_needed = get_header_storage_needed(0); } while (header_storage_needed > old_header_req); @@ -1007,6 +1012,10 @@ int toi_prepare_image(void) int result = 1, tries = 1; main_storage_allocated = 0; + + // Force recalculation of the amount of header storage needed for fs info. + fs_info_space_needed(1); + no_ps2_needed = 0; if (attempt_to_freeze()) diff --git a/kernel/power/tuxonice_prepare_image.h b/kernel/power/tuxonice_prepare_image.h index c1508975c..f7f2b695c 100644 --- a/kernel/power/tuxonice_prepare_image.h +++ b/kernel/power/tuxonice_prepare_image.h @@ -33,6 +33,6 @@ extern void free_attention_list(void); #define ZONE_HIGHMEM (MAX_NR_ZONES + 1) #endif -unsigned long get_header_storage_needed(void); +unsigned long get_header_storage_needed(int reset); unsigned long any_to_free(int use_image_size_limit); int try_allocate_extra_memory(void); |