Skip to content

Commit 91f41f0

Browse files
AndrewAtDaynixmstsirkin
authored andcommitted
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>
1 parent c7114b1 commit 91f41f0

1 file changed

Lines changed: 49 additions & 6 deletions

File tree

drivers/net/virtio_net.c

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ struct virtnet_info {
227227

228228
/* Host supports rss and/or hash report */
229229
bool has_rss;
230+
bool has_rss_hash_report;
230231
u8 rss_key_size;
231232
u16 rss_indir_table_size;
232233
u32 rss_hash_types_supported;
@@ -1148,6 +1149,35 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
11481149
return NULL;
11491150
}
11501151

1152+
static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_hash,
1153+
struct sk_buff *skb)
1154+
{
1155+
enum pkt_hash_types rss_hash_type;
1156+
1157+
if (!hdr_hash || !skb)
1158+
return;
1159+
1160+
switch ((int)hdr_hash->hash_report) {
1161+
case VIRTIO_NET_HASH_REPORT_TCPv4:
1162+
case VIRTIO_NET_HASH_REPORT_UDPv4:
1163+
case VIRTIO_NET_HASH_REPORT_TCPv6:
1164+
case VIRTIO_NET_HASH_REPORT_UDPv6:
1165+
case VIRTIO_NET_HASH_REPORT_TCPv6_EX:
1166+
case VIRTIO_NET_HASH_REPORT_UDPv6_EX:
1167+
rss_hash_type = PKT_HASH_TYPE_L4;
1168+
break;
1169+
case VIRTIO_NET_HASH_REPORT_IPv4:
1170+
case VIRTIO_NET_HASH_REPORT_IPv6:
1171+
case VIRTIO_NET_HASH_REPORT_IPv6_EX:
1172+
rss_hash_type = PKT_HASH_TYPE_L3;
1173+
break;
1174+
case VIRTIO_NET_HASH_REPORT_NONE:
1175+
default:
1176+
rss_hash_type = PKT_HASH_TYPE_NONE;
1177+
}
1178+
skb_set_hash(skb, (unsigned int)hdr_hash->hash_value, rss_hash_type);
1179+
}
1180+
11511181
static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
11521182
void *buf, unsigned int len, void **ctx,
11531183
unsigned int *xdp_xmit,
@@ -1182,6 +1212,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
11821212
return;
11831213

11841214
hdr = skb_vnet_hdr(skb);
1215+
if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
1216+
virtio_skb_set_hash((const struct virtio_net_hdr_v1_hash *)hdr, skb);
11851217

11861218
if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
11871219
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2232,7 +2264,8 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi)
22322264
sg_set_buf(&sgs[3], vi->ctrl->rss.key, sg_buf_size);
22332265

22342266
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
2235-
VIRTIO_NET_CTRL_MQ_RSS_CONFIG, sgs)) {
2267+
vi->has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG
2268+
: VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs)) {
22362269
dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n");
22372270
return false;
22382271
}
@@ -3231,6 +3264,8 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
32313264
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR,
32323265
"VIRTIO_NET_F_CTRL_VQ") ||
32333266
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_RSS,
3267+
"VIRTIO_NET_F_CTRL_VQ") ||
3268+
VIRTNET_FAIL_ON(vdev, VIRTIO_NET_F_HASH_REPORT,
32343269
"VIRTIO_NET_F_CTRL_VQ"))) {
32353270
return false;
32363271
}
@@ -3366,8 +3401,13 @@ static int virtnet_probe(struct virtio_device *vdev)
33663401
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
33673402
vi->mergeable_rx_bufs = true;
33683403

3369-
if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) {
3404+
if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT))
3405+
vi->has_rss_hash_report = true;
3406+
3407+
if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS))
33703408
vi->has_rss = true;
3409+
3410+
if (vi->has_rss || vi->has_rss_hash_report) {
33713411
vi->rss_indir_table_size =
33723412
virtio_cread16(vdev, offsetof(struct virtio_net_config,
33733413
rss_max_indirection_table_length));
@@ -3383,8 +3423,11 @@ static int virtnet_probe(struct virtio_device *vdev)
33833423

33843424
dev->hw_features |= NETIF_F_RXHASH;
33853425
}
3386-
if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) ||
3387-
virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
3426+
3427+
if (vi->has_rss_hash_report)
3428+
vi->hdr_len = sizeof(struct virtio_net_hdr_v1_hash);
3429+
else if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF) ||
3430+
virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
33883431
vi->hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
33893432
else
33903433
vi->hdr_len = sizeof(struct virtio_net_hdr);
@@ -3451,7 +3494,7 @@ static int virtnet_probe(struct virtio_device *vdev)
34513494
}
34523495
}
34533496

3454-
if (vi->has_rss)
3497+
if (vi->has_rss || vi->has_rss_hash_report)
34553498
virtnet_init_default_rss(vi);
34563499

34573500
err = register_netdev(dev);
@@ -3586,7 +3629,7 @@ static struct virtio_device_id id_table[] = {
35863629
VIRTIO_NET_F_CTRL_MAC_ADDR, \
35873630
VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
35883631
VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \
3589-
VIRTIO_NET_F_RSS
3632+
VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT
35903633

35913634
static unsigned int features[] = {
35923635
VIRTNET_FEATURES,

0 commit comments

Comments
 (0)