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;
}

Reply via email to