Re: PATCH 7/8] lguest: the block driver
On 4/11/07, Rusty Russell <[EMAIL PROTECTED]> wrote: What a question! end_request() doesn't end a request! What a crazy idea! Aah, indeed, end_request() uses req->hard_cur_sectors while end_entire_request() uses req->hard_nr_sectors which I missed. On 4/11/07, Rusty Russell <[EMAIL PROTECTED]> wrote: Hope that clarifies! It does. Thanks Rusty :) Pekka - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
On Tue, 2007-04-10 at 14:36 +0300, Pekka Enberg wrote: > On 4/10/07, Rusty Russell <[EMAIL PROTECTED]> wrote: > > > +/* Jens gave me this nice helper to end all chunks of a request. */ > > > +static void end_entire_request(struct request *req, int uptodate) > > > +{ > > > + if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) > > > + BUG(); > > > + add_disk_randomness(req->rq_disk); > > > + blkdev_dequeue_request(req); > > > + end_that_request_last(req, uptodate); > > > +} > > On 4/10/07, Pekka Enberg <[EMAIL PROTECTED]> wrote: > > Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? Yeah, Jens said to put it in here and he'd hoist it later. > Uhm, I am bit confused now. Why don't you just use end_request() here? What a question! end_request() doesn't end a request! What a crazy idea! As far as I can tell, every name in the block layer is actually some variant of "fuck off, this is too complicated for you to understand". Hope that clarifies! Rusty. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
On 4/10/07, Rusty Russell <[EMAIL PROTECTED]> wrote: > +/* Jens gave me this nice helper to end all chunks of a request. */ > +static void end_entire_request(struct request *req, int uptodate) > +{ > + if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) > + BUG(); > + add_disk_randomness(req->rq_disk); > + blkdev_dequeue_request(req); > + end_that_request_last(req, uptodate); > +} On 4/10/07, Pekka Enberg <[EMAIL PROTECTED]> wrote: Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? Uhm, I am bit confused now. Why don't you just use end_request() here? - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
Hi Rusty, On 4/10/07, Rusty Russell <[EMAIL PROTECTED]> wrote: +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) + BUG(); + add_disk_randomness(req->rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
PATCH 7/8] lguest: the block driver
Lguest block driver A simple block driver for lguest. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> --- drivers/block/Makefile |1 drivers/block/lguest_blk.c | 271 2 files changed, 272 insertions(+) === --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -28,4 +28,5 @@ obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o obj-$(CONFIG_BLK_DEV_UB) += ub.o +obj-$(CONFIG_LGUEST_GUEST) += lguest_blk.o === --- /dev/null +++ b/drivers/block/lguest_blk.c @@ -0,0 +1,271 @@ +/* A simple block driver for lguest. + * + * Copyright 2006 Rusty Russell <[EMAIL PROTECTED]> IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +//#define DEBUG +#include +#include +#include +#include +#include + +static char next_block_index = 'a'; + +struct blockdev +{ + spinlock_t lock; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* The major number for this disk. */ + int major; + int irq; + + unsigned long phys_addr; + /* The ioremap'ed block page. */ + struct lguest_block_page *lb_page; + + /* We only have a single request outstanding at a time. */ + struct lguest_dma dma; + struct request *req; +}; + +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) + BUG(); + add_disk_randomness(req->rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} + +static irqreturn_t lgb_irq(int irq, void *_bd) +{ + struct blockdev *bd = _bd; + unsigned long flags; + + if (!bd->req) { + pr_debug("No work!\n"); + return IRQ_NONE; + } + + if (!bd->lb_page->result) { + pr_debug("No result!\n"); + return IRQ_NONE; + } + + spin_lock_irqsave(>lock, flags); + end_entire_request(bd->req, bd->lb_page->result == 1); + bd->req = NULL; + bd->dma.used_len = 0; + blk_start_queue(bd->disk->queue); + spin_unlock_irqrestore(>lock, flags); + return IRQ_HANDLED; +} + +static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma) +{ + unsigned int i = 0, idx, len = 0; + struct bio *bio; + + rq_for_each_bio(bio, req) { + struct bio_vec *bvec; + bio_for_each_segment(bvec, bio, idx) { + BUG_ON(i == LGUEST_MAX_DMA_SECTIONS); + BUG_ON(!bvec->bv_len); + dma->addr[i] = page_to_phys(bvec->bv_page) + + bvec->bv_offset; + dma->len[i] = bvec->bv_len; + len += bvec->bv_len; + i++; + } + } + if (i < LGUEST_MAX_DMA_SECTIONS) + dma->len[i] = 0; + return len; +} + +static void empty_dma(struct lguest_dma *dma) +{ + dma->len[0] = 0; +} + +static void setup_req(struct blockdev *bd, + int type, struct request *req, struct lguest_dma *dma) +{ + bd->lb_page->type = type; + bd->lb_page->sector = req->sector; + bd->lb_page->result = 0; + bd->req = req; + bd->lb_page->bytes = req_to_dma(req, dma); +} + +static void do_write(struct blockdev *bd, struct request *req) +{ + struct lguest_dma send; + + pr_debug("lgb: WRITE sector %li\n", (long)req->sector); + setup_req(bd, 1, req, ); + + hcall(LHCALL_SEND_DMA, bd->phys_addr, __pa(), 0); +} + +static void do_read(struct blockdev *bd, struct request *req) +{ + struct lguest_dma ping; + + pr_debug("lgb: READ sector %li\n", (long)req->sector); + setup_req(bd, 0, req, >dma); + + empty_dma(); + hcall(LHCALL_SEND_DMA, bd->phys_addr, __pa(), 0); +} + +static void do_lgb_request(request_queue_t *q) +{ + struct blockdev *bd; + struct request *req; + +again: +
PATCH 7/8] lguest: the block driver
Lguest block driver A simple block driver for lguest. Signed-off-by: Rusty Russell [EMAIL PROTECTED] --- drivers/block/Makefile |1 drivers/block/lguest_blk.c | 271 2 files changed, 272 insertions(+) === --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -28,4 +28,5 @@ obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_VIODASD) += viodasd.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o obj-$(CONFIG_BLK_DEV_UB) += ub.o +obj-$(CONFIG_LGUEST_GUEST) += lguest_blk.o === --- /dev/null +++ b/drivers/block/lguest_blk.c @@ -0,0 +1,271 @@ +/* A simple block driver for lguest. + * + * Copyright 2006 Rusty Russell [EMAIL PROTECTED] IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +//#define DEBUG +#include linux/init.h +#include linux/types.h +#include linux/blkdev.h +#include linux/interrupt.h +#include linux/lguest_bus.h + +static char next_block_index = 'a'; + +struct blockdev +{ + spinlock_t lock; + + /* The disk structure for the kernel. */ + struct gendisk *disk; + + /* The major number for this disk. */ + int major; + int irq; + + unsigned long phys_addr; + /* The ioremap'ed block page. */ + struct lguest_block_page *lb_page; + + /* We only have a single request outstanding at a time. */ + struct lguest_dma dma; + struct request *req; +}; + +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req-hard_nr_sectors)) + BUG(); + add_disk_randomness(req-rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} + +static irqreturn_t lgb_irq(int irq, void *_bd) +{ + struct blockdev *bd = _bd; + unsigned long flags; + + if (!bd-req) { + pr_debug(No work!\n); + return IRQ_NONE; + } + + if (!bd-lb_page-result) { + pr_debug(No result!\n); + return IRQ_NONE; + } + + spin_lock_irqsave(bd-lock, flags); + end_entire_request(bd-req, bd-lb_page-result == 1); + bd-req = NULL; + bd-dma.used_len = 0; + blk_start_queue(bd-disk-queue); + spin_unlock_irqrestore(bd-lock, flags); + return IRQ_HANDLED; +} + +static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma) +{ + unsigned int i = 0, idx, len = 0; + struct bio *bio; + + rq_for_each_bio(bio, req) { + struct bio_vec *bvec; + bio_for_each_segment(bvec, bio, idx) { + BUG_ON(i == LGUEST_MAX_DMA_SECTIONS); + BUG_ON(!bvec-bv_len); + dma-addr[i] = page_to_phys(bvec-bv_page) + + bvec-bv_offset; + dma-len[i] = bvec-bv_len; + len += bvec-bv_len; + i++; + } + } + if (i LGUEST_MAX_DMA_SECTIONS) + dma-len[i] = 0; + return len; +} + +static void empty_dma(struct lguest_dma *dma) +{ + dma-len[0] = 0; +} + +static void setup_req(struct blockdev *bd, + int type, struct request *req, struct lguest_dma *dma) +{ + bd-lb_page-type = type; + bd-lb_page-sector = req-sector; + bd-lb_page-result = 0; + bd-req = req; + bd-lb_page-bytes = req_to_dma(req, dma); +} + +static void do_write(struct blockdev *bd, struct request *req) +{ + struct lguest_dma send; + + pr_debug(lgb: WRITE sector %li\n, (long)req-sector); + setup_req(bd, 1, req, send); + + hcall(LHCALL_SEND_DMA, bd-phys_addr, __pa(send), 0); +} + +static void do_read(struct blockdev *bd, struct request *req) +{ + struct lguest_dma ping; + + pr_debug(lgb: READ sector %li\n, (long)req-sector); + setup_req(bd, 0, req, bd-dma); + + empty_dma(ping); + hcall(LHCALL_SEND_DMA, bd-phys_addr, __pa(ping), 0); +} + +static void do_lgb_request(request_queue_t *q) +{ + struct blockdev
Re: PATCH 7/8] lguest: the block driver
Hi Rusty, On 4/10/07, Rusty Russell [EMAIL PROTECTED] wrote: +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req-hard_nr_sectors)) + BUG(); + add_disk_randomness(req-rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
On 4/10/07, Rusty Russell [EMAIL PROTECTED] wrote: +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req-hard_nr_sectors)) + BUG(); + add_disk_randomness(req-rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} On 4/10/07, Pekka Enberg [EMAIL PROTECTED] wrote: Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? Uhm, I am bit confused now. Why don't you just use end_request() here? - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
On Tue, 2007-04-10 at 14:36 +0300, Pekka Enberg wrote: On 4/10/07, Rusty Russell [EMAIL PROTECTED] wrote: +/* Jens gave me this nice helper to end all chunks of a request. */ +static void end_entire_request(struct request *req, int uptodate) +{ + if (end_that_request_first(req, uptodate, req-hard_nr_sectors)) + BUG(); + add_disk_randomness(req-rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req, uptodate); +} On 4/10/07, Pekka Enberg [EMAIL PROTECTED] wrote: Perhaps we should move this to generic code (i.e. block/ll_rw_blk.c)? Yeah, Jens said to put it in here and he'd hoist it later. Uhm, I am bit confused now. Why don't you just use end_request() here? What a question! end_request() doesn't end a request! What a crazy idea! As far as I can tell, every name in the block layer is actually some variant of fuck off, this is too complicated for you to understand. Hope that clarifies! Rusty. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PATCH 7/8] lguest: the block driver
On 4/11/07, Rusty Russell [EMAIL PROTECTED] wrote: What a question! end_request() doesn't end a request! What a crazy idea! Aah, indeed, end_request() uses req-hard_cur_sectors while end_entire_request() uses req-hard_nr_sectors which I missed. On 4/11/07, Rusty Russell [EMAIL PROTECTED] wrote: Hope that clarifies! It does. Thanks Rusty :) Pekka - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/