[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 05/10] xen/blkfront: negotiate number of queues/rings to be used with backend
On Mon, Nov 02, 2015 at 12:21:41PM +0800, Bob Liu wrote: > The number of hardware queues for xen/blkfront is set by parameter > 'max_queues'(default 4), while the max value xen/blkback supported is notified > through xenstore("multi-queue-max-queues"). That is not right. s/The number/The max number/ The second part: ",while the max value xen/blkback supported is..". I think you are trying to say: "it is also capped by the max value that the xen/blkback exposes through XenStore key 'multi-queue-max-queues'. > > The negotiated number is the smaller one and would be written back to xenstore > as "multi-queue-num-queues", blkback need to read this negotiated number. s/blkback need to read/blkback needs to read this/ > > Signed-off-by: Bob Liu <bob.liu@xxxxxxxxxx> > --- > drivers/block/xen-blkfront.c | 166 > +++++++++++++++++++++++++++++++------------ > 1 file changed, 120 insertions(+), 46 deletions(-) > > diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c > index 8cc5995..23096d7 100644 > --- a/drivers/block/xen-blkfront.c > +++ b/drivers/block/xen-blkfront.c > @@ -98,6 +98,10 @@ static unsigned int xen_blkif_max_segments = 32; > module_param_named(max, xen_blkif_max_segments, int, S_IRUGO); > MODULE_PARM_DESC(max, "Maximum amount of segments in indirect requests > (default is 32)"); > > +static unsigned int xen_blkif_max_queues = 4; > +module_param_named(max_queues, xen_blkif_max_queues, uint, S_IRUGO); > +MODULE_PARM_DESC(max_queues, "Maximum number of hardware queues/rings used > per virtual disk"); > + > /* > * Maximum order of pages to be used for the shared ring between front and > * backend, 4KB page granularity is used. > @@ -113,6 +117,7 @@ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of > pages to be used for the > * characters are enough. Define to 20 to keep consist with backend. > */ > #define RINGREF_NAME_LEN (20) > +#define QUEUE_NAME_LEN (12) Little bit of documentation please. Why 12? Why not 31415 for example? I presume it is 'queue-%u' and since so that is 7 + 10 (UINT_MAX is 4294967295) = 17! > > /* > * Per-ring info. > @@ -695,7 +700,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 > sector_size, > > memset(&info->tag_set, 0, sizeof(info->tag_set)); > info->tag_set.ops = &blkfront_mq_ops; > - info->tag_set.nr_hw_queues = 1; > + info->tag_set.nr_hw_queues = info->nr_rings; > info->tag_set.queue_depth = BLK_RING_SIZE(info); > info->tag_set.numa_node = NUMA_NO_NODE; > info->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE; > @@ -1352,6 +1357,51 @@ fail: > return err; > } > > +static int write_per_ring_nodes(struct xenbus_transaction xbt, > + struct blkfront_ring_info *rinfo, const char > *dir) > +{ > + int err, i; Please make 'i' be an unsigned int. Especially as you are using '%u' in the snprintf. > + const char *message = NULL; > + struct blkfront_info *info = rinfo->dev_info; > + > + if (info->nr_ring_pages == 1) { > + err = xenbus_printf(xbt, dir, "ring-ref", "%u", > rinfo->ring_ref[0]); > + if (err) { > + message = "writing ring-ref"; > + goto abort_transaction; > + } > + pr_info("%s: write ring-ref:%d\n", dir, rinfo->ring_ref[0]); Ewww. No. > + } else { > + for (i = 0; i < info->nr_ring_pages; i++) { > + char ring_ref_name[RINGREF_NAME_LEN]; > + > + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", > i); > + err = xenbus_printf(xbt, dir, ring_ref_name, > + "%u", rinfo->ring_ref[i]); > + if (err) { > + message = "writing ring-ref"; > + goto abort_transaction; > + } > + pr_info("%s: write ring-ref:%d\n", dir, > rinfo->ring_ref[i]); No no please. > + } > + } > + > + err = xenbus_printf(xbt, dir, "event-channel", "%u", rinfo->evtchn); That is not right. That only creates one. But the blkif.h says (And the example agrees) that there are N 'event-channel' for N-rings. Shouldn't this be part of the above loop? > + if (err) { > + message = "writing event-channel"; > + goto abort_transaction; > + } > + pr_info("%s: write event-channel:%d\n", dir, rinfo->evtchn); Please no. > + > + return 0; > + > +abort_transaction: > + xenbus_transaction_end(xbt, 1); > + if (message) > + xenbus_dev_fatal(info->xbdev, err, "%s", message); > + > + return err; > +} > > /* Common code used when first setting up, and when resuming. */ > static int talk_to_blkback(struct xenbus_device *dev, > @@ -1362,7 +1412,6 @@ static int talk_to_blkback(struct xenbus_device *dev, > int err, i; > unsigned int max_page_order = 0; > unsigned int ring_page_order = 0; > - struct blkfront_ring_info *rinfo; > > err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, > "max-ring-page-order", "%u", &max_page_order); > @@ -1374,7 +1423,8 @@ static int talk_to_blkback(struct xenbus_device *dev, > } > > for (i = 0; i < info->nr_rings; i++) { > - rinfo = &info->rinfo[i]; > + struct blkfront_ring_info *rinfo = &info->rinfo[i]; > + > /* Create shared ring, alloc event channel. */ > err = setup_blkring(dev, rinfo); > if (err) > @@ -1388,45 +1438,51 @@ again: > goto destroy_blkring; > } > > - if (info->nr_rings == 1) { > - rinfo = &info->rinfo[0]; > - if (info->nr_ring_pages == 1) { > - err = xenbus_printf(xbt, dev->nodename, > - "ring-ref", "%u", > rinfo->ring_ref[0]); > - if (err) { > - message = "writing ring-ref"; > - goto abort_transaction; > - } > - } else { > - err = xenbus_printf(xbt, dev->nodename, > - "ring-page-order", "%u", > ring_page_order); > - if (err) { > - message = "writing ring-page-order"; > - goto abort_transaction; > - } > + if (info->nr_ring_pages > 1) { > + err = xenbus_printf(xbt, dev->nodename, "ring-page-order", "%u", > + ring_page_order); > + if (err) { > + message = "writing ring-page-order"; > + goto abort_transaction; > + } > + } > > - for (i = 0; i < info->nr_ring_pages; i++) { > - char ring_ref_name[RINGREF_NAME_LEN]; > + /* We already got the number of queues/rings in _probe */ > + if (info->nr_rings == 1) { > + err = write_per_ring_nodes(xbt, &info->rinfo[0], dev->nodename); > + if (err) > + goto destroy_blkring; > + } else { > + char *path; > + size_t pathsize; > > - snprintf(ring_ref_name, RINGREF_NAME_LEN, > "ring-ref%u", i); > - err = xenbus_printf(xbt, dev->nodename, > ring_ref_name, > - "%u", rinfo->ring_ref[i]); > - if (err) { > - message = "writing ring-ref"; > - goto abort_transaction; > - } > - } > - } > - err = xenbus_printf(xbt, dev->nodename, > - "event-channel", "%u", rinfo->evtchn); > + err = xenbus_printf(xbt, dev->nodename, > "multi-queue-num-queues", "%u", > + info->nr_rings); > if (err) { > - message = "writing event-channel"; > + message = "writing multi-queue-num-queues"; > goto abort_transaction; > } > - } else { > - /* Not supported at this stage */ > - goto abort_transaction; > + > + pathsize = strlen(dev->nodename) + QUEUE_NAME_LEN; > + path = kmalloc(pathsize, GFP_KERNEL); > + if (!path) { > + err = -ENOMEM; > + message = "ENOMEM while writing ring references"; > + goto abort_transaction; > + } > + > + for (i = 0; i < info->nr_rings; i++) { > + memset(path, 0, pathsize); > + snprintf(path, pathsize, "%s/queue-%u", dev->nodename, > i); > + err = write_per_ring_nodes(xbt, &info->rinfo[i], path); > + if (err) { > + kfree(path); > + goto destroy_blkring; > + } > + } > + kfree(path); > } > + > err = xenbus_printf(xbt, dev->nodename, "protocol", "%s", > XEN_IO_PROTO_ABI_NATIVE); > if (err) { > @@ -1449,7 +1505,7 @@ again: > > for (i = 0; i < info->nr_rings; i++) { > int j; > - rinfo = &info->rinfo[i]; > + struct blkfront_ring_info *rinfo = &info->rinfo[i]; > > for (j = 0; j < BLK_RING_SIZE(info); j++) > rinfo->shadow[j].req.u.rw.id = j + 1; > @@ -1480,6 +1536,7 @@ static int blkfront_probe(struct xenbus_device *dev, > { > int err, vdevice, r_index; > struct blkfront_info *info; > + unsigned int backend_max_queues = 0; > > /* FIXME: Use dynamic device id if this is not set. */ > err = xenbus_scanf(XBT_NIL, dev->nodename, > @@ -1529,7 +1586,25 @@ static int blkfront_probe(struct xenbus_device *dev, > return -ENOMEM; > } > > - info->nr_rings = 1; > + mutex_init(&info->mutex); > + spin_lock_init(&info->dev_lock); > + info->xbdev = dev; > + info->vdevice = vdevice; > + INIT_LIST_HEAD(&info->grants); > + info->connected = BLKIF_STATE_DISCONNECTED; > + > + /* Check if backend supports multiple queues */ Missing full stop. > + err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, > + "multi-queue-max-queues", "%u", &backend_max_queues); > + if (err < 0) > + backend_max_queues = 1; > + > + info->nr_rings = min(backend_max_queues, xen_blkif_max_queues); > + if (info->nr_rings <= 0) It can't be < 0. 'nr_rings' is unsigned int. Perhaps 'if (!info->nr_rings) > + info->nr_rings = 1; > + pr_debug("Number of queues to be used:%u, though backend supports > max-queues:%u\n", > + info->nr_rings, backend_max_queues); > + How about putting this in 'xlvbd_flush'? It can report that there. And I am not sure if there is any need to include the backend_max_queues value. One can find that from XenStore. > info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * > info->nr_rings, GFP_KERNEL); > if (!info->rinfo) { > xenbus_dev_fatal(dev, -ENOMEM, "allocating ring_info > structure"); > @@ -1547,14 +1622,6 @@ static int blkfront_probe(struct xenbus_device *dev, > spin_lock_init(&rinfo->ring_lock); > } > > - mutex_init(&info->mutex); > - spin_lock_init(&info->dev_lock); > - info->xbdev = dev; > - info->vdevice = vdevice; > - INIT_LIST_HEAD(&info->grants); > - info->persistent_gnts_c = 0; > - info->connected = BLKIF_STATE_DISCONNECTED; > - > /* Front end dir is a number, which is used as the id. */ > info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); > dev_set_drvdata(&dev->dev, info); > @@ -2216,6 +2283,7 @@ static struct xenbus_driver blkfront_driver = { > static int __init xlblk_init(void) > { > int ret; > + int nr_cpus = num_online_cpus(); > > if (!xen_domain()) > return -ENODEV; > @@ -2226,6 +2294,12 @@ static int __init xlblk_init(void) > xen_blkif_max_ring_order = 0; > } > > + if (xen_blkif_max_queues > nr_cpus) { > + pr_info("Invalid max_queues (%d), will use default max: %d.\n", > + xen_blkif_max_queues, nr_cpus); > + xen_blkif_max_queues = nr_cpus; > + } > + > if (!xen_has_pv_disk_devices()) > return -ENODEV; > > -- > 1.8.3.1 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |