Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PM: hibernate: dynamically allocate crc->unc_len/unc for configurable threads

Convert crc->unc_len and crc->unc from fixed-size arrays to dynamically
allocated arrays, sized according to the actual number of threads selected
at runtime. This removes the fixed limit imposed by CMP_THREADS.

Signed-off-by: Xueqin Luo <luoxueqin@kylinos.cn>
Link: https://patch.msgid.link/b5db63bb95729482d2649b12d3a11cb7547b7fcc.1761046167.git.luoxueqin@kylinos.cn
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Xueqin Luo and committed by
Rafael J. Wysocki
e114e2eb d3db87f8

+44 -14
+44 -14
kernel/power/swap.c
··· 585 585 wait_queue_head_t go; /* start crc update */ 586 586 wait_queue_head_t done; /* crc update done */ 587 587 u32 *crc32; /* points to handle's crc32 */ 588 - size_t *unc_len[CMP_THREADS]; /* uncompressed lengths */ 589 - unsigned char *unc[CMP_THREADS]; /* uncompressed data */ 588 + size_t **unc_len; /* uncompressed lengths */ 589 + unsigned char **unc; /* uncompressed data */ 590 590 }; 591 + 592 + static struct crc_data *alloc_crc_data(int nr_threads) 593 + { 594 + struct crc_data *crc; 595 + 596 + crc = kzalloc(sizeof(*crc), GFP_KERNEL); 597 + if (!crc) 598 + return NULL; 599 + 600 + crc->unc = kcalloc(nr_threads, sizeof(*crc->unc), GFP_KERNEL); 601 + if (!crc->unc) 602 + goto err_free_crc; 603 + 604 + crc->unc_len = kcalloc(nr_threads, sizeof(*crc->unc_len), GFP_KERNEL); 605 + if (!crc->unc_len) 606 + goto err_free_unc; 607 + 608 + return crc; 609 + 610 + err_free_unc: 611 + kfree(crc->unc); 612 + err_free_crc: 613 + kfree(crc); 614 + return NULL; 615 + } 616 + 617 + static void free_crc_data(struct crc_data *crc) 618 + { 619 + if (!crc) 620 + return; 621 + 622 + if (crc->thr) 623 + kthread_stop(crc->thr); 624 + 625 + kfree(crc->unc_len); 626 + kfree(crc->unc); 627 + kfree(crc); 628 + } 591 629 592 630 /* 593 631 * CRC32 update function that runs in its own thread. ··· 757 719 goto out_clean; 758 720 } 759 721 760 - crc = kzalloc(sizeof(*crc), GFP_KERNEL); 722 + crc = alloc_crc_data(nr_threads); 761 723 if (!crc) { 762 724 pr_err("Failed to allocate crc\n"); 763 725 ret = -ENOMEM; ··· 923 885 924 886 out_clean: 925 887 hib_finish_batch(&hb); 926 - if (crc) { 927 - if (crc->thr) 928 - kthread_stop(crc->thr); 929 - kfree(crc); 930 - } 888 + free_crc_data(crc); 931 889 if (data) { 932 890 for (thr = 0; thr < nr_threads; thr++) { 933 891 if (data[thr].thr) ··· 1273 1239 goto out_clean; 1274 1240 } 1275 1241 1276 - crc = kzalloc(sizeof(*crc), GFP_KERNEL); 1242 + crc = alloc_crc_data(nr_threads); 1277 1243 if (!crc) { 1278 1244 pr_err("Failed to allocate crc\n"); 1279 1245 ret = -ENOMEM; ··· 1540 1506 hib_finish_batch(&hb); 1541 1507 for (i = 0; i < ring_size; i++) 1542 1508 free_page((unsigned long)page[i]); 1543 - if (crc) { 1544 - if (crc->thr) 1545 - kthread_stop(crc->thr); 1546 - kfree(crc); 1547 - } 1509 + free_crc_data(crc); 1548 1510 if (data) { 1549 1511 for (thr = 0; thr < nr_threads; thr++) { 1550 1512 if (data[thr].thr)