/* I like... big packets and I cannot lie! */
        bool big_packets;
 
+       /* number of sg entries allocated for big packets */
+       unsigned int big_packets_num_skbfrags;
+
        /* Host will merge rx buffers for big packets (shake it! shake it!) */
        bool mergeable_rx_bufs;
 
        char *p;
        int i, err, offset;
 
-       sg_init_table(rq->sg, MAX_SKB_FRAGS + 2);
+       sg_init_table(rq->sg, vi->big_packets_num_skbfrags + 2);
 
-       /* page in rq->sg[MAX_SKB_FRAGS + 1] is list tail */
-       for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
+       /* page in rq->sg[vi->big_packets_num_skbfrags + 1] is list tail */
+       for (i = vi->big_packets_num_skbfrags + 1; i > 1; --i) {
                first = get_a_page(rq, gfp);
                if (!first) {
                        if (list)
 
        /* chain first in list head */
        first->private = (unsigned long)list;
-       err = virtqueue_add_inbuf(rq->vq, rq->sg, MAX_SKB_FRAGS + 2,
+       err = virtqueue_add_inbuf(rq->vq, rq->sg, vi->big_packets_num_skbfrags + 2,
                                  first, gfp);
        if (err < 0)
                give_pages(rq, first);
                virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO);
 }
 
+static void virtnet_set_big_packets(struct virtnet_info *vi, const int mtu)
+{
+       bool guest_gso = virtnet_check_guest_gso(vi);
+
+       /* If device can receive ANY guest GSO packets, regardless of mtu,
+        * allocate packets of maximum size, otherwise limit it to only
+        * mtu size worth only.
+        */
+       if (mtu > ETH_DATA_LEN || guest_gso) {
+               vi->big_packets = true;
+               vi->big_packets_num_skbfrags = guest_gso ? MAX_SKB_FRAGS : DIV_ROUND_UP(mtu, PAGE_SIZE);
+       }
+}
+
 static int virtnet_probe(struct virtio_device *vdev)
 {
        int i, err = -ENOMEM;
        struct net_device *dev;
        struct virtnet_info *vi;
        u16 max_queue_pairs;
-       int mtu;
+       int mtu = 0;
 
        /* Find if host supports multiqueue/rss virtio_net device */
        max_queue_pairs = 1;
        INIT_WORK(&vi->config_work, virtnet_config_changed_work);
        spin_lock_init(&vi->refill_lock);
 
-       /* If we can receive ANY GSO packets, we must allocate large ones. */
-       if (virtnet_check_guest_gso(vi))
-               vi->big_packets = true;
-
        if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
                vi->mergeable_rx_bufs = true;
 
 
                dev->mtu = mtu;
                dev->max_mtu = mtu;
-
-               /* TODO: size buffers correctly in this case. */
-               if (dev->mtu > ETH_DATA_LEN)
-                       vi->big_packets = true;
        }
 
+       virtnet_set_big_packets(vi, mtu);
+
        if (vi->any_header_sg)
                dev->needed_headroom = vi->hdr_len;