[Devel] [PATCH RHEL7 COMMIT] vziolimit: add bc cgroup control

Konstantin Khorenko khorenko at odin.com
Tue May 5 05:37:42 PDT 2015


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 <dmonakhov at 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 <dmonakhov at openvz.org>
    Acked-by: Vladimir Davydov <vdavydov at 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);
 }



More information about the Devel mailing list