Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions block/bfq-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ static void bfqg_stats_xfer_dead(struct bfq_group *bfqg)

parent = bfqg_parent(bfqg);

lockdep_assert_held(&bfqg_to_blkg(bfqg)->q->queue_lock);
lockdep_assert_held(&bfqg_to_blkg(bfqg)->q->blkcg_mutex);

if (unlikely(!parent))
return;
Expand Down Expand Up @@ -604,6 +604,16 @@ static void bfq_link_bfqg(struct bfq_data *bfqd, struct bfq_group *bfqg)
}
}

static void bfq_bio_update_blkg(struct bio *bio, struct blkcg_gq *blkg)
{
if (bio->bi_blkg == blkg)
return;

blkg_get(blkg);
blkg_put(bio->bi_blkg);
bio->bi_blkg = blkg;
}

struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
{
struct blkcg_gq *blkg = bio->bi_blkg;
Expand All @@ -616,13 +626,13 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
}
bfqg = blkg_to_bfqg(blkg);
if (bfqg->pd.online) {
bio_associate_blkg_from_css(bio, &blkg->blkcg->css);
bfq_bio_update_blkg(bio, blkg);
return bfqg;
}
blkg = blkg->parent;
}
bio_associate_blkg_from_css(bio,
&bfqg_to_blkg(bfqd->root_group)->blkcg->css);
blkg = bfqg_to_blkg(bfqd->root_group);
bfq_bio_update_blkg(bio, blkg);
return bfqd->root_group;
}

Expand Down Expand Up @@ -874,7 +884,7 @@ static void bfq_reparent_active_queues(struct bfq_data *bfqd,
* and reparent its children entities.
* @pd: descriptor of the policy going offline.
*
* blkio already grabs the queue_lock for us, so no need to use
* blkio already grabs the blkcg_mutex for us, so no need to use
* RCU-based magic
*/
static void bfq_pd_offline(struct blkg_policy_data *pd)
Expand Down Expand Up @@ -947,8 +957,7 @@ void bfq_end_wr_async(struct bfq_data *bfqd)
struct blkcg_gq *blkg;

mutex_lock(&q->blkcg_mutex);
spin_lock_irq(&q->queue_lock);
spin_lock(&bfqd->lock);
spin_lock_irq(&bfqd->lock);

list_for_each_entry(blkg, &q->blkg_list, q_node) {
struct bfq_group *bfqg = blkg_to_bfqg(blkg);
Expand All @@ -957,8 +966,7 @@ void bfq_end_wr_async(struct bfq_data *bfqd)
}
bfq_end_wr_async_queues(bfqd, bfqd->root_group);

spin_unlock(&bfqd->lock);
spin_unlock_irq(&q->queue_lock);
spin_unlock_irq(&bfqd->lock);
mutex_unlock(&q->blkcg_mutex);
}

Expand Down
50 changes: 42 additions & 8 deletions block/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table,
bio->bi_blkg = NULL;
bio->issue_time_ns = 0;
if (bdev)
bio_associate_blkg(bio);
bio_associate_blkg(bio, false);
#ifdef CONFIG_BLK_CGROUP_IOCOST
bio->bi_iocost_cost = 0;
#endif
Expand All @@ -259,6 +259,20 @@ void bio_init(struct bio *bio, struct block_device *bdev, struct bio_vec *table,
}
EXPORT_SYMBOL(bio_init);

static bool bio_init_nowait(struct bio *bio, struct block_device *bdev,
struct bio_vec *table, unsigned short max_vecs, blk_opf_t opf)
{
bio_init(bio, NULL, table, max_vecs, opf);
if (bdev) {
bio_set_dev_no_blkg(bio, bdev);
if (bio_associate_blkg(bio, true))
return true;
bio_uninit(bio);
return false;
}
return true;
}

/**
* bio_reset - reinitialize a bio
* @bio: bio to reset
Expand All @@ -281,7 +295,7 @@ void bio_reset(struct bio *bio, struct block_device *bdev, blk_opf_t opf)
bio->bi_io_vec = bv;
bio->bi_bdev = bdev;
if (bio->bi_bdev)
bio_associate_blkg(bio);
bio_associate_blkg(bio, false);
bio->bi_opf = opf;
}
EXPORT_SYMBOL(bio_reset);
Expand Down Expand Up @@ -599,12 +613,25 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
}
}

if (nr_vecs && nr_vecs <= BIO_INLINE_VECS)
bio_init_inline(bio, bdev, nr_vecs, opf);
else
bio_init(bio, bdev, bvecs, nr_vecs, opf);
if (nr_vecs && nr_vecs <= BIO_INLINE_VECS) {
bvecs = bio_inline_vecs(bio);
if (gfpflags_allow_blocking(saved_gfp))
bio_init(bio, bdev, bvecs, nr_vecs, opf);
else if (!bio_init_nowait(bio, bdev, bvecs, nr_vecs, opf))
goto fail_free_bio;
} else {
if (gfpflags_allow_blocking(saved_gfp))
bio_init(bio, bdev, bvecs, nr_vecs, opf);
else if (!bio_init_nowait(bio, bdev, bvecs, nr_vecs, opf))
goto fail_free_bio;
}
bio->bi_pool = bs;
return bio;

fail_free_bio:
bio->bi_pool = bs;
bio_put(bio);
return NULL;
}
EXPORT_SYMBOL(bio_alloc_bioset);

Expand Down Expand Up @@ -857,7 +884,9 @@ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
if (bio->bi_bdev == bio_src->bi_bdev &&
bio_flagged(bio_src, BIO_REMAPPED))
bio_set_flag(bio, BIO_REMAPPED);
bio_clone_blkg_association(bio, bio_src);
if (!bio_clone_blkg_association(bio, bio_src,
!gfpflags_allow_blocking(gfp)))
return -ENOMEM;
}

if (bio_crypt_clone(bio, bio_src, gfp) < 0)
Expand Down Expand Up @@ -913,9 +942,14 @@ EXPORT_SYMBOL(bio_alloc_clone);
int bio_init_clone(struct block_device *bdev, struct bio *bio,
struct bio *bio_src, gfp_t gfp)
{
bool blocking = gfpflags_allow_blocking(gfp);
int ret;

bio_init(bio, bdev, bio_src->bi_io_vec, 0, bio_src->bi_opf);
if (blocking)
bio_init(bio, bdev, bio_src->bi_io_vec, 0, bio_src->bi_opf);
else if (!bio_init_nowait(bio, bdev, bio_src->bi_io_vec, 0,
bio_src->bi_opf))
return -ENOMEM;
ret = __bio_clone(bio, bio_src, gfp);
if (ret)
bio_uninit(bio);
Expand Down
Loading
Loading