[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 |