[SLOF] [PATCH v4] virtio-scsi: initialize vring avail queue buffers
Alexey Kardashevskiy
aik at ozlabs.ru
Fri Feb 3 14:04:17 AEDT 2017
On 03/02/17 03:02, Laurent Vivier wrote:
> Ping?
Please repost with "Signed-off" or I can add the line myself but I need you
ack for this. Thanks.
Also, one question - how did you recreate the situation when SLOF cannot
access the address set by the kernel?
>
> Laurent
>
> On 24/01/2017 11:54, Laurent Vivier wrote:
>> From: Laurent Vivier <lvivier at ibm-p8-virt-03.lab.eng.rdu.redhat.com>
>>
>> virtioscsi_init() uses the result of virtio_get_vring_avail() whereas
>> the queue is not enabled: on the first boot, its value is NULL and
>> the driver uses this to communicate with the device. After a reboot,
>> its value is the one given by the OS driver, and it works if the
>> address is in a range SLOF can access.
>>
>> In some cases, for instance with NUMA nodes and hotplugged memory,
>> SLOF cannot access the address set by the kernel, and virtioscsi_init()
>> fails with a data storage exception.
>>
>> To set the vring avail buffer address, we need to enable the queue, what
>> is done by virtio_set_qaddr().
>>
>> This patch fixes the problem by calling virtio_queue_init_vq() (like other
>> virtio drivers) in virtioscsi_init() as it allocates memory and enables the
>> queue. virtio_queue_init_vq() also replaces the calls to virtio_vring_size()
>> and virtio_get_vring_avail().
>> ---
>> v4: remove queue-control-addr, queue-event-addr, queue-cmd-addr
>>
>> v3: remove setup-virt-queues
>>
>> v2: move vqs declarations to the function
>> only call virtio_cpu_to_modern16() once
>> add CC: to Nikunj
>>
>> board-qemu/slof/virtio-scsi.fs | 21 ---------------------
>> lib/libvirtio/virtio-scsi.c | 28 +++++++++++++++-------------
>> 2 files changed, 15 insertions(+), 34 deletions(-)
>>
>> diff --git a/board-qemu/slof/virtio-scsi.fs b/board-qemu/slof/virtio-scsi.fs
>> index 4fedeee..d52741e 100644
>> --- a/board-qemu/slof/virtio-scsi.fs
>> +++ b/board-qemu/slof/virtio-scsi.fs
>> @@ -165,26 +165,6 @@ scsi-open
>>
>> scsi-close \ no further scsi words required
>>
>> -0 VALUE queue-control-addr
>> -0 VALUE queue-event-addr
>> -0 VALUE queue-cmd-addr
>> -
>> -: setup-virt-queues
>> - \ add 3 queues 0-controlq, 1-eventq, 2-cmdq
>> - \ fixme: do we need to find more than the above 3 queues if exists
>> - virtiodev 0 virtio-get-qsize virtio-vring-size
>> - alloc-mem to queue-control-addr
>> - virtiodev 0 queue-control-addr virtio-set-qaddr
>> -
>> - virtiodev 1 virtio-get-qsize virtio-vring-size
>> - alloc-mem to queue-event-addr
>> - virtiodev 1 queue-event-addr virtio-set-qaddr
>> -
>> - virtiodev 2 virtio-get-qsize virtio-vring-size
>> - alloc-mem to queue-cmd-addr
>> - virtiodev 2 queue-cmd-addr virtio-set-qaddr
>> -;
>> -
>> \ Set scsi alias if none is set yet
>> : setup-alias
>> s" scsi" find-alias 0= IF
>> @@ -212,7 +192,6 @@ scsi-close \ no further scsi words required
>> \ Scan the VSCSI bus:
>> virtiodev virtio-scsi-init
>> 0= IF
>> - setup-virt-queues
>> scsi-find-disks
>> setup-alias
>> TRUE to initialized?
>> diff --git a/lib/libvirtio/virtio-scsi.c b/lib/libvirtio/virtio-scsi.c
>> index 36b62d1..e95352d 100644
>> --- a/lib/libvirtio/virtio-scsi.c
>> +++ b/lib/libvirtio/virtio-scsi.c
>> @@ -99,10 +99,9 @@ int virtioscsi_send(struct virtio_device *dev,
>> */
>> int virtioscsi_init(struct virtio_device *dev)
>> {
>> - struct vring_avail *vq_avail;
>> - unsigned int idx = 0;
>> - int qsize = 0;
>> + struct vqs vq_ctrl, vq_event, vq_request;
>> int status = VIRTIO_STAT_ACKNOWLEDGE;
>> + uint16_t flags;
>>
>> /* Reset device */
>> // XXX That will clear the virtq base. We need to move
>> @@ -126,17 +125,20 @@ int virtioscsi_init(struct virtio_device *dev)
>> virtio_set_guest_features(dev, 0);
>> }
>>
>> - while(1) {
>> - qsize = virtio_get_qsize(dev, idx);
>> - if (!qsize)
>> - break;
>> - virtio_vring_size(qsize);
>> + if (virtio_queue_init_vq(dev, &vq_ctrl, VIRTIO_SCSI_CONTROL_VQ) ||
>> + virtio_queue_init_vq(dev, &vq_event, VIRTIO_SCSI_EVENT_VQ) ||
>> + virtio_queue_init_vq(dev, &vq_request, VIRTIO_SCSI_REQUEST_VQ))
>> + goto dev_error;
>>
>> - vq_avail = virtio_get_vring_avail(dev, idx);
>> - vq_avail->flags = virtio_cpu_to_modern16(dev, VRING_AVAIL_F_NO_INTERRUPT);
>> - vq_avail->idx = 0;
>> - idx++;
>> - }
>> + flags = virtio_cpu_to_modern16(dev, VRING_AVAIL_F_NO_INTERRUPT);
>> + vq_ctrl.avail->flags = flags;
>> + vq_ctrl.avail->idx = 0;
>> +
>> + vq_event.avail->flags = flags;
>> + vq_event.avail->idx = 0;
>> +
>> + vq_request.avail->flags = flags;
>> + vq_request.avail->idx = 0;
>>
>> /* Tell HV that setup succeeded */
>> status |= VIRTIO_STAT_DRIVER_OK;
>>
>
> _______________________________________________
> SLOF mailing list
> SLOF at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/slof
>
--
Alexey
More information about the SLOF
mailing list