Re: [PATCH] xfs: handle register_shrinker error
From: Tetsuo Handa
Date: Thu Nov 23 2017 - 11:17:50 EST
Michal Hocko wrote:
> Hmm, you are right. I have (blindly) followed the current code flow
> which is wrong as well. The following should do the trick. Should I
> split that into two patches?
Well, xfs_alloc_buftarg() needs to be more careful.
xfs_alloc_buftarg(
struct xfs_mount *mp,
struct block_device *bdev,
struct dax_device *dax_dev)
{
xfs_buftarg_t *btp;
btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS); // This is GFP_NOFS context. But...
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
btp->bt_daxdev = dax_dev;
if (xfs_setsize_buftarg_early(btp, bdev))
goto error;
if (list_lru_init(&btp->bt_lru)) // This is GFP_KERNEL context.
goto error;
if (percpu_counter_init(&btp->bt_io_count, 0, GFP_KERNEL)) // This is GFP_KERNEL context.
goto error; // Need to undo list_lru_init() before kmem_free().
btp->bt_shrinker.count_objects = xfs_buftarg_shrink_count;
btp->bt_shrinker.scan_objects = xfs_buftarg_shrink_scan;
btp->bt_shrinker.seeks = DEFAULT_SEEKS;
btp->bt_shrinker.flags = SHRINKER_NUMA_AWARE;
register_shrinker(&btp->bt_shrinker); // This is GFP_KERNEL context.
return btp;
error:
kmem_free(btp);
return NULL;
}