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: Andrew Melnychenko <andrew@daynix.com> Link: https://lore.kernel.org/r/20220328175336.10802-4-andrew@daynix.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
c7114b1249
commit
91f41f01d2
1 changed files with 49 additions and 6 deletions
|
@ -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 @@ xdp_xmit:
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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[] = {
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue