From: plc@novell.com
Subject: add support for new operation type BLKIF_OP_PACKET
Patch-mainline: n/a
References: fate#300964
--- head.orig/drivers/xen/blkback/blkback.c 2014-02-06 15:35:21.000000000 +0100
+++ head/drivers/xen/blkback/blkback.c 2014-04-01 12:16:55.000000000 +0200
@@ -214,10 +214,11 @@ static void fast_flush_area(pending_req_
static void print_stats(blkif_t *blkif)
{
printk(KERN_DEBUG "%s: oo %3lu | rd %4lu | wr %4lu | br %4lu"
- " | fl %4lu | ds %4lu\n",
+ " | fl %4lu | ds %4lu | pk %4lu\n",
current->comm, blkif->st_oo_req,
blkif->st_rd_req, blkif->st_wr_req,
- blkif->st_br_req, blkif->st_fl_req, blkif->st_ds_req);
+ blkif->st_br_req, blkif->st_fl_req,
+ blkif->st_ds_req, blkif->st_pk_req);
blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
blkif->st_rd_req = 0;
blkif->st_wr_req = 0;
@@ -225,6 +226,7 @@ static void print_stats(blkif_t *blkif)
blkif->st_br_req = 0;
blkif->st_fl_req = 0;
blkif->st_ds_req = 0;
+ blkif->st_pk_req = 0;
}
int blkif_schedule(void *arg)
@@ -543,6 +545,14 @@ static int _do_block_io_op(blkif_t *blki
barrier();
dispatch_indirect(blkif, (void *)&req, pending_req);
break;
+ case BLKIF_OP_PACKET:
+ blk_rings->common.req_cons = rc;
+ barrier();
+ blkif->st_pk_req++;
+ DPRINTK("error: block operation BLKIF_OP_PACKET not implemented\n");
+ make_response(blkif, req.id, req.operation,
+ BLKIF_RSP_ERROR);
+ break;
default:
/* A good sign something is wrong: sleep for a while to
* avoid excessive CPU consumption by a bad guest. */
--- head.orig/drivers/xen/blkback/common.h 2013-06-20 15:39:29.000000000 +0200
+++ head/drivers/xen/blkback/common.h 2013-04-03 11:39:52.000000000 +0200
@@ -106,6 +106,7 @@ typedef struct blkif_st {
unsigned long st_br_req;
unsigned long st_fl_req;
unsigned long st_ds_req;
+ unsigned long st_pk_req;
unsigned long st_rd_sect;
unsigned long st_wr_sect;
--- head.orig/drivers/xen/blkback/xenbus.c 2013-10-01 17:07:49.000000000 +0200
+++ head/drivers/xen/blkback/xenbus.c 2013-05-31 13:41:36.000000000 +0200
@@ -126,6 +126,7 @@ VBD_SHOW(wr_req, "%lu\n", be->blkif->st
VBD_SHOW(br_req, "%lu\n", be->blkif->st_br_req);
VBD_SHOW(fl_req, "%lu\n", be->blkif->st_fl_req);
VBD_SHOW(ds_req, "%lu\n", be->blkif->st_ds_req);
+VBD_SHOW(pk_req, "%lu\n", be->blkif->st_pk_req);
VBD_SHOW(rd_sect, "%lu\n", be->blkif->st_rd_sect);
VBD_SHOW(wr_sect, "%lu\n", be->blkif->st_wr_sect);
@@ -136,6 +137,7 @@ static struct attribute *vbdstat_attrs[]
&dev_attr_br_req.attr,
&dev_attr_fl_req.attr,
&dev_attr_ds_req.attr,
+ &dev_attr_pk_req.attr,
&dev_attr_rd_sect.attr,
&dev_attr_wr_sect.attr,
NULL
--- head.orig/drivers/xen/blkfront/blkfront.c 2014-05-12 10:12:31.000000000 +0200
+++ head/drivers/xen/blkfront/blkfront.c 2014-04-01 12:16:52.000000000 +0200
@@ -769,6 +769,7 @@ static const char *op_name(unsigned int
[BLKIF_OP_WRITE] = "write",
[BLKIF_OP_WRITE_BARRIER] = "barrier",
[BLKIF_OP_FLUSH_DISKCACHE] = "flush",
+ [BLKIF_OP_PACKET] = "packet",
[BLKIF_OP_DISCARD] = "discard",
[BLKIF_OP_INDIRECT] = "indirect",
};
@@ -1141,6 +1142,8 @@ static int blkif_queue_request(struct re
if (req->cmd_flags & REQ_HARDBARRIER)
#endif
ring_req->operation = info->flush_op;
+ if (req->cmd_type == REQ_TYPE_BLOCK_PC)
+ ring_req->operation = BLKIF_OP_PACKET;
if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) {
struct blkif_request_discard *discard = (void *)ring_req;
@@ -1236,7 +1239,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 || req->cmd_len)) ||
((req->cmd_flags & (REQ_FLUSH | REQ_FUA)) &&
!info->flush_op)) {
req->errors = (DID_ERROR << 16) |
@@ -1353,6 +1357,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 %s request: %d\n",
op_name(bret->operation),
--- head.orig/drivers/xen/blktap/blktap.c 2013-05-28 10:33:09.000000000 +0200
+++ head/drivers/xen/blktap/blktap.c 2013-06-20 15:39:46.000000000 +0200
@@ -1144,13 +1144,14 @@ static void fast_flush_area(pending_req_
static void print_stats(blkif_t *blkif)
{
- printk(KERN_DEBUG "%s: oo %3lu | rd %4lu | wr %4lu\n",
+ printk(KERN_DEBUG "%s: oo %3lu | rd %4lu | wr %4lu | pk %4lu\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)
@@ -1412,6 +1413,11 @@ static int _do_block_io_op(blkif_t *blki
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.orig/drivers/xen/blktap/common.h 2013-06-20 15:32:34.000000000 +0200
+++ head/drivers/xen/blktap/common.h 2013-04-03 11:08:02.000000000 +0200
@@ -70,6 +70,7 @@ typedef struct blkif_st {
unsigned long st_rd_req;
unsigned long st_wr_req;
unsigned long st_oo_req;
+ unsigned long st_pk_req;
unsigned long st_rd_sect;
unsigned long st_wr_sect;
--- head.orig/drivers/xen/blktap/xenbus.c 2013-06-20 15:39:35.000000000 +0200
+++ head/drivers/xen/blktap/xenbus.c 2013-04-03 11:39:28.000000000 +0200
@@ -136,6 +136,7 @@ static int blktap_name(blkif_t *blkif, c
VBD_SHOW(oo_req, "%lu\n", be->blkif->st_oo_req);
VBD_SHOW(rd_req, "%lu\n", be->blkif->st_rd_req);
VBD_SHOW(wr_req, "%lu\n", be->blkif->st_wr_req);
+VBD_SHOW(pk_req, "%lu\n", be->blkif->st_pk_req);
VBD_SHOW(rd_sect, "%lu\n", be->blkif->st_rd_sect);
VBD_SHOW(wr_sect, "%lu\n", be->blkif->st_wr_sect);
@@ -143,6 +144,7 @@ static struct attribute *tapstat_attrs[]
&dev_attr_oo_req.attr,
&dev_attr_rd_req.attr,
&dev_attr_wr_req.attr,
+ &dev_attr_pk_req.attr,
&dev_attr_rd_sect.attr,
&dev_attr_wr_sect.attr,
NULL
--- head.orig/drivers/xen/blktap2/blktap.h 2014-05-05 16:17:17.000000000 +0200
+++ head/drivers/xen/blktap2/blktap.h 2012-06-08 10:40:23.000000000 +0200
@@ -141,6 +141,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.orig/drivers/xen/blktap2/device.c 2013-05-24 14:33:30.000000000 +0200
+++ head/drivers/xen/blktap2/device.c 2013-05-24 15:47:25.000000000 +0200
@@ -342,7 +342,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);
@@ -383,6 +384,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);
@@ -620,6 +622,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;
@@ -685,7 +689,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.orig/drivers/xen/blktap2-new/blktap.h 2011-02-24 15:00:29.000000000 +0100
+++ head/drivers/xen/blktap2-new/blktap.h 2012-06-08 10:40:25.000000000 +0200
@@ -114,6 +114,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.orig/drivers/xen/blktap2-new/device.c 2013-05-24 14:33:17.000000000 +0200
+++ head/drivers/xen/blktap2-new/device.c 2013-05-24 15:47:27.000000000 +0200
@@ -188,6 +188,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.orig/drivers/xen/blktap2-new/ring.c 2012-10-30 14:55:51.000000000 +0100
+++ head/drivers/xen/blktap2-new/ring.c 2012-10-31 12:26:30.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;
}
}
@@ -482,20 +488,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.orig/include/xen/interface/io/blkif.h 2014-01-30 10:36:20.000000000 +0100
+++ head/include/xen/interface/io/blkif.h 2013-06-20 15:39:43.000000000 +0200
@@ -450,10 +450,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
/*
* Indicate to the backend device that a region of storage is no longer in
* use, and may be discarded at any time without impact to the client. If