aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo2012-03-05 15:15:08 -0600
committerJens Axboe2012-03-06 14:27:22 -0600
commit4bfd482e73b30284cb21e10834ce729fa81aa256 (patch)
tree2c39e09592113946e3545013199b0e00a21f60f2 /block/blk-cgroup.c
parente56da7e287967667474a58c4f60c286279e3f487 (diff)
downloadkernel-common-4bfd482e73b30284cb21e10834ce729fa81aa256.tar.gz
kernel-common-4bfd482e73b30284cb21e10834ce729fa81aa256.tar.xz
kernel-common-4bfd482e73b30284cb21e10834ce729fa81aa256.zip
blkcg: kill blkio_policy_node
Now that blkcg configuration lives in blkg's, blkio_policy_node is no longer necessary. Kill it. blkio_policy_parse_and_set() now fails if invoked for missing device and functions to print out configurations are updated to print from blkg's. cftype_blkg_same_policy() is dropped along with other policy functions for consistency. Its one line is open coded in the only user - blkio_read_blkg_stats(). -v2: Update to reflect the retry-on-bypass logic change of the previous patch. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r--block/blk-cgroup.c437
1 files changed, 59 insertions, 378 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index fe8ce148017..adf61c99258 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -59,54 +59,6 @@ struct cgroup_subsys blkio_subsys = {
59}; 59};
60EXPORT_SYMBOL_GPL(blkio_subsys); 60EXPORT_SYMBOL_GPL(blkio_subsys);
61 61
62static inline void blkio_policy_insert_node(struct blkio_cgroup *blkcg,
63 struct blkio_policy_node *pn)
64{
65 list_add(&pn->node, &blkcg->policy_list);
66}
67
68static inline bool cftype_blkg_same_policy(struct cftype *cft,
69 struct blkio_group *blkg)
70{
71 enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private);
72
73 if (blkg->plid == plid)
74 return 1;
75
76 return 0;
77}
78
79/* Determines if policy node matches cgroup file being accessed */
80static inline bool pn_matches_cftype(struct cftype *cft,
81 struct blkio_policy_node *pn)
82{
83 enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private);
84 int fileid = BLKIOFILE_ATTR(cft->private);
85
86 return (plid == pn->plid && fileid == pn->fileid);
87}
88
89/* Must be called with blkcg->lock held */
90static inline void blkio_policy_delete_node(struct blkio_policy_node *pn)
91{
92 list_del(&pn->node);
93}
94
95/* Must be called with blkcg->lock held */
96static struct blkio_policy_node *
97blkio_policy_search_node(const struct blkio_cgroup *blkcg, dev_t dev,
98 enum blkio_policy_id plid, int fileid)
99{
100 struct blkio_policy_node *pn;
101
102 list_for_each_entry(pn, &blkcg->policy_list, node) {
103 if (pn->dev == dev && pn->plid == plid && pn->fileid == fileid)
104 return pn;
105 }
106
107 return NULL;
108}
109
110struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) 62struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
111{ 63{
112 return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id), 64 return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id),
@@ -854,10 +806,8 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg,
854 return disk_total; 806 return disk_total;
855} 807}
856 808
857static int blkio_policy_parse_and_set(char *buf, 809static int blkio_policy_parse_and_set(char *buf, enum blkio_policy_id plid,
858 struct blkio_policy_node *newpn, 810 int fileid, struct blkio_cgroup *blkcg)
859 enum blkio_policy_id plid, int fileid,
860 struct blkio_cgroup *blkcg)
861{ 811{
862 struct gendisk *disk = NULL; 812 struct gendisk *disk = NULL;
863 struct blkio_group *blkg = NULL; 813 struct blkio_group *blkg = NULL;
@@ -905,78 +855,51 @@ static int blkio_policy_parse_and_set(char *buf,
905 if (strict_strtoull(s[1], 10, &temp)) 855 if (strict_strtoull(s[1], 10, &temp))
906 goto out; 856 goto out;
907 857
908 /* For rule removal, do not check for device presence. */
909 disk = get_gendisk(dev, &part); 858 disk = get_gendisk(dev, &part);
910 859 if (!disk || part)
911 if ((!disk || part) && temp) {
912 ret = -ENODEV;
913 goto out; 860 goto out;
914 }
915 861
916 rcu_read_lock(); 862 rcu_read_lock();
917 863
918 if (disk && !part) { 864 spin_lock_irq(disk->queue->queue_lock);
919 spin_lock_irq(disk->queue->queue_lock); 865 blkg = blkg_lookup_create(blkcg, disk->queue, plid, false);
920 blkg = blkg_lookup_create(blkcg, disk->queue, plid, false); 866 spin_unlock_irq(disk->queue->queue_lock);
921 spin_unlock_irq(disk->queue->queue_lock);
922 867
923 if (IS_ERR(blkg)) { 868 if (IS_ERR(blkg)) {
924 ret = PTR_ERR(blkg); 869 ret = PTR_ERR(blkg);
925 if (ret == -EBUSY) 870 goto out_unlock;
926 goto out_unlock;
927 blkg = NULL;
928 }
929 } 871 }
930 872
931 newpn->dev = dev;
932
933 switch (plid) { 873 switch (plid) {
934 case BLKIO_POLICY_PROP: 874 case BLKIO_POLICY_PROP:
935 if ((temp < BLKIO_WEIGHT_MIN && temp > 0) || 875 if ((temp < BLKIO_WEIGHT_MIN && temp > 0) ||
936 temp > BLKIO_WEIGHT_MAX) 876 temp > BLKIO_WEIGHT_MAX)
937 goto out_unlock; 877 goto out_unlock;
938 878
939 newpn->plid = plid; 879 blkg->conf.weight = temp;
940 newpn->fileid = fileid; 880 blkio_update_group_weight(blkg, temp ?: blkcg->weight);
941 newpn->val.weight = temp;
942 if (blkg)
943 blkg->conf.weight = temp;
944 break; 881 break;
945 case BLKIO_POLICY_THROTL: 882 case BLKIO_POLICY_THROTL:
946 switch(fileid) { 883 switch(fileid) {
947 case BLKIO_THROTL_read_bps_device: 884 case BLKIO_THROTL_read_bps_device:
948 if (blkg) 885 blkg->conf.bps[READ] = temp;
949 blkg->conf.bps[READ] = temp; 886 blkio_update_group_bps(blkg, temp ?: -1, fileid);
950 newpn->plid = plid;
951 newpn->fileid = fileid;
952 newpn->val.bps = temp;
953 break; 887 break;
954 case BLKIO_THROTL_write_bps_device: 888 case BLKIO_THROTL_write_bps_device:
955 if (blkg) 889 blkg->conf.bps[WRITE] = temp;
956 blkg->conf.bps[WRITE] = temp; 890 blkio_update_group_bps(blkg, temp ?: -1, fileid);
957 newpn->plid = plid;
958 newpn->fileid = fileid;
959 newpn->val.bps = temp;
960 break; 891 break;
961 case BLKIO_THROTL_read_iops_device: 892 case BLKIO_THROTL_read_iops_device:
962 if (temp > THROTL_IOPS_MAX) 893 if (temp > THROTL_IOPS_MAX)
963 goto out_unlock; 894 goto out_unlock;
964 895 blkg->conf.iops[READ] = temp;
965 if (blkg) 896 blkio_update_group_iops(blkg, temp ?: -1, fileid);
966 blkg->conf.iops[READ] = temp;
967 newpn->plid = plid;
968 newpn->fileid = fileid;
969 newpn->val.iops = (unsigned int)temp;
970 break; 897 break;
971 case BLKIO_THROTL_write_iops_device: 898 case BLKIO_THROTL_write_iops_device:
972 if (temp > THROTL_IOPS_MAX) 899 if (temp > THROTL_IOPS_MAX)
973 goto out_unlock; 900 goto out_unlock;
974 901 blkg->conf.iops[WRITE] = temp;
975 if (blkg) 902 blkio_update_group_iops(blkg, temp ?: -1, fileid);
976 blkg->conf.iops[WRITE] = temp;
977 newpn->plid = plid;
978 newpn->fileid = fileid;
979 newpn->val.iops = (unsigned int)temp;
980 break; 903 break;
981 } 904 }
982 break; 905 break;
@@ -1002,212 +925,12 @@ out:
1002 return ret; 925 return ret;
1003} 926}
1004 927
1005unsigned int blkcg_get_weight(struct blkio_cgroup *blkcg,
1006 dev_t dev)
1007{
1008 struct blkio_policy_node *pn;
1009 unsigned long flags;
1010 unsigned int weight;
1011
1012 spin_lock_irqsave(&blkcg->lock, flags);
1013
1014 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_PROP,
1015 BLKIO_PROP_weight_device);
1016 if (pn)
1017 weight = pn->val.weight;
1018 else
1019 weight = blkcg->weight;
1020
1021 spin_unlock_irqrestore(&blkcg->lock, flags);
1022
1023 return weight;
1024}
1025EXPORT_SYMBOL_GPL(blkcg_get_weight);
1026
1027uint64_t blkcg_get_read_bps(struct blkio_cgroup *blkcg, dev_t dev)
1028{
1029 struct blkio_policy_node *pn;
1030 unsigned long flags;
1031 uint64_t bps = -1;
1032
1033 spin_lock_irqsave(&blkcg->lock, flags);
1034 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
1035 BLKIO_THROTL_read_bps_device);
1036 if (pn)
1037 bps = pn->val.bps;
1038 spin_unlock_irqrestore(&blkcg->lock, flags);
1039
1040 return bps;
1041}
1042
1043uint64_t blkcg_get_write_bps(struct blkio_cgroup *blkcg, dev_t dev)
1044{
1045 struct blkio_policy_node *pn;
1046 unsigned long flags;
1047 uint64_t bps = -1;
1048
1049 spin_lock_irqsave(&blkcg->lock, flags);
1050 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
1051 BLKIO_THROTL_write_bps_device);
1052 if (pn)
1053 bps = pn->val.bps;
1054 spin_unlock_irqrestore(&blkcg->lock, flags);
1055
1056 return bps;
1057}
1058
1059unsigned int blkcg_get_read_iops(struct blkio_cgroup *blkcg, dev_t dev)
1060{
1061 struct blkio_policy_node *pn;
1062 unsigned long flags;
1063 unsigned int iops = -1;
1064
1065 spin_lock_irqsave(&blkcg->lock, flags);
1066 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
1067 BLKIO_THROTL_read_iops_device);
1068 if (pn)
1069 iops = pn->val.iops;
1070 spin_unlock_irqrestore(&blkcg->lock, flags);
1071
1072 return iops;
1073}
1074
1075unsigned int blkcg_get_write_iops(struct blkio_cgroup *blkcg, dev_t dev)
1076{
1077 struct blkio_policy_node *pn;
1078 unsigned long flags;
1079 unsigned int iops = -1;
1080
1081 spin_lock_irqsave(&blkcg->lock, flags);
1082 pn = blkio_policy_search_node(blkcg, dev, BLKIO_POLICY_THROTL,
1083 BLKIO_THROTL_write_iops_device);
1084 if (pn)
1085 iops = pn->val.iops;
1086 spin_unlock_irqrestore(&blkcg->lock, flags);
1087
1088 return iops;
1089}
1090
1091/* Checks whether user asked for deleting a policy rule */
1092static bool blkio_delete_rule_command(struct blkio_policy_node *pn)
1093{
1094 switch(pn->plid) {
1095 case BLKIO_POLICY_PROP:
1096 if (pn->val.weight == 0)
1097 return 1;
1098 break;
1099 case BLKIO_POLICY_THROTL:
1100 switch(pn->fileid) {
1101 case BLKIO_THROTL_read_bps_device:
1102 case BLKIO_THROTL_write_bps_device:
1103 if (pn->val.bps == 0)
1104 return 1;
1105 break;
1106 case BLKIO_THROTL_read_iops_device:
1107 case BLKIO_THROTL_write_iops_device:
1108 if (pn->val.iops == 0)
1109 return 1;
1110 }
1111 break;
1112 default:
1113 BUG();
1114 }
1115
1116 return 0;
1117}
1118
1119static void blkio_update_policy_rule(struct blkio_policy_node *oldpn,
1120 struct blkio_policy_node *newpn)
1121{
1122 switch(oldpn->plid) {
1123 case BLKIO_POLICY_PROP:
1124 oldpn->val.weight = newpn->val.weight;
1125 break;
1126 case BLKIO_POLICY_THROTL:
1127 switch(newpn->fileid) {
1128 case BLKIO_THROTL_read_bps_device:
1129 case BLKIO_THROTL_write_bps_device:
1130 oldpn->val.bps = newpn->val.bps;
1131 break;
1132 case BLKIO_THROTL_read_iops_device:
1133 case BLKIO_THROTL_write_iops_device:
1134 oldpn->val.iops = newpn->val.iops;
1135 }
1136 break;
1137 default:
1138 BUG();
1139 }
1140}
1141
1142/*
1143 * Some rules/values in blkg have changed. Propagate those to respective
1144 * policies.
1145 */
1146static void blkio_update_blkg_policy(struct blkio_cgroup *blkcg,
1147 struct blkio_group *blkg, struct blkio_policy_node *pn)
1148{
1149 struct blkio_group_conf *conf = &blkg->conf;
1150
1151 switch(pn->plid) {
1152 case BLKIO_POLICY_PROP:
1153 blkio_update_group_weight(blkg, conf->weight ?: blkcg->weight);
1154 break;
1155 case BLKIO_POLICY_THROTL:
1156 switch(pn->fileid) {
1157 case BLKIO_THROTL_read_bps_device:
1158 blkio_update_group_bps(blkg, conf->bps[READ] ?: -1,
1159 pn->fileid);
1160 break;
1161 case BLKIO_THROTL_write_bps_device:
1162 blkio_update_group_bps(blkg, conf->bps[WRITE] ?: -1,
1163 pn->fileid);
1164 break;
1165 case BLKIO_THROTL_read_iops_device:
1166 blkio_update_group_iops(blkg, conf->iops[READ] ?: -1,
1167 pn->fileid);
1168 break;
1169 case BLKIO_THROTL_write_iops_device:
1170 blkio_update_group_iops(blkg, conf->iops[WRITE] ?: -1,
1171 pn->fileid);
1172 break;
1173 }
1174 break;
1175 default:
1176 BUG();
1177 }
1178}
1179
1180/*
1181 * A policy node rule has been updated. Propagate this update to all the
1182 * block groups which might be affected by this update.
1183 */
1184static void blkio_update_policy_node_blkg(struct blkio_cgroup *blkcg,
1185 struct blkio_policy_node *pn)
1186{
1187 struct blkio_group *blkg;
1188 struct hlist_node *n;
1189
1190 spin_lock(&blkio_list_lock);
1191 spin_lock_irq(&blkcg->lock);
1192
1193 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) {
1194 if (pn->dev != blkg->dev || pn->plid != blkg->plid)
1195 continue;
1196 blkio_update_blkg_policy(blkcg, blkg, pn);
1197 }
1198
1199 spin_unlock_irq(&blkcg->lock);
1200 spin_unlock(&blkio_list_lock);
1201}
1202
1203static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft, 928static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft,
1204 const char *buffer) 929 const char *buffer)
1205{ 930{
1206 int ret = 0; 931 int ret = 0;
1207 char *buf; 932 char *buf;
1208 struct blkio_policy_node *newpn, *pn;
1209 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp); 933 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
1210 int keep_newpn = 0;
1211 enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private); 934 enum blkio_policy_id plid = BLKIOFILE_POLICY(cft->private);
1212 int fileid = BLKIOFILE_ATTR(cft->private); 935 int fileid = BLKIOFILE_ATTR(cft->private);
1213 936
@@ -1215,69 +938,42 @@ static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft,
1215 if (!buf) 938 if (!buf)
1216 return -ENOMEM; 939 return -ENOMEM;
1217 940
1218 newpn = kzalloc(sizeof(*newpn), GFP_KERNEL); 941 ret = blkio_policy_parse_and_set(buf, plid, fileid, blkcg);
1219 if (!newpn) {
1220 ret = -ENOMEM;
1221 goto free_buf;
1222 }
1223
1224 ret = blkio_policy_parse_and_set(buf, newpn, plid, fileid, blkcg);
1225 if (ret)
1226 goto free_newpn;
1227
1228 spin_lock_irq(&blkcg->lock);
1229
1230 pn = blkio_policy_search_node(blkcg, newpn->dev, plid, fileid);
1231 if (!pn) {
1232 if (!blkio_delete_rule_command(newpn)) {
1233 blkio_policy_insert_node(blkcg, newpn);
1234 keep_newpn = 1;
1235 }
1236 spin_unlock_irq(&blkcg->lock);
1237 goto update_io_group;
1238 }
1239
1240 if (blkio_delete_rule_command(newpn)) {
1241 blkio_policy_delete_node(pn);
1242 kfree(pn);
1243 spin_unlock_irq(&blkcg->lock);
1244 goto update_io_group;
1245 }
1246 spin_unlock_irq(&blkcg->lock);
1247
1248 blkio_update_policy_rule(pn, newpn);
1249
1250update_io_group:
1251 blkio_update_policy_node_blkg(blkcg, newpn);
1252
1253free_newpn:
1254 if (!keep_newpn)
1255 kfree(newpn);
1256free_buf:
1257 kfree(buf); 942 kfree(buf);
1258 return ret; 943 return ret;
1259} 944}
1260 945
1261static void 946static void blkio_print_group_conf(struct cftype *cft, struct blkio_group *blkg,
1262blkio_print_policy_node(struct seq_file *m, struct blkio_policy_node *pn) 947 struct seq_file *m)
1263{ 948{
1264 switch(pn->plid) { 949 int fileid = BLKIOFILE_ATTR(cft->private);
950 int rw = WRITE;
951
952 switch (blkg->plid) {
1265 case BLKIO_POLICY_PROP: 953 case BLKIO_POLICY_PROP:
1266 if (pn->fileid == BLKIO_PROP_weight_device) 954 if (blkg->conf.weight)
1267 seq_printf(m, "%u:%u\t%u\n", MAJOR(pn->dev), 955 seq_printf(m, "%u:%u\t%u\n", MAJOR(blkg->dev),
1268 MINOR(pn->dev), pn->val.weight); 956 MINOR(blkg->dev), blkg->conf.weight);
1269 break; 957 break;
1270 case BLKIO_POLICY_THROTL: 958 case BLKIO_POLICY_THROTL:
1271 switch(pn->fileid) { 959 switch (fileid) {
1272 case BLKIO_THROTL_read_bps_device: 960 case BLKIO_THROTL_read_bps_device:
961 rw = READ;
1273 case BLKIO_THROTL_write_bps_device: 962 case BLKIO_THROTL_write_bps_device:
1274 seq_printf(m, "%u:%u\t%llu\n", MAJOR(pn->dev), 963 if (blkg->conf.bps[rw])
1275 MINOR(pn->dev), pn->val.bps); 964 seq_printf(m, "%u:%u\t%llu\n",
965 MAJOR(blkg->dev),
966 MINOR(blkg->dev),
967 blkg->conf.bps[rw]);
1276 break; 968 break;
1277 case BLKIO_THROTL_read_iops_device: 969 case BLKIO_THROTL_read_iops_device:
970 rw = READ;
1278 case BLKIO_THROTL_write_iops_device: 971 case BLKIO_THROTL_write_iops_device:
1279 seq_printf(m, "%u:%u\t%u\n", MAJOR(pn->dev), 972 if (blkg->conf.iops[rw])
1280 MINOR(pn->dev), pn->val.iops); 973 seq_printf(m, "%u:%u\t%u\n",
974 MAJOR(blkg->dev),
975 MINOR(blkg->dev),
976 blkg->conf.iops[rw]);
1281 break; 977 break;
1282 } 978 }
1283 break; 979 break;
@@ -1287,20 +983,17 @@ blkio_print_policy_node(struct seq_file *m, struct blkio_policy_node *pn)
1287} 983}
1288 984
1289/* cgroup files which read their data from policy nodes end up here */ 985/* cgroup files which read their data from policy nodes end up here */
1290static void blkio_read_policy_node_files(struct cftype *cft, 986static void blkio_read_conf(struct cftype *cft, struct blkio_cgroup *blkcg,
1291 struct blkio_cgroup *blkcg, struct seq_file *m) 987 struct seq_file *m)
1292{ 988{
1293 struct blkio_policy_node *pn; 989 struct blkio_group *blkg;
990 struct hlist_node *n;
1294 991
1295 if (!list_empty(&blkcg->policy_list)) { 992 spin_lock_irq(&blkcg->lock);
1296 spin_lock_irq(&blkcg->lock); 993 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node)
1297 list_for_each_entry(pn, &blkcg->policy_list, node) { 994 if (BLKIOFILE_POLICY(cft->private) == blkg->plid)
1298 if (!pn_matches_cftype(cft, pn)) 995 blkio_print_group_conf(cft, blkg, m);
1299 continue; 996 spin_unlock_irq(&blkcg->lock);
1300 blkio_print_policy_node(m, pn);
1301 }
1302 spin_unlock_irq(&blkcg->lock);
1303 }
1304} 997}
1305 998
1306static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft, 999static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft,
@@ -1316,7 +1009,7 @@ static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft,
1316 case BLKIO_POLICY_PROP: 1009 case BLKIO_POLICY_PROP:
1317 switch(name) { 1010 switch(name) {
1318 case BLKIO_PROP_weight_device: 1011 case BLKIO_PROP_weight_device:
1319 blkio_read_policy_node_files(cft, blkcg, m); 1012 blkio_read_conf(cft, blkcg, m);
1320 return 0; 1013 return 0;
1321 default: 1014 default:
1322 BUG(); 1015 BUG();
@@ -1328,7 +1021,7 @@ static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft,
1328 case BLKIO_THROTL_write_bps_device: 1021 case BLKIO_THROTL_write_bps_device:
1329 case BLKIO_THROTL_read_iops_device: 1022 case BLKIO_THROTL_read_iops_device:
1330 case BLKIO_THROTL_write_iops_device: 1023 case BLKIO_THROTL_write_iops_device:
1331 blkio_read_policy_node_files(cft, blkcg, m); 1024 blkio_read_conf(cft, blkcg, m);
1332 return 0; 1025 return 0;
1333 default: 1026 default:
1334 BUG(); 1027 BUG();
@@ -1352,7 +1045,7 @@ static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg,
1352 rcu_read_lock(); 1045 rcu_read_lock();
1353 hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) { 1046 hlist_for_each_entry_rcu(blkg, n, &blkcg->blkg_list, blkcg_node) {
1354 if (blkg->dev) { 1047 if (blkg->dev) {
1355 if (!cftype_blkg_same_policy(cft, blkg)) 1048 if (BLKIOFILE_POLICY(cft->private) != blkg->plid)
1356 continue; 1049 continue;
1357 if (pcpu) 1050 if (pcpu)
1358 cgroup_total += blkio_get_stat_cpu(blkg, cb, 1051 cgroup_total += blkio_get_stat_cpu(blkg, cb,
@@ -1451,11 +1144,10 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft,
1451 return 0; 1144 return 0;
1452} 1145}
1453 1146
1454static int blkio_weight_write(struct blkio_cgroup *blkcg, u64 val) 1147static int blkio_weight_write(struct blkio_cgroup *blkcg, int plid, u64 val)
1455{ 1148{
1456 struct blkio_group *blkg; 1149 struct blkio_group *blkg;
1457 struct hlist_node *n; 1150 struct hlist_node *n;
1458 struct blkio_policy_node *pn;
1459 1151
1460 if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX) 1152 if (val < BLKIO_WEIGHT_MIN || val > BLKIO_WEIGHT_MAX)
1461 return -EINVAL; 1153 return -EINVAL;
@@ -1464,14 +1156,10 @@ static int blkio_weight_write(struct blkio_cgroup *blkcg, u64 val)
1464 spin_lock_irq(&blkcg->lock); 1156 spin_lock_irq(&blkcg->lock);
1465 blkcg->weight = (unsigned int)val; 1157 blkcg->weight = (unsigned int)val;
1466 1158
1467 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node) { 1159 hlist_for_each_entry(blkg, n, &blkcg->blkg_list, blkcg_node)
1468 pn = blkio_policy_search_node(blkcg, blkg->dev, 1160 if (blkg->plid == plid && !blkg->conf.weight)
1469 BLKIO_POLICY_PROP, BLKIO_PROP_weight_device); 1161 blkio_update_group_weight(blkg, blkcg->weight);
1470 if (pn)
1471 continue;
1472 1162
1473 blkio_update_group_weight(blkg, blkcg->weight);
1474 }
1475 spin_unlock_irq(&blkcg->lock); 1163 spin_unlock_irq(&blkcg->lock);
1476 spin_unlock(&blkio_list_lock); 1164 spin_unlock(&blkio_list_lock);
1477 return 0; 1165 return 0;
@@ -1510,7 +1198,7 @@ blkiocg_file_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
1510 case BLKIO_POLICY_PROP: 1198 case BLKIO_POLICY_PROP:
1511 switch(name) { 1199 switch(name) {
1512 case BLKIO_PROP_weight: 1200 case BLKIO_PROP_weight:
1513 return blkio_weight_write(blkcg, val); 1201 return blkio_weight_write(blkcg, plid, val);
1514 } 1202 }
1515 break; 1203 break;
1516 default: 1204 default:
@@ -1691,7 +1379,6 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
1691 struct blkio_group *blkg; 1379 struct blkio_group *blkg;
1692 struct request_queue *q; 1380 struct request_queue *q;
1693 struct blkio_policy_type *blkiop; 1381 struct blkio_policy_type *blkiop;
1694 struct blkio_policy_node *pn, *pntmp;
1695 1382
1696 rcu_read_lock(); 1383 rcu_read_lock();
1697 do { 1384 do {
@@ -1723,11 +1410,6 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
1723 spin_unlock(&blkio_list_lock); 1410 spin_unlock(&blkio_list_lock);
1724 } while (1); 1411 } while (1);
1725 1412
1726 list_for_each_entry_safe(pn, pntmp, &blkcg->policy_list, node) {
1727 blkio_policy_delete_node(pn);
1728 kfree(pn);
1729 }
1730
1731 free_css_id(&blkio_subsys, &blkcg->css); 1413 free_css_id(&blkio_subsys, &blkcg->css);
1732 rcu_read_unlock(); 1414 rcu_read_unlock();
1733 if (blkcg != &blkio_root_cgroup) 1415 if (blkcg != &blkio_root_cgroup)
@@ -1754,7 +1436,6 @@ done:
1754 spin_lock_init(&blkcg->lock); 1436 spin_lock_init(&blkcg->lock);
1755 INIT_HLIST_HEAD(&blkcg->blkg_list); 1437 INIT_HLIST_HEAD(&blkcg->blkg_list);
1756 1438
1757 INIT_LIST_HEAD(&blkcg->policy_list);
1758 return &blkcg->css; 1439 return &blkcg->css;
1759} 1440}
1760 1441