summaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2014-05-21 15:55:39 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-23 14:49:00 -0400
commit307f099520b66504cf6c5638f3f404c48b9fb45b (patch)
tree1e401d359547bb836ad7cce9214bf7fd578c5b91 /drivers/net/hyperv
parent915f15ca52d8aefa253e0f13c7daa33b9f6ab399 (diff)
hyperv: Add hash value into RNDIS Per-packet info
It passes the hash value as the RNDIS Per-packet info to the Hyper-V host, so that the send completion notices can be spread across multiple channels. MS-TFS: 140273 Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r--drivers/net/hyperv/hyperv_net.h4
-rw-r--r--drivers/net/hyperv/netvsc_drv.c18
2 files changed, 18 insertions, 4 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 4b7df5a5c966..6cc37c15e0bf 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -791,6 +791,7 @@ enum ndis_per_pkt_info_type {
791 IEEE_8021Q_INFO, 791 IEEE_8021Q_INFO,
792 ORIGINAL_PKTINFO, 792 ORIGINAL_PKTINFO,
793 PACKET_CANCEL_ID, 793 PACKET_CANCEL_ID,
794 NBL_HASH_VALUE = PACKET_CANCEL_ID,
794 ORIGINAL_NET_BUFLIST, 795 ORIGINAL_NET_BUFLIST,
795 CACHED_NET_BUFLIST, 796 CACHED_NET_BUFLIST,
796 SHORT_PKT_PADINFO, 797 SHORT_PKT_PADINFO,
@@ -937,6 +938,9 @@ struct ndis_tcp_lso_info {
937#define NDIS_LSO_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \ 938#define NDIS_LSO_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
938 sizeof(struct ndis_tcp_lso_info)) 939 sizeof(struct ndis_tcp_lso_info))
939 940
941#define NDIS_HASH_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
942 sizeof(u32))
943
940/* Format of Information buffer passed in a SetRequest for the OID */ 944/* Format of Information buffer passed in a SetRequest for the OID */
941/* OID_GEN_RNDIS_CONFIG_PARAMETER. */ 945/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
942struct rndis_config_parameter_info { 946struct rndis_config_parameter_info {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 2e967a7bdb33..4fd71b75e666 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -224,9 +224,11 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
224 if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1) 224 if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1)
225 return 0; 225 return 0;
226 226
227 if (netvsc_set_hash(&hash, skb)) 227 if (netvsc_set_hash(&hash, skb)) {
228 q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] % 228 q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
229 ndev->real_num_tx_queues; 229 ndev->real_num_tx_queues;
230 skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
231 }
230 232
231 return q_idx; 233 return q_idx;
232} 234}
@@ -384,6 +386,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
384 struct ndis_tcp_lso_info *lso_info; 386 struct ndis_tcp_lso_info *lso_info;
385 int hdr_offset; 387 int hdr_offset;
386 u32 net_trans_info; 388 u32 net_trans_info;
389 u32 hash;
387 390
388 391
389 /* We will atmost need two pages to describe the rndis 392 /* We will atmost need two pages to describe the rndis
@@ -402,9 +405,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
402 packet = kzalloc(sizeof(struct hv_netvsc_packet) + 405 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
403 (num_data_pgs * sizeof(struct hv_page_buffer)) + 406 (num_data_pgs * sizeof(struct hv_page_buffer)) +
404 sizeof(struct rndis_message) + 407 sizeof(struct rndis_message) +
405 NDIS_VLAN_PPI_SIZE + 408 NDIS_VLAN_PPI_SIZE + NDIS_CSUM_PPI_SIZE +
406 NDIS_CSUM_PPI_SIZE + 409 NDIS_LSO_PPI_SIZE + NDIS_HASH_PPI_SIZE, GFP_ATOMIC);
407 NDIS_LSO_PPI_SIZE, GFP_ATOMIC);
408 if (!packet) { 410 if (!packet) {
409 /* out of memory, drop packet */ 411 /* out of memory, drop packet */
410 netdev_err(net, "unable to allocate hv_netvsc_packet\n"); 412 netdev_err(net, "unable to allocate hv_netvsc_packet\n");
@@ -443,6 +445,14 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
443 445
444 rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet); 446 rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet);
445 447
448 hash = skb_get_hash_raw(skb);
449 if (hash != 0 && net->real_num_tx_queues > 1) {
450 rndis_msg_size += NDIS_HASH_PPI_SIZE;
451 ppi = init_ppi_data(rndis_msg, NDIS_HASH_PPI_SIZE,
452 NBL_HASH_VALUE);
453 *(u32 *)((void *)ppi + ppi->ppi_offset) = hash;
454 }
455
446 if (isvlan) { 456 if (isvlan) {
447 struct ndis_pkt_8021q_info *vlan; 457 struct ndis_pkt_8021q_info *vlan;
448 458