aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/lguest/lguest.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-07-29 10:58:37 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-07-28 19:58:37 -0400
commit398f187d74b89d5ab198fcf9b8d86edbefecec4d (patch)
tree7aee6787f46a8db0099f37e9dfea787499ecbcd1 /Documentation/lguest/lguest.c
parent9254926f85466979ef5f0e16386c294bf0973a90 (diff)
lguest: Use GSO/IFF_VNET_HDR extensions on tun/tap
Guest -> Host 1GB TCP: Before 20.1974 seconds xmit 214510 recv 5 timeout 214491 usec 278 After 8.43625 seconds xmit 95640 recv 198266 timeout 49771 usec 1252 Host -> Guest 1GB TCP: Before: Seconds 9.98854 xmit 172166 recv 5344 timeout 172157 usec 251 After: Seconds 5.72803 xmit 244322 recv 9919 timeout 244302 usec 156 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r--Documentation/lguest/lguest.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 0d1b0265d8e2..dc49f50e04ac 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -929,11 +929,9 @@ static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
929 while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) { 929 while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
930 if (in) 930 if (in)
931 errx(1, "Input buffers in output queue?"); 931 errx(1, "Input buffers in output queue?");
932 /* Check header, but otherwise ignore it (we told the Guest we 932 len = writev(vq->dev->fd, iov, out);
933 * supported no features, so it shouldn't have anything 933 if (len < 0)
934 * interesting). */ 934 err(1, "Writing network packet to tun");
935 (void)convert(&iov[0], struct virtio_net_hdr);
936 len = writev(vq->dev->fd, iov+1, out-1);
937 add_used_and_trigger(fd, vq, head, len); 935 add_used_and_trigger(fd, vq, head, len);
938 num++; 936 num++;
939 } 937 }
@@ -958,7 +956,6 @@ static bool handle_tun_input(int fd, struct device *dev)
958 unsigned int head, in_num, out_num; 956 unsigned int head, in_num, out_num;
959 int len; 957 int len;
960 struct iovec iov[dev->vq->vring.num]; 958 struct iovec iov[dev->vq->vring.num];
961 struct virtio_net_hdr *hdr;
962 959
963 /* First we need a network buffer from the Guests's recv virtqueue. */ 960 /* First we need a network buffer from the Guests's recv virtqueue. */
964 head = get_vq_desc(dev->vq, iov, &out_num, &in_num); 961 head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
@@ -977,18 +974,13 @@ static bool handle_tun_input(int fd, struct device *dev)
977 } else if (out_num) 974 } else if (out_num)
978 errx(1, "Output buffers in network recv queue?"); 975 errx(1, "Output buffers in network recv queue?");
979 976
980 /* First element is the header: we set it to 0 (no features). */
981 hdr = convert(&iov[0], struct virtio_net_hdr);
982 hdr->flags = 0;
983 hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
984
985 /* Read the packet from the device directly into the Guest's buffer. */ 977 /* Read the packet from the device directly into the Guest's buffer. */
986 len = readv(dev->fd, iov+1, in_num-1); 978 len = readv(dev->fd, iov, in_num);
987 if (len <= 0) 979 if (len <= 0)
988 err(1, "reading network"); 980 err(1, "reading network");
989 981
990 /* Tell the Guest about the new packet. */ 982 /* Tell the Guest about the new packet. */
991 add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len); 983 add_used_and_trigger(fd, dev->vq, head, len);
992 984
993 verbose("tun input packet len %i [%02x %02x] (%s)\n", len, 985 verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
994 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1], 986 ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
@@ -1490,11 +1482,15 @@ static int get_tun_device(char tapif[IFNAMSIZ])
1490 * the truth, I completely blundered my way through this code, but it 1482 * the truth, I completely blundered my way through this code, but it
1491 * works now! */ 1483 * works now! */
1492 netfd = open_or_die("/dev/net/tun", O_RDWR); 1484 netfd = open_or_die("/dev/net/tun", O_RDWR);
1493 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 1485 ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
1494 strcpy(ifr.ifr_name, "tap%d"); 1486 strcpy(ifr.ifr_name, "tap%d");
1495 if (ioctl(netfd, TUNSETIFF, &ifr) != 0) 1487 if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
1496 err(1, "configuring /dev/net/tun"); 1488 err(1, "configuring /dev/net/tun");
1497 1489
1490 if (ioctl(netfd, TUNSETOFFLOAD,
1491 TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0)
1492 err(1, "Could not set features for tun device");
1493
1498 /* We don't need checksums calculated for packets coming in this 1494 /* We don't need checksums calculated for packets coming in this
1499 * device: trust us! */ 1495 * device: trust us! */
1500 ioctl(netfd, TUNSETNOCSUM, 1); 1496 ioctl(netfd, TUNSETNOCSUM, 1);
@@ -1561,6 +1557,16 @@ static void setup_tun_net(char *arg)
1561 /* Tell Guest what MAC address to use. */ 1557 /* Tell Guest what MAC address to use. */
1562 add_feature(dev, VIRTIO_NET_F_MAC); 1558 add_feature(dev, VIRTIO_NET_F_MAC);
1563 add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); 1559 add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
1560 /* Expect Guest to handle everything except UFO */
1561 add_feature(dev, VIRTIO_NET_F_CSUM);
1562 add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
1563 add_feature(dev, VIRTIO_NET_F_MAC);
1564 add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
1565 add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
1566 add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
1567 add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
1568 add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
1569 add_feature(dev, VIRTIO_NET_F_HOST_ECN);
1564 set_config(dev, sizeof(conf), &conf); 1570 set_config(dev, sizeof(conf), &conf);
1565 1571
1566 /* We don't need the socket any more; setup is done. */ 1572 /* We don't need the socket any more; setup is done. */