tun: switch to use skb array for tx
We used to queue tx packets in sk_receive_queue, this is less efficient since it requires spinlocks to synchronize between producer and consumer. This patch tries to address this by: - switch from sk_receive_queue to a skb_array, and resize it when tx_queue_len was changed. - introduce a new proto_ops peek_len which was used for peeking the skb length. - implement a tun version of peek_len for vhost_net to use and convert vhost_net to use peek_len if possible. Pktgen test shows about 15.3% improvement on guest receiving pps for small buffers: Before: ~1300000pps After : ~1500000pps Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
08294a26e1
commit
1576d98605
@@ -481,10 +481,14 @@ out:
|
||||
|
||||
static int peek_head_len(struct sock *sk)
|
||||
{
|
||||
struct socket *sock = sk->sk_socket;
|
||||
struct sk_buff *head;
|
||||
int len = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (sock->ops->peek_len)
|
||||
return sock->ops->peek_len(sock);
|
||||
|
||||
spin_lock_irqsave(&sk->sk_receive_queue.lock, flags);
|
||||
head = skb_peek(&sk->sk_receive_queue);
|
||||
if (likely(head)) {
|
||||
@@ -497,6 +501,16 @@ static int peek_head_len(struct sock *sk)
|
||||
return len;
|
||||
}
|
||||
|
||||
static int sk_has_rx_data(struct sock *sk)
|
||||
{
|
||||
struct socket *sock = sk->sk_socket;
|
||||
|
||||
if (sock->ops->peek_len)
|
||||
return sock->ops->peek_len(sock);
|
||||
|
||||
return skb_queue_empty(&sk->sk_receive_queue);
|
||||
}
|
||||
|
||||
static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
|
||||
{
|
||||
struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_TX];
|
||||
@@ -513,7 +527,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
|
||||
endtime = busy_clock() + vq->busyloop_timeout;
|
||||
|
||||
while (vhost_can_busy_poll(&net->dev, endtime) &&
|
||||
skb_queue_empty(&sk->sk_receive_queue) &&
|
||||
!sk_has_rx_data(sk) &&
|
||||
vhost_vq_avail_empty(&net->dev, vq))
|
||||
cpu_relax_lowlatency();
|
||||
|
||||
|
Reference in New Issue
Block a user