The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-123.1.2.vz7.4.9 ------> commit 2954da8377f2be38c31142d8aea37e22d8cefc4a Author: Dmitry Monakhov <dmonak...@openvz.org> Date: Tue May 5 16:37:42 2015 +0400
vziolimit: add bc cgroup control Example: Equivalent if: vzctl set $VE --iopslimit 10 --save echo 15000 > /sys/fs/cgroup/beancounter/$VE/beancounter.iopslimit.burst echo 1000 > /sys/fs/cgroup/beancounter/$VE/beancounter.iopslimit.latency echo 10 > /sys/fs/cgroup/beancounter/$VE/beancounter.iopslimit.speed https://jira.sw.ru/browse/PSBM-32281 Signed-off-by: Dmitry Monakhov <dmonak...@openvz.org> Acked-by: Vladimir Davydov <vdavy...@parallels.com> khorenko@: Need new cgroup interface because we need to identify Container not via CTID, but via string (CT UUID, in particular). --- include/bc/beancounter.h | 7 +++ kernel/bc/beancounter.c | 7 +-- kernel/ve/vziolimit.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 159 insertions(+), 7 deletions(-) diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h index 3ee6389..faf0197 100644 --- a/include/bc/beancounter.h +++ b/include/bc/beancounter.h @@ -178,6 +178,13 @@ enum ub_severity { UB_HARD, UB_SOFT, UB_FORCE }; #define UB_TEST 0x100 #define UB_SEV_FLAGS UB_TEST +extern struct cgroup_subsys ub_subsys; +static inline struct user_beancounter *cgroup_ub(struct cgroup *cg) +{ + return container_of(cgroup_subsys_state(cg, ub_subsys_id), + struct user_beancounter, css); +} + static inline int ub_barrier_hit(struct user_beancounter *ub, int resource) { return ub->ub_parms[resource].held > ub->ub_parms[resource].barrier; diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c index c9b17de..76936e0 100644 --- a/kernel/bc/beancounter.c +++ b/kernel/bc/beancounter.c @@ -319,12 +319,6 @@ LIST_HEAD(ub_list_head); /* protected by ub_list_lock */ EXPORT_SYMBOL(ub_list_head); int ub_count; -static inline struct user_beancounter *cgroup_ub(struct cgroup *cg) -{ - return container_of(cgroup_subsys_state(cg, ub_subsys_id), - struct user_beancounter, css); -} - /* * Per user resource beancounting. Resources are tied to their luid. * The resource structure itself is tagged both to the process and @@ -713,6 +707,7 @@ struct cgroup_subsys ub_subsys = { .attach = ub_cgroup_attach, .use_id = true, }; +EXPORT_SYMBOL(ub_subsys); /* * Generic resource charging stuff diff --git a/kernel/ve/vziolimit.c b/kernel/ve/vziolimit.c index a6f900d..fc8b24a 100644 --- a/kernel/ve/vziolimit.c +++ b/kernel/ve/vziolimit.c @@ -24,6 +24,16 @@ struct throttle { long long state; /* current state in units */ }; +enum { + UB_CGROUP_IOLIMIT_SPEED = 0, + UB_CGROUP_IOLIMIT_BURST = 1, + UB_CGROUP_IOLIMIT_LATENCY = 2, + UB_CGROUP_IOPSLIMIT_SPEED = 3, + UB_CGROUP_IOPSLIMIT_BURST = 4, + UB_CGROUP_IOPSLIMIT_LATENCY = 5, + +}; + /** * set throttler initial state, externally serialized * @speed maximum speed (1/sec) @@ -349,16 +359,156 @@ static struct vzioctlinfo iolimit_vzioctl = { .owner = THIS_MODULE, }; +static ssize_t iolimit_cgroup_read(struct cgroup *cg, struct cftype *cft, + struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + struct user_beancounter *ub = cgroup_ub(cg); + struct iolimit *iolimit = ub->private_data2; + unsigned long val = 0; + int len; + char str[32]; + + if (!iolimit) + goto out; + + spin_lock_irq(&ub->ub_lock); + switch (cft->private) { + case UB_CGROUP_IOLIMIT_SPEED: + val = iolimit->throttle.speed; + break; + case UB_CGROUP_IOLIMIT_BURST: + val = iolimit->throttle.burst; + break; + case UB_CGROUP_IOLIMIT_LATENCY: + val = iolimit->throttle.latency; + break; + + case UB_CGROUP_IOPSLIMIT_SPEED: + val = iolimit->iops.speed; + break; + case UB_CGROUP_IOPSLIMIT_BURST: + val = iolimit->iops.burst; + break; + case UB_CGROUP_IOPSLIMIT_LATENCY: + val = iolimit->iops.latency; + break; + default: + BUG(); + } + spin_unlock_irq(&ub->ub_lock); +out: + len = scnprintf(str, sizeof(str), "%lu\n", val); + return simple_read_from_buffer(buf, nbytes, ppos, str, len); +} + +static int iolimit_cgroup_write_u64(struct cgroup *cg, struct cftype *cft, u64 val) +{ + struct user_beancounter *ub = cgroup_ub(cg); + struct iolimit *iolimit; + + iolimit = iolimit_get(ub); + if (!iolimit) + return -ENOMEM; + + spin_lock_irq(&ub->ub_lock); + iolimit->throttle.time = iolimit->iops.time = jiffies; + + switch (cft->private) { + case UB_CGROUP_IOLIMIT_SPEED: + wmb(); + iolimit->throttle.speed = val; + break; + case UB_CGROUP_IOPSLIMIT_SPEED: + wmb(); + iolimit->iops.speed = val; + break; + case UB_CGROUP_IOLIMIT_BURST: + iolimit->throttle.burst = val; + break; + case UB_CGROUP_IOLIMIT_LATENCY: + iolimit->throttle.latency = val; + break; + case UB_CGROUP_IOPSLIMIT_BURST: + iolimit->iops.burst = val; + break; + case UB_CGROUP_IOPSLIMIT_LATENCY: + iolimit->iops.latency = val; + break; + default: + BUG(); + } + wake_up_all(&iolimit->wq); + spin_unlock_irq(&ub->ub_lock); + return 0; +} + +static struct cftype vziolimit_cftypes[] = { + { + .name = "iolimit.speed", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOLIMIT_SPEED, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + { + .name = "iolimit.burst", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOLIMIT_BURST, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + { + .name = "iolimit.latency", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOLIMIT_LATENCY, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + + { + .name = "iopslimit.speed", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOPSLIMIT_SPEED, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + { + .name = "iopslimit.burst", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOPSLIMIT_BURST, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + { + .name = "iopslimit.latency", + .flags = CFTYPE_NOT_ON_ROOT, + .private = UB_CGROUP_IOPSLIMIT_LATENCY, + .read = iolimit_cgroup_read, + .write_u64 = iolimit_cgroup_write_u64, + }, + { } +}; + static int __init iolimit_init(void) { + int err; virtinfo_notifier_register(VITYPE_IO, &iolimit_virtinfo_nb); vzioctl_register(&iolimit_vzioctl); - + err = cgroup_add_cftypes(&ub_subsys, vziolimit_cftypes); + if (err) + goto err_cgroup; return 0; + +err_cgroup: + vzioctl_unregister(&iolimit_vzioctl); + virtinfo_notifier_unregister(VITYPE_IO, &iolimit_virtinfo_nb); + return err; } static void __exit iolimit_exit(void) { + cgroup_rm_cftypes(&ub_subsys, vziolimit_cftypes); vzioctl_unregister(&iolimit_vzioctl); virtinfo_notifier_unregister(VITYPE_IO, &iolimit_virtinfo_nb); } _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel