zram: Fix kernel panic revolving around zram_free_page()

[1] causes a kernel panic at init with the following logs

<1>[    0.401821] Unable to handle kernel paging request at virtual address 08000008
<1>[    0.401828] Mem abort info:
<1>[    0.401832]   Exception class = DABT (current EL), IL = 32 bits
<1>[    0.401834]   SET = 0, FnV = 0
<1>[    0.401836]   EA = 0, S1PTW = 0
<1>[    0.401840]   FSC = 5
<1>[    0.401841] Data abort info:
<1>[    0.401844]   ISV = 0, ISS = 0x00000005
<1>[    0.401847]   CM = 0, WnR = 0
<1>[    0.401850] [0000000008000008] user address but active_mm is swapper
<0>[    0.401854] Internal error: Oops: 96000005 [#1] PREEMPT SMP
<0>[    0.401859] Process swapper/0 (pid: 1, stack limit = 0x        (ptrval))
<4>[    0.401864] CPU: 6 PID: 1 Comm: swapper/0 Tainted: G S              4.14.255StormBreaker-X10 #1
<4>[    0.401868] Hardware name: Qualcomm Technologies, Inc. SDMMAGPIE PM6150 IDP (DT)
<4>[    0.401873] task:         (ptrval) task.stack:         (ptrval)
<4>[    0.401887] pc : zram_free_page+0x28/0x1d0
<4>[    0.401891] lr : zram_add+0x94/0x170
<4>[    0.401893] sp : ffffff801005bc00 pstate : 80800045
<4>[    0.401896] x29: ffffff801005bc10 x28: 0000000000000000
<4>[    0.401899] x27: 0000000000000000 x26: 0000000000000000
<4>[    0.401903] x25: 0000000000000000 x24: ffffff94a02d1ae0
<4>[    0.401906] x23: ffffff94a0705000 x22: 0000000000000000
<4>[    0.401909] x21: ffffff94a047c000 x20: 0000000000000000
<4>[    0.401911] x19: ffffff94a047c180 x18: 0000000000000000
<4>[    0.401914] x17: 0000000000000000 x16: 00000000000000e4
<4>[    0.401917] x15: ffffff949fa318d4 x14: 0000000000000000
<4>[    0.401919] x13: 00b0406fdcffffff x12: 00000047dc60b000
<4>[    0.401922] x11: 0000000000000000 x10: 0000000008000000
<4>[    0.401924] x9 : 0000000008000000 x8 : 0000000008000000
<4>[    0.401927] x7 : 0000000000000000 x6 : 000000000000003f
<4>[    0.401929] x5 : 0000000000000000 x4 : 0000000000000000
<4>[    0.401931] x3 : ffffffdc6fb1f800 x2 : ffffff94a047c188
<4>[    0.401934] x1 : 0000000000000000 x0 : ffffff94a047c180
<4>[    0.401938]
<4>[    0.401938] PC: 0xffffff949ebf6f88:
<4>[    0.401940] 6f88  f9001a7f b9004a7f f9001e68 f9002268 f9002a7f b9004e7f d10103ff f9400008
<4>[    0.401947] 6fa8  a9034ff4 aa0103f4 a90257f6 aa0003f3 92407c36 8b34510a a9017bfd 910043fd
<4>[    0.401953] 6fc8  f8408d49 37e80289 d37ceed5 37e00329 8b16110a 9100214a 37d00489 37c807a9
<4>[    0.401959] 6fe8  f8756901 b4000a81 f9400660 97e18683 f9400268 9101a261 8b161108 f9400508
<4>[    0.401965]
<4>[    0.401965] LR: 0xffffff949ebf6e84:
<4>[    0.401968] 6e84  910023e1 72a02802 12b00003 a900ffff 9438d8af aa0003f4 b140041f 54000448
<4>[    0.401974] 6ea4  d000c420 f94013e1 91060000 aa1403e2 aa1303e3 aa1f03e4 aa1f03e5 9438d440
<4>[    0.401979] 6ec4  f94013e8 b4000248 b9400be9 1200152a 52800029 53067d4b 9aca212a 8b2b4d0b
<4>[    0.401985] 6ee4  f941156c ea0c015f 540001c0 9108a16b 8a2a018a f900016a f941150a b500012a
<4>[    0.401991]
<4>[    0.401991] SP: 0xffffff801005bbc0:
<4>[    0.401993] bbc0  9ebf6fc8 ffffff94 80800045 00000000 00000000 014002c0 7547d700 ffffffdc
<4>[    0.401998] bbe0  ffffffff ffffffff 9ebf6e98 ffffff94 1005bc10 ffffff80 9ebf6fc8 ffffff94
<4>[    0.402004] bc00  00000000 00000000 00000000 00000000 1005bc70 ffffff80 9ebf6ec4 ffffff94
<4>[    0.402009] bc20  7547d700 ffffffdc a047c000 ffffff94 00000000 00000000 6fb1f800 ffffffdc
<4>[    0.402014]
<4>[    0.402017] Call trace:
<4>[    0.402020]  zram_free_page+0x28/0x1d0
<4>[    0.402023]  zram_add+0x94/0x170
<4>[    0.402028]  zram_init+0x11c/0x3a0
<4>[    0.402032]  do_one_initcall+0x1c0/0x210
<4>[    0.402035]  kernel_init_freeable+0x5cc/0x710
<4>[    0.402038]  kernel_init+0x10/0x280
<4>[    0.402044]  ret_from_fork+0x10/0x18
<0>[    0.402047] Code: 92407c36 8b34510a a9017bfd 910043fd (f8408d49)
<4>[    0.402050] ---[ end trace 4d61b66acb6a904c ]---
<0>[    0.403950] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
<0>[    0.403950]
<2>[    0.403957] SMP: stopping secondary CPUs
<3>[    1.004015] ipa ipa3_active_clients_panic_notifier:293
<3>[    1.004015] ---- Active Clients Table ----
<3>[    1.004015]
<3>[    1.004015] Total active clients count: 0
<3>[    1.004015]
<0>[    1.004020] Kernel Offset: 0x148e200000 from 0xffffff8010000000
<0>[    1.004024] CPU features: 0x11002228
<0>[    1.004026] Memory Limit: none

Tracing back zram_free_page() and zram_add() with GDB reveals that [1]{"BACKPORT: zram: convert to blk_alloc_disk/blk_cleanup_disk"} caused the panic.

[1]: 753eb019a7

Test: Reverted [1], compiled and it booted with Clang 14.0.0
Co-authored-by: Forenche <prahul2003@gmail.com>
Suggested-by: Jebaitedneko <Jebaitedneko@gmail.com>
Signed-off-by: Forenche <prahul2003@gmail.com>
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
Cyber Knight 2021-11-22 12:44:14 +08:00 committed by azrim
parent 83edc9f553
commit 615a3c653a
No known key found for this signature in database
GPG Key ID: 497F8FB059B45D1C

View File

@ -2039,22 +2039,29 @@ static int zram_add(void)
#ifdef CONFIG_ZRAM_WRITEBACK
spin_lock_init(&zram->wb_limit_lock);
#endif
blk_queue_make_request(queue, zram_make_request);
/* gendisk structure */
zram->disk = blk_alloc_disk(NUMA_NO_NODE);
if (!zram->disk) {
pr_err("Error allocating disk structure for device %d\n",
queue = blk_alloc_queue(GFP_KERNEL);
if (!queue) {
pr_err("Error allocating disk queue for device %d\n",
device_id);
ret = -ENOMEM;
goto out_free_idr;
}
blk_queue_make_request(queue, zram_make_request);
/* gendisk structure */
zram->disk = alloc_disk(1);
if (!zram->disk) {
pr_err("Error allocating disk structure for device %d\n",
device_id);
ret = -ENOMEM;
goto out_free_queue;
}
zram->disk->major = zram_major;
zram->disk->first_minor = device_id;
zram->disk->minors = 1;
zram->disk->fops = &zram_devops;
zram->disk->queue = queue;
zram->disk->private_data = zram;
snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
@ -2099,6 +2106,8 @@ static int zram_add(void)
pr_info("Added device: %s\n", zram->disk->disk_name);
return device_id;
out_free_queue:
blk_cleanup_queue(queue);
out_free_idr:
idr_remove(&zram_index_idr, device_id);
out_free_dev:
@ -2153,8 +2162,8 @@ static int zram_remove(struct zram *zram)
* anything allocated with disksize_store()
*/
zram_reset_device(zram);
blk_cleanup_disk(zram->disk);
blk_cleanup_queue(zram->disk->queue);
put_disk(zram->disk);
kfree(zram);
return 0;
}