Skip to content

Commit 4c55f4f

Browse files
htejunaxboe
authored andcommitted
blkcg: restructure blkg_policy_data allocation in blkcg_activate_policy()
When a policy gets activated, it needs to allocate and install its policy data on all existing blkg's (blkcg_gq's). Because blkg iteration is protected by a spinlock, it currently counts the total number of blkg's in the system, allocates the matching number of policy data on a list and installs them during a single iteration. This can be simplified by using speculative GFP_NOWAIT allocations while iterating and falling back to a preallocated policy data on failure. If the preallocated one has already been consumed, it releases the lock, preallocate with GFP_KERNEL and then restarts the iteration. This can be a bit more expensive than before but policy activation is a very cold path and shouldn't matter. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent bc915e6 commit 4c55f4f

File tree

2 files changed

+21
-37
lines changed

2 files changed

+21
-37
lines changed

block/blk-cgroup.c

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,65 +1047,52 @@ EXPORT_SYMBOL_GPL(blkio_cgrp_subsys);
10471047
int blkcg_activate_policy(struct request_queue *q,
10481048
const struct blkcg_policy *pol)
10491049
{
1050-
LIST_HEAD(pds);
1050+
struct blkg_policy_data *pd_prealloc = NULL;
10511051
struct blkcg_gq *blkg;
1052-
struct blkg_policy_data *pd, *nd;
1053-
int cnt = 0, ret;
1052+
int ret;
10541053

10551054
if (blkcg_policy_enabled(q, pol))
10561055
return 0;
10571056

1058-
/* count and allocate policy_data for all existing blkgs */
10591057
blk_queue_bypass_start(q);
1060-
spin_lock_irq(q->queue_lock);
1061-
list_for_each_entry(blkg, &q->blkg_list, q_node)
1062-
cnt++;
1063-
spin_unlock_irq(q->queue_lock);
1064-
1065-
/* allocate per-blkg policy data for all existing blkgs */
1066-
while (cnt--) {
1067-
pd = kzalloc_node(pol->pd_size, GFP_KERNEL, q->node);
1068-
if (!pd) {
1058+
pd_prealloc:
1059+
if (!pd_prealloc) {
1060+
pd_prealloc = kzalloc_node(pol->pd_size, GFP_KERNEL, q->node);
1061+
if (!pd_prealloc) {
10691062
ret = -ENOMEM;
1070-
goto out_free;
1063+
goto out_bypass_end;
10711064
}
1072-
list_add_tail(&pd->alloc_node, &pds);
10731065
}
10741066

1075-
/*
1076-
* Install the allocated pds and cpds. With @q bypassing, no new blkg
1077-
* should have been created while the queue lock was dropped.
1078-
*/
10791067
spin_lock_irq(q->queue_lock);
10801068

10811069
list_for_each_entry(blkg, &q->blkg_list, q_node) {
1082-
if (WARN_ON(list_empty(&pds))) {
1083-
/* umm... this shouldn't happen, just abort */
1084-
ret = -ENOMEM;
1085-
goto out_unlock;
1086-
}
1087-
pd = list_first_entry(&pds, struct blkg_policy_data, alloc_node);
1088-
list_del_init(&pd->alloc_node);
1070+
struct blkg_policy_data *pd;
10891071

1090-
/* grab blkcg lock too while installing @pd on @blkg */
1091-
spin_lock(&blkg->blkcg->lock);
1072+
if (blkg->pd[pol->plid])
1073+
continue;
1074+
1075+
pd = kzalloc_node(pol->pd_size, GFP_NOWAIT, q->node);
1076+
if (!pd)
1077+
swap(pd, pd_prealloc);
1078+
if (!pd) {
1079+
spin_unlock_irq(q->queue_lock);
1080+
goto pd_prealloc;
1081+
}
10921082

10931083
blkg->pd[pol->plid] = pd;
10941084
pd->blkg = blkg;
10951085
pd->plid = pol->plid;
10961086
pol->pd_init_fn(blkg);
1097-
1098-
spin_unlock(&blkg->blkcg->lock);
10991087
}
11001088

11011089
__set_bit(pol->plid, q->blkcg_pols);
11021090
ret = 0;
1103-
out_unlock:
1091+
11041092
spin_unlock_irq(q->queue_lock);
1105-
out_free:
1093+
out_bypass_end:
11061094
blk_queue_bypass_end(q);
1107-
list_for_each_entry_safe(pd, nd, &pds, alloc_node)
1108-
kfree(pd);
1095+
kfree(pd_prealloc);
11091096
return ret;
11101097
}
11111098
EXPORT_SYMBOL_GPL(blkcg_activate_policy);

include/linux/blk-cgroup.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ struct blkg_policy_data {
8080
/* the blkg and policy id this per-policy data belongs to */
8181
struct blkcg_gq *blkg;
8282
int plid;
83-
84-
/* used during policy activation */
85-
struct list_head alloc_node;
8683
};
8784

8885
/*

0 commit comments

Comments
 (0)