From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rusty Russell Subject: Re: [PATCH V2 RFC 9/9] virtio_scsi: verify if queue is broken after virtqueue_get_buf() Date: Tue, 29 Oct 2013 11:34:07 +1030 Message-ID: <87vc0gevlk.fsf@rustcorp.com.au> References: <1382628200-42956-1-git-send-email-graalfs@linux.vnet.ibm.com> <1382628200-42956-10-git-send-email-graalfs@linux.vnet.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1382628200-42956-10-git-send-email-graalfs@linux.vnet.ibm.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: virtualization-bounces@lists.linux-foundation.org Errors-To: virtualization-bounces@lists.linux-foundation.org To: Heinz Graalfs , mst@redhat.com, virtualization@lists.linux-foundation.org Cc: borntraeger@de.ibm.com List-Id: virtualization@lists.linuxfoundation.org Heinz Graalfs writes: > If virtqueue_get_buf() returned with a NULL pointer avoid a possibly > endless loop by checking for a broken virtqueue. > > Signed-off-by: Heinz Graalfs > --- > drivers/scsi/virtio_scsi.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c > index 74b88ef..45bcdb5 100644 > --- a/drivers/scsi/virtio_scsi.c > +++ b/drivers/scsi/virtio_scsi.c > @@ -224,7 +224,8 @@ static void virtscsi_vq_done(struct virtio_scsi *vscsi, > virtqueue_disable_cb(vq); > while ((buf = virtqueue_get_buf(vq, &len)) != NULL) > fn(vscsi, buf); > - } while (!virtqueue_enable_cb(vq)); > + } while (unlikely(!virtqueue_is_broken(vq)) && > + !virtqueue_enable_cb(vq)); > spin_unlock_irqrestore(&virtscsi_vq->vq_lock, flags); unlikely(!virtqueue_is_broken(vq))? I didn't apply this one. I'd prefer: spin_lock_irqsave(&virtscsi_vq->vq_lock, flags); do { virtqueue_disable_cb(vq); while ((buf = virtqueue_get_buf(vq, &len)) != NULL) fn(vscsi, buf); if (unlikely(virtqueue_is_broken(vq))) break; } while (!virtqueue_enable_cb(vq)); spin_unlock_irqrestore(&virtscsi_vq->vq_lock, flags); Thanks, Rusty.