diff options
Diffstat (limited to 'block/blk-cgroup.c')
| -rw-r--r-- | block/blk-cgroup.c | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b1231524a097..2d4d7d6d9ae9 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
| @@ -31,7 +31,7 @@ static LIST_HEAD(all_q_list); | |||
| 31 | struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; | 31 | struct blkio_cgroup blkio_root_cgroup = { .cfq_weight = 2 * CFQ_WEIGHT_DEFAULT }; |
| 32 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); | 32 | EXPORT_SYMBOL_GPL(blkio_root_cgroup); |
| 33 | 33 | ||
| 34 | static struct blkio_policy_type *blkio_policy[BLKIO_NR_POLICIES]; | 34 | static struct blkio_policy_type *blkio_policy[BLKCG_MAX_POLS]; |
| 35 | 35 | ||
| 36 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) | 36 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) |
| 37 | { | 37 | { |
| @@ -67,7 +67,7 @@ static void blkg_free(struct blkio_group *blkg) | |||
| 67 | if (!blkg) | 67 | if (!blkg) |
| 68 | return; | 68 | return; |
| 69 | 69 | ||
| 70 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 70 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
| 71 | struct blkio_policy_type *pol = blkio_policy[i]; | 71 | struct blkio_policy_type *pol = blkio_policy[i]; |
| 72 | struct blkg_policy_data *pd = blkg->pd[i]; | 72 | struct blkg_policy_data *pd = blkg->pd[i]; |
| 73 | 73 | ||
| @@ -107,7 +107,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, | |||
| 107 | blkg->refcnt = 1; | 107 | blkg->refcnt = 1; |
| 108 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); | 108 | cgroup_path(blkcg->css.cgroup, blkg->path, sizeof(blkg->path)); |
| 109 | 109 | ||
| 110 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 110 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
| 111 | struct blkio_policy_type *pol = blkio_policy[i]; | 111 | struct blkio_policy_type *pol = blkio_policy[i]; |
| 112 | struct blkg_policy_data *pd; | 112 | struct blkg_policy_data *pd; |
| 113 | 113 | ||
| @@ -127,7 +127,7 @@ static struct blkio_group *blkg_alloc(struct blkio_cgroup *blkcg, | |||
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | /* invoke per-policy init */ | 129 | /* invoke per-policy init */ |
| 130 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 130 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
| 131 | struct blkio_policy_type *pol = blkio_policy[i]; | 131 | struct blkio_policy_type *pol = blkio_policy[i]; |
| 132 | 132 | ||
| 133 | if (pol) | 133 | if (pol) |
| @@ -320,7 +320,7 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) | |||
| 320 | * anyway. If you get hit by a race, retry. | 320 | * anyway. If you get hit by a race, retry. |
| 321 | */ | 321 | */ |
| 322 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { | 322 | hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { |
| 323 | for (i = 0; i < BLKIO_NR_POLICIES; i++) { | 323 | for (i = 0; i < BLKCG_MAX_POLS; i++) { |
| 324 | struct blkio_policy_type *pol = blkio_policy[i]; | 324 | struct blkio_policy_type *pol = blkio_policy[i]; |
| 325 | 325 | ||
| 326 | if (pol && pol->ops.blkio_reset_group_stats_fn) | 326 | if (pol && pol->ops.blkio_reset_group_stats_fn) |
| @@ -729,46 +729,75 @@ struct cgroup_subsys blkio_subsys = { | |||
| 729 | }; | 729 | }; |
| 730 | EXPORT_SYMBOL_GPL(blkio_subsys); | 730 | EXPORT_SYMBOL_GPL(blkio_subsys); |
| 731 | 731 | ||
| 732 | void blkio_policy_register(struct blkio_policy_type *blkiop) | 732 | /** |
| 733 | * blkio_policy_register - register a blkcg policy | ||
| 734 | * @blkiop: blkcg policy to register | ||
| 735 | * | ||
| 736 | * Register @blkiop with blkcg core. Might sleep and @blkiop may be | ||
| 737 | * modified on successful registration. Returns 0 on success and -errno on | ||
| 738 | * failure. | ||
| 739 | */ | ||
| 740 | int blkio_policy_register(struct blkio_policy_type *blkiop) | ||
| 733 | { | 741 | { |
| 734 | struct request_queue *q; | 742 | struct request_queue *q; |
| 743 | int i, ret; | ||
| 735 | 744 | ||
| 736 | mutex_lock(&blkcg_pol_mutex); | 745 | mutex_lock(&blkcg_pol_mutex); |
| 737 | 746 | ||
| 738 | blkcg_bypass_start(); | 747 | /* find an empty slot */ |
| 748 | ret = -ENOSPC; | ||
| 749 | for (i = 0; i < BLKCG_MAX_POLS; i++) | ||
| 750 | if (!blkio_policy[i]) | ||
| 751 | break; | ||
| 752 | if (i >= BLKCG_MAX_POLS) | ||
| 753 | goto out_unlock; | ||
| 739 | 754 | ||
| 740 | BUG_ON(blkio_policy[blkiop->plid]); | 755 | /* register and update blkgs */ |
| 741 | blkio_policy[blkiop->plid] = blkiop; | 756 | blkiop->plid = i; |
| 757 | blkio_policy[i] = blkiop; | ||
| 758 | |||
| 759 | blkcg_bypass_start(); | ||
| 742 | list_for_each_entry(q, &all_q_list, all_q_node) | 760 | list_for_each_entry(q, &all_q_list, all_q_node) |
| 743 | update_root_blkg_pd(q, blkiop); | 761 | update_root_blkg_pd(q, blkiop); |
| 744 | |||
| 745 | blkcg_bypass_end(); | 762 | blkcg_bypass_end(); |
| 746 | 763 | ||
| 764 | /* everything is in place, add intf files for the new policy */ | ||
| 747 | if (blkiop->cftypes) | 765 | if (blkiop->cftypes) |
| 748 | WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); | 766 | WARN_ON(cgroup_add_cftypes(&blkio_subsys, blkiop->cftypes)); |
| 749 | 767 | ret = 0; | |
| 768 | out_unlock: | ||
| 750 | mutex_unlock(&blkcg_pol_mutex); | 769 | mutex_unlock(&blkcg_pol_mutex); |
| 770 | return ret; | ||
| 751 | } | 771 | } |
| 752 | EXPORT_SYMBOL_GPL(blkio_policy_register); | 772 | EXPORT_SYMBOL_GPL(blkio_policy_register); |
| 753 | 773 | ||
| 774 | /** | ||
| 775 | * blkiop_policy_unregister - unregister a blkcg policy | ||
| 776 | * @blkiop: blkcg policy to unregister | ||
| 777 | * | ||
| 778 | * Undo blkio_policy_register(@blkiop). Might sleep. | ||
| 779 | */ | ||
| 754 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) | 780 | void blkio_policy_unregister(struct blkio_policy_type *blkiop) |
| 755 | { | 781 | { |
| 756 | struct request_queue *q; | 782 | struct request_queue *q; |
| 757 | 783 | ||
| 758 | mutex_lock(&blkcg_pol_mutex); | 784 | mutex_lock(&blkcg_pol_mutex); |
| 759 | 785 | ||
| 786 | if (WARN_ON(blkio_policy[blkiop->plid] != blkiop)) | ||
| 787 | goto out_unlock; | ||
| 788 | |||
| 789 | /* kill the intf files first */ | ||
| 760 | if (blkiop->cftypes) | 790 | if (blkiop->cftypes) |
| 761 | cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); | 791 | cgroup_rm_cftypes(&blkio_subsys, blkiop->cftypes); |
| 762 | 792 | ||
| 763 | blkcg_bypass_start(); | 793 | /* unregister and update blkgs */ |
| 764 | |||
| 765 | BUG_ON(blkio_policy[blkiop->plid] != blkiop); | ||
| 766 | blkio_policy[blkiop->plid] = NULL; | 794 | blkio_policy[blkiop->plid] = NULL; |
| 767 | 795 | ||
| 796 | blkcg_bypass_start(); | ||
| 768 | list_for_each_entry(q, &all_q_list, all_q_node) | 797 | list_for_each_entry(q, &all_q_list, all_q_node) |
| 769 | update_root_blkg_pd(q, blkiop); | 798 | update_root_blkg_pd(q, blkiop); |
| 770 | blkcg_bypass_end(); | 799 | blkcg_bypass_end(); |
| 771 | 800 | out_unlock: | |
| 772 | mutex_unlock(&blkcg_pol_mutex); | 801 | mutex_unlock(&blkcg_pol_mutex); |
| 773 | } | 802 | } |
| 774 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); | 803 | EXPORT_SYMBOL_GPL(blkio_policy_unregister); |
