OVS-DPDK VM出现 virtio_net virtio4: output.0:id 30 is not a head 问题 dpdk-vhost bug fix

来源:互联网 发布:mirrorlink认证软件 编辑:程序博客网 时间:2024/05/19 14:40
       转载请注明出处:http://write.blog.csdn.net/postedit/51694243
      云环境中,部分vm运行一段时间,不对外发包,可正常收包,system log中出现:kernel: virtio_net virtio4: output.0:id 30 is not a head。
      gdb ovs进程,发现rte_vhost_dequeue_burst 中
void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len){…   if (unlikely(!vq->data[i])) {                                                                                           BAD_RING(vq, "id %u is not a head!\n", i);                                                                          return NULL;                                                                                                }                /* detach_buf clears data, so grab it now. */                                                                     ret = vq->data[i];                                                                                                detach_buf(vq, i);                                                                                                vq->last_used_idx++;….}
       vq->last_used_idx == avail_idx ,dpdk-vhost判断没有数据可读。


查看linux virtio驱动源码,drivers/virtio/virtio_ring.c

void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len){…   if (unlikely(!vq->data[i])) {                                                                                           BAD_RING(vq, "id %u is not a head!\n", i);                                                                          return NULL;                                                                                                }                /* detach_buf clears data, so grab it now. */                                                                     ret = vq->data[i];                                                                                                detach_buf(vq, i);                                                                                                vq->last_used_idx++;….}
      vm认为共享mem满,不能发送数据。
      出现这个问题之前,主机log中,ovs 收到vm set_vring_call, vq->callfd被修改。 推测可能是ovs收包之后,kick vm用的是老的 callfd. 这时需要用新的callfd kick vm,通知vm共享mem 有数据被取出。kick会触发中断,对vm上vring的状态修改.
       修改这里后,再也没有出现问题。patch如下:
Date: Fri, 4 Mar 2016 11:00:19 +0800Subject: [PATCH] bug fix vm kernel: virtio_net virtio4: output.0:id 30 is not a head--- dpdk-2.2.0/lib/librte_vhost/rte_virtio_net.h | 4 +++- dpdk-2.2.0/lib/librte_vhost/vhost_rxtx.c     | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-)diff --git a/dpdk-2.2.0/lib/librte_vhost/rte_virtio_net.h b/dpdk-2.2.0/lib/librte_vhost/rte_virtio_net.hindex 8fea176..65401c5 100644--- a/dpdk-2.2.0/lib/librte_vhost/rte_virtio_net.h+++ b/dpdk-2.2.0/lib/librte_vhost/rte_virtio_net.h@@ -90,7 +90,9 @@ struct vhost_virtqueue { intcallfd;/**< Used to notify the guest (trigger interrupt). */ intkickfd;/**< Currently unused as polling mode is enabled. */ intenabled;-uint64_treserved[16];/**< Reserve some spaces for future extension. */+    int         prev_callfd;+    int         reserved32;+uint64_treserved[15];/**< Reserve some spaces for future extension. */ struct buf_vectorbuf_vec[BUF_VECTOR_MAX];/**< for scatter RX. */ } __rte_cache_aligned; diff --git a/dpdk-2.2.0/lib/librte_vhost/vhost_rxtx.c b/dpdk-2.2.0/lib/librte_vhost/vhost_rxtx.cindex bbf3fac..c846020 100644--- a/dpdk-2.2.0/lib/librte_vhost/vhost_rxtx.c+++ b/dpdk-2.2.0/lib/librte_vhost/vhost_rxtx.c@@ -592,7 +592,11 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,  /* If there are no available buffers then return. */ if (vq->last_used_idx == avail_idx)+    {+        if (vq->prev_callfd != vq->callfd)+             goto event_out;  return 0;+    }  LOG_DEBUG(VHOST_DATA, "%s (%"PRIu64")\n", __func__, dev->device_fh);@@ -773,8 +777,12 @@ rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,  rte_compiler_barrier(); vq->used->idx += entry_success;+event_out: /* Kick guest if required. */ if (!(vq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))+    { eventfd_write(vq->callfd, (eventfd_t)1);+        vq->prev_callfd = vq->callfd;+    } return entry_success; }



      
0 0
原创粉丝点击