aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2010-09-15 17:06:36 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-09-16 02:42:58 -0400
commit7702e8f45b0a3bb262b9366c60beb5445758d94c (patch)
treebd61754827def804fe5a1f790f3eb303154df63d /block
parente43473b7f223ec866f7db273697e76c337c390f9 (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>
Diffstat (limited to 'block')
-rw-r--r--block/blk-cgroup.c139
-rw-r--r--block/blk-cgroup.h13
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
152static 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
783unsigned 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
795unsigned 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 */
748static bool blkio_delete_rule_command(struct blkio_policy_node *pn) 807static 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,
785static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg, 861static 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 {
93enum blkcg_file_name_throtl { 93enum 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);
178extern uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, 181extern uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg,
179 dev_t dev); 182 dev_t dev);
183extern unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg,
184 dev_t dev);
185extern unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg,
186 dev_t dev);
180 187
181typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg); 188typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
182typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg, 189typedef 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);
186typedef void (blkio_update_group_write_bps_fn) (struct blkio_group *blkg, 193typedef void (blkio_update_group_write_bps_fn) (struct blkio_group *blkg,
187 u64 write_bps); 194 u64 write_bps);
195typedef void (blkio_update_group_read_iops_fn) (struct blkio_group *blkg,
196 unsigned int read_iops);
197typedef void (blkio_update_group_write_iops_fn) (struct blkio_group *blkg,
198 unsigned int write_iops);
188 199
189struct blkio_policy_ops { 200struct 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
196struct blkio_policy_type { 209struct blkio_policy_type {