Enhance blkback to be capable of dealing with bi-modal operation (frontend running in with different word size than backend). Index: sle10-sp1-2006-12-05/drivers/xen/blkback/blkback.c =================================================================== --- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/blkback.c 2006-12-07 16:43:52.000000000 +0100 +++ sle10-sp1-2006-12-05/drivers/xen/blkback/blkback.c 2006-12-07 16:45:02.000000000 +0100 @@ -70,7 +70,7 @@ module_param(debug_lvl, int, 0644); */ typedef struct { blkif_t *blkif; - unsigned long id; + uint64_t id; int nr_pages; atomic_t pendcnt; unsigned short operation; @@ -105,9 +105,9 @@ static inline unsigned long vaddr(pendin static int do_block_io_op(blkif_t *blkif); static void dispatch_rw_block_io(blkif_t *blkif, - blkif_request_t *req, + blkif_request_u *req, pending_req_t *pending_req); -static void make_response(blkif_t *blkif, unsigned long id, +static void make_response(blkif_t *blkif, uint64_t id, unsigned short op, int st); /****************************************************************** @@ -295,17 +295,24 @@ irqreturn_t blkif_be_int(int irq, void * /****************************************************************** * DOWNWARD CALLS -- These interface with the block-device layer proper. */ +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define req(op) (blkif_native(blkif) ? (req.nat.op) : (req.alt.op)) +#define preq(op) (blkif_native(blkif) ? (req->nat.op) : (req->alt.op)) +#else +#define req(op) (req.op) +#define preq(op) (req->op) +#endif static int do_block_io_op(blkif_t *blkif) { blkif_back_ring_t *blk_ring = &blkif->blk_ring; - blkif_request_t req; + blkif_request_u req; pending_req_t *pending_req; RING_IDX rc, rp; int more_to_do = 0; rc = blk_ring->req_cons; - rp = blk_ring->sring->req_prod; + rp = blk_ring->BB_SRING(sring)->req_prod; rmb(); /* Ensure we see queued requests up to 'rp'. */ while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) { @@ -317,10 +324,10 @@ static int do_block_io_op(blkif_t *blkif break; } - memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req)); + BB_RING_COPY_REQUEST(req, blk_ring, rc); blk_ring->req_cons = ++rc; /* before make_response() */ - switch (req.operation) { + switch (req(operation)) { case BLKIF_OP_READ: blkif->st_rd_req++; dispatch_rw_block_io(blkif, &req, pending_req); @@ -334,8 +341,8 @@ static int do_block_io_op(blkif_t *blkif break; default: DPRINTK("error: unknown block io operation [%d]\n", - req.operation); - make_response(blkif, req.id, req.operation, + req(operation)); + make_response(blkif, req(id), req(operation), BLKIF_RSP_ERROR); free_req(pending_req); break; @@ -345,7 +352,7 @@ static int do_block_io_op(blkif_t *blkif } static void dispatch_rw_block_io(blkif_t *blkif, - blkif_request_t *req, + blkif_request_u *req, pending_req_t *pending_req) { extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]); @@ -359,7 +366,7 @@ static void dispatch_rw_block_io(blkif_t int ret, i, nbio = 0; int operation; - switch (req->operation) { + switch (preq(operation)) { case BLKIF_OP_READ: operation = READ; break; @@ -375,31 +382,31 @@ static void dispatch_rw_block_io(blkif_t } /* Check that number of segments is sane. */ - nseg = req->nr_segments; + nseg = preq(nr_segments); if (unlikely(nseg == 0) || unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { DPRINTK("Bad number of segments in request (%d)\n", nseg); goto fail_response; } - preq.dev = req->handle; - preq.sector_number = req->sector_number; + preq.dev = preq(handle); + preq.sector_number = preq(sector_number); preq.nr_sects = 0; pending_req->blkif = blkif; - pending_req->id = req->id; - pending_req->operation = req->operation; + pending_req->id = preq(id); + pending_req->operation = preq(operation); pending_req->status = BLKIF_RSP_OKAY; pending_req->nr_pages = nseg; for (i = 0; i < nseg; i++) { uint32_t flags; - seg[i].nsec = req->seg[i].last_sect - - req->seg[i].first_sect + 1; + seg[i].nsec = preq(seg)[i].last_sect - + preq(seg)[i].first_sect + 1; - if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) || - (req->seg[i].last_sect < req->seg[i].first_sect)) + if ((preq(seg)[i].last_sect >= (PAGE_SIZE >> 9)) || + (preq(seg)[i].last_sect < preq(seg)[i].first_sect)) goto fail_response; preq.nr_sects += seg[i].nsec; @@ -407,7 +414,7 @@ static void dispatch_rw_block_io(blkif_t if (operation != READ) flags |= GNTMAP_readonly; gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, - req->seg[i].gref, blkif->domid); + preq(seg)[i].gref, blkif->domid); } ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); @@ -429,7 +436,7 @@ static void dispatch_rw_block_io(blkif_t pending_req, i)) >> PAGE_SHIFT, FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); seg[i].buf = map[i].dev_bus_addr | - (req->seg[i].first_sect << 9); + (preq(seg)[i].first_sect << 9); } if (ret) @@ -484,10 +491,11 @@ static void dispatch_rw_block_io(blkif_t fail_flush: fast_flush_area(pending_req); fail_response: - make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR); + make_response(blkif, preq(id), preq(operation), BLKIF_RSP_ERROR); free_req(pending_req); } +#undef req /****************************************************************** @@ -495,10 +503,15 @@ static void dispatch_rw_block_io(blkif_t */ -static void make_response(blkif_t *blkif, unsigned long id, +static void make_response(blkif_t *blkif, uint64_t id, unsigned short op, int st) { - blkif_response_t *resp; + blkif_response_u resp; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define resp(op) (blkif_native(blkif) ? (resp.nat->op) : (resp.alt->op)) +#else +#define resp(op) (resp->op) +#endif unsigned long flags; blkif_back_ring_t *blk_ring = &blkif->blk_ring; int more_to_do = 0; @@ -507,12 +520,12 @@ static void make_response(blkif_t *blkif spin_lock_irqsave(&blkif->blk_ring_lock, flags); /* Place on the response ring for the relevant domain. */ - resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); - resp->id = id; - resp->operation = op; - resp->status = st; + BB_RING_GET_RESPONSE(resp, blk_ring, blk_ring->rsp_prod_pvt); + resp(id = id); + resp(operation = op); + resp(status = st); blk_ring->rsp_prod_pvt++; - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); + BB_RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify); if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) { /* @@ -520,9 +533,9 @@ static void make_response(blkif_t *blkif * notifications if requests are already in flight (lower * overheads and promotes batching). */ - RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); + BB_RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do); - } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { + } else if (BB_RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { more_to_do = 1; } @@ -532,6 +545,7 @@ static void make_response(blkif_t *blkif blkif_notify_work(blkif); if (notify) notify_remote_via_irq(blkif->irq); +#undef resp } static int __init blkif_init(void) Index: sle10-sp1-2006-12-05/drivers/xen/blkback/common.h =================================================================== --- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/common.h 2006-12-07 16:43:52.000000000 +0100 +++ sle10-sp1-2006-12-05/drivers/xen/blkback/common.h 2006-12-07 16:45:02.000000000 +0100 @@ -40,8 +40,10 @@ #include #include #include +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define BLKIF_BIMODAL +#endif #include -#include #include #include #include @@ -63,6 +65,9 @@ struct backend_info; typedef struct blkif_st { /* Unique identifier for this interface. */ domid_t domid; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS + unsigned char native; +#endif unsigned int handle; /* Physical parameters of the comms window. */ unsigned int evtchn; @@ -96,6 +101,15 @@ typedef struct blkif_st { grant_ref_t shmem_ref; } blkif_t; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define blkif_native(blkif) ((blkif)->native) +static inline int ring_native(const blkif_back_ring_t *ring) { + return blkif_native(container_of(ring, blkif_t, blk_ring)); +} +#else +#define blkif_native(blkif) 1 +#endif + blkif_t *blkif_alloc(domid_t domid); void blkif_disconnect(blkif_t *blkif); void blkif_free(blkif_t *blkif); Index: sle10-sp1-2006-12-05/drivers/xen/blkback/interface.c =================================================================== --- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/interface.c 2006-12-07 16:43:52.000000000 +0100 +++ sle10-sp1-2006-12-05/drivers/xen/blkback/interface.c 2006-12-07 16:45:02.000000000 +0100 @@ -46,6 +46,9 @@ blkif_t *blkif_alloc(domid_t domid) memset(blkif, 0, sizeof(*blkif)); blkif->domid = domid; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS + blkif->native = 1; /* XXX */ +#endif spin_lock_init(&blkif->blk_ring_lock); atomic_set(&blkif->refcnt, 1); init_waitqueue_head(&blkif->wq); @@ -95,7 +98,7 @@ static void unmap_frontend_page(blkif_t int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { - blkif_sring_t *sring; + blkif_sring_u sring; int err; struct evtchn_bind_interdomain bind_interdomain; @@ -125,7 +128,7 @@ int blkif_map(blkif_t *blkif, unsigned l blkif->evtchn = bind_interdomain.local_port; - sring = (blkif_sring_t *)blkif->blk_ring_area->addr; + BB_SRING(sring) = (void *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); blkif->irq = bind_evtchn_to_irqhandler( @@ -150,10 +153,10 @@ void blkif_disconnect(blkif_t *blkif) blkif->irq = 0; } - if (blkif->blk_ring.sring) { + if (blkif->blk_ring.BB_SRING(sring)) { unmap_frontend_page(blkif); free_vm_area(blkif->blk_ring_area); - blkif->blk_ring.sring = NULL; + blkif->blk_ring.BB_SRING(sring) = NULL; } }