aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-throttle.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-throttle.c')
-rw-r--r--block/blk-throttle.c153
1 files changed, 58 insertions, 95 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 27f7960dd421..004964bb6fdd 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -924,20 +924,6 @@ throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay)
924 } 924 }
925} 925}
926 926
927/*
928 * Can not take queue lock in update functions as queue lock under
929 * blkcg_lock is not allowed. Under other paths we take blkcg_lock under
930 * queue_lock.
931 */
932static void throtl_update_blkio_group_common(struct throtl_data *td,
933 struct throtl_grp *tg)
934{
935 xchg(&tg->limits_changed, true);
936 xchg(&td->limits_changed, true);
937 /* Schedule a work now to process the limit change */
938 throtl_schedule_delayed_work(td, 0);
939}
940
941static u64 tg_prfill_cpu_rwstat(struct seq_file *sf, 927static u64 tg_prfill_cpu_rwstat(struct seq_file *sf,
942 struct blkg_policy_data *pd, int off) 928 struct blkg_policy_data *pd, int off)
943{ 929{
@@ -968,68 +954,48 @@ static int tg_print_cpu_rwstat(struct cgroup *cgrp, struct cftype *cft,
968 return 0; 954 return 0;
969} 955}
970 956
971static u64 blkg_prfill_conf_u64(struct seq_file *sf, 957static u64 tg_prfill_conf_u64(struct seq_file *sf, struct blkg_policy_data *pd,
972 struct blkg_policy_data *pd, int off) 958 int off)
973{ 959{
974 u64 v = *(u64 *)((void *)&pd->conf + off); 960 u64 v = *(u64 *)((void *)pd->pdata + off);
975 961
976 if (!v) 962 if (v == -1)
977 return 0; 963 return 0;
978 return __blkg_prfill_u64(sf, pd, v); 964 return __blkg_prfill_u64(sf, pd, v);
979} 965}
980 966
981static int blkcg_print_conf_u64(struct cgroup *cgrp, struct cftype *cft, 967static u64 tg_prfill_conf_uint(struct seq_file *sf, struct blkg_policy_data *pd,
982 struct seq_file *sf) 968 int off)
983{ 969{
984 blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp), 970 unsigned int v = *(unsigned int *)((void *)pd->pdata + off);
985 blkg_prfill_conf_u64, BLKIO_POLICY_THROTL,
986 cft->private, false);
987 return 0;
988}
989 971
990static void throtl_update_blkio_group_read_bps(struct blkio_group *blkg, 972 if (v == -1)
991 u64 read_bps) 973 return 0;
992{ 974 return __blkg_prfill_u64(sf, pd, v);
993 struct throtl_grp *tg = blkg_to_tg(blkg);
994
995 tg->bps[READ] = read_bps;
996 throtl_update_blkio_group_common(blkg->q->td, tg);
997}
998
999static void throtl_update_blkio_group_write_bps(struct blkio_group *blkg,
1000 u64 write_bps)
1001{
1002 struct throtl_grp *tg = blkg_to_tg(blkg);
1003
1004 tg->bps[WRITE] = write_bps;
1005 throtl_update_blkio_group_common(blkg->q->td, tg);
1006} 975}
1007 976
1008static void throtl_update_blkio_group_read_iops(struct blkio_group *blkg, 977static int tg_print_conf_u64(struct cgroup *cgrp, struct cftype *cft,
1009 u64 read_iops) 978 struct seq_file *sf)
1010{ 979{
1011 struct throtl_grp *tg = blkg_to_tg(blkg); 980 blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp), tg_prfill_conf_u64,
1012 981 BLKIO_POLICY_THROTL, cft->private, false);
1013 tg->iops[READ] = read_iops; 982 return 0;
1014 throtl_update_blkio_group_common(blkg->q->td, tg);
1015} 983}
1016 984
1017static void throtl_update_blkio_group_write_iops(struct blkio_group *blkg, 985static int tg_print_conf_uint(struct cgroup *cgrp, struct cftype *cft,
1018 u64 write_iops) 986 struct seq_file *sf)
1019{ 987{
1020 struct throtl_grp *tg = blkg_to_tg(blkg); 988 blkcg_print_blkgs(sf, cgroup_to_blkio_cgroup(cgrp), tg_prfill_conf_uint,
1021 989 BLKIO_POLICY_THROTL, cft->private, false);
1022 tg->iops[WRITE] = write_iops; 990 return 0;
1023 throtl_update_blkio_group_common(blkg->q->td, tg);
1024} 991}
1025 992
1026static int blkcg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft, 993static int tg_set_conf(struct cgroup *cgrp, struct cftype *cft, const char *buf,
1027 const char *buf, 994 bool is_u64)
1028 void (*update)(struct blkio_group *, u64))
1029{ 995{
1030 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp); 996 struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgrp);
1031 struct blkg_policy_data *pd;
1032 struct blkg_conf_ctx ctx; 997 struct blkg_conf_ctx ctx;
998 struct throtl_grp *tg;
1033 int ret; 999 int ret;
1034 1000
1035 ret = blkg_conf_prep(blkcg, buf, &ctx); 1001 ret = blkg_conf_prep(blkcg, buf, &ctx);
@@ -1037,10 +1003,23 @@ static int blkcg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft,
1037 return ret; 1003 return ret;
1038 1004
1039 ret = -EINVAL; 1005 ret = -EINVAL;
1040 pd = ctx.blkg->pd[BLKIO_POLICY_THROTL]; 1006 tg = blkg_to_tg(ctx.blkg);
1041 if (pd) { 1007 if (tg) {
1042 *(u64 *)((void *)&pd->conf + cft->private) = ctx.v; 1008 struct throtl_data *td = ctx.blkg->q->td;
1043 update(ctx.blkg, ctx.v ?: -1); 1009
1010 if (!ctx.v)
1011 ctx.v = -1;
1012
1013 if (is_u64)
1014 *(u64 *)((void *)tg + cft->private) = ctx.v;
1015 else
1016 *(unsigned int *)((void *)tg + cft->private) = ctx.v;
1017
1018 /* XXX: we don't need the following deferred processing */
1019 xchg(&tg->limits_changed, true);
1020 xchg(&td->limits_changed, true);
1021 throtl_schedule_delayed_work(td, 0);
1022
1044 ret = 0; 1023 ret = 0;
1045 } 1024 }
1046 1025
@@ -1048,61 +1027,45 @@ static int blkcg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft,
1048 return ret; 1027 return ret;
1049} 1028}
1050 1029
1051static int blkcg_set_conf_bps_r(struct cgroup *cgrp, struct cftype *cft, 1030static int tg_set_conf_u64(struct cgroup *cgrp, struct cftype *cft,
1052 const char *buf) 1031 const char *buf)
1053{
1054 return blkcg_set_conf_u64(cgrp, cft, buf,
1055 throtl_update_blkio_group_read_bps);
1056}
1057
1058static int blkcg_set_conf_bps_w(struct cgroup *cgrp, struct cftype *cft,
1059 const char *buf)
1060{
1061 return blkcg_set_conf_u64(cgrp, cft, buf,
1062 throtl_update_blkio_group_write_bps);
1063}
1064
1065static int blkcg_set_conf_iops_r(struct cgroup *cgrp, struct cftype *cft,
1066 const char *buf)
1067{ 1032{
1068 return blkcg_set_conf_u64(cgrp, cft, buf, 1033 return tg_set_conf(cgrp, cft, buf, true);
1069 throtl_update_blkio_group_read_iops);
1070} 1034}
1071 1035
1072static int blkcg_set_conf_iops_w(struct cgroup *cgrp, struct cftype *cft, 1036static int tg_set_conf_uint(struct cgroup *cgrp, struct cftype *cft,
1073 const char *buf) 1037 const char *buf)
1074{ 1038{
1075 return blkcg_set_conf_u64(cgrp, cft, buf, 1039 return tg_set_conf(cgrp, cft, buf, false);
1076 throtl_update_blkio_group_write_iops);
1077} 1040}
1078 1041
1079static struct cftype throtl_files[] = { 1042static struct cftype throtl_files[] = {
1080 { 1043 {
1081 .name = "throttle.read_bps_device", 1044 .name = "throttle.read_bps_device",
1082 .private = offsetof(struct blkio_group_conf, bps[READ]), 1045 .private = offsetof(struct throtl_grp, bps[READ]),
1083 .read_seq_string = blkcg_print_conf_u64, 1046 .read_seq_string = tg_print_conf_u64,
1084 .write_string = blkcg_set_conf_bps_r, 1047 .write_string = tg_set_conf_u64,
1085 .max_write_len = 256, 1048 .max_write_len = 256,
1086 }, 1049 },
1087 { 1050 {
1088 .name = "throttle.write_bps_device", 1051 .name = "throttle.write_bps_device",
1089 .private = offsetof(struct blkio_group_conf, bps[WRITE]), 1052 .private = offsetof(struct throtl_grp, bps[WRITE]),
1090 .read_seq_string = blkcg_print_conf_u64, 1053 .read_seq_string = tg_print_conf_u64,
1091 .write_string = blkcg_set_conf_bps_w, 1054 .write_string = tg_set_conf_u64,
1092 .max_write_len = 256, 1055 .max_write_len = 256,
1093 }, 1056 },
1094 { 1057 {
1095 .name = "throttle.read_iops_device", 1058 .name = "throttle.read_iops_device",
1096 .private = offsetof(struct blkio_group_conf, iops[READ]), 1059 .private = offsetof(struct throtl_grp, iops[READ]),
1097 .read_seq_string = blkcg_print_conf_u64, 1060 .read_seq_string = tg_print_conf_uint,
1098 .write_string = blkcg_set_conf_iops_r, 1061 .write_string = tg_set_conf_uint,
1099 .max_write_len = 256, 1062 .max_write_len = 256,
1100 }, 1063 },
1101 { 1064 {
1102 .name = "throttle.write_iops_device", 1065 .name = "throttle.write_iops_device",
1103 .private = offsetof(struct blkio_group_conf, iops[WRITE]), 1066 .private = offsetof(struct throtl_grp, iops[WRITE]),
1104 .read_seq_string = blkcg_print_conf_u64, 1067 .read_seq_string = tg_print_conf_uint,
1105 .write_string = blkcg_set_conf_iops_w, 1068 .write_string = tg_set_conf_uint,
1106 .max_write_len = 256, 1069 .max_write_len = 256,
1107 }, 1070 },
1108 { 1071 {