summaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@citrix.com>2015-05-05 11:25:56 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2015-10-23 09:20:40 -0400
commit67de5dfbc176ea86ab0278658b5d55f64207ff2d (patch)
tree0c03545ee47352eddd9b61171546a1e76fccb73c /drivers/block/xen-blkback
parentc004a6fe0c405e2aa91b2a88aa1428724e6d06f6 (diff)
block/xen-blkback: Make it running on 64KB page granularity
The PV block protocol is using 4KB page granularity. The goal of this patch is to allow a Linux using 64KB page granularity behaving as a block backend on a non-modified Xen. It's only necessary to adapt the ring size and the number of request per indirect frames. The rest of the code is relying on the grant table code. Note that the grant table code is allocating a Linux page per grant which will result to waste 6OKB for every grant when Linux is using 64KB page granularity. This could be improved by sharing the page between multiple grants. Signed-off-by: Julien Grall <julien.grall@citrix.com> Acked-by: "Roger Pau Monné" <roger.pau@citrix.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'drivers/block/xen-blkback')
-rw-r--r--drivers/block/xen-blkback/blkback.c5
-rw-r--r--drivers/block/xen-blkback/common.h17
-rw-r--r--drivers/block/xen-blkback/xenbus.c9
3 files changed, 22 insertions, 9 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 6a685aec6994..809634ce3b67 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -961,7 +961,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
961 seg[n].nsec = segments[i].last_sect - 961 seg[n].nsec = segments[i].last_sect -
962 segments[i].first_sect + 1; 962 segments[i].first_sect + 1;
963 seg[n].offset = (segments[i].first_sect << 9); 963 seg[n].offset = (segments[i].first_sect << 9);
964 if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) || 964 if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
965 (segments[i].last_sect < segments[i].first_sect)) { 965 (segments[i].last_sect < segments[i].first_sect)) {
966 rc = -EINVAL; 966 rc = -EINVAL;
967 goto unmap; 967 goto unmap;
@@ -1210,6 +1210,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
1210 1210
1211 req_operation = req->operation == BLKIF_OP_INDIRECT ? 1211 req_operation = req->operation == BLKIF_OP_INDIRECT ?
1212 req->u.indirect.indirect_op : req->operation; 1212 req->u.indirect.indirect_op : req->operation;
1213
1213 if ((req->operation == BLKIF_OP_INDIRECT) && 1214 if ((req->operation == BLKIF_OP_INDIRECT) &&
1214 (req_operation != BLKIF_OP_READ) && 1215 (req_operation != BLKIF_OP_READ) &&
1215 (req_operation != BLKIF_OP_WRITE)) { 1216 (req_operation != BLKIF_OP_WRITE)) {
@@ -1268,7 +1269,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
1268 seg[i].nsec = req->u.rw.seg[i].last_sect - 1269 seg[i].nsec = req->u.rw.seg[i].last_sect -
1269 req->u.rw.seg[i].first_sect + 1; 1270 req->u.rw.seg[i].first_sect + 1;
1270 seg[i].offset = (req->u.rw.seg[i].first_sect << 9); 1271 seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
1271 if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) || 1272 if ((req->u.rw.seg[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
1272 (req->u.rw.seg[i].last_sect < 1273 (req->u.rw.seg[i].last_sect <
1273 req->u.rw.seg[i].first_sect)) 1274 req->u.rw.seg[i].first_sect))
1274 goto fail_response; 1275 goto fail_response;
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 45a044a53d1e..68e87a037b99 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -39,6 +39,7 @@
39#include <asm/pgalloc.h> 39#include <asm/pgalloc.h>
40#include <asm/hypervisor.h> 40#include <asm/hypervisor.h>
41#include <xen/grant_table.h> 41#include <xen/grant_table.h>
42#include <xen/page.h>
42#include <xen/xenbus.h> 43#include <xen/xenbus.h>
43#include <xen/interface/io/ring.h> 44#include <xen/interface/io/ring.h>
44#include <xen/interface/io/blkif.h> 45#include <xen/interface/io/blkif.h>
@@ -51,12 +52,20 @@ extern unsigned int xen_blkif_max_ring_order;
51 */ 52 */
52#define MAX_INDIRECT_SEGMENTS 256 53#define MAX_INDIRECT_SEGMENTS 256
53 54
54#define SEGS_PER_INDIRECT_FRAME \ 55/*
55 (PAGE_SIZE/sizeof(struct blkif_request_segment)) 56 * Xen use 4K pages. The guest may use different page size (4K or 64K)
57 * Number of Xen pages per segment
58 */
59#define XEN_PAGES_PER_SEGMENT (PAGE_SIZE / XEN_PAGE_SIZE)
60
61#define XEN_PAGES_PER_INDIRECT_FRAME \
62 (XEN_PAGE_SIZE/sizeof(struct blkif_request_segment))
63#define SEGS_PER_INDIRECT_FRAME \
64 (XEN_PAGES_PER_INDIRECT_FRAME / XEN_PAGES_PER_SEGMENT)
65
56#define MAX_INDIRECT_PAGES \ 66#define MAX_INDIRECT_PAGES \
57 ((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) 67 ((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
58#define INDIRECT_PAGES(_segs) \ 68#define INDIRECT_PAGES(_segs) DIV_ROUND_UP(_segs, XEN_PAGES_PER_INDIRECT_FRAME)
59 ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
60 69
61/* Not a real protocol. Used to generate ring structs which contain 70/* Not a real protocol. Used to generate ring structs which contain
62 * the elements common to all protocols only. This way we get a 71 * the elements common to all protocols only. This way we get a
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 767657565de6..01c6b41de4e5 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -176,21 +176,24 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
176 { 176 {
177 struct blkif_sring *sring; 177 struct blkif_sring *sring;
178 sring = (struct blkif_sring *)blkif->blk_ring; 178 sring = (struct blkif_sring *)blkif->blk_ring;
179 BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE * nr_grefs); 179 BACK_RING_INIT(&blkif->blk_rings.native, sring,
180 XEN_PAGE_SIZE * nr_grefs);
180 break; 181 break;
181 } 182 }
182 case BLKIF_PROTOCOL_X86_32: 183 case BLKIF_PROTOCOL_X86_32:
183 { 184 {
184 struct blkif_x86_32_sring *sring_x86_32; 185 struct blkif_x86_32_sring *sring_x86_32;
185 sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring; 186 sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring;
186 BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE * nr_grefs); 187 BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32,
188 XEN_PAGE_SIZE * nr_grefs);
187 break; 189 break;
188 } 190 }
189 case BLKIF_PROTOCOL_X86_64: 191 case BLKIF_PROTOCOL_X86_64:
190 { 192 {
191 struct blkif_x86_64_sring *sring_x86_64; 193 struct blkif_x86_64_sring *sring_x86_64;
192 sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring; 194 sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring;
193 BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE * nr_grefs); 195 BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64,
196 XEN_PAGE_SIZE * nr_grefs);
194 break; 197 break;
195 } 198 }
196 default: 199 default: