]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Dec 2008 01:37:25 +0000 (17:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Dec 2008 01:37:25 +0000 (17:37 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  lguest: struct device - replace bus_id with dev_name()
  lguest: move the initial guest page table creation code to the host
  kvm-s390: implement config_changed for virtio on s390
  virtio_console: support console resizing
  virtio: add PCI device release() function
  virtio_blk: fix type warning
  virtio: block: dynamic maximum segments
  virtio: set max_segment_size and max_sectors to infinite.
  virtio: avoid implicit use of Linux page size in balloon interface
  virtio: hand virtio ring alignment as argument to vring_new_virtqueue
  virtio: use KVM_S390_VIRTIO_RING_ALIGN instead of relying on pagesize
  virtio: use LGUEST_VRING_ALIGN instead of relying on pagesize
  virtio: Don't use PAGE_SIZE for vring alignment in virtio_pci.
  virtio: rename 'pagesize' arg to vring_init/vring_size
  virtio: Don't use PAGE_SIZE in virtio_pci.c
  virtio: struct device - replace bus_id with dev_name(), dev_set_name()
  virtio-pci queue allocation not page-aligned

1  2 
drivers/block/virtio_blk.c

index f151592ecf738d42866a2a9f7fef818d4ca513b0,300078b02e5d98d687596d3cb952870042211bae..5d34764c8a8726d5103e6e723eaae6ab28a6a422
@@@ -6,7 -6,6 +6,6 @@@
  #include <linux/virtio_blk.h>
  #include <linux/scatterlist.h>
  
- #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS)
  #define PART_BITS 4
  
  static int major, index;
@@@ -26,8 -25,11 +25,11 @@@ struct virtio_bl
  
        mempool_t *pool;
  
+       /* What host tells us, plus 2 for header & tailer. */
+       unsigned int sg_elems;
        /* Scatterlist: can be too big for stack. */
-       struct scatterlist sg[VIRTIO_MAX_SG];
+       struct scatterlist sg[/*sg_elems*/];
  };
  
  struct virtblk_req
@@@ -97,8 -99,6 +99,6 @@@ static bool do_req(struct request_queu
        if (blk_barrier_rq(vbr->req))
                vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
  
-       /* This init could be done at vblk creation time */
-       sg_init_table(vblk->sg, VIRTIO_MAX_SG);
        sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
        num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
        sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status));
@@@ -130,7 -130,7 +130,7 @@@ static void do_virtblk_request(struct r
  
        while ((req = elv_next_request(q)) != NULL) {
                vblk = req->rq_disk->private_data;
-               BUG_ON(req->nr_phys_segments > ARRAY_SIZE(vblk->sg));
+               BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
  
                /* If this request fails, stop queue and wait for something to
                   finish to restart it. */
@@@ -196,12 -196,22 +196,22 @@@ static int virtblk_probe(struct virtio_
        int err;
        u64 cap;
        u32 v;
-       u32 blk_size;
+       u32 blk_size, sg_elems;
  
        if (index_to_minor(index) >= 1 << MINORBITS)
                return -ENOSPC;
  
-       vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
+       /* We need to know how many segments before we allocate. */
+       err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
+                               offsetof(struct virtio_blk_config, seg_max),
+                               &sg_elems);
+       if (err)
+               sg_elems = 1;
+       /* We need an extra sg elements at head and tail. */
+       sg_elems += 2;
+       vdev->priv = vblk = kmalloc(sizeof(*vblk) +
+                                   sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL);
        if (!vblk) {
                err = -ENOMEM;
                goto out;
        INIT_LIST_HEAD(&vblk->reqs);
        spin_lock_init(&vblk->lock);
        vblk->vdev = vdev;
+       vblk->sg_elems = sg_elems;
+       sg_init_table(vblk->sg, vblk->sg_elems);
  
        /* We expect one virtqueue, for output. */
        vblk->vq = vdev->config->find_vq(vdev, 0, blk_done);
                goto out_put_disk;
        }
  
 +      queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue);
 +
        if (index < 26) {
                sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
        } else if (index < (26 + 1) * 26) {
        }
        set_capacity(vblk->disk, cap);
  
+       /* We can handle whatever the host told us to handle. */
+       blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2);
+       blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2);
+       /* No real sector limit. */
+       blk_queue_max_sectors(vblk->disk->queue, -1U);
        /* Host can optionally specify maximum segment size and number of
         * segments. */
        err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX,
                                &v);
        if (!err)
                blk_queue_max_segment_size(vblk->disk->queue, v);
-       err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
-                               offsetof(struct virtio_blk_config, seg_max),
-                               &v);
-       if (!err)
-               blk_queue_max_hw_segments(vblk->disk->queue, v);
+       else
+               blk_queue_max_segment_size(vblk->disk->queue, -1U);
  
        /* Host can optionally specify the block size of the device */
        err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE,