Volodya, please review it from the interface's point of view. -- Best regards,
Konstantin Khorenko, Virtuozzo Linux Kernel Team On 04/27/2015 05:50 PM, Dmitry Monakhov wrote: > 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 > > Signed-off-by: Dmitry Monakhov <dmonak...@openvz.org> > --- > 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 9e2b014..d78bf27 100644 > --- a/kernel/ve/vziolimit.c > +++ b/kernel/ve/vziolimit.c > @@ -25,6 +25,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) > @@ -350,16 +360,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