On Sat, Mar 06, 2021 at 02:20:34AM +0000, Luis Chamberlain wrote: > The zram driver makes use of cpu hotplug multistate support, > whereby it associates a zram compression stream per CPU. To > support CPU hotplug multistate a callback enabled to allow > the driver to do what it needs when a CPU hotplugs. > > It is however currently possible to end up removing the > zram driver callback prior to removing the zram compression > streams per CPU. This would leave these compression streams > hanging. > > We need to fix ordering for driver load / removal, zram > device additions, in light of the driver's use of cpu > hotplug multistate. Since the zram driver exposes many > sysfs attribute which can also muck with the comrpession > streams this also means we can hit page faults today easily. Hi Luis, First of all, thanks for reporting the ancient bugs. Looks like you found several bugs and I am trying to digest them from your description to understand more clear. I need to ask stupid questions, first. If I understand correctly, bugs you found were related to module unloading race while the zram are still working. If so, couldn't we fix the bug like this(it's not a perfect patch but just wanted to show close module unloading race)? (I might miss other pieces here. Let me know. Thanks!) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index a711a2e2a794..646ae9e0b710 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1696,6 +1696,8 @@ static void zram_reset_device(struct zram *zram) return; } + module_put(THIS_MODULE); + comp = zram->comp; disksize = zram->disksize; zram->disksize = 0; @@ -1744,13 +1746,19 @@ static ssize_t disksize_store(struct device *dev, goto out_free_meta; } + if (!try_module_get(THIS_MODULE)) + goto out_free_zcomp; + zram->comp = comp; zram->disksize = disksize; + set_capacity_and_notify(zram->disk, zram->disksize >> SECTOR_SHIFT); up_write(&zram->init_lock); return len; +out_free_zcomp: + zcomp_destroy(comp); out_free_meta: zram_meta_free(zram, disksize); out_unlock: