|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] blkback disk I/O limit patch
On Fri, Feb 01, 2013 at 10:53:46AM +0400, Vasiliy Tolstov wrote:
> Sorry,
Ugh, you didn't inline it - you just copied and pasted it.
Also you are missing an SoB and a description of what this patch does
and why is it better than existing device mapper I/O limiting work?
>
> diff -NruabBEp xen_blkback_limit.orig/blkback.c
> xen_blkback_limit.new//blkback.c
> --- xen_blkback_limit.orig/blkback.c 2012-12-04 13:03:58.000000000 +0400
> +++ xen_blkback_limit.new//blkback.c 2013-01-28 08:11:30.000000000 +0400
> @@ -211,10 +211,18 @@ static void print_stats(blkif_t *blkif)
> blkif->st_pk_req = 0;
> }
>
> +static void refill_iops(blkif_t *blkif)
> +{
> + blkif->reqtime = jiffies + msecs_to_jiffies(1000);
> + blkif->reqcount = 0;
> +}
> +
> int blkif_schedule(void *arg)
> {
> blkif_t *blkif = arg;
> struct vbd *vbd = &blkif->vbd;
> + int ret = 0;
> + struct timeval cur_time;
>
> blkif_get(blkif);
>
> @@ -237,10 +245,22 @@ int blkif_schedule(void *arg)
> blkif->waiting_reqs = 0;
> smp_mb(); /* clear flag *before* checking for work */
>
> - if (do_block_io_op(blkif))
> + ret = do_block_io_op(blkif);
> + if (ret)
> blkif->waiting_reqs = 1;
> unplug_queue(blkif);
>
> + if (blkif->reqrate) {
> + if (2 == ret && (blkif->reqtime > jiffies)) {
> + jiffies_to_timeval(jiffies, &cur_time);
> +
> + set_current_state(TASK_INTERRUPTIBLE);
> + schedule_timeout(blkif->reqtime - jiffies);
> + }
> + if (time_after(jiffies, blkif->reqtime))
> + refill_iops(blkif);
> + }
> +
> if (log_stats && time_after(jiffies, blkif->st_print))
> print_stats(blkif);
> }
> @@ -394,10 +414,19 @@ static int _do_block_io_op(blkif_t *blki
> rp = blk_rings->common.sring->req_prod;
> rmb(); /* Ensure we see queued requests up to 'rp'. */
>
> + if (blkif->reqrate && (blkif->reqcount >= blkif->reqrate)) {
> + return (rc != rp) ? 2 : 0;
> + }
> +
> while (rc != rp) {
> if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
> break;
>
> + if (blkif->reqrate) {
> + if (blkif->reqcount >= blkif->reqrate)
> + return 2;
> + }
> +
> if (kthread_should_stop())
> return 1;
>
> @@ -434,8 +463,8 @@ static int _do_block_io_op(blkif_t *blki
>
> /* Apply all sanity checks to /private copy/ of request. */
> barrier();
> -
> dispatch_rw_block_io(blkif, &req, pending_req);
> + blkif->reqcount++;
> break;
> case BLKIF_OP_DISCARD:
> blk_rings->common.req_cons = rc;
> @@ -452,7 +481,7 @@ static int _do_block_io_op(blkif_t *blki
> break;
> default:
> /* A good sign something is wrong: sleep for a while to
> - * avoid excessive CPU consumption by a bad guest. */
> + * avoid excessive CPU consumption by a bad guest.*/
> msleep(1);
> blk_rings->common.req_cons = rc;
> barrier();
> @@ -501,6 +530,7 @@ static void dispatch_rw_block_io(blkif_t
> uint32_t flags;
> int ret, i;
> int operation;
> + struct timeval cur_time;
>
> switch (req->operation) {
> case BLKIF_OP_READ:
> @@ -658,6 +688,7 @@ static void dispatch_rw_block_io(blkif_t
> else
> blkif->st_wr_sect += preq.nr_sects;
>
> + jiffies_to_timeval(jiffies, &cur_time);
> return;
>
> fail_flush:
> diff -NruabBEp xen_blkback_limit.orig/common.h xen_blkback_limit.new//common.h
> --- xen_blkback_limit.orig/common.h 2012-12-04 13:03:58.000000000 +0400
> +++ xen_blkback_limit.new//common.h 2013-01-28 08:09:35.000000000 +0400
> @@ -82,6 +82,11 @@ typedef struct blkif_st {
> unsigned int waiting_reqs;
> struct request_queue *plug;
>
> + /* qos information */
> + unsigned long reqtime;
> + int reqcount;
> + int reqrate;
> +
> /* statistics */
> unsigned long st_print;
> int st_rd_req;
> @@ -106,6 +111,8 @@ struct backend_info
> unsigned major;
> unsigned minor;
> char *mode;
> + /* qos information */
> + struct xenbus_watch reqrate_watch;
> };
>
> blkif_t *blkif_alloc(domid_t domid);
> diff -NruabBEp xen_blkback_limit.orig/xenbus.c xen_blkback_limit.new//xenbus.c
> --- xen_blkback_limit.orig/xenbus.c 2012-12-04 13:03:58.000000000 +0400
> +++ xen_blkback_limit.new//xenbus.c 2013-01-28 08:22:26.000000000 +0400
> @@ -120,6 +120,79 @@ static void update_blkif_status(blkif_t
> } \
> static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
>
> +static ssize_t
> +show_reqrate(struct device *_dev, struct device_attribute *attr, char *buf)
> +{
> + ssize_t ret = -ENODEV;
> + struct xenbus_device *dev;
> + struct backend_info *be;
> +
> + if (!get_device(_dev))
> + return ret;
> +
> + dev = to_xenbus_device(_dev);
> + be = dev_get_drvdata(&dev->dev);
> +
> + if (be != NULL)
> + ret = sprintf(buf, "%d\n", be->blkif->reqrate);
> +
> + put_device(_dev);
> +
> + return ret;
> +}
> +
> +static ssize_t
> +store_reqrate(struct device *_dev, struct device_attribute *attr,
> + const char *buf, size_t size)
> +{
> + int value;
> + struct xenbus_device *dev;
> + struct backend_info *be;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + if (!get_device(_dev))
> + return -ENODEV;
> +
> + if (sscanf(buf, "%d", &value) != 1)
> + return -EINVAL;
> +
> + dev = to_xenbus_device(_dev);
> + be = dev_get_drvdata(&dev->dev);
> +
> + if (be != NULL)
> + be->blkif->reqrate = value;
> +
> + put_device(_dev);
> +
> + return size;
> +}
> +static DEVICE_ATTR(reqrate, S_IRUGO | S_IWUSR, show_reqrate,
> + store_reqrate);
> +
> +static ssize_t
> +show_reqcount(struct device *_dev, struct device_attribute *attr, char *buf)
> +{
> + ssize_t ret = -ENODEV;
> + struct xenbus_device *dev;
> + struct backend_info *be;
> +
> + if (!get_device(_dev))
> + return ret;
> +
> + dev = to_xenbus_device(_dev);
> + be = dev_get_drvdata(&dev->dev);
> +
> + if (be != NULL)
> + ret = sprintf(buf, "%d\n", be->blkif->reqcount);
> +
> + put_device(_dev);
> +
> + return ret;
> +}
> +static DEVICE_ATTR(reqcount, S_IRUGO | S_IWUSR, show_reqcount, NULL);
> +
> VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
> VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
> VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
> @@ -146,6 +219,17 @@ static const struct attribute_group vbds
> .attrs = vbdstat_attrs,
> };
>
> +static struct attribute *vbdreq_attrs[] = {
> + &dev_attr_reqrate.attr,
> + &dev_attr_reqcount.attr,
> + NULL
> +};
> +
> +static const struct attribute_group vbdreq_group = {
> + .name = "qos",
> + .attrs = vbdreq_attrs,
> +};
> +
> VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
> VBD_SHOW(mode, "%s\n", be->mode);
>
> @@ -165,8 +249,13 @@ int xenvbd_sysfs_addif(struct xenbus_dev
> if (error)
> goto fail3;
>
> + error = sysfs_create_group(&dev->dev.kobj, &vbdreq_group);
> + if (error)
> + goto fail4;
> +
> return 0;
>
> +fail4: sysfs_remove_group(&dev->dev.kobj, &vbdreq_group);
> fail3: sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
> fail2: device_remove_file(&dev->dev, &dev_attr_mode);
> fail1: device_remove_file(&dev->dev, &dev_attr_physical_device);
> @@ -175,6 +264,7 @@ fail1: device_remove_file(&dev->dev, &de
>
> void xenvbd_sysfs_delif(struct xenbus_device *dev)
> {
> + sysfs_remove_group(&dev->dev.kobj, &vbdreq_group);
> sysfs_remove_group(&dev->dev.kobj, &vbdstat_group);
> device_remove_file(&dev->dev, &dev_attr_mode);
> device_remove_file(&dev->dev, &dev_attr_physical_device);
> @@ -201,6 +291,12 @@ static int blkback_remove(struct xenbus_
> be->cdrom_watch.node = NULL;
> }
>
> + if (be->reqrate_watch.node) {
> + unregister_xenbus_watch(&be->reqrate_watch);
> + kfree(be->reqrate_watch.node);
> + be->reqrate_watch.node = NULL;
> + }
> +
> if (be->blkif) {
> blkif_disconnect(be->blkif);
> vbd_free(&be->blkif->vbd);
> @@ -338,6 +434,7 @@ static void backend_changed(struct xenbu
> struct xenbus_device *dev = be->dev;
> int cdrom = 0;
> char *device_type;
> + char name[TASK_COMM_LEN];
>
> DPRINTK("");
>
> @@ -376,6 +473,21 @@ static void backend_changed(struct xenbu
> kfree(device_type);
> }
>
> + /* gather information about QoS policy for this device. */
> + err = blkback_name(be->blkif, name);
> + if (err) {
> + xenbus_dev_error(be->dev, err, "get blkback dev name");
> + return;
> + }
> +
> + err = xenbus_gather(XBT_NIL, dev->otherend,
> + "reqrate", "%d", &be->blkif->reqrate,
> + NULL);
> + if (err)
> + DPRINTK("%s xenbus_gather(reqrate) error", name);
> +
> + be->blkif->reqtime = jiffies;
> +
> if (be->major == 0 && be->minor == 0) {
> /* Front end dir is a number, which is used as the handle. */
>
> @@ -482,6 +594,30 @@ static void frontend_changed(struct xenb
>
> /* ** Connection ** */
>
> +static void reqrate_changed(struct xenbus_watch *watch,
> + const char **vec, unsigned int len)
> +{
> + struct backend_info *be = container_of(watch, struct backend_info,
> + reqrate_watch);
> + int err;
> + char name[TASK_COMM_LEN];
> +
> + err = blkback_name(be->blkif, name);
> + if (err) {
> + xenbus_dev_error(be->dev, err, "get blkback dev name");
> + return;
> + }
> +
> + err = xenbus_gather(XBT_NIL, be->dev->otherend,
> + "reqrate", "%d",
> + &be->blkif->reqrate, NULL);
> + if (err) {
> + DPRINTK("%s xenbus_gather(reqrate) error", name);
> + } else {
> + if (be->blkif->reqrate <= 0)
> + be->blkif->reqrate = 0;
> + }
> +}
>
> /**
> * Write the physical details regarding the block device to the store, and
> @@ -542,6 +678,21 @@ again:
> xenbus_dev_fatal(dev, err, "%s: switching to Connected state",
> dev->nodename);
>
> + if (be->reqrate_watch.node) {
> + unregister_xenbus_watch(&be->reqrate_watch);
> + kfree(be->reqrate_watch.node);
> + be->reqrate_watch.node = NULL;
> + }
> +
> + err = xenbus_watch_path2(dev, dev->otherend, "reqrate",
> + &be->reqrate_watch,
> + reqrate_changed);
> + if (err) {
> + xenbus_dev_fatal(dev, err, "%s: watching reqrate",
> + dev->nodename);
> + goto abort;
> + }
> +
> return;
> abort:
> xenbus_transaction_end(xbt, 1);
>
> 2013/1/31 Wei Liu <wei.liu2@xxxxxxxxxx>:
> > On Thu, 2013-01-31 at 05:14 +0000, Vasiliy Tolstov wrote:
> >> Sorry forget to send patch
> >> https://bitbucket.org/go2clouds/patches/raw/master/xen_blkback_limit/3.6.9-1.patch
> >> Patch for kernel 3.6.9, but if that needed i can rebase it to current
> >> git Linus tree.
> >
> > Can you inline your patch in your email so that developer can comment on
> > it.
> >
> >
> > Wei.
> >
>
>
>
> --
> Vasiliy Tolstov,
> Clodo.ru
> e-mail: v.tolstov@xxxxxxxxx
> jabber: vase@xxxxxxxxx
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |