Re: PATCH 7/8] lguest: the block driver

2007-04-10 Thread Pekka Enberg

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

2007-04-10 Thread Rusty Russell
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

2007-04-10 Thread Pekka Enberg

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

2007-04-10 Thread Pekka Enberg

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

2007-04-10 Thread Rusty Russell
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

2007-04-10 Thread Rusty Russell
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

2007-04-10 Thread Pekka Enberg

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

2007-04-10 Thread Pekka Enberg

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

2007-04-10 Thread Rusty Russell
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

2007-04-10 Thread Pekka Enberg

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/