[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [PATCH V4 2/3] xen-blkfront: teach blkfront driver to handle discard requests
On Fri, Sep 02, 2011 at 02:30:03PM +0800, Li Dongyang wrote: > On Thu, Sep 1, 2011 at 11:25 PM, Konrad Rzeszutek Wilk > <konrad.wilk@xxxxxxxxxx> wrote: > > On Thu, Sep 01, 2011 at 06:39:09PM +0800, Li Dongyang wrote: > >> The blkfront driver now will read discard related nodes from xenstore, > >> and set up the request queue, then we can forward the > >> discard requests to backend driver. > > > > > > A better description is as follow: > > > > xen-blkfront: Handle discard requests. > > > > If the backend advertises 'feature-discard', then interrogate > > the backend for alignment, granularity, and max discard block size. > > Setup the request queue with the appropiate values and send the > > discard operation as required. > > > thanks for the description, way better than mine :-) OK. Lets use that. .. snip.. > >> + if (info->feature_discard) { > >> + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, rq); > >> + blk_queue_max_discard_sectors(rq, get_capacity(gd)); > > > > This is not correct. I took a look at the SCSI support for this > > ('sd_config_discard') and if you look there carefully you will see that > > the value can be 64KB for example. > well I don't think so, max_discard_sectors are used to split the bio, > make them not to > exceed the max_discard_sectors, see blkdev_issue_discard, and > that's fine if we use the capacity as max_discard_sectors > in guest: for file backend, there's no need for max_discard_sectors, > and for phy backend, we'll make the blkfront sent out a single big > discard request, Right, one sector for the whole disk size. > and when we deal with that in blkback by calling blkdev_issue_discard, > the real max_discard_sectors > from phy dev will be used, and take care of splitting bios, Thanks Ah, you are right: if (nr_sects > max_discard_sectors) { bio->bi_size = max_discard_sectors << 9; nr_sects -= max_discard_sectors; sector += max_discard_sectors; } else { handles when that value (nr_sects == get_capacity(x)) is extremely large. OK, that was the only issue I had - and that has been resolved. So stuck your patchset series in my tree - but they are not yet visisble at kernel.org > > > > > You need to provide a mechanism similar to 'discard-*' to fetch that data > > from the backend. > > > >> + rq->limits.discard_granularity = info->discard_granularity; > >> + rq->limits.discard_alignment = info->discard_alignment; > >> + } > >> + > >> /* Hard sector size and max sectors impersonate the equiv. hardware. > >> */ > >> blk_queue_logical_block_size(rq, sector_size); > >> blk_queue_max_hw_sectors(rq, 512); > >> @@ -722,6 +740,19 @@ static irqreturn_t blkif_interrupt(int irq, void > >> *dev_id) > >> > >> error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; > >> switch (bret->operation) { > >> + case BLKIF_OP_DISCARD: > >> + if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { > >> + struct request_queue *rq = info->rq; > >> + printk(KERN_WARNING "blkfront: %s: discard > >> op failed\n", > >> + info->gd->disk_name); > >> + error = -EOPNOTSUPP; > >> + info->feature_discard = 0; > >> + spin_lock(rq->queue_lock); > >> + queue_flag_clear(QUEUE_FLAG_DISCARD, rq); > >> + spin_unlock(rq->queue_lock); > >> + } > >> + __blk_end_request_all(req, error); > >> + break; > >> case BLKIF_OP_FLUSH_DISKCACHE: > >> case BLKIF_OP_WRITE_BARRIER: > >> if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { > >> @@ -1098,6 +1129,33 @@ blkfront_closing(struct blkfront_info *info) > >> bdput(bdev); > >> } > >> > >> +static void blkfront_setup_discard(struct blkfront_info *info) > >> +{ > >> + int err; > >> + char *type; > >> + unsigned int discard_granularity; > >> + unsigned int discard_alignment; > >> + > >> + type = xenbus_read(XBT_NIL, info->xbdev->otherend, "type", NULL); > >> + if (IS_ERR(type)) > >> + return; > >> + > >> + if (strncmp(type, "phy", 3) == 0) { > >> + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, > >> + "discard-granularity", "%u", &discard_granularity, > >> + "discard-alignment", "%u", &discard_alignment, > >> + NULL); > >> + if (!err) { > >> + info->feature_discard = 1; > >> + info->discard_granularity = discard_granularity; > >> + info->discard_alignment = discard_alignment; > >> + } > >> + } else if (strncmp(type, "file", 4) == 0) > >> + info->feature_discard = 1; > >> + > >> + kfree(type); > >> +} > >> + > >> /* > >> * Invoked when the backend is finally 'ready' (and has told produced > >> * the details about the physical device - #sectors, size, etc). > >> @@ -1108,7 +1166,7 @@ static void blkfront_connect(struct blkfront_info > >> *info) > >> unsigned long sector_size; > >> unsigned int binfo; > >> int err; > >> - int barrier, flush; > >> + int barrier, flush, discard; > >> > >> switch (info->connected) { > >> case BLKIF_STATE_CONNECTED: > >> @@ -1178,7 +1236,14 @@ static void blkfront_connect(struct blkfront_info > >> *info) > >> info->feature_flush = REQ_FLUSH; > >> info->flush_op = BLKIF_OP_FLUSH_DISKCACHE; > >> } > >> - > >> + > >> + err = xenbus_gather(XBT_NIL, info->xbdev->otherend, > >> + "feature-discard", "%d", &discard, > >> + NULL); > >> + > >> + if (!err && discard) > >> + blkfront_setup_discard(info); > >> + > >> err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); > >> if (err) { > >> xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", > >> -- > >> 1.7.6 > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |