All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrea Righi <righi.andrea@gmail.com>
To: Li Zefan <lizf@cn.fujitsu.com>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>,
	Paul Menage <menage@google.com>,
	akpm@linux-foundation.org,
	Carl Henrik Lunde <chlunde@ping.uio.no>,
	axboe@kernel.dk, matt@bluehost.com, roberto@unbit.it,
	randy.dunlap@oracle.com, Divyesh Shah <dpshah@google.com>,
	subrata@linux.vnet.ibm.com, eric.rannaud@gmail.com,
	containers@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH -mm 2/3] i/o bandwidth controller infrastructure
Date: Mon, 14 Jul 2008 23:26:51 +0200	[thread overview]
Message-ID: <487BC49B.7080105@gmail.com> (raw)
In-Reply-To: <487AB912.9090908@cn.fujitsu.com>

Li Zefan wrote:
>> +/* The various types of throttling algorithms */
>> +enum iothrottle_strategy {
>> +	IOTHROTTLE_LEAKY_BUCKET,
> 
> It's better to explicitly assigned 0 to IOTHROTTLE_LEAKY_BUCKET.

OK.

> 
>> +	IOTHROTTLE_TOKEN_BUCKET,
>> +};
> 
>> +static int iothrottle_parse_args(char *buf, size_t nbytes, dev_t *dev,
>> +					u64 *iorate,
>> +					enum iothrottle_strategy *strategy,
>> +					s64 *bucket_size)
>> +{
>> +	char *p = buf;
>> +	int count = 0;
>> +	char *s[3];
>> +	unsigned long strategy_val;
>> +	int ret;
>> +
>> +	/* split the colon-delimited input string into its elements */
>> +	memset(s, 0, sizeof(s));
>> +	while (count < ARRAY_SIZE(s)) {
>> +		p = memchr(p, ':', buf + nbytes - p);
>> +		if (!p)
>> +			break;
>> +		*p++ = '\0';
>> +		if (p >= buf + nbytes)
>> +			break;
>> +		s[count++] = p;
>> +	}
> 
> use strsep()

OK.

> 
>> +
>> +	/* i/o bandwidth limit */
>> +	if (!s[0])
>> +		return -EINVAL;
>> +	ret = strict_strtoull(s[0], 10, iorate);
>> +	if (ret < 0)
>> +		return ret;
>> +	if (!*iorate) {
>> +		/*
>> +		 * we're deleting a limiting rule, so just ignore the other
>> +		 * parameters
>> +		 */
>> +		*strategy = 0;
>> +		*bucket_size = 0;
>> +		goto out;
>> +	}
>> +	*iorate = ALIGN(*iorate, 1024);
>> +
>> +	/* throttling strategy */
>> +	if (!s[1])
>> +		return -EINVAL;
>> +	ret = strict_strtoul(s[1], 10, &strategy_val);
>> +	if (ret < 0)
>> +		return ret;
>> +	*strategy = (enum iothrottle_strategy)strategy_val;
>> +	switch (*strategy) {
>> +	case IOTHROTTLE_LEAKY_BUCKET:
>> +		/* leaky bucket ignores bucket size */
>> +		*bucket_size = 0;
>> +		goto out;
>> +	case IOTHROTTLE_TOKEN_BUCKET:
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* bucket size */
>> +	if (!s[2])
>> +		return -EINVAL;
>> +	ret = strict_strtoll(s[2], 10, bucket_size);
>> +	if (ret < 0)
>> +		return ret;
>> +	if (*bucket_size < 0)
>> +		return -EINVAL;
>> +	*bucket_size = ALIGN(*bucket_size, 1024);
>> +out:
>> +
>> +	/* block device number */
>> +	*dev = devname2dev_t(buf);
> 
> why not parse dev before parse bandwidth limit ?

Well... due to the filesystem lookup in devname2dev_t() this option is
the most expensive to be parsed. For this reason I put it at the end, so
if any other parameter is wrong we can skip the lookup_bdev(). Does it
make sense?

> 
>> +	return *dev ? 0 : -EINVAL;
>> +}
>> +
>> +static int iothrottle_write(struct cgroup *cgrp, struct cftype *cft,
>> +				const char *buffer)
>> +{
>> +	struct iothrottle *iot;
>> +	struct iothrottle_node *n, *newn = NULL;
>> +	dev_t dev;
>> +	u64 iorate;
>> +	enum iothrottle_strategy strategy;
>> +	s64 bucket_size;
>> +	char *buf;
>> +	size_t nbytes = strlen(buffer);
>> +	int ret = 0;
>> +
>> +	buf = kmalloc(nbytes + 1, GFP_KERNEL);
>> +	if (!buf)
>> +		return -ENOMEM;
>> +	memcpy(buf, buffer, nbytes + 1);
>> +
> 
> redundant kmalloc, just use buffer, and ...


uhmm... I would apply strsep() directly to buffer in this way, that is
a const char *.

> 
>> +	ret = iothrottle_parse_args(buf, nbytes, &dev, &iorate,
>> +					&strategy, &bucket_size);
>> +	if (ret)
>> +		goto out1;
>> +	if (iorate) {
>> +		newn = kmalloc(sizeof(*newn), GFP_KERNEL);
>> +		if (!newn) {
>> +			ret = -ENOMEM;
>> +			goto out1;
>> +		}
>> +		newn->dev = dev;
>> +		newn->iorate = iorate;
>> +		newn->strategy = strategy;
>> +		newn->bucket_size = bucket_size;
>> +		newn->timestamp = jiffies;
>> +		atomic_long_set(&newn->stat, 0);
>> +		atomic_long_set(&newn->token, 0);
>> +	}
>> +	if (!cgroup_lock_live_group(cgrp)) {
>> +		kfree(newn);
>> +		ret = -ENODEV;
>> +		goto out1;
>> +	}
>> +	iot = cgroup_to_iothrottle(cgrp);
>> +
>> +	spin_lock(&iot->lock);
>> +	if (!iorate) {
>> +		/* Delete a block device limiting rule */
>> +		n = iothrottle_delete_node(iot, dev);
>> +		goto out2;
>> +	}
>> +	n = iothrottle_search_node(iot, dev);
>> +	if (n) {
>> +		/* Update a block device limiting rule */
>> +		iothrottle_replace_node(iot, n, newn);
>> +		goto out2;
>> +	}
>> +	/* Add a new block device limiting rule */
>> +	iothrottle_insert_node(iot, newn);
>> +out2:
>> +	spin_unlock(&iot->lock);
>> +	cgroup_unlock();
>> +	if (n) {
>> +		synchronize_rcu();
>> +		kfree(n);
>> +	}
>> +out1:
>> +	kfree(buf);
>> +	return ret;
>> +}
>> +
>> +static struct cftype files[] = {
>> +	{
>> +		.name = "bandwidth",
>> +		.read_seq_string = iothrottle_read,
>> +		.write_string = iothrottle_write,
> 
> and you should specify .max_write_len = XXX unless XXX <= 64.
> You use 1024 in v4.

OK. Anyway, probably something like 256 would be enough.

Thanks again for the detailed revision Li! I'll include your fixes in
a new patchset version.

-Andrea

  reply	other threads:[~2008-07-14 21:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-12 11:31 [PATCH -mm 2/3] i/o bandwidth controller infrastructure Andrea Righi
2008-07-14  2:25 ` Li Zefan
2008-07-14 21:26   ` Andrea Righi [this message]
     [not found]   ` <487AB912.9090908-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
2008-07-14 21:26     ` Andrea Righi
     [not found] ` <1215862291-26719-3-git-send-email-righi.andrea-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2008-07-14  2:25   ` Li Zefan
  -- strict thread matches above, loose matches on Subject: below --
2008-07-22 20:58 Andrea Righi
2008-07-22 20:58 ` Andrea Righi
2008-07-15 20:40 Andrea Righi
2008-07-15 20:40 Andrea Righi
2008-07-12 11:31 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=487BC49B.7080105@gmail.com \
    --to=righi.andrea@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=axboe@kernel.dk \
    --cc=balbir@linux.vnet.ibm.com \
    --cc=chlunde@ping.uio.no \
    --cc=containers@lists.linux-foundation.org \
    --cc=dpshah@google.com \
    --cc=eric.rannaud@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizf@cn.fujitsu.com \
    --cc=matt@bluehost.com \
    --cc=menage@google.com \
    --cc=randy.dunlap@oracle.com \
    --cc=roberto@unbit.it \
    --cc=subrata@linux.vnet.ibm.com \
    /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.