Thread (8 messages) 8 messages, 2 authors, 2024-02-06

Re: [PATCH net-next v5 5/5] tools: virtio: introduce vhost_net_test

From: Yunsheng Lin <hidden>
Date: 2024-02-06 07:24:06
Also in: lkml, virtualization

On 2024/2/6 11:08, Jason Wang wrote:

...
quoted
+
+static void wait_for_interrupt(struct vq_info *vq)
+{
+       unsigned long long val;
+
+       poll(&vq->fds, 1, -1);
It's not good to wait indefinitely.
How about a timeout value of 100ms as below?
poll(&vq->fds, 1, 100);
quoted
+
+       if (vq->fds.revents & POLLIN)
+               read(vq->fds.fd, &val, sizeof(val));
+}
+
+static void verify_res_buf(char *res_buf)
+{
+       int i;
+
+       for (i = ETHER_HDR_LEN; i < TEST_BUF_LEN; i++)
+               assert(res_buf[i] == (char)i);
+}
+
+static void run_tx_test(struct vdev_info *dev, struct vq_info *vq,
+                       bool delayed, int bufs)
+{
+       long long spurious = 0;
+       struct scatterlist sl;
+       unsigned int len;
+       int r;
+
+       for (;;) {
+               long started_before = vq->started;
+               long completed_before = vq->completed;
+
+               virtqueue_disable_cb(vq->vq);
+               do {
+                       while (vq->started < bufs &&
+                              (vq->started - vq->completed) < 1) {
+                               sg_init_one(&sl, dev->test_buf, HDR_LEN + TEST_BUF_LEN);
+                               r = virtqueue_add_outbuf(vq->vq, &sl, 1,
+                                                        dev->test_buf + vq->started,
+                                                        GFP_ATOMIC);
+                               if (unlikely(r != 0))
+                                       break;
+
+                               ++vq->started;
If we never decrease started/completed shouldn't we use unsigned here?
(as well as completed)

Otherwise we may get unexpected results for vq->started as well as
vq->completed.
We have "vq->started < bufs" checking before the increasing as above,
and there is 'assert(nbufs > 0)' when getting optarg in main(), which
means we never allow started/completed to be greater than nbufs as
my understanding.
quoted
+
+                               if (unlikely(!virtqueue_kick(vq->vq))) {
+                                       r = -1;
+                                       break;
+                               }
+                       }
+
+                       if (vq->started >= bufs)
+                               r = -1;
Which condition do we reach here?
It is also a copy & paste of virtio_test.c
It means we have finished adding the outbuf in virtqueue, and set 'r'
to be '-1' so that we can break the inner while loop if there is no
result for virtqueue_get_buf() as my understanding.
quoted
+
+                       /* Flush out completed bufs if any */
+                       while (virtqueue_get_buf(vq->vq, &len)) {
+                               int n;
+
+                               n = recvfrom(dev->sock, dev->res_buf, TEST_BUF_LEN, 0, NULL, NULL);
+                               assert(n == TEST_BUF_LEN);
+                               verify_res_buf(dev->res_buf);
+
+                               ++vq->completed;
+                               r = 0;
+                       }
+               } while (r == 0);
+
+               if (vq->completed == completed_before && vq->started == started_before)
+                       ++spurious;
+
+               assert(vq->completed <= bufs);
+               assert(vq->started <= bufs);
+               if (vq->completed == bufs)
+                       break;
+
+               if (delayed) {
+                       if (virtqueue_enable_cb_delayed(vq->vq))
+                               wait_for_interrupt(vq);
+               } else {
+                       if (virtqueue_enable_cb(vq->vq))
+                               wait_for_interrupt(vq);
+               }
This could be simplified with

if (delayed)
else

wait_for_interrupt(vq)
I am not sure if I understand the above comment.
The wait_for_interrupt() is only called conditionally depending on the
returning of virtqueue_enable_cb_delayed() and virtqueue_enable_cb().
quoted
+       }
+       printf("TX spurious wakeups: 0x%llx started=0x%lx completed=0x%lx\n",
+              spurious, vq->started, vq->completed);
+}
+
...
quoted
+
+                       /* Flush out completed bufs if any */
+                       while (virtqueue_get_buf(vq->vq, &len)) {
+                               struct ether_header *eh;
+
+                               eh = (struct ether_header *)(dev->res_buf + HDR_LEN);
+
+                               /* tun netdev is up and running, ignore the
+                                * non-TEST_PTYPE packet.
+                                */
+                               if (eh->ether_type != htons(TEST_PTYPE)) {
+                                       ++vq->completed;
+                                       r = 0;
+                                       continue;
+                               }
+
+                               assert(len == TEST_BUF_LEN + HDR_LEN);
+                               verify_res_buf(dev->res_buf + HDR_LEN);
Let's simply the logic here:

if (ether_type == htons()) {
    assert()
    verify_res_buf()
}

r = 0;
++vq->completed;
Sure.
Others look good.
Thanks for the reviewing.
Thanks

.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help