[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] blkback disk I/O limit patch



Thanks for help and sorry for delay. I'm not fully understand how to
send patch via git send-email for specific mail thread.
May be i have missing message id (i cur it from last message, not first)

2013/2/1 Konrad Rzeszutek Wilk <konrad@xxxxxxxxxx>:
> 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
>>



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.