29
29
#include <linux/slab.h>
30
30
#include <linux/cpu.h>
31
31
#include <linux/average.h>
32
+ #include <net/route.h>
32
33
33
34
static int napi_weight = NAPI_POLL_WEIGHT ;
34
35
module_param (napi_weight , int , 0444 );
@@ -98,6 +99,9 @@ struct receive_queue {
98
99
/* RX: fragments + linear part + virtio header */
99
100
struct scatterlist sg [MAX_SKB_FRAGS + 2 ];
100
101
102
+ /* Min single buffer size for mergeable buffers case. */
103
+ unsigned int min_buf_len ;
104
+
101
105
/* Name of this receive queue: input.$index */
102
106
char name [40 ];
103
107
};
@@ -831,13 +835,14 @@ static int add_recvbuf_big(struct virtnet_info *vi, struct receive_queue *rq,
831
835
return err ;
832
836
}
833
837
834
- static unsigned int get_mergeable_buf_len (struct ewma_pkt_len * avg_pkt_len )
838
+ static unsigned int get_mergeable_buf_len (struct receive_queue * rq ,
839
+ struct ewma_pkt_len * avg_pkt_len )
835
840
{
836
841
const size_t hdr_len = sizeof (struct virtio_net_hdr_mrg_rxbuf );
837
842
unsigned int len ;
838
843
839
844
len = hdr_len + clamp_t (unsigned int , ewma_pkt_len_read (avg_pkt_len ),
840
- GOOD_PACKET_LEN , PAGE_SIZE - hdr_len );
845
+ rq -> min_buf_len - hdr_len , PAGE_SIZE - hdr_len );
841
846
return ALIGN (len , L1_CACHE_BYTES );
842
847
}
843
848
@@ -851,7 +856,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
851
856
int err ;
852
857
unsigned int len , hole ;
853
858
854
- len = get_mergeable_buf_len (& rq -> mrg_avg_pkt_len );
859
+ len = get_mergeable_buf_len (rq , & rq -> mrg_avg_pkt_len );
855
860
if (unlikely (!skb_page_frag_refill (len + headroom , alloc_frag , gfp )))
856
861
return - ENOMEM ;
857
862
@@ -2023,6 +2028,21 @@ static void virtnet_del_vqs(struct virtnet_info *vi)
2023
2028
virtnet_free_queues (vi );
2024
2029
}
2025
2030
2031
+ /* How large should a single buffer be so a queue full of these can fit at
2032
+ * least one full packet?
2033
+ * Logic below assumes the mergeable buffer header is used.
2034
+ */
2035
+ static unsigned int mergeable_min_buf_len (struct virtnet_info * vi , struct virtqueue * vq )
2036
+ {
2037
+ const unsigned int hdr_len = sizeof (struct virtio_net_hdr_mrg_rxbuf );
2038
+ unsigned int rq_size = virtqueue_get_vring_size (vq );
2039
+ unsigned int packet_len = vi -> big_packets ? IP_MAX_MTU : vi -> dev -> max_mtu ;
2040
+ unsigned int buf_len = hdr_len + ETH_HLEN + VLAN_HLEN + packet_len ;
2041
+ unsigned int min_buf_len = DIV_ROUND_UP (buf_len , rq_size );
2042
+
2043
+ return max (min_buf_len , hdr_len );
2044
+ }
2045
+
2026
2046
static int virtnet_find_vqs (struct virtnet_info * vi )
2027
2047
{
2028
2048
vq_callback_t * * callbacks ;
@@ -2088,6 +2108,7 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
2088
2108
2089
2109
for (i = 0 ; i < vi -> max_queue_pairs ; i ++ ) {
2090
2110
vi -> rq [i ].vq = vqs [rxq2vq (i )];
2111
+ vi -> rq [i ].min_buf_len = mergeable_min_buf_len (vi , vi -> rq [i ].vq );
2091
2112
vi -> sq [i ].vq = vqs [txq2vq (i )];
2092
2113
}
2093
2114
@@ -2174,7 +2195,8 @@ static ssize_t mergeable_rx_buffer_size_show(struct netdev_rx_queue *queue,
2174
2195
2175
2196
BUG_ON (queue_index >= vi -> max_queue_pairs );
2176
2197
avg = & vi -> rq [queue_index ].mrg_avg_pkt_len ;
2177
- return sprintf (buf , "%u\n" , get_mergeable_buf_len (avg ));
2198
+ return sprintf (buf , "%u\n" ,
2199
+ get_mergeable_buf_len (& vi -> rq [queue_index ], avg ));
2178
2200
}
2179
2201
2180
2202
static struct rx_queue_attribute mergeable_rx_buffer_size_attribute =
0 commit comments