diff options
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r-- | block/blk-cgroup.c | 437 |
1 files changed, 59 insertions, 378 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index fe8ce148017a..adf61c99258c 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -59,54 +59,6 @@ struct cgroup_subsys blkio_subsys = { | |||
59 | }; | 59 | }; |
60 | EXPORT_SYMBOL_GPL(blkio_subsys); | 60 | EXPORT_SYMBOL_GPL(blkio_subsys); |
61 | 61 | ||
62 | static 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 | |||
68 | static 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 */ | ||
80 | static 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 */ | ||
90 | static 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 */ | ||
96 | static struct blkio_policy_node * | ||
97 | blkio_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 | |||
110 | struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) | 62 | struct 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 | ||
857 | static int blkio_policy_parse_and_set(char *buf, | 809 | static 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 | ||
1005 | unsigned 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 | } | ||
1025 | EXPORT_SYMBOL_GPL(blkcg_get_weight); | ||
1026 | |||
1027 | uint64_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 | |||
1043 | uint64_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 | |||
1059 | unsigned 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 | |||
1075 | unsigned 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 */ | ||
1092 | static 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 | |||
1119 | static 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 | */ | ||
1146 | static 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 | */ | ||
1184 | static 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 | |||
1203 | static int blkiocg_file_write(struct cgroup *cgrp, struct cftype *cft, | 928 | static 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 | |||
1250 | update_io_group: | ||
1251 | blkio_update_policy_node_blkg(blkcg, newpn); | ||
1252 | |||
1253 | free_newpn: | ||
1254 | if (!keep_newpn) | ||
1255 | kfree(newpn); | ||
1256 | free_buf: | ||
1257 | kfree(buf); | 942 | kfree(buf); |
1258 | return ret; | 943 | return ret; |
1259 | } | 944 | } |
1260 | 945 | ||
1261 | static void | 946 | static void blkio_print_group_conf(struct cftype *cft, struct blkio_group *blkg, |
1262 | blkio_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 */ |
1290 | static void blkio_read_policy_node_files(struct cftype *cft, | 986 | static 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 | ||
1306 | static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft, | 999 | static 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 | ||
1454 | static int blkio_weight_write(struct blkio_cgroup *blkcg, u64 val) | 1147 | static 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 | ||