Skip to content

Commit

Permalink
Merge branch 'stable/for-jens-3.9' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/konrad/xen into for-linus

Konrad writes:

[the branch] has a bunch of fixes. They vary from being able to deal
with unknown requests, overflow in statistics, compile warnings, bug in
the error path, removal of unnecessary logic. There is also one
performance fix - which is to allocate pages for requests when the
driver loads - instead of doing it per request
  • Loading branch information
Jens Axboe committed Mar 22, 2013
2 parents 351a2c6 + b1173e3 commit 7fbaee7
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 107 deletions.
68 changes: 39 additions & 29 deletions drivers/block/xen-blkback/blkback.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static void make_response(struct xen_blkif *blkif, u64 id,

#define foreach_grant_safe(pos, n, rbtree, node) \
for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \
(n) = rb_next(&(pos)->node); \
(n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL; \
&(pos)->node != NULL; \
(pos) = container_of(n, typeof(*(pos)), node), \
(n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
Expand Down Expand Up @@ -381,8 +381,8 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)

static void print_stats(struct xen_blkif *blkif)
{
pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d"
" | ds %4d\n",
pr_info("xen-blkback (%s): oo %3llu | rd %4llu | wr %4llu | f %4llu"
" | ds %4llu\n",
current->comm, blkif->st_oo_req,
blkif->st_rd_req, blkif->st_wr_req,
blkif->st_f_req, blkif->st_ds_req);
Expand Down Expand Up @@ -442,7 +442,7 @@ int xen_blkif_schedule(void *arg)
}

struct seg_buf {
unsigned long buf;
unsigned int offset;
unsigned int nsec;
};
/*
Expand Down Expand Up @@ -621,30 +621,21 @@ static int xen_blkbk_map(struct blkif_request *req,
* If this is a new persistent grant
* save the handler
*/
persistent_gnts[i]->handle = map[j].handle;
persistent_gnts[i]->dev_bus_addr =
map[j++].dev_bus_addr;
persistent_gnts[i]->handle = map[j++].handle;
}
pending_handle(pending_req, i) =
persistent_gnts[i]->handle;

if (ret)
continue;

seg[i].buf = persistent_gnts[i]->dev_bus_addr |
(req->u.rw.seg[i].first_sect << 9);
} else {
pending_handle(pending_req, i) = map[j].handle;
pending_handle(pending_req, i) = map[j++].handle;
bitmap_set(pending_req->unmap_seg, i, 1);

if (ret) {
j++;
if (ret)
continue;
}

seg[i].buf = map[j++].dev_bus_addr |
(req->u.rw.seg[i].first_sect << 9);
}
seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
}
return ret;
}
Expand Down Expand Up @@ -679,6 +670,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
return err;
}

static int dispatch_other_io(struct xen_blkif *blkif,
struct blkif_request *req,
struct pending_req *pending_req)
{
free_req(pending_req);
make_response(blkif, req->u.other.id, req->operation,
BLKIF_RSP_EOPNOTSUPP);
return -EIO;
}

static void xen_blk_drain_io(struct xen_blkif *blkif)
{
atomic_set(&blkif->drain, 1);
Expand Down Expand Up @@ -800,17 +801,30 @@ __do_block_io_op(struct xen_blkif *blkif)

/* Apply all sanity checks to /private copy/ of request. */
barrier();
if (unlikely(req.operation == BLKIF_OP_DISCARD)) {

switch (req.operation) {
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER:
case BLKIF_OP_FLUSH_DISKCACHE:
if (dispatch_rw_block_io(blkif, &req, pending_req))
goto done;
break;
case BLKIF_OP_DISCARD:
free_req(pending_req);
if (dispatch_discard_io(blkif, &req))
break;
} else if (dispatch_rw_block_io(blkif, &req, pending_req))
goto done;
break;
default:
if (dispatch_other_io(blkif, &req, pending_req))
goto done;
break;
}

/* Yield point for this unbounded loop. */
cond_resched();
}

done:
return more_to_do;
}

Expand Down Expand Up @@ -904,7 +918,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n",
operation == READ ? "read" : "write",
preq.sector_number,
preq.sector_number + preq.nr_sects, preq.dev);
preq.sector_number + preq.nr_sects,
blkif->vbd.pdevice);
goto fail_response;
}

Expand Down Expand Up @@ -947,7 +962,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
(bio_add_page(bio,
pages[i],
seg[i].nsec << 9,
seg[i].buf & ~PAGE_MASK) == 0)) {
seg[i].offset) == 0)) {

bio = bio_alloc(GFP_KERNEL, nseg-i);
if (unlikely(bio == NULL))
Expand Down Expand Up @@ -977,13 +992,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
bio->bi_end_io = end_block_io_op;
}

/*
* We set it one so that the last submit_bio does not have to call
* atomic_inc.
*/
atomic_set(&pending_req->pendcnt, nbio);

/* Get a reference count for the disk queue and start sending I/O */
blk_start_plug(&plug);

for (i = 0; i < nbio; i++)
Expand Down Expand Up @@ -1011,6 +1020,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
fail_put_bio:
for (i = 0; i < nbio; i++)
bio_put(biolist[i]);
atomic_set(&pending_req->pendcnt, 1);
__end_block_io_op(pending_req, -EINVAL);
msleep(1); /* back off a bit */
return -EIO;
Expand Down
40 changes: 32 additions & 8 deletions drivers/block/xen-blkback/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,18 @@ struct blkif_x86_32_request_discard {
uint64_t nr_sectors;
} __attribute__((__packed__));

struct blkif_x86_32_request_other {
uint8_t _pad1;
blkif_vdev_t _pad2;
uint64_t id; /* private guest value, echoed in resp */
} __attribute__((__packed__));

struct blkif_x86_32_request {
uint8_t operation; /* BLKIF_OP_??? */
union {
struct blkif_x86_32_request_rw rw;
struct blkif_x86_32_request_discard discard;
struct blkif_x86_32_request_other other;
} u;
} __attribute__((__packed__));

Expand Down Expand Up @@ -113,11 +120,19 @@ struct blkif_x86_64_request_discard {
uint64_t nr_sectors;
} __attribute__((__packed__));

struct blkif_x86_64_request_other {
uint8_t _pad1;
blkif_vdev_t _pad2;
uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */
uint64_t id; /* private guest value, echoed in resp */
} __attribute__((__packed__));

struct blkif_x86_64_request {
uint8_t operation; /* BLKIF_OP_??? */
union {
struct blkif_x86_64_request_rw rw;
struct blkif_x86_64_request_discard discard;
struct blkif_x86_64_request_other other;
} u;
} __attribute__((__packed__));

Expand Down Expand Up @@ -172,7 +187,6 @@ struct persistent_gnt {
struct page *page;
grant_ref_t gnt;
grant_handle_t handle;
uint64_t dev_bus_addr;
struct rb_node node;
};

Expand Down Expand Up @@ -208,13 +222,13 @@ struct xen_blkif {

/* statistics */
unsigned long st_print;
int st_rd_req;
int st_wr_req;
int st_oo_req;
int st_f_req;
int st_ds_req;
int st_rd_sect;
int st_wr_sect;
unsigned long long st_rd_req;
unsigned long long st_wr_req;
unsigned long long st_oo_req;
unsigned long long st_f_req;
unsigned long long st_ds_req;
unsigned long long st_rd_sect;
unsigned long long st_wr_sect;

wait_queue_head_t waiting_to_free;
};
Expand Down Expand Up @@ -278,6 +292,11 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
break;
default:
/*
* Don't know how to translate this op. Only get the
* ID so failure can be reported to the frontend.
*/
dst->u.other.id = src->u.other.id;
break;
}
}
Expand Down Expand Up @@ -309,6 +328,11 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
break;
default:
/*
* Don't know how to translate this op. Only get the
* ID so failure can be reported to the frontend.
*/
dst->u.other.id = src->u.other.id;
break;
}
}
Expand Down
14 changes: 7 additions & 7 deletions drivers/block/xen-blkback/xenbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,13 @@ int __init xen_blkif_interface_init(void)
} \
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)

VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req);
VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req);
VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req);
VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req);
VBD_SHOW(ds_req, "%d\n", be->blkif->st_ds_req);
VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
VBD_SHOW(oo_req, "%llu\n", be->blkif->st_oo_req);
VBD_SHOW(rd_req, "%llu\n", be->blkif->st_rd_req);
VBD_SHOW(wr_req, "%llu\n", be->blkif->st_wr_req);
VBD_SHOW(f_req, "%llu\n", be->blkif->st_f_req);
VBD_SHOW(ds_req, "%llu\n", be->blkif->st_ds_req);
VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect);
VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect);

static struct attribute *xen_vbdstat_attrs[] = {
&dev_attr_oo_req.attr,
Expand Down
Loading

0 comments on commit 7fbaee7

Please sign in to comment.