diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 00da55c6ec43..5b7a32293dc6 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -884,7 +884,11 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, parent = blkcg_parent(parent); } - /* Drop locks to do new blkg allocation with GFP_KERNEL. */ + /* + * Drop the spinlock to allocate the new blkg. rq_qos_mutex and + * blkcg_mutex stay held, and both are taken with the queue + * frozen elsewhere: GFP_NOIO. + */ spin_unlock_irq(&q->queue_lock); new_blkg = blkg_alloc(pos, disk, GFP_NOIO); @@ -893,7 +897,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, goto fail_exit; } - if (radix_tree_preload(GFP_KERNEL)) { + if (radix_tree_preload(GFP_NOIO)) { blkg_free(new_blkg); ret = -ENOMEM; goto fail_exit; @@ -1648,7 +1652,8 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol) if (!pd) { /* * GFP_NOWAIT failed. Free the existing one and - * prealloc for @blkg w/ GFP_KERNEL. + * prealloc for @blkg w/ GFP_NOIO: blkcg_mutex is held, + * and a bio based queue has not been frozen above. */ if (pinned_blkg) blkg_put(pinned_blkg); @@ -1660,7 +1665,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol) if (pd_prealloc) pol->pd_free_fn(pd_prealloc); pd_prealloc = pol->pd_alloc_fn(disk, blkg->blkcg, - GFP_KERNEL); + GFP_NOIO); if (pd_prealloc) goto retry; else diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 7b5d865d8c14..47bea7f31408 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2938,11 +2938,12 @@ static int blk_iocost_init(struct gendisk *disk) struct ioc *ioc; int i, cpu, ret; - ioc = kzalloc_obj(*ioc); + /* The caller holds rq_qos_mutex, which is taken with the queue frozen */ + ioc = kzalloc_obj(*ioc, GFP_NOIO); if (!ioc) return -ENOMEM; - ioc->pcpu_stat = alloc_percpu(struct ioc_pcpu_stat); + ioc->pcpu_stat = alloc_percpu_gfp(struct ioc_pcpu_stat, GFP_NOIO); if (!ioc->pcpu_stat) { kfree(ioc); return -ENOMEM; diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index c15b1aba606c..a3bd153c67be 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -761,7 +761,8 @@ static int blk_iolatency_init(struct gendisk *disk) struct blk_iolatency *blkiolat; int ret; - blkiolat = kzalloc_obj(*blkiolat); + /* The caller holds rq_qos_mutex, which is taken with the queue frozen */ + blkiolat = kzalloc_obj(*blkiolat, GFP_NOIO); if (!blkiolat) return -ENOMEM; diff --git a/block/blk-throttle.c b/block/blk-throttle.c index c46807a0faab..c5e26551956a 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1322,7 +1322,8 @@ static int blk_throtl_init(struct gendisk *disk) unsigned int memflags; int ret; - td = kzalloc_node(sizeof(*td), GFP_KERNEL, q->node); + /* The caller holds rq_qos_mutex, which is taken with the queue frozen */ + td = kzalloc_node(sizeof(*td), GFP_NOIO, q->node); if (!td) return -ENOMEM;