Commit 91f41f01 authored by Andrew Melnychenko's avatar Andrew Melnychenko Committed by Michael S. Tsirkin

drivers/net/virtio_net: Added RSS hash report.

Added features for RSS hash report.
If hash is provided - it sets to skb.
Added checks if rss and/or hash are enabled together.
Signed-off-by: default avatarAndrew Melnychenko <andrew@daynix.com>
Link: https://lore.kernel.org/r/20220328175336.10802-4-andrew@daynix.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent c7114b12
...@@ -227,6 +227,7 @@ struct virtnet_info { ...@@ -227,6 +227,7 @@ struct virtnet_info {
/* Host supports rss and/or hash report */ /* Host supports rss and/or hash report */
bool has_rss; bool has_rss;
bool has_rss_hash_report;
u8 rss_key_size; u8 rss_key_size;
u16 rss_indir_table_size; u16 rss_indir_table_size;
u32 rss_hash_types_supported; u32 rss_hash_types_supported;
...@@ -1148,6 +1149,35 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, ...@@ -1148,6 +1149,35 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
return NULL; return NULL;
} }
static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
struct sk_buff *skb)
{
enum pkt_hash_types rss_hash_type;
if (!hdr_hash || !skb)
return;
switch ((int)hdr_hash->hash_report) {
case VIRTIO_NET_HASH_REPORT_TCPv4:
case VIRTIO_NET_HASH_REPORT_UDPv4:
case VIRTIO_NET_HASH_REPORT_TCPv6:
case VIRTIO_NET_HASH_REPORT_UDPv6:
case VIRTIO_NET_HASH_REPORT_TCPv6_EX:
case VIRTIO_NET_HASH_REPORT_UDPv6_EX:
rss_hash_type = PKT_HASH_TYPE_L4;
break;
case VIRTIO_NET_HASH_REPORT_IPv4:
case VIRTIO_NET_HASH_REPORT_IPv6:
case VIRTIO_NET_HASH_REPORT_IPv6_EX:
rss_hash_type = PKT_HASH_TYPE_L3;
break;
case VIRTIO_NET_HASH_REPORT_NONE:
default:
rss_hash_type = PKT_HASH_TYPE_NONE;
}
skb_set_hash(skb, (unsigned int)hdr_hash->hash_value, rss_hash_type);
}
static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
void *buf, unsigned int len, void **ctx, void *buf, unsigned int len, void **ctx,
unsigned int *xdp_xmit, unsigned int *xdp_xmit,
...@@ -1182,6 +1212,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq, ...@@ -1182,6 +1212,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
return; return;
hdr = skb_vnet_hdr(skb); hdr = skb_vnet_hdr(skb);
if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID) if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
...@@ -2232,7 +2264,8 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi) ...@@ -2232,7 +2264,8 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi)
sg_set_buf(&sgs[3], vi->ctrl->rss.key, sg_buf_size); sg_set_buf(&sgs[3], vi->ctrl->rss.key, sg_buf_size);
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
VIRTIO_NET_CTRL_MQ_RSS_CONFIG, sgs)) { vi->has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG
: VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs)) {
dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n"); dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n");
return false; return false;
} }
...@@ -3231,6 +3264,8 @@ static bool virtnet_validate_features(struct virtio_device *vdev) ...@@ -3231,6 +3264,8 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR, VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR,
"VIRTIO_NET_F_CTRL_VQ") || "VIRTIO_NET_F_CTRL_VQ") ||
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS, VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS,
"VIRTIO_NET_F_CTRL_VQ") ||
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_HASH_REPORT,
"VIRTIO_NET_F_CTRL_VQ"))) { "VIRTIO_NET_F_CTRL_VQ"))) {
return false; return false;
} }
...@@ -3366,8 +3401,13 @@ static int virtnet_probe(struct virtio_device *vdev) ...@@ -3366,8 +3401,13 @@ static int virtnet_probe(struct virtio_device *vdev)
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
vi->mergeable_rx_bufs = true; vi->mergeable_rx_bufs = true;
if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT))
vi->has_rss_hash_report = true;
if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS))
vi->has_rss = true; vi->has_rss = true;
if (vi->has_rss || vi->has_rss_hash_report) {
vi->rss_indir_table_size = vi->rss_indir_table_size =
virtio_cread16(vdev, offsetof(struct virtio_net_config, virtio_cread16(vdev, offsetof(struct virtio_net_config,
rss_max_indirection_table_length)); rss_max_indirection_table_length));
...@@ -3383,8 +3423,11 @@ static int virtnet_probe(struct virtio_device *vdev) ...@@ -3383,8 +3423,11 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->hw_features |= NETIF_F_RXHASH; dev->hw_features |= NETIF_F_RXHASH;
} }
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) ||
virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) if (vi->has_rss_hash_report)
vi->hdr_len = sizeof(struct virtio_net_hdr_v1_hash);
else if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) ||
virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
vi->hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf); vi->hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else else
vi->hdr_len = sizeof(struct virtio_net_hdr); vi->hdr_len = sizeof(struct virtio_net_hdr);
...@@ -3451,7 +3494,7 @@ static int virtnet_probe(struct virtio_device *vdev) ...@@ -3451,7 +3494,7 @@ static int virtnet_probe(struct virtio_device *vdev)
} }
} }
if (vi->has_rss) if (vi->has_rss || vi->has_rss_hash_report)
virtnet_init_default_rss(vi); virtnet_init_default_rss(vi);
err = register_netdev(dev); err = register_netdev(dev);
...@@ -3586,7 +3629,7 @@ static struct virtio_device_id id_table[] = { ...@@ -3586,7 +3629,7 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_CTRL_MAC_ADDR, \ VIRTIO_NET_F_CTRL_MAC_ADDR, \
VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \ VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \ VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \
VIRTIO_NET_F_RSS VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT
static unsigned int features[] = { static unsigned int features[] = {
VIRTNET_FEATURES, VIRTNET_FEATURES,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment