Linux_SDK_V1.5.4

Signed-off-by: thead_admin <occ_thead@service.alibaba.com>
This commit is contained in:
thead_admin
2024-04-26 03:07:38 +00:00
committed by Han Gao
parent 89d6663712
commit 7563179071
105 changed files with 3730 additions and 1716 deletions

View File

@@ -407,7 +407,10 @@ static int create_image(int platform_mode)
return error;
}
void async_swsusp_free(void *data, async_cookie_t cookie)
{
swsusp_free();
}
/**
* hibernation_snapshot - Quiesce devices and create a hibernation image.
* @platform_mode: If set, use platform driver to prepare for the transition.
@@ -466,8 +469,10 @@ int hibernation_snapshot(int platform_mode)
*/
/* We may need to release the preallocated image pages here. */
if (error || !in_suspend)
if (error )
swsusp_free();
else if ( !in_suspend )
async_schedule(async_swsusp_free,NULL);
msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
dpm_resume(msg);
@@ -1071,6 +1076,15 @@ static int software_resume(void)
pm_restore_console();
pr_info("resume failed (%d)\n", error);
hibernate_release();
/* If hibernate image exists, this bootup dtb is cut as minimal system,
* need reboot for normal bootup dtb */
if(error)
{
mutex_unlock(&system_transition_mutex);
pr_err("Hibernation resume error %d !\n",error);
kernel_restart(NULL);
return error;
}
/* For success case, the suspend path will release the lock */
Unlock:
mutex_unlock(&system_transition_mutex);
@@ -1243,6 +1257,42 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
power_attr(resume);
/*only set device, not do software_resume*/
static ssize_t resume_dev_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
return sprintf(buf, "%d:%d\n", MAJOR(swsusp_resume_device),
MINOR(swsusp_resume_device));
}
static ssize_t resume_dev_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
dev_t res;
int len = n;
char *name;
if (len && buf[len-1] == '\n')
len--;
name = kstrndup(buf, len, GFP_KERNEL);
if (!name)
return -ENOMEM;
res = name_to_dev_t(name);
kfree(name);
if (!res)
return -EINVAL;
lock_system_sleep();
swsusp_resume_device = res;
unlock_system_sleep();
pm_pr_dbg("Configured hibernation resume from disk to %u\n",
swsusp_resume_device);
return n;
}
power_attr(resume_dev);
static ssize_t resume_offset_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -1313,6 +1363,7 @@ static struct attribute *g[] = {
&disk_attr.attr,
&resume_offset_attr.attr,
&resume_attr.attr,
&resume_dev_attr.attr,
&image_size_attr.attr,
&reserved_size_attr.attr,
NULL,
@@ -1398,6 +1449,7 @@ static int __init nohibernate_setup(char *str)
return 1;
}
__setup("noresume", noresume_setup);
__setup("resume_offset=", resume_offset_setup);
__setup("resume=", resume_setup);

View File

@@ -2644,7 +2644,7 @@ static int prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
/* Preallocate memory for the image */
nr_pages = nr_copy_pages - nr_highmem - allocated_unsafe_pages;
while (nr_pages > 0) {
lp = (struct linked_page *)get_zeroed_page(GFP_ATOMIC);
lp = (struct linked_page *)__get_free_pages(GFP_ATOMIC,0);
if (!lp) {
error = -ENOMEM;
goto Free;
@@ -2729,7 +2729,7 @@ int snapshot_write_next(struct snapshot_handle *handle)
{
static struct chain_allocator ca;
int error = 0;
ktime_t start;
/* Check if we have already loaded the entire image */
if (handle->cur > 1 && handle->cur > nr_meta_pages + nr_copy_pages)
return 0;
@@ -2763,10 +2763,12 @@ int snapshot_write_next(struct snapshot_handle *handle)
return error;
if (handle->cur == nr_meta_pages + 1) {
start = ktime_get();
error = prepare_image(&orig_bm, &copy_bm);
if (error)
return error;
pr_info("prepare image took %lldms\n",ktime_to_ms( ktime_sub(ktime_get(),start)) );
chain_init(&ca, GFP_ATOMIC, PG_SAFE);
memory_bm_position_reset(&orig_bm);
restore_pblist = NULL;

View File

@@ -512,7 +512,12 @@ static int swap_writer_finish(struct swap_map_handle *handle,
}
/* We need to remember how much compressed data we need to read. */
#define LZO_HEADER sizeof(size_t)
struct hib_lzo_header {
size_t cmp_len;
u32 unc_crc32;
}__packed;
#define LZO_HEADER (8*DIV_ROUND_UP((sizeof(struct hib_lzo_header)),8))
/* Number of pages/bytes we'll compress at one time. */
#define LZO_UNC_PAGES 32
@@ -524,12 +529,16 @@ static int swap_writer_finish(struct swap_map_handle *handle,
#define LZO_CMP_SIZE (LZO_CMP_PAGES * PAGE_SIZE)
/* Maximum number of threads for compression/decompression. */
#define LZO_THREADS 3
#define LZO_THREADS 4
/* Minimum/maximum number of pages for read buffering. */
#define LZO_MIN_RD_PAGES 1024
#define LZO_MAX_RD_PAGES 8192
static inline u32 get_header_crc32(struct hib_lzo_header *h)
{
return h->unc_crc32;
}
/**
* save_image - save the suspend image data
@@ -579,48 +588,6 @@ static int save_image(struct swap_map_handle *handle,
return ret;
}
/**
* Structure used for CRC32.
*/
struct crc_data {
struct task_struct *thr; /* thread */
atomic_t ready; /* ready to start flag */
atomic_t stop; /* ready to stop flag */
unsigned run_threads; /* nr current threads */
wait_queue_head_t go; /* start crc update */
wait_queue_head_t done; /* crc update done */
u32 *crc32; /* points to handle's crc32 */
size_t *unc_len[LZO_THREADS]; /* uncompressed lengths */
unsigned char *unc[LZO_THREADS]; /* uncompressed data */
};
/**
* CRC32 update function that runs in its own thread.
*/
static int crc32_threadfn(void *data)
{
struct crc_data *d = data;
unsigned i;
while (1) {
wait_event(d->go, atomic_read(&d->ready) ||
kthread_should_stop());
if (kthread_should_stop()) {
d->thr = NULL;
atomic_set(&d->stop, 1);
wake_up(&d->done);
break;
}
atomic_set(&d->ready, 0);
for (i = 0; i < d->run_threads; i++)
*d->crc32 = crc32_le(*d->crc32,
d->unc[i], *d->unc_len[i]);
atomic_set(&d->stop, 1);
wake_up(&d->done);
}
return 0;
}
/**
* Structure used for LZO data compression.
*/
@@ -639,12 +606,17 @@ struct cmp_data {
};
/**
* Compression function that runs in its own thread.
* Compression & crc32 compute function that runs in its own thread.
* In this method,crc32 compute cost is much less by multi-cores in
* multi-threads.
* The value of crc32 stored in the header of LZO,which descripted with
* ' struct hib_lzo_header '.
*/
static int lzo_compress_threadfn(void *data)
{
struct cmp_data *d = data;
struct hib_lzo_header *lzo_head;
pr_info("compress thread on core %d\n",smp_processor_id());
while (1) {
wait_event(d->go, atomic_read(&d->ready) ||
kthread_should_stop());
@@ -660,6 +632,9 @@ static int lzo_compress_threadfn(void *data)
d->ret = lzo1x_1_compress(d->unc, d->unc_len,
d->cmp + LZO_HEADER, &d->cmp_len,
d->wrk);
lzo_head = (struct hib_lzo_header *)d->cmp;
lzo_head->cmp_len = d->cmp_len;
lzo_head->unc_crc32 = crc32_le(0,d->cmp + LZO_HEADER, d->cmp_len);
atomic_set(&d->stop, 1);
wake_up(&d->done);
}
@@ -687,7 +662,6 @@ static int save_image_lzo(struct swap_map_handle *handle,
unsigned thr, run_threads, nr_threads;
unsigned char *page = NULL;
struct cmp_data *data = NULL;
struct crc_data *crc = NULL;
hib_init_batch(&hb);
@@ -714,16 +688,8 @@ static int save_image_lzo(struct swap_map_handle *handle,
for (thr = 0; thr < nr_threads; thr++)
memset(&data[thr], 0, offsetof(struct cmp_data, go));
crc = kmalloc(sizeof(*crc), GFP_KERNEL);
if (!crc) {
pr_err("Failed to allocate crc\n");
ret = -ENOMEM;
goto out_clean;
}
memset(crc, 0, offsetof(struct crc_data, go));
/*
* Start the compression threads.
* Start the compression & crc32 compute threads.
*/
for (thr = 0; thr < nr_threads; thr++) {
init_waitqueue_head(&data[thr].go);
@@ -740,27 +706,6 @@ static int save_image_lzo(struct swap_map_handle *handle,
}
}
/*
* Start the CRC32 thread.
*/
init_waitqueue_head(&crc->go);
init_waitqueue_head(&crc->done);
handle->crc32 = 0;
crc->crc32 = &handle->crc32;
for (thr = 0; thr < nr_threads; thr++) {
crc->unc[thr] = data[thr].unc;
crc->unc_len[thr] = &data[thr].unc_len;
}
crc->thr = kthread_run(crc32_threadfn, crc, "image_crc32");
if (IS_ERR(crc->thr)) {
crc->thr = NULL;
pr_err("Cannot start CRC32 thread\n");
ret = -ENOMEM;
goto out_clean;
}
/*
* Adjust the number of required free pages after all allocations have
* been done. We don't want to run out of pages when writing.
@@ -805,9 +750,6 @@ static int save_image_lzo(struct swap_map_handle *handle,
if (!thr)
break;
crc->run_threads = thr;
atomic_set(&crc->ready, 1);
wake_up(&crc->go);
for (run_threads = thr, thr = 0; thr < run_threads; thr++) {
wait_event(data[thr].done,
@@ -850,8 +792,6 @@ static int save_image_lzo(struct swap_map_handle *handle,
}
}
wait_event(crc->done, atomic_read(&crc->stop));
atomic_set(&crc->stop, 0);
}
out_finish:
@@ -864,11 +804,7 @@ out_finish:
swsusp_show_speed(start, stop, nr_to_write, "Wrote");
out_clean:
hib_finish_batch(&hb);
if (crc) {
if (crc->thr)
kthread_stop(crc->thr);
kfree(crc);
}
if (data) {
for (thr = 0; thr < nr_threads; thr++)
if (data[thr].thr)
@@ -1122,15 +1058,19 @@ struct dec_data {
size_t cmp_len; /* compressed length */
unsigned char unc[LZO_UNC_SIZE]; /* uncompressed buffer */
unsigned char cmp[LZO_CMP_SIZE]; /* compressed buffer */
int crc32_err;
};
/**
* Deompression function that runs in its own thread.
* Deompression and crc32 function that runs in its own thread.
*/
static int lzo_decompress_threadfn(void *data)
{
struct dec_data *d = data;
ktime_t start = 0;
ktime_t total = 0;
u32 unc_crc32;
pr_info("decompress thread on core %d\n",smp_processor_id());
while (1) {
wait_event(d->go, atomic_read(&d->ready) ||
kthread_should_stop());
@@ -1142,10 +1082,16 @@ static int lzo_decompress_threadfn(void *data)
break;
}
atomic_set(&d->ready, 0);
start = ktime_get();
d->unc_len = LZO_UNC_SIZE;
d->ret = lzo1x_decompress_safe(d->cmp + LZO_HEADER, d->cmp_len,
d->unc, &d->unc_len);
unc_crc32 = crc32_le(0,d->cmp + LZO_HEADER, d->cmp_len);
if(unc_crc32 != get_header_crc32((struct hib_lzo_header *)&d->cmp) ) {
d->crc32_err++;
}
total += ktime_sub(ktime_get(), start);
if (clean_pages_on_decompress)
flush_icache_range((unsigned long)d->unc,
(unsigned long)d->unc + d->unc_len);
@@ -1153,6 +1099,7 @@ static int lzo_decompress_threadfn(void *data)
atomic_set(&d->stop, 1);
wake_up(&d->done);
}
pr_info("Deompression and crc32 took %lldms\n",ktime_to_ms(total));
return 0;
}
@@ -1172,6 +1119,8 @@ static int load_image_lzo(struct swap_map_handle *handle,
struct hib_bio_batch hb;
ktime_t start;
ktime_t stop;
ktime_t disk_start;
ktime_t disk_total = 0;
unsigned nr_pages;
size_t off;
unsigned i, thr, run_threads, nr_threads;
@@ -1180,7 +1129,8 @@ static int load_image_lzo(struct swap_map_handle *handle,
unsigned long read_pages = 0;
unsigned char **page = NULL;
struct dec_data *data = NULL;
struct crc_data *crc = NULL;
volatile u32 crc32_result[LZO_THREADS];
int crc_err = 0;
hib_init_batch(&hb);
@@ -1207,13 +1157,6 @@ static int load_image_lzo(struct swap_map_handle *handle,
for (thr = 0; thr < nr_threads; thr++)
memset(&data[thr], 0, offsetof(struct dec_data, go));
crc = kmalloc(sizeof(*crc), GFP_KERNEL);
if (!crc) {
pr_err("Failed to allocate crc\n");
ret = -ENOMEM;
goto out_clean;
}
memset(crc, 0, offsetof(struct crc_data, go));
clean_pages_on_decompress = true;
@@ -1223,7 +1166,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
for (thr = 0; thr < nr_threads; thr++) {
init_waitqueue_head(&data[thr].go);
init_waitqueue_head(&data[thr].done);
data[thr].crc32_err = 0;
data[thr].thr = kthread_run(lzo_decompress_threadfn,
&data[thr],
"image_decompress/%u", thr);
@@ -1235,27 +1178,6 @@ static int load_image_lzo(struct swap_map_handle *handle,
}
}
/*
* Start the CRC32 thread.
*/
init_waitqueue_head(&crc->go);
init_waitqueue_head(&crc->done);
handle->crc32 = 0;
crc->crc32 = &handle->crc32;
for (thr = 0; thr < nr_threads; thr++) {
crc->unc[thr] = data[thr].unc;
crc->unc_len[thr] = &data[thr].unc_len;
}
crc->thr = kthread_run(crc32_threadfn, crc, "image_crc32");
if (IS_ERR(crc->thr)) {
crc->thr = NULL;
pr_err("Cannot start CRC32 thread\n");
ret = -ENOMEM;
goto out_clean;
}
/*
* Set the number of pages for read buffering.
* This is complete guesswork, because we'll only know the real
@@ -1286,7 +1208,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
}
want = ring_size = i;
pr_info("Using %u thread(s) for decompression\n", nr_threads);
pr_info("Using %u thread(s) for decompression & crc\n", nr_threads);
pr_info("Loading and decompressing image data (%u pages)...\n",
nr_to_read);
m = nr_to_read / 10;
@@ -1300,6 +1222,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
goto out_finish;
for(;;) {
disk_start = ktime_get();
for (i = 0; !eof && i < want; i++) {
ret = swap_read_page(handle, page[ring], &hb);
if (ret) {
@@ -1329,6 +1252,9 @@ static int load_image_lzo(struct swap_map_handle *handle,
break;
ret = hib_wait_io(&hb);
disk_total += ktime_sub(ktime_get(), disk_start);
disk_start = ktime_get();
pr_info(" asked %d wait disk io took %lldms\n",asked,ktime_to_ms(disk_total));
if (ret)
goto out_finish;
have += asked;
@@ -1337,12 +1263,6 @@ static int load_image_lzo(struct swap_map_handle *handle,
eof = 2;
}
if (crc->run_threads) {
wait_event(crc->done, atomic_read(&crc->stop));
atomic_set(&crc->stop, 0);
crc->run_threads = 0;
}
for (thr = 0; have && thr < nr_threads; thr++) {
data[thr].cmp_len = *(size_t *)page[pg];
if (unlikely(!data[thr].cmp_len ||
@@ -1390,7 +1310,7 @@ static int load_image_lzo(struct swap_map_handle *handle,
if (eof)
eof = 2;
}
disk_total += ktime_sub(ktime_get(), disk_start);
for (run_threads = thr, thr = 0; thr < run_threads; thr++) {
wait_event(data[thr].done,
atomic_read(&data[thr].stop));
@@ -1423,23 +1343,17 @@ static int load_image_lzo(struct swap_map_handle *handle,
ret = snapshot_write_next(snapshot);
if (ret <= 0) {
crc->run_threads = thr + 1;
atomic_set(&crc->ready, 1);
wake_up(&crc->go);
goto out_finish;
}
}
}
crc->run_threads = thr;
atomic_set(&crc->ready, 1);
wake_up(&crc->go);
}
out_finish:
if (crc->run_threads) {
wait_event(crc->done, atomic_read(&crc->stop));
atomic_set(&crc->stop, 0);
for (thr = 0;thr < nr_threads; thr++) {
crc_err += data[thr].crc32_err;
}
stop = ktime_get();
if (!ret) {
@@ -1449,23 +1363,20 @@ out_finish:
ret = -ENODATA;
if (!ret) {
if (swsusp_header->flags & SF_CRC32_MODE) {
if(handle->crc32 != swsusp_header->crc32) {
if(crc_err) {
pr_err("Invalid image CRC32!\n");
ret = -ENODATA;
}
}
}
}
pr_info("Additonal wait disk io took %lldms\n",ktime_to_ms(disk_total));
swsusp_show_speed(start, stop, nr_to_read, "Read");
out_clean:
hib_finish_batch(&hb);
for (i = 0; i < ring_size; i++)
free_page((unsigned long)page[i]);
if (crc) {
if (crc->thr)
kthread_stop(crc->thr);
kfree(crc);
}
if (data) {
for (thr = 0; thr < nr_threads; thr++)
if (data[thr].thr)
@@ -1562,11 +1473,13 @@ int swsusp_check(void)
swsusp_can_retry = true;
else
swsusp_can_retry = false;
memcpy(swsusp_header->sig, swsusp_header->orig_sig, 10);
/* Reset swap signature now */
error = hib_submit_io(REQ_OP_WRITE, REQ_SYNC,
swsusp_resume_block,
swsusp_header, NULL);
} else {
error = -EINVAL;
}

View File

@@ -6854,6 +6854,17 @@ void __init ftrace_free_init_mem(void)
ftrace_free_mem(NULL, start, end);
}
static bool noftrace_init = false;
/* noftrace bootargs: for option not init ftrace*/
static int __init noftrace_setup(char *str)
{
noftrace_init = true;
return 1;
}
__setup("noftrace", noftrace_setup);
void __init ftrace_init(void)
{
extern unsigned long __start_mcount_loc[];
@@ -6861,6 +6872,9 @@ void __init ftrace_init(void)
unsigned long count, flags;
int ret;
if(noftrace_init)
goto failed;
local_irq_save(flags);
ret = ftrace_dyn_arch_init();
local_irq_restore(flags);

View File

@@ -184,6 +184,16 @@ static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;
static char *default_bootup_tracer;
static bool allocate_snapshot;
static bool notrace_init;
/* notrace bootargs: for option not init trace*/
static int __init notrace_setup(char *str)
{
notrace_init = 1;
return 1;
}
__setup("notrace", notrace_setup);
static int __init set_cmdline_ftrace(char *str)
{
@@ -9170,6 +9180,8 @@ static __init int tracer_init_tracefs(void)
{
int ret;
if(notrace_init)
return 0;
trace_access_lock_init();
ret = tracing_init_dentry();