Skip to contentSkip to conversation

virtio: fix oops on OOM

PATCH In review Rusty Russell 2 participants 5 messages Jul 23, 2010 – Jul 26, 2010 virtio core

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 virtio: fix oops on OOM

From: "Michael S. Tsirkin" <[email protected]>

virtio ring was changed to return an error code on OOM, but one caller was missed and still checks for vq->vring.num. The fix is just to check for <0 error code.

Long term it might make sense to change goto add_head to just return an error on oom instead, but let's apply a minimal fix for 2.6.35.

---

drivers/virtio/virtio_ring.c +3 -2
index dd35b34..bffec32 100644
@@ -164,7 +164,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 			  gfp_t gfp)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
-	unsigned int i, avail, head, uninitialized_var(prev);
+	unsigned int i, avail, uninitialized_var(prev);
+	int head;
 
 	START_USE(vq);
 
@@ -174,8 +175,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 	 * buffers, then go indirect. FIXME: tune this threshold */
 	if (vq->indirect && (out + in) > 1 && vq->num_free) {
 		head = vring_add_indirect(vq, sg, out, in, gfp);
-		if (head != vq->vring.num)
+		if (likely(head >= 0))
 			goto add_head;
 	}
 
 	BUG_ON(out + in > vq->vring.num);
#1 lore raw

On Fri, 23 Jul 2010 15:48:37 +0930
Rusty Russell <[email protected]> wrote:

Note that commit 686d363786a53ed28ee875b84ef24e6d5126ef6f, which caused this problem, is already queued for -stable, so it should either be removed or this should be sent for -stable as well.

Quoted 41 lines

From: "Michael S. Tsirkin" <[email protected]>

virtio ring was changed to return an error code on OOM, but one caller was missed and still checks for vq->vring.num. The fix is just to check for <0 error code.

Long term it might make sense to change goto add_head to just return an error on oom instead, but let's apply a minimal fix for 2.6.35.

---

drivers/virtio/virtio_ring.c +3 -3
index dd35b34..bffec32 100644
@@ -164,7 +164,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 			  gfp_t gfp)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
-	unsigned int i, avail, head, uninitialized_var(prev);
+	unsigned int i, avail, uninitialized_var(prev);
+	int head;
 
 	START_USE(vq);
 
@@ -174,8 +175,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 	 * buffers, then go indirect. FIXME: tune this threshold */
 	if (vq->indirect && (out + in) > 1 && vq->num_free) {
 		head = vring_add_indirect(vq, sg, out, in, gfp);
-		if (head != vq->vring.num)
+		if (likely(head >= 0))
 			goto add_head;
 	}
 
 	BUG_ON(out + in > vq->vring.num);
--
#2 lore raw
In reply to Rusty Russell

On Fri, 23 Jul 2010 15:48:37 +0930
Rusty Russell <[email protected]> wrote:

Note that commit 686d363786a53ed28ee875b84ef24e6d5126ef6f, which caused this problem, is already queued for -stable, so it should either be removed or this should be sent for -stable as well.

Quoted 41 lines

From: "Michael S. Tsirkin" <[email protected]>

virtio ring was changed to return an error code on OOM, but one caller was missed and still checks for vq->vring.num. The fix is just to check for <0 error code.

Long term it might make sense to change goto add_head to just return an error on oom instead, but let's apply a minimal fix for 2.6.35.

---

drivers/virtio/virtio_ring.c +3 -3
index dd35b34..bffec32 100644
@@ -164,7 +164,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 			  gfp_t gfp)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
-	unsigned int i, avail, head, uninitialized_var(prev);
+	unsigned int i, avail, uninitialized_var(prev);
+	int head;
 
 	START_USE(vq);
 
@@ -174,8 +175,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 	 * buffers, then go indirect. FIXME: tune this threshold */
 	if (vq->indirect && (out + in) > 1 && vq->num_free) {
 		head = vring_add_indirect(vq, sg, out, in, gfp);
-		if (head != vq->vring.num)
+		if (likely(head >= 0))
 			goto add_head;
 	}
 
 	BUG_ON(out + in > vq->vring.num);
--
#3 lore raw

PATCH 1/1 virtio: fix oops on OOM

In reply to Rusty Russell

From: "Michael S. Tsirkin" <[email protected]>

virtio ring was changed to return an error code on OOM, but one caller was missed and still checks for vq->vring.num. The fix is just to check for <0 error code.

Long term it might make sense to change goto add_head to just return an error on oom instead, but let's apply a minimal fix for 2.6.35.

---
 drivers/virtio/virtio_ring.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/virtio/virtio_ring.c +3 -2
index dd35b34..bffec32 100644
@@ -164,7 +164,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 			  gfp_t gfp)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
-	unsigned int i, avail, head, uninitialized_var(prev);
+	unsigned int i, avail, uninitialized_var(prev);
+	int head;
 
 	START_USE(vq);
 
@@ -174,8 +175,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 	 * buffers, then go indirect. FIXME: tune this threshold */
 	if (vq->indirect && (out + in) > 1 && vq->num_free) {
 		head = vring_add_indirect(vq, sg, out, in, gfp);
-		if (head != vq->vring.num)
+		if (likely(head >= 0))
 			goto add_head;
 	}
 
 	BUG_ON(out + in > vq->vring.num);
#4 lore raw

PATCH 1/1 virtio: fix oops on OOM

In reply to Rusty Russell

From: "Michael S. Tsirkin" <[email protected]>

virtio ring was changed to return an error code on OOM, but one caller was missed and still checks for vq->vring.num. The fix is just to check for <0 error code.

Long term it might make sense to change goto add_head to just return an error on oom instead, but let's apply a minimal fix for 2.6.35.

---
 drivers/virtio/virtio_ring.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/virtio/virtio_ring.c +3 -2
index dd35b34..bffec32 100644
@@ -164,7 +164,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 			  gfp_t gfp)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
-	unsigned int i, avail, head, uninitialized_var(prev);
+	unsigned int i, avail, uninitialized_var(prev);
+	int head;
 
 	START_USE(vq);
 
@@ -174,8 +175,8 @@ int virtqueue_add_buf_gfp(struct virtqueue *_vq,
 	 * buffers, then go indirect. FIXME: tune this threshold */
 	if (vq->indirect && (out + in) > 1 && vq->num_free) {
 		head = vring_add_indirect(vq, sg, out, in, gfp);
-		if (head != vq->vring.num)
+		if (likely(head >= 0))
 			goto add_head;
 	}
 
 	BUG_ON(out + in > vq->vring.num);