|
@@ -182,6 +182,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
|
|
struct blkcg_gq *new_blkg)
|
|
|
{
|
|
|
struct blkcg_gq *blkg;
|
|
|
+ struct bdi_writeback_congested *wb_congested;
|
|
|
int i, ret;
|
|
|
|
|
|
WARN_ON_ONCE(!rcu_read_lock_held());
|
|
@@ -193,22 +194,30 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
|
|
goto err_free_blkg;
|
|
|
}
|
|
|
|
|
|
+ wb_congested = wb_congested_get_create(&q->backing_dev_info,
|
|
|
+ blkcg->css.id, GFP_ATOMIC);
|
|
|
+ if (!wb_congested) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto err_put_css;
|
|
|
+ }
|
|
|
+
|
|
|
/* allocate */
|
|
|
if (!new_blkg) {
|
|
|
new_blkg = blkg_alloc(blkcg, q, GFP_ATOMIC);
|
|
|
if (unlikely(!new_blkg)) {
|
|
|
ret = -ENOMEM;
|
|
|
- goto err_put_css;
|
|
|
+ goto err_put_congested;
|
|
|
}
|
|
|
}
|
|
|
blkg = new_blkg;
|
|
|
+ blkg->wb_congested = wb_congested;
|
|
|
|
|
|
/* link parent */
|
|
|
if (blkcg_parent(blkcg)) {
|
|
|
blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
|
|
|
if (WARN_ON_ONCE(!blkg->parent)) {
|
|
|
ret = -EINVAL;
|
|
|
- goto err_put_css;
|
|
|
+ goto err_put_congested;
|
|
|
}
|
|
|
blkg_get(blkg->parent);
|
|
|
}
|
|
@@ -245,6 +254,8 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
|
|
|
blkg_put(blkg);
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
+err_put_congested:
|
|
|
+ wb_congested_put(wb_congested);
|
|
|
err_put_css:
|
|
|
css_put(&blkcg->css);
|
|
|
err_free_blkg:
|
|
@@ -391,6 +402,8 @@ void __blkg_release_rcu(struct rcu_head *rcu_head)
|
|
|
if (blkg->parent)
|
|
|
blkg_put(blkg->parent);
|
|
|
|
|
|
+ wb_congested_put(blkg->wb_congested);
|
|
|
+
|
|
|
blkg_free(blkg);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(__blkg_release_rcu);
|