aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2015-08-18 17:55:09 -0400
committerJens Axboe <axboe@fb.com>2015-08-18 18:49:16 -0400
commit4c55f4f9ad3001ac1fefdd8d8ca7641d18558e23 (patch)
tree66be4a0f4881ba200b7e31e9f0efac8912ab0f21 /block
parentbc915e61cde25d0b429f536cec9e83039bf23504 (diff)
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>
Diffstat (limited to 'block')
-rw-r--r--block/blk-cgroup.c55
1 files changed, 21 insertions, 34 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index f91a4e09e0c9..9e9b0df339ee 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -1047,65 +1047,52 @@ EXPORT_SYMBOL_GPL(blkio_cgrp_subsys);
1047int blkcg_activate_policy(struct request_queue *q, 1047int blkcg_activate_policy(struct request_queue *q,
1048 const struct blkcg_policy *pol) 1048 const struct blkcg_policy *pol)
1049{ 1049{
1050 LIST_HEAD(pds); 1050 struct blkg_policy_data *pd_prealloc = NULL;
1051 struct blkcg_gq *blkg; 1051 struct blkcg_gq *blkg;
1052 struct blkg_policy_data *pd, *nd; 1052 int ret;
1053 int cnt = 0, ret;
1054 1053
1055 if (blkcg_policy_enabled(q, pol)) 1054 if (blkcg_policy_enabled(q, pol))
1056 return 0; 1055 return 0;
1057 1056
1058 /* count and allocate policy_data for all existing blkgs */
1059 blk_queue_bypass_start(q); 1057 blk_queue_bypass_start(q);
1060 spin_lock_irq(q->queue_lock); 1058pd_prealloc:
1061 list_for_each_entry(blkg, &q->blkg_list, q_node) 1059 if (!pd_prealloc) {
1062 cnt++; 1060 pd_prealloc = kzalloc_node(pol->pd_size, GFP_KERNEL, q->node);
1063 spin_unlock_irq(q->queue_lock); 1061 if (!pd_prealloc) {
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) {
1069 ret = -ENOMEM; 1062 ret = -ENOMEM;
1070 goto out_free; 1063 goto out_bypass_end;
1071 } 1064 }
1072 list_add_tail(&pd->alloc_node, &pds);
1073 } 1065 }
1074 1066
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 */
1079 spin_lock_irq(q->queue_lock); 1067 spin_lock_irq(q->queue_lock);
1080 1068
1081 list_for_each_entry(blkg, &q->blkg_list, q_node) { 1069 list_for_each_entry(blkg, &q->blkg_list, q_node) {
1082 if (WARN_ON(list_empty(&pds))) { 1070 struct blkg_policy_data *pd;
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);
1089 1071
1090 /* grab blkcg lock too while installing @pd on @blkg */ 1072 if (blkg->pd[pol->plid])
1091 spin_lock(&blkg->blkcg->lock); 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 }
1092 1082
1093 blkg->pd[pol->plid] = pd; 1083 blkg->pd[pol->plid] = pd;
1094 pd->blkg = blkg; 1084 pd->blkg = blkg;
1095 pd->plid = pol->plid; 1085 pd->plid = pol->plid;
1096 pol->pd_init_fn(blkg); 1086 pol->pd_init_fn(blkg);
1097
1098 spin_unlock(&blkg->blkcg->lock);
1099 } 1087 }
1100 1088
1101 __set_bit(pol->plid, q->blkcg_pols); 1089 __set_bit(pol->plid, q->blkcg_pols);
1102 ret = 0; 1090 ret = 0;
1103out_unlock: 1091
1104 spin_unlock_irq(q->queue_lock); 1092 spin_unlock_irq(q->queue_lock);
1105out_free: 1093out_bypass_end:
1106 blk_queue_bypass_end(q); 1094 blk_queue_bypass_end(q);
1107 list_for_each_entry_safe(pd, nd, &pds, alloc_node) 1095 kfree(pd_prealloc);
1108 kfree(pd);
1109 return ret; 1096 return ret;
1110} 1097}
1111EXPORT_SYMBOL_GPL(blkcg_activate_policy); 1098EXPORT_SYMBOL_GPL(blkcg_activate_policy);