diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2010-09-15 17:06:36 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-09-16 02:42:58 -0400 |
commit | 7702e8f45b0a3bb262b9366c60beb5445758d94c (patch) | |
tree | bd61754827def804fe5a1f790f3eb303154df63d | |
parent | e43473b7f223ec866f7db273697e76c337c390f9 (diff) |
blk-cgroup: cgroup changes for IOPS limit support
o cgroup changes for IOPS throttling rules.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r-- | block/blk-cgroup.c | 139 | ||||
-rw-r--r-- | block/blk-cgroup.h | 13 |
2 files changed, 135 insertions, 17 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index aae8c930a6f8..20ce6f584e43 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -149,6 +149,27 @@ static inline void blkio_update_group_bps(struct blkio_group *blkg, u64 bps, | |||
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline void blkio_update_group_iops(struct blkio_group *blkg, | ||
153 | unsigned int iops, int fileid) | ||
154 | { | ||
155 | struct blkio_policy_type *blkiop; | ||
156 | |||
157 | list_for_each_entry(blkiop, &blkio_list, list) { | ||
158 | |||
159 | /* If this policy does not own the blkg, do not send updates */ | ||
160 | if (blkiop->plid != blkg->plid) | ||
161 | continue; | ||
162 | |||
163 | if (fileid == BLKIO_THROTL_read_iops_device | ||
164 | && blkiop->ops.blkio_update_group_read_iops_fn) | ||
165 | blkiop->ops.blkio_update_group_read_iops_fn(blkg, iops); | ||
166 | |||
167 | if (fileid == BLKIO_THROTL_write_iops_device | ||
168 | && blkiop->ops.blkio_update_group_write_iops_fn) | ||
169 | blkiop->ops.blkio_update_group_write_iops_fn(blkg,iops); | ||
170 | } | ||
171 | } | ||
172 | |||
152 | /* | 173 | /* |
153 | * Add to the appropriate stat variable depending on the request type. | 174 | * Add to the appropriate stat variable depending on the request type. |
154 | * This should be called with the blkg->stats_lock held. | 175 | * This should be called with the blkg->stats_lock held. |
@@ -630,7 +651,7 @@ static int blkio_policy_parse_and_set(char *buf, | |||
630 | { | 651 | { |
631 | char *s[4], *p, *major_s = NULL, *minor_s = NULL; | 652 | char *s[4], *p, *major_s = NULL, *minor_s = NULL; |
632 | int ret; | 653 | int ret; |
633 | unsigned long major, minor, temp; | 654 | unsigned long major, minor, temp, iops; |
634 | int i = 0; | 655 | int i = 0; |
635 | dev_t dev; | 656 | dev_t dev; |
636 | u64 bps; | 657 | u64 bps; |
@@ -692,13 +713,28 @@ static int blkio_policy_parse_and_set(char *buf, | |||
692 | newpn->val.weight = temp; | 713 | newpn->val.weight = temp; |
693 | break; | 714 | break; |
694 | case BLKIO_POLICY_THROTL: | 715 | case BLKIO_POLICY_THROTL: |
695 | ret = strict_strtoull(s[1], 10, &bps); | 716 | switch(fileid) { |
696 | if (ret) | 717 | case BLKIO_THROTL_read_bps_device: |
697 | return -EINVAL; | 718 | case BLKIO_THROTL_write_bps_device: |
719 | ret = strict_strtoull(s[1], 10, &bps); | ||
720 | if (ret) | ||
721 | return -EINVAL; | ||
698 | 722 | ||
699 | newpn->plid = plid; | 723 | newpn->plid = plid; |
700 | newpn->fileid = fileid; | 724 | newpn->fileid = fileid; |
701 | newpn->val.bps = bps; | 725 | newpn->val.bps = bps; |
726 | break; | ||
727 | case BLKIO_THROTL_read_iops_device: | ||
728 | case BLKIO_THROTL_write_iops_device: | ||
729 | ret = strict_strtoul(s[1], 10, &iops); | ||
730 | if (ret) | ||
731 | return -EINVAL; | ||
732 | |||
733 | newpn->plid = plid; | ||
734 | newpn->fileid = fileid; | ||
735 | newpn->val.iops = iops; | ||
736 | break; | ||
737 | } | ||
702 | break; | 738 | break; |
703 | default: | 739 | default: |
704 | BUG(); | 740 | BUG(); |
@@ -744,6 +780,29 @@ uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev) | |||
744 | return -1; | 780 | return -1; |
745 | } | 781 | } |
746 | 782 | ||
783 | unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev) | ||
784 | { | ||
785 | struct blkio_policy_node *pn; | ||
786 | |||
787 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | ||
788 | BLKIO_THROTL_read_iops_device); | ||
789 | if (pn) | ||
790 | return pn->val.iops; | ||
791 | else | ||
792 | return -1; | ||
793 | } | ||
794 | |||
795 | unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev) | ||
796 | { | ||
797 | struct blkio_policy_node *pn; | ||
798 | pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL, | ||
799 | BLKIO_THROTL_write_iops_device); | ||
800 | if (pn) | ||
801 | return pn->val.iops; | ||
802 | else | ||
803 | return -1; | ||
804 | } | ||
805 | |||
747 | /* Checks whether user asked for deleting a policy rule */ | 806 | /* Checks whether user asked for deleting a policy rule */ |
748 | static bool blkio_delete_rule_command(struct blkio_policy_node *pn) | 807 | static bool blkio_delete_rule_command(struct blkio_policy_node *pn) |
749 | { | 808 | { |
@@ -753,8 +812,17 @@ static bool blkio_delete_rule_command(struct blkio_policy_node *pn) | |||
753 | return 1; | 812 | return 1; |
754 | break; | 813 | break; |
755 | case BLKIO_POLICY_THROTL: | 814 | case BLKIO_POLICY_THROTL: |
756 | if (pn->val.bps == 0) | 815 | switch(pn->fileid) { |
757 | return 1; | 816 | case BLKIO_THROTL_read_bps_device: |
817 | case BLKIO_THROTL_write_bps_device: | ||
818 | if (pn->val.bps == 0) | ||
819 | return 1; | ||
820 | break; | ||
821 | case BLKIO_THROTL_read_iops_device: | ||
822 | case BLKIO_THROTL_write_iops_device: | ||
823 | if (pn->val.iops == 0) | ||
824 | return 1; | ||
825 | } | ||
758 | break; | 826 | break; |
759 | default: | 827 | default: |
760 | BUG(); | 828 | BUG(); |
@@ -771,7 +839,15 @@ static void blkio_update_policy_rule(struct blkio_policy_node *oldpn, | |||
771 | oldpn->val.weight = newpn->val.weight; | 839 | oldpn->val.weight = newpn->val.weight; |
772 | break; | 840 | break; |
773 | case BLKIO_POLICY_THROTL: | 841 | case BLKIO_POLICY_THROTL: |
774 | oldpn->val.bps = newpn->val.bps; | 842 | switch(newpn->fileid) { |
843 | case BLKIO_THROTL_read_bps_device: | ||
844 | case BLKIO_THROTL_write_bps_device: | ||
845 | oldpn->val.bps = newpn->val.bps; | ||
846 | break; | ||
847 | case BLKIO_THROTL_read_iops_device: | ||
848 | case BLKIO_THROTL_write_iops_device: | ||
849 | oldpn->val.iops = newpn->val.iops; | ||
850 | } | ||
775 | break; | 851 | break; |
776 | default: | 852 | default: |
777 | BUG(); | 853 | BUG(); |
@@ -785,7 +861,7 @@ static void blkio_update_policy_rule(struct blkio_policy_node *oldpn, | |||
785 | static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, | 861 | static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, |
786 | struct blkio_group *blkg, struct blkio_policy_node *pn) | 862 | struct blkio_group *blkg, struct blkio_policy_node *pn) |
787 | { | 863 | { |
788 | unsigned int weight; | 864 | unsigned int weight, iops; |
789 | u64 bps; | 865 | u64 bps; |
790 | 866 | ||
791 | switch(pn->plid) { | 867 | switch(pn->plid) { |
@@ -801,6 +877,11 @@ static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, | |||
801 | bps = pn->val.bps ? pn->val.bps : (-1); | 877 | bps = pn->val.bps ? pn->val.bps : (-1); |
802 | blkio_update_group_bps(blkg, bps, pn->fileid); | 878 | blkio_update_group_bps(blkg, bps, pn->fileid); |
803 | break; | 879 | break; |
880 | case BLKIO_THROTL_read_iops_device: | ||
881 | case BLKIO_THROTL_write_iops_device: | ||
882 | iops = pn->val.iops ? pn->val.iops : (-1); | ||
883 | blkio_update_group_iops(blkg, iops, pn->fileid); | ||
884 | break; | ||
804 | } | 885 | } |
805 | break; | 886 | break; |
806 | default: | 887 | default: |
@@ -900,14 +981,18 @@ blkio_print_policy_node(struct seq_file *m, struct blkio_policy_node *pn) | |||
900 | MINOR(pn->dev), pn->val.weight); | 981 | MINOR(pn->dev), pn->val.weight); |
901 | break; | 982 | break; |
902 | case BLKIO_POLICY_THROTL: | 983 | case BLKIO_POLICY_THROTL: |
903 | if (pn->fileid == BLKIO_THROTL_read_bps_device) | 984 | switch(pn->fileid) { |
985 | case BLKIO_THROTL_read_bps_device: | ||
986 | case BLKIO_THROTL_write_bps_device: | ||
904 | seq_printf(m, "%u:%u\t%llu\n", MAJOR(pn->dev), | 987 | seq_printf(m, "%u:%u\t%llu\n", MAJOR(pn->dev), |
905 | MINOR(pn->dev), pn->val.bps); | 988 | MINOR(pn->dev), pn->val.bps); |
906 | else if (pn->fileid == BLKIO_THROTL_write_bps_device) | 989 | break; |
907 | seq_printf(m, "%u:%u\t%llu\n", MAJOR(pn->dev), | 990 | case BLKIO_THROTL_read_iops_device: |
908 | MINOR(pn->dev), pn->val.bps); | 991 | case BLKIO_THROTL_write_iops_device: |
909 | else | 992 | seq_printf(m, "%u:%u\t%u\n", MAJOR(pn->dev), |
910 | BUG(); | 993 | MINOR(pn->dev), pn->val.iops); |
994 | break; | ||
995 | } | ||
911 | break; | 996 | break; |
912 | default: | 997 | default: |
913 | BUG(); | 998 | BUG(); |
@@ -954,6 +1039,8 @@ static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft, | |||
954 | switch(name){ | 1039 | switch(name){ |
955 | case BLKIO_THROTL_read_bps_device: | 1040 | case BLKIO_THROTL_read_bps_device: |
956 | case BLKIO_THROTL_write_bps_device: | 1041 | case BLKIO_THROTL_write_bps_device: |
1042 | case BLKIO_THROTL_read_iops_device: | ||
1043 | case BLKIO_THROTL_write_iops_device: | ||
957 | blkio_read_policy_node_files(cft, blkcg, m); | 1044 | blkio_read_policy_node_files(cft, blkcg, m); |
958 | return 0; | 1045 | return 0; |
959 | default: | 1046 | default: |
@@ -1171,6 +1258,24 @@ struct cftype blkio_files[] = { | |||
1171 | .write_string = blkiocg_file_write, | 1258 | .write_string = blkiocg_file_write, |
1172 | .max_write_len = 256, | 1259 | .max_write_len = 256, |
1173 | }, | 1260 | }, |
1261 | |||
1262 | { | ||
1263 | .name = "throttle.read_iops_device", | ||
1264 | .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_THROTL, | ||
1265 | BLKIO_THROTL_read_iops_device), | ||
1266 | .read_seq_string = blkiocg_file_read, | ||
1267 | .write_string = blkiocg_file_write, | ||
1268 | .max_write_len = 256, | ||
1269 | }, | ||
1270 | |||
1271 | { | ||
1272 | .name = "throttle.write_iops_device", | ||
1273 | .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_THROTL, | ||
1274 | BLKIO_THROTL_write_iops_device), | ||
1275 | .read_seq_string = blkiocg_file_read, | ||
1276 | .write_string = blkiocg_file_write, | ||
1277 | .max_write_len = 256, | ||
1278 | }, | ||
1174 | { | 1279 | { |
1175 | .name = "time", | 1280 | .name = "time", |
1176 | .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_PROP, | 1281 | .private = BLKIOFILE_PRIVATE(BLKIO_POLICY_PROP, |
diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h index 1b738827b2f6..2070053a30b1 100644 --- a/block/blk-cgroup.h +++ b/block/blk-cgroup.h | |||
@@ -93,6 +93,8 @@ enum blkcg_file_name_prop { | |||
93 | enum blkcg_file_name_throtl { | 93 | enum blkcg_file_name_throtl { |
94 | BLKIO_THROTL_read_bps_device, | 94 | BLKIO_THROTL_read_bps_device, |
95 | BLKIO_THROTL_write_bps_device, | 95 | BLKIO_THROTL_write_bps_device, |
96 | BLKIO_THROTL_read_iops_device, | ||
97 | BLKIO_THROTL_write_iops_device, | ||
96 | BLKIO_THROTL_io_service_bytes, | 98 | BLKIO_THROTL_io_service_bytes, |
97 | BLKIO_THROTL_io_serviced, | 99 | BLKIO_THROTL_io_serviced, |
98 | }; | 100 | }; |
@@ -168,6 +170,7 @@ struct blkio_policy_node { | |||
168 | * by file type "fileid". | 170 | * by file type "fileid". |
169 | */ | 171 | */ |
170 | u64 bps; | 172 | u64 bps; |
173 | unsigned int iops; | ||
171 | } val; | 174 | } val; |
172 | }; | 175 | }; |
173 | 176 | ||
@@ -177,6 +180,10 @@ extern uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, | |||
177 | dev_t dev); | 180 | dev_t dev); |
178 | extern uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, | 181 | extern uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, |
179 | dev_t dev); | 182 | dev_t dev); |
183 | extern unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, | ||
184 | dev_t dev); | ||
185 | extern unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, | ||
186 | dev_t dev); | ||
180 | 187 | ||
181 | typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg); | 188 | typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg); |
182 | typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg, | 189 | typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg, |
@@ -185,12 +192,18 @@ typedef void (blkio_update_group_read_bps_fn) (struct blkio_group *blkg, | |||
185 | u64 read_bps); | 192 | u64 read_bps); |
186 | typedef void (blkio_update_group_write_bps_fn) (struct blkio_group *blkg, | 193 | typedef void (blkio_update_group_write_bps_fn) (struct blkio_group *blkg, |
187 | u64 write_bps); | 194 | u64 write_bps); |
195 | typedef void (blkio_update_group_read_iops_fn) (struct blkio_group *blkg, | ||
196 | unsigned int read_iops); | ||
197 | typedef void (blkio_update_group_write_iops_fn) (struct blkio_group *blkg, | ||
198 | unsigned int write_iops); | ||
188 | 199 | ||
189 | struct blkio_policy_ops { | 200 | struct blkio_policy_ops { |
190 | blkio_unlink_group_fn *blkio_unlink_group_fn; | 201 | blkio_unlink_group_fn *blkio_unlink_group_fn; |
191 | blkio_update_group_weight_fn *blkio_update_group_weight_fn; | 202 | blkio_update_group_weight_fn *blkio_update_group_weight_fn; |
192 | blkio_update_group_read_bps_fn *blkio_update_group_read_bps_fn; | 203 | blkio_update_group_read_bps_fn *blkio_update_group_read_bps_fn; |
193 | blkio_update_group_write_bps_fn *blkio_update_group_write_bps_fn; | 204 | blkio_update_group_write_bps_fn *blkio_update_group_write_bps_fn; |
205 | blkio_update_group_read_iops_fn *blkio_update_group_read_iops_fn; | ||
206 | blkio_update_group_write_iops_fn *blkio_update_group_write_iops_fn; | ||
194 | }; | 207 | }; |
195 | 208 | ||
196 | struct blkio_policy_type { | 209 | struct blkio_policy_type { |