diff options
author | Michael Dalton <mwdalton@google.com> | 2014-01-17 01:23:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-17 02:46:07 -0500 |
commit | fbf28d78f54016faa7f0b68cf632ac739f2204f7 (patch) | |
tree | 1d77e0acd1ff34398fba2fa211fe965dde712ba9 /drivers/net/virtio_net.c | |
parent | 03144b5869d2921dafbea477246aeb5d4eb5fc38 (diff) |
virtio-net: initial rx sysfs support, export mergeable rx buffer size
Add initial support for per-rx queue sysfs attributes to virtio-net. If
mergeable packet buffers are enabled, adds a read-only mergeable packet
buffer size sysfs attribute for each RX queue.
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael Dalton <mwdalton@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index dacd43b276d4..d75f8edf4fb3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -600,18 +600,25 @@ static int add_recvbuf_big(struct receive_queue *rq, gfp_t gfp) | |||
600 | return err; | 600 | return err; |
601 | } | 601 | } |
602 | 602 | ||
603 | static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp) | 603 | static unsigned int get_mergeable_buf_len(struct ewma *avg_pkt_len) |
604 | { | 604 | { |
605 | const size_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf); | 605 | const size_t hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf); |
606 | unsigned int len; | ||
607 | |||
608 | len = hdr_len + clamp_t(unsigned int, ewma_read(avg_pkt_len), | ||
609 | GOOD_PACKET_LEN, PAGE_SIZE - hdr_len); | ||
610 | return ALIGN(len, MERGEABLE_BUFFER_ALIGN); | ||
611 | } | ||
612 | |||
613 | static int add_recvbuf_mergeable(struct receive_queue *rq, gfp_t gfp) | ||
614 | { | ||
606 | struct page_frag *alloc_frag = &rq->alloc_frag; | 615 | struct page_frag *alloc_frag = &rq->alloc_frag; |
607 | char *buf; | 616 | char *buf; |
608 | unsigned long ctx; | 617 | unsigned long ctx; |
609 | int err; | 618 | int err; |
610 | unsigned int len, hole; | 619 | unsigned int len, hole; |
611 | 620 | ||
612 | len = hdr_len + clamp_t(unsigned int, ewma_read(&rq->mrg_avg_pkt_len), | 621 | len = get_mergeable_buf_len(&rq->mrg_avg_pkt_len); |
613 | GOOD_PACKET_LEN, PAGE_SIZE - hdr_len); | ||
614 | len = ALIGN(len, MERGEABLE_BUFFER_ALIGN); | ||
615 | if (unlikely(!skb_page_frag_refill(len, alloc_frag, gfp))) | 622 | if (unlikely(!skb_page_frag_refill(len, alloc_frag, gfp))) |
616 | return -ENOMEM; | 623 | return -ENOMEM; |
617 | 624 | ||
@@ -1584,6 +1591,33 @@ err: | |||
1584 | return ret; | 1591 | return ret; |
1585 | } | 1592 | } |
1586 | 1593 | ||
1594 | #ifdef CONFIG_SYSFS | ||
1595 | static ssize_t mergeable_rx_buffer_size_show(struct netdev_rx_queue *queue, | ||
1596 | struct rx_queue_attribute *attribute, char *buf) | ||
1597 | { | ||
1598 | struct virtnet_info *vi = netdev_priv(queue->dev); | ||
1599 | unsigned int queue_index = get_netdev_rx_queue_index(queue); | ||
1600 | struct ewma *avg; | ||
1601 | |||
1602 | BUG_ON(queue_index >= vi->max_queue_pairs); | ||
1603 | avg = &vi->rq[queue_index].mrg_avg_pkt_len; | ||
1604 | return sprintf(buf, "%u\n", get_mergeable_buf_len(avg)); | ||
1605 | } | ||
1606 | |||
1607 | static struct rx_queue_attribute mergeable_rx_buffer_size_attribute = | ||
1608 | __ATTR_RO(mergeable_rx_buffer_size); | ||
1609 | |||
1610 | static struct attribute *virtio_net_mrg_rx_attrs[] = { | ||
1611 | &mergeable_rx_buffer_size_attribute.attr, | ||
1612 | NULL | ||
1613 | }; | ||
1614 | |||
1615 | static const struct attribute_group virtio_net_mrg_rx_group = { | ||
1616 | .name = "virtio_net", | ||
1617 | .attrs = virtio_net_mrg_rx_attrs | ||
1618 | }; | ||
1619 | #endif | ||
1620 | |||
1587 | static int virtnet_probe(struct virtio_device *vdev) | 1621 | static int virtnet_probe(struct virtio_device *vdev) |
1588 | { | 1622 | { |
1589 | int i, err; | 1623 | int i, err; |
@@ -1698,6 +1732,10 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1698 | if (err) | 1732 | if (err) |
1699 | goto free_stats; | 1733 | goto free_stats; |
1700 | 1734 | ||
1735 | #ifdef CONFIG_SYSFS | ||
1736 | if (vi->mergeable_rx_bufs) | ||
1737 | dev->sysfs_rx_queue_group = &virtio_net_mrg_rx_group; | ||
1738 | #endif | ||
1701 | netif_set_real_num_tx_queues(dev, vi->curr_queue_pairs); | 1739 | netif_set_real_num_tx_queues(dev, vi->curr_queue_pairs); |
1702 | netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs); | 1740 | netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs); |
1703 | 1741 | ||