hyperv/hn: Extract RSS hash value and type.
MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6287
This commit is contained in:
parent
a7ed172cbf
commit
effd024064
@ -1164,6 +1164,7 @@ struct hn_rx_ring {
|
||||
u_long hn_lro_tried;
|
||||
u_long hn_small_pkts;
|
||||
u_long hn_pkts;
|
||||
u_long hn_rss_pkts;
|
||||
|
||||
/* Rarely used stuffs */
|
||||
struct sysctl_oid *hn_rx_sysctl_tree;
|
||||
|
@ -140,7 +140,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define HN_RNDIS_MSG_LEN \
|
||||
(sizeof(rndis_msg) + \
|
||||
RNDIS_HASH_PPI_SIZE + \
|
||||
RNDIS_HASHVAL_PPI_SIZE + \
|
||||
RNDIS_VLAN_PPI_SIZE + \
|
||||
RNDIS_TSO_PPI_SIZE + \
|
||||
RNDIS_CSUM_PPI_SIZE)
|
||||
@ -866,7 +866,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
|
||||
rndis_msg *rndis_mesg;
|
||||
rndis_packet *rndis_pkt;
|
||||
rndis_per_packet_info *rppi;
|
||||
struct ndis_hash_info *hash_info;
|
||||
struct rndis_hash_value *hash_value;
|
||||
uint32_t rndis_msg_size;
|
||||
|
||||
packet = &txd->netvsc_pkt;
|
||||
@ -892,16 +892,16 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
|
||||
rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
|
||||
|
||||
/*
|
||||
* Set the hash info for this packet, so that the host could
|
||||
* Set the hash value for this packet, so that the host could
|
||||
* dispatch the TX done event for this packet back to this TX
|
||||
* ring's channel.
|
||||
*/
|
||||
rndis_msg_size += RNDIS_HASH_PPI_SIZE;
|
||||
rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASH_PPI_SIZE,
|
||||
rndis_msg_size += RNDIS_HASHVAL_PPI_SIZE;
|
||||
rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASHVAL_PPI_SIZE,
|
||||
nbl_hash_value);
|
||||
hash_info = (struct ndis_hash_info *)((uint8_t *)rppi +
|
||||
hash_value = (struct rndis_hash_value *)((uint8_t *)rppi +
|
||||
rppi->per_packet_info_offset);
|
||||
hash_info->hash = txr->hn_tx_idx;
|
||||
hash_value->hash_value = txr->hn_tx_idx;
|
||||
|
||||
if (m_head->m_flags & M_VLANTAG) {
|
||||
ndis_8021q_info *rppi_vlan_info;
|
||||
@ -1291,7 +1291,9 @@ hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
|
||||
*/
|
||||
int
|
||||
netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
|
||||
rndis_tcp_ip_csum_info *csum_info)
|
||||
rndis_tcp_ip_csum_info *csum_info,
|
||||
const struct rndis_hash_info *hash_info,
|
||||
const struct rndis_hash_value *hash_value)
|
||||
{
|
||||
struct hn_rx_ring *rxr = chan->hv_chan_rxr;
|
||||
struct ifnet *ifp = rxr->hn_ifp;
|
||||
@ -1400,7 +1402,6 @@ netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
|
||||
CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
m_new->m_pkthdr.csum_data = 0xffff;
|
||||
}
|
||||
/* Rely on SW csum verification though... */
|
||||
do_lro = 1;
|
||||
} else if (pr == IPPROTO_UDP) {
|
||||
if (do_csum &&
|
||||
@ -1427,8 +1428,50 @@ netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
|
||||
m_new->m_flags |= M_VLANTAG;
|
||||
}
|
||||
|
||||
m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
|
||||
M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE);
|
||||
if (hash_info != NULL && hash_value != NULL) {
|
||||
int hash_type = M_HASHTYPE_OPAQUE;
|
||||
|
||||
rxr->hn_rss_pkts++;
|
||||
m_new->m_pkthdr.flowid = hash_value->hash_value;
|
||||
if ((hash_info->hash_info & NDIS_HASH_FUNCTION_MASK) ==
|
||||
NDIS_HASH_FUNCTION_TOEPLITZ) {
|
||||
uint32_t type =
|
||||
(hash_info->hash_info & NDIS_HASH_TYPE_MASK);
|
||||
|
||||
switch (type) {
|
||||
case NDIS_HASH_IPV4:
|
||||
hash_type = M_HASHTYPE_RSS_IPV4;
|
||||
break;
|
||||
|
||||
case NDIS_HASH_TCP_IPV4:
|
||||
hash_type = M_HASHTYPE_RSS_TCP_IPV4;
|
||||
break;
|
||||
|
||||
case NDIS_HASH_IPV6:
|
||||
hash_type = M_HASHTYPE_RSS_IPV6;
|
||||
break;
|
||||
|
||||
case NDIS_HASH_IPV6_EX:
|
||||
hash_type = M_HASHTYPE_RSS_IPV6_EX;
|
||||
break;
|
||||
|
||||
case NDIS_HASH_TCP_IPV6:
|
||||
hash_type = M_HASHTYPE_RSS_TCP_IPV6;
|
||||
break;
|
||||
|
||||
case NDIS_HASH_TCP_IPV6_EX:
|
||||
hash_type = M_HASHTYPE_RSS_TCP_IPV6_EX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
M_HASHTYPE_SET(m_new, hash_type);
|
||||
} else {
|
||||
if (hash_value != NULL)
|
||||
m_new->m_pkthdr.flowid = hash_value->hash_value;
|
||||
else
|
||||
m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
|
||||
M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Moved RX completion back to hv_nv_on_receive() so all
|
||||
@ -2219,6 +2262,11 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
|
||||
SYSCTL_CHILDREN(rxr->hn_rx_sysctl_tree),
|
||||
OID_AUTO, "packets", CTLFLAG_RW,
|
||||
&rxr->hn_pkts, "# of packets received");
|
||||
SYSCTL_ADD_ULONG(ctx,
|
||||
SYSCTL_CHILDREN(rxr->hn_rx_sysctl_tree),
|
||||
OID_AUTO, "rss_pkts", CTLFLAG_RW,
|
||||
&rxr->hn_rss_pkts,
|
||||
"# of packets w/ RSS info received");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -617,6 +617,7 @@ typedef enum ndis_per_pkt_infotype_ {
|
||||
} ndis_per_pkt_infotype;
|
||||
|
||||
#define nbl_hash_value pkt_cancel_id
|
||||
#define nbl_hash_info original_netbuf_list
|
||||
|
||||
typedef struct ndis_8021q_info_ {
|
||||
union {
|
||||
@ -630,10 +631,6 @@ typedef struct ndis_8021q_info_ {
|
||||
} u1;
|
||||
} ndis_8021q_info;
|
||||
|
||||
struct ndis_hash_info {
|
||||
uint32_t hash;
|
||||
} __packed;
|
||||
|
||||
struct rndis_object_header {
|
||||
uint8_t type;
|
||||
uint8_t revision;
|
||||
@ -694,6 +691,28 @@ typedef struct rndis_tcp_ip_csum_info_ {
|
||||
};
|
||||
} rndis_tcp_ip_csum_info;
|
||||
|
||||
struct rndis_hash_value {
|
||||
uint32_t hash_value;
|
||||
} __packed;
|
||||
|
||||
struct rndis_hash_info {
|
||||
uint32_t hash_info;
|
||||
} __packed;
|
||||
|
||||
#define NDIS_HASH_FUNCTION_MASK 0x000000FF /* see hash function */
|
||||
#define NDIS_HASH_TYPE_MASK 0x00FFFF00 /* see hash type */
|
||||
|
||||
/* hash function */
|
||||
#define NDIS_HASH_FUNCTION_TOEPLITZ 0x00000001
|
||||
|
||||
/* hash type */
|
||||
#define NDIS_HASH_IPV4 0x00000100
|
||||
#define NDIS_HASH_TCP_IPV4 0x00000200
|
||||
#define NDIS_HASH_IPV6 0x00000400
|
||||
#define NDIS_HASH_IPV6_EX 0x00000800
|
||||
#define NDIS_HASH_TCP_IPV6 0x00001000
|
||||
#define NDIS_HASH_TCP_IPV6_EX 0x00002000
|
||||
|
||||
typedef struct rndis_tcp_tso_info_ {
|
||||
union {
|
||||
struct {
|
||||
@ -727,8 +746,8 @@ typedef struct rndis_tcp_tso_info_ {
|
||||
};
|
||||
} rndis_tcp_tso_info;
|
||||
|
||||
#define RNDIS_HASH_PPI_SIZE (sizeof(rndis_per_packet_info) + \
|
||||
sizeof(struct ndis_hash_info))
|
||||
#define RNDIS_HASHVAL_PPI_SIZE (sizeof(rndis_per_packet_info) + \
|
||||
sizeof(struct rndis_hash_value))
|
||||
|
||||
#define RNDIS_VLAN_PPI_SIZE (sizeof(rndis_per_packet_info) + \
|
||||
sizeof(ndis_8021q_info))
|
||||
@ -1066,7 +1085,9 @@ typedef struct rndismp_rx_bufs_info_ {
|
||||
struct hv_vmbus_channel;
|
||||
|
||||
int netvsc_recv(struct hv_vmbus_channel *chan,
|
||||
netvsc_packet *packet, rndis_tcp_ip_csum_info *csum_info);
|
||||
netvsc_packet *packet, rndis_tcp_ip_csum_info *csum_info,
|
||||
const struct rndis_hash_info *hash_info,
|
||||
const struct rndis_hash_value *hash_value);
|
||||
void netvsc_channel_rollup(struct hv_vmbus_channel *chan);
|
||||
|
||||
void* hv_set_rppi_data(rndis_msg *rndis_mesg,
|
||||
|
@ -444,6 +444,8 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
|
||||
ndis_8021q_info *rppi_vlan_info;
|
||||
uint32_t data_offset;
|
||||
rndis_tcp_ip_csum_info *csum_info = NULL;
|
||||
const struct rndis_hash_info *hash_info;
|
||||
const struct rndis_hash_value *hash_value;
|
||||
device_t dev = device->net_dev->dev->device;
|
||||
|
||||
rndis_pkt = &message->msg.packet;
|
||||
@ -476,7 +478,9 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
|
||||
}
|
||||
|
||||
csum_info = hv_get_ppi_data(rndis_pkt, tcpip_chksum_info);
|
||||
netvsc_recv(chan, pkt, csum_info);
|
||||
hash_value = hv_get_ppi_data(rndis_pkt, nbl_hash_value);
|
||||
hash_info = hv_get_ppi_data(rndis_pkt, nbl_hash_info);
|
||||
netvsc_recv(chan, pkt, csum_info, hash_info, hash_value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user