From: plc@novell.com Subject: add support for new operation type BLKIF_OP_PACKET Patch-mainline: n/a References: fate#300964 --- head-2011-03-17.orig/drivers/xen/blkback/blkback.c 2011-02-28 14:15:32.000000000 +0100 +++ head-2011-03-17/drivers/xen/blkback/blkback.c 2011-02-28 14:23:53.000000000 +0100 @@ -194,13 +194,15 @@ static void fast_flush_area(pending_req_ static void print_stats(blkif_t *blkif) { - printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d\n", + printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | br %4d | pk %4d\n", current->comm, blkif->st_oo_req, - blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req); + blkif->st_rd_req, blkif->st_wr_req, blkif->st_br_req, + blkif->st_pk_req); blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); blkif->st_rd_req = 0; blkif->st_wr_req = 0; blkif->st_oo_req = 0; + blkif->st_pk_req = 0; } int blkif_schedule(void *arg) @@ -365,6 +367,13 @@ static int do_block_io_op(blkif_t *blkif blkif->st_wr_req++; dispatch_rw_block_io(blkif, &req, pending_req); break; + case BLKIF_OP_PACKET: + DPRINTK("error: block operation BLKIF_OP_PACKET not implemented\n"); + blkif->st_pk_req++; + make_response(blkif, req.id, req.operation, + BLKIF_RSP_ERROR); + free_req(pending_req); + break; default: /* A good sign something is wrong: sleep for a while to * avoid excessive CPU consumption by a bad guest. */ --- head-2011-03-17.orig/drivers/xen/blkback/common.h 2010-09-23 16:58:21.000000000 +0200 +++ head-2011-03-17/drivers/xen/blkback/common.h 2010-11-23 15:06:50.000000000 +0100 @@ -89,6 +89,7 @@ typedef struct blkif_st { int st_wr_req; int st_oo_req; int st_br_req; + int st_pk_req; int st_rd_sect; int st_wr_sect; --- head-2011-03-17.orig/drivers/xen/blkfront/blkfront.c 2011-02-03 12:37:02.000000000 +0100 +++ head-2011-03-17/drivers/xen/blkfront/blkfront.c 2010-12-06 15:01:01.000000000 +0100 @@ -708,6 +708,8 @@ static int blkif_queue_request(struct re if (req->cmd_flags & REQ_HARDBARRIER) #endif ring_req->operation = BLKIF_OP_WRITE_BARRIER; + if (req->cmd_type == REQ_TYPE_BLOCK_PC) + ring_req->operation = BLKIF_OP_PACKET; ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); @@ -765,7 +767,8 @@ void do_blkif_request(struct request_que blk_start_request(req); - if (req->cmd_type != REQ_TYPE_FS) { + if (req->cmd_type != REQ_TYPE_FS + && req->cmd_type != REQ_TYPE_BLOCK_PC) { __blk_end_request_all(req, -EIO); continue; } @@ -852,6 +855,7 @@ static irqreturn_t blkif_int(int irq, vo /* fall through */ case BLKIF_OP_READ: case BLKIF_OP_WRITE: + case BLKIF_OP_PACKET: if (unlikely(bret->status != BLKIF_RSP_OKAY)) DPRINTK("Bad return from blkdev data " "request: %x\n", bret->status); --- head-2011-03-17.orig/drivers/xen/blktap/blktap.c 2011-02-28 14:21:49.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap/blktap.c 2011-02-28 14:25:05.000000000 +0100 @@ -1129,13 +1129,14 @@ static void fast_flush_area(pending_req_ static void print_stats(blkif_t *blkif) { - printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d\n", + printk(KERN_DEBUG "%s: oo %3d | rd %4d | wr %4d | pk %4d\n", current->comm, blkif->st_oo_req, - blkif->st_rd_req, blkif->st_wr_req); + blkif->st_rd_req, blkif->st_wr_req, blkif->st_pk_req); blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000); blkif->st_rd_req = 0; blkif->st_wr_req = 0; blkif->st_oo_req = 0; + blkif->st_pk_req = 0; } int tap_blkif_schedule(void *arg) @@ -1382,6 +1383,11 @@ static int do_block_io_op(blkif_t *blkif dispatch_rw_block_io(blkif, &req, pending_req); break; + case BLKIF_OP_PACKET: + blkif->st_pk_req++; + dispatch_rw_block_io(blkif, &req, pending_req); + break; + default: /* A good sign something is wrong: sleep for a while to * avoid excessive CPU consumption by a bad guest. */ --- head-2011-03-17.orig/drivers/xen/blktap/common.h 2011-01-31 17:56:27.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap/common.h 2010-11-23 15:06:50.000000000 +0100 @@ -74,6 +74,7 @@ typedef struct blkif_st { int st_rd_req; int st_wr_req; int st_oo_req; + int st_pk_req; int st_rd_sect; int st_wr_sect; --- head-2011-03-17.orig/drivers/xen/blktap2/blktap.h 2011-02-24 15:24:27.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap2/blktap.h 2010-11-23 15:06:50.000000000 +0100 @@ -140,6 +140,7 @@ struct blktap_statistics { int st_rd_req; int st_wr_req; int st_oo_req; + int st_pk_req; int st_rd_sect; int st_wr_sect; s64 st_rd_cnt; --- head-2011-03-17.orig/drivers/xen/blktap2/device.c 2011-02-07 14:13:37.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap2/device.c 2010-11-23 15:06:50.000000000 +0100 @@ -366,7 +366,8 @@ blktap_device_fail_pending_requests(stru BTERR("%u:%u: failing pending %s of %d pages\n", blktap_device_major, tap->minor, - (request->operation == BLKIF_OP_READ ? + (request->operation == BLKIF_OP_PACKET ? + "packet" : request->operation == BLKIF_OP_READ ? "read" : "write"), request->nr_pages); blktap_unmap(tap, request); @@ -407,6 +408,7 @@ blktap_device_finish_request(struct blkt switch (request->operation) { case BLKIF_OP_READ: case BLKIF_OP_WRITE: + case BLKIF_OP_PACKET: if (unlikely(res->status != BLKIF_RSP_OKAY)) BTERR("Bad return from device data " "request: %x\n", res->status); @@ -644,6 +646,8 @@ blktap_device_process_request(struct blk blkif_req.handle = 0; blkif_req.operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; + if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC)) + blkif_req.operation = BLKIF_OP_PACKET; request->id = (unsigned long)req; request->operation = blkif_req.operation; @@ -709,7 +713,9 @@ blktap_device_process_request(struct blk wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */ ring->ring.req_prod_pvt++; - if (rq_data_dir(req)) { + if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC)) + tap->stats.st_pk_req++; + else if (rq_data_dir(req)) { tap->stats.st_wr_sect += nr_sects; tap->stats.st_wr_req++; } else { --- head-2011-03-17.orig/drivers/xen/blktap2-new/blktap.h 2011-02-24 15:00:29.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap2-new/blktap.h 2011-02-24 15:27:07.000000000 +0100 @@ -113,6 +113,7 @@ struct blktap_statistics { int st_rd_req; int st_wr_req; int st_oo_req; + int st_pk_req; int st_rd_sect; int st_wr_sect; s64 st_rd_cnt; --- head-2011-03-17.orig/drivers/xen/blktap2-new/device.c 2011-03-11 00:00:00.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap2-new/device.c 2011-03-11 11:09:10.000000000 +0100 @@ -189,6 +189,8 @@ blktap_device_make_request(struct blktap request->rq = rq; request->operation = write ? BLKIF_OP_WRITE : BLKIF_OP_READ; + if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC)) + request->operation = BLKIF_OP_PACKET; err = blktap_request_get_pages(tap, request, nsegs); if (err) --- head-2011-03-17.orig/drivers/xen/blktap2-new/ring.c 2011-02-24 15:10:15.000000000 +0100 +++ head-2011-03-17/drivers/xen/blktap2-new/ring.c 2011-02-24 15:39:28.000000000 +0100 @@ -153,11 +153,11 @@ blktap_ring_map_request(struct blktap *t int seg, err = 0; int write; - write = request->operation == BLKIF_OP_WRITE; + write = request->operation != BLKIF_OP_READ; for (seg = 0; seg < request->nr_pages; seg++) { if (write) - blktap_request_bounce(tap, request, seg, write); + blktap_request_bounce(tap, request, seg, 1); err = blktap_ring_map_segment(tap, request, seg); if (err) @@ -181,11 +181,11 @@ blktap_ring_unmap_request(struct blktap uaddr = MMAP_VADDR(ring->user_vstart, request->usr_idx, 0); size = request->nr_pages << PAGE_SHIFT; - read = request->operation == BLKIF_OP_READ; + read = request->operation != BLKIF_OP_WRITE; if (read) for (seg = 0; seg < request->nr_pages; seg++) - blktap_request_bounce(tap, request, seg, !read); + blktap_request_bounce(tap, request, seg, 0); zap_page_range(ring->vma, uaddr, size, NULL); } @@ -269,14 +269,20 @@ blktap_ring_submit_request(struct blktap do_gettimeofday(&request->time); - if (request->operation == BLKIF_OP_WRITE) { + switch (request->operation) { + case BLKIF_OP_WRITE: tap->stats.st_wr_sect += nsecs; tap->stats.st_wr_req++; - } + break; - if (request->operation == BLKIF_OP_READ) { + case BLKIF_OP_READ: tap->stats.st_rd_sect += nsecs; tap->stats.st_rd_req++; + break; + + case BLKIF_OP_PACKET: + tap->stats.st_pk_req++; + break; } } @@ -483,20 +489,24 @@ blktap_ring_debug(struct blktap *tap, ch for (usr_idx = 0; usr_idx < MAX_PENDING_REQS; usr_idx++) { struct blktap_request *request; struct timeval *time; - int write; + char op = '?'; request = ring->pending[usr_idx]; if (!request) continue; - write = request->operation == BLKIF_OP_WRITE; + switch (request->operation) { + case BLKIF_OP_WRITE: op = 'W'; break; + case BLKIF_OP_READ: op = 'R'; break; + case BLKIF_OP_PACKET: op = 'P'; break; + } time = &request->time; s += snprintf(s, end - s, "%02d: usr_idx:%02d " "op:%c nr_pages:%02d time:%lu.%09lu\n", usr_idx, request->usr_idx, - write ? 'W' : 'R', request->nr_pages, + op, request->nr_pages, time->tv_sec, time->tv_usec); } --- head-2011-03-17.orig/include/xen/interface/io/blkif.h 2011-03-17 13:50:24.000000000 +0100 +++ head-2011-03-17/include/xen/interface/io/blkif.h 2011-03-17 14:34:04.000000000 +0100 @@ -77,10 +77,9 @@ */ #define BLKIF_OP_FLUSH_DISKCACHE 3 /* - * Used in SLES sources for device specific command packet - * contained within the request. Reserved for that purpose. + * Device specific command packet contained within the request */ -#define BLKIF_OP_RESERVED_1 4 +#define BLKIF_OP_PACKET 4 /* * Recognised only if "feature-trim" is present in backend xenbus info. * The "feature-trim" node contains a boolean indicating whether trim