Browse Source

[virtio] Cap queue size to MAX_QUEUE_NUM

vpm_find_vqs incorrectly accepted the host provided queue size with no
regard to iPXE's internal limitations. Virtio 1.0 makes it possible for
the driver to override the queue size to reduce memory requirements and
iPXE is a great use case for this feature.

Also removing the extra vq->vring.num assignment which is already
handled in vring_init.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Ladi Prosek 8 years ago
parent
commit
e45451c699
2 changed files with 10 additions and 4 deletions
  1. 7
    1
      src/drivers/bus/virtio-pci.c
  2. 3
    3
      src/include/ipxe/virtio-ring.h

+ 7
- 1
src/drivers/bus/virtio-pci.c View File

358
             return -EINVAL;
358
             return -EINVAL;
359
         }
359
         }
360
 
360
 
361
+        if (size > MAX_QUEUE_NUM) {
362
+            /* iPXE networking tends to be not perf critical so there's no
363
+             * need to accept large queue sizes.
364
+             */
365
+            size = MAX_QUEUE_NUM;
366
+        }
367
+
361
         vq = &vqs[i];
368
         vq = &vqs[i];
362
         vq->queue_index = i;
369
         vq->queue_index = i;
363
 
370
 
364
         /* get offset of notification word for this vq */
371
         /* get offset of notification word for this vq */
365
         off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
372
         off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
366
-        vq->vring.num = size;
367
 
373
 
368
         vring_init(&vq->vring, size, (unsigned char *)vq->queue);
374
         vring_init(&vq->vring, size, (unsigned char *)vq->queue);
369
 
375
 

+ 3
- 3
src/include/ipxe/virtio-ring.h View File

95
    unsigned int i;
95
    unsigned int i;
96
    unsigned long pa;
96
    unsigned long pa;
97
 
97
 
98
-        vr->num = num;
98
+   vr->num = num;
99
 
99
 
100
    /* physical address of desc must be page aligned */
100
    /* physical address of desc must be page aligned */
101
 
101
 
103
    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
103
    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
104
    vr->desc = phys_to_virt(pa);
104
    vr->desc = phys_to_virt(pa);
105
 
105
 
106
-        vr->avail = (struct vring_avail *)&vr->desc[num];
106
+   vr->avail = (struct vring_avail *)&vr->desc[num];
107
 
107
 
108
    /* physical address of used must be page aligned */
108
    /* physical address of used must be page aligned */
109
 
109
 
110
    pa = virt_to_phys(&vr->avail->ring[num]);
110
    pa = virt_to_phys(&vr->avail->ring[num]);
111
    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
111
    pa = (pa + PAGE_MASK) & ~PAGE_MASK;
112
-        vr->used = phys_to_virt(pa);
112
+   vr->used = phys_to_virt(pa);
113
 
113
 
114
    for (i = 0; i < num - 1; i++)
114
    for (i = 0; i < num - 1; i++)
115
            vr->desc[i].next = i + 1;
115
            vr->desc[i].next = i + 1;

Loading…
Cancel
Save