From: Andrea Righi <righi.andrea@gmail.com>
To: Paul Menage <menage@google.com>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>,
Gui Jianfeng <guijianfeng@cn.fujitsu.com>,
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
agk@sourceware.org, akpm@linux-foundation.org, axboe@kernel.dk,
tytso@mit.edu, baramsori72@gmail.com,
Carl Henrik Lunde <chlunde@ping.uio.no>,
dave@linux.vnet.ibm.com, Divyesh Shah <dpshah@google.com>,
eric.rannaud@gmail.com, fernando@oss.ntt.co.jp,
Hirokazu Takahashi <taka@valinux.co.jp>,
Li Zefan <lizf@cn.fujitsu.com>,
matt@bluehost.com, dradford@bluehost.com, ngupta@google.com,
randy.dunlap@oracle.com, roberto@unbit.it,
Ryo Tsuruta <ryov@valinux.co.jp>,
Satoshi UCHIDA <s-uchida@ap.jp.nec.com>,
subrata@linux.vnet.ibm.com, yoshikawa.takuya@oss.ntt.co.jp,
Nauman Rafique <nauman@google.com>,
fchecconi@gmail.com, paolo.valente@unimore.it,
m-ikeda@ds.jp.nec.com, paulmck@linux.vnet.ibm.com,
containers@lists.linux-foundation.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v15 2/7] res_counter: introduce ratelimiting attributes
Date: Tue, 28 Apr 2009 16:39:29 +0200 [thread overview]
Message-ID: <20090428143927.GA990@linux> (raw)
In-Reply-To: <1240908234-15434-3-git-send-email-righi.andrea@gmail.com>
Subject: io-throttle: reduce the size of res_counter
Reduce the size of struct res_counter after the introduction of
ratelimited resources:
- replace policy with a more generic unsigned long flags and encode the
throttling policy using a single bit of flags
- remove the attribute capacity: max_usage is not used in ratelimited
resources and capacity is not used in all the other cases (it has been
introduced only for token-bucket ratelimited resources), so just merge
capacitiy into max_usage
On a 64-bit architecture:
vanilla: sizeof(struct res_counter) = 48
with-io-throttle: sizeof(struct res_counter) = 72
with-io-throttle-and-reduced-res-counter: sizeof(struct res_counter) = 64
[ This patch must be applied on top of io-throttle v15. ]
Signed-off-by: Andrea Righi <righi.andrea@gmail.com>
---
block/blk-io-throttle.c | 14 ++++++++------
include/linux/res_counter.h | 40 +++++++++++++++++++++++++---------------
kernel/res_counter.c | 23 ++++++-----------------
3 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/block/blk-io-throttle.c b/block/blk-io-throttle.c
index 8dc2c93..a7edc47 100644
--- a/block/blk-io-throttle.c
+++ b/block/blk-io-throttle.c
@@ -257,10 +257,11 @@ static void iothrottle_show_limit(struct seq_file *m, dev_t dev,
{
if (!res->limit)
return;
- seq_printf(m, "%u %u %llu %llu %lli %llu %li\n",
+ /* maj min bw-limit ratelimit-policy usage bucket-size delta-time */
+ seq_printf(m, "%u %u %llu %lu %lli %llu %li\n",
MAJOR(dev), MINOR(dev),
- res->limit, res->policy,
- (long long)res->usage, res->capacity,
+ res->limit, res_counter_flagged(res, RES_COUNTER_POLICY),
+ (long long)res->usage, res->max_usage,
jiffies_to_clock_t(res_counter_ratelimit_delta_t(res)));
}
@@ -361,7 +362,7 @@ static dev_t devname2dev_t(const char *buf)
*/
static int iothrottle_parse_args(char *buf, size_t nbytes, int filetype,
dev_t *dev, unsigned long long *iolimit,
- unsigned long long *strategy,
+ unsigned long *strategy,
unsigned long long *bucket_size)
{
char *p;
@@ -396,7 +397,7 @@ static int iothrottle_parse_args(char *buf, size_t nbytes, int filetype,
/* throttling strategy (leaky bucket / token bucket) */
if (!s[2])
return -EINVAL;
- ret = strict_strtoull(s[2], 10, strategy);
+ ret = strict_strtoul(s[2], 10, strategy);
if (ret < 0)
return ret;
switch (*strategy) {
@@ -429,7 +430,8 @@ static int iothrottle_write(struct cgroup *cgrp, struct cftype *cft,
struct iothrottle *iot;
struct iothrottle_node *n, *newn = NULL;
dev_t dev;
- unsigned long long iolimit, strategy, bucket_size;
+ unsigned long long iolimit, bucket_size;
+ unsigned long strategy;
char *buf;
size_t nbytes = strlen(buffer);
int ret = 0;
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 9bed6af..c18cee2 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -16,6 +16,15 @@
#include <linux/cgroup.h>
#include <linux/jiffies.h>
+/*
+ * res_counter flags
+ *
+ * bit 0 -- ratelimiting policy: leaky bucket / token bucket
+ */
+#define RES_COUNTER_POLICY 0
+
+#define res_counter_flagged(rc, flag) ((rc)->flags & (1 << (flag)))
+
/* The various policies that can be used for ratelimiting resources */
#define RATELIMIT_LEAKY_BUCKET 0
#define RATELIMIT_TOKEN_BUCKET 1
@@ -23,35 +32,32 @@
/**
* struct res_counter - the core object to account cgroup resources
*
+ * @flags: resource counter attributes
* @usage: the current resource consumption level
- * @max_usage: the maximal value of the usage from the counter creation
+ * @max_usage: the maximal value of the usage from the counter creation,
+ * or the maximum capacity of the resource (for ratelimited
+ * resources)
* @limit: the limit that usage cannot be exceeded
* @failcnt: the number of unsuccessful attempts to consume the resource
- * @policy: the limiting policy / algorithm
- * @capacity: the maximum capacity of the resource
* @timestamp: timestamp of the last accounted resource request
- * @lock: the lock to protect all of the above.
- * The routines below consider this to be IRQ-safe
+ * @lock: the lock to protect all of the above
+ * @parent: Parent counter, used for hierarchial resource accounting
*
* The cgroup that wishes to account for some resource may include this counter
* into its structures and use the helpers described beyond.
*/
struct res_counter {
+ unsigned long flags;
unsigned long long usage;
unsigned long long max_usage;
unsigned long long limit;
unsigned long long failcnt;
- unsigned long long policy;
- unsigned long long capacity;
unsigned long long timestamp;
/*
* the lock to protect all of the above.
* the routines below consider this to be IRQ-safe
*/
spinlock_t lock;
- /*
- * Parent counter, used for hierarchial resource accounting
- */
struct res_counter *parent;
};
@@ -90,9 +96,7 @@ enum {
RES_USAGE,
RES_MAX_USAGE,
RES_LIMIT,
- RES_POLICY,
RES_TIMESTAMP,
- RES_CAPACITY,
RES_FAILCNT,
};
@@ -183,15 +187,21 @@ static inline void res_counter_reset_failcnt(struct res_counter *cnt)
static inline int
res_counter_ratelimit_set_limit(struct res_counter *cnt,
- unsigned long long policy,
+ unsigned long policy,
unsigned long long limit, unsigned long long max)
{
unsigned long flags;
spin_lock_irqsave(&cnt->lock, flags);
cnt->limit = limit;
- cnt->capacity = max;
- cnt->policy = policy;
+ /*
+ * In ratelimited res_counter max_usage is used to save the token
+ * bucket capacity.
+ */
+ cnt->max_usage = max;
+ cnt->flags = 0;
+ if (policy == RATELIMIT_TOKEN_BUCKET)
+ set_bit(RES_COUNTER_POLICY, &cnt->flags);
cnt->timestamp = get_jiffies_64();
cnt->usage = 0;
spin_unlock_irqrestore(&cnt->lock, flags);
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 6f882c6..f6d97a2 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -21,7 +21,6 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent)
spin_lock_init(&counter->lock);
counter->limit = (unsigned long long)LLONG_MAX;
counter->parent = parent;
- counter->capacity = (unsigned long long)LLONG_MAX;
counter->timestamp = get_jiffies_64();
}
@@ -102,12 +101,8 @@ res_counter_member(struct res_counter *counter, int member)
return &counter->max_usage;
case RES_LIMIT:
return &counter->limit;
- case RES_POLICY:
- return &counter->policy;
case RES_TIMESTAMP:
return &counter->timestamp;
- case RES_CAPACITY:
- return &counter->capacity;
case RES_FAILCNT:
return &counter->failcnt;
};
@@ -205,7 +200,7 @@ ratelimit_token_bucket(struct res_counter *res, ssize_t val)
res->timestamp = get_jiffies_64();
tok = (long long)res->usage * MSEC_PER_SEC;
if (delta) {
- long long max = (long long)res->capacity * MSEC_PER_SEC;
+ long long max = (long long)res->max_usage * MSEC_PER_SEC;
tok += delta * res->limit;
tok = max_t(long long, tok, max);
@@ -221,18 +216,12 @@ res_counter_ratelimit_sleep(struct res_counter *res, ssize_t val)
unsigned long flags;
spin_lock_irqsave(&res->lock, flags);
- if (res->limit)
- switch (res->policy) {
- case RATELIMIT_LEAKY_BUCKET:
- sleep = ratelimit_leaky_bucket(res, val);
- break;
- case RATELIMIT_TOKEN_BUCKET:
+ if (res->limit) {
+ if (res_counter_flagged(res, RES_COUNTER_POLICY))
sleep = ratelimit_token_bucket(res, val);
- break;
- default:
- WARN_ON(1);
- break;
- }
+ else
+ sleep = ratelimit_leaky_bucket(res, val);
+ }
spin_unlock_irqrestore(&res->lock, flags);
return sleep;
}
next prev parent reply other threads:[~2009-04-28 14:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-28 8:43 [PATCH v15 0/7] cgroup: io-throttle controller Andrea Righi
2009-04-28 8:43 ` [PATCH v15 1/7] io-throttle documentation Andrea Righi
2009-04-28 8:43 ` [PATCH v15 2/7] res_counter: introduce ratelimiting attributes Andrea Righi
[not found] ` <1240908234-15434-3-git-send-email-righi.andrea-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-04-28 14:39 ` Andrea Righi
2009-04-28 14:39 ` Andrea Righi [this message]
2009-04-28 8:43 ` [PATCH v15 3/7] page_cgroup: provide a generic page tracking infrastructure Andrea Righi
2009-04-28 8:43 ` [PATCH v15 4/7] io-throttle controller infrastructure Andrea Righi
[not found] ` <1240908234-15434-5-git-send-email-righi.andrea-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-04-28 14:50 ` Andrea Righi
2009-04-28 14:50 ` Andrea Righi
[not found] ` <1240908234-15434-1-git-send-email-righi.andrea-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-04-28 8:43 ` [PATCH v15 1/7] io-throttle documentation Andrea Righi
2009-04-28 8:43 ` [PATCH v15 2/7] res_counter: introduce ratelimiting attributes Andrea Righi
2009-04-28 8:43 ` [PATCH v15 3/7] page_cgroup: provide a generic page tracking infrastructure Andrea Righi
2009-04-28 8:43 ` [PATCH v15 4/7] io-throttle controller infrastructure Andrea Righi
2009-04-28 8:43 ` [PATCH v15 5/7] kiothrottled: throttle buffered (writeback) IO Andrea Righi
2009-04-28 8:43 ` [PATCH v15 6/7] io-throttle instrumentation Andrea Righi
2009-04-28 8:43 ` [PATCH v15 7/7] io-throttle: export per-task statistics to userspace Andrea Righi
2009-04-28 8:47 ` [PATCH v15 0/7] cgroup: io-throttle controller Andrea Righi
2009-04-28 8:43 ` [PATCH v15 5/7] kiothrottled: throttle buffered (writeback) IO Andrea Righi
2009-04-28 8:43 ` [PATCH v15 6/7] io-throttle instrumentation Andrea Righi
2009-04-28 8:43 ` [PATCH v15 7/7] io-throttle: export per-task statistics to userspace Andrea Righi
2009-04-28 8:47 ` [PATCH v15 0/7] cgroup: io-throttle controller Andrea Righi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090428143927.GA990@linux \
--to=righi.andrea@gmail.com \
--cc=agk@sourceware.org \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=balbir@linux.vnet.ibm.com \
--cc=baramsori72@gmail.com \
--cc=chlunde@ping.uio.no \
--cc=containers@lists.linux-foundation.org \
--cc=dave@linux.vnet.ibm.com \
--cc=dpshah@google.com \
--cc=dradford@bluehost.com \
--cc=eric.rannaud@gmail.com \
--cc=fchecconi@gmail.com \
--cc=fernando@oss.ntt.co.jp \
--cc=guijianfeng@cn.fujitsu.com \
--cc=kamezawa.hiroyu@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=m-ikeda@ds.jp.nec.com \
--cc=matt@bluehost.com \
--cc=menage@google.com \
--cc=nauman@google.com \
--cc=ngupta@google.com \
--cc=paolo.valente@unimore.it \
--cc=paulmck@linux.vnet.ibm.com \
--cc=randy.dunlap@oracle.com \
--cc=roberto@unbit.it \
--cc=ryov@valinux.co.jp \
--cc=s-uchida@ap.jp.nec.com \
--cc=subrata@linux.vnet.ibm.com \
--cc=taka@valinux.co.jp \
--cc=tytso@mit.edu \
--cc=yoshikawa.takuya@oss.ntt.co.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.