]> git.ipfire.org Git - people/dweismueller/ipfire-2.x.git/blobdiff - src/patches/linux/0021-hyperv-Add-hash-value-into-RNDIS-Per-packet-info.patch
Merge branch 'hyper-v-fixes' into next
[people/dweismueller/ipfire-2.x.git] / src / patches / linux / 0021-hyperv-Add-hash-value-into-RNDIS-Per-packet-info.patch
diff --git a/src/patches/linux/0021-hyperv-Add-hash-value-into-RNDIS-Per-packet-info.patch b/src/patches/linux/0021-hyperv-Add-hash-value-into-RNDIS-Per-packet-info.patch
new file mode 100644 (file)
index 0000000..c522d28
--- /dev/null
@@ -0,0 +1,93 @@
+From 1267d9b235e7612f8cdfa842a0433bb82e75f7fb Mon Sep 17 00:00:00 2001
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Wed, 21 May 2014 12:55:39 -0700
+Subject: [PATCH 21/25] 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>
+---
+ drivers/net/hyperv/hyperv_net.h |  4 ++++
+ drivers/net/hyperv/netvsc_drv.c | 18 ++++++++++++++----
+ 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 {
+       IEEE_8021Q_INFO,
+       ORIGINAL_PKTINFO,
+       PACKET_CANCEL_ID,
++      NBL_HASH_VALUE = PACKET_CANCEL_ID,
+       ORIGINAL_NET_BUFLIST,
+       CACHED_NET_BUFLIST,
+       SHORT_PKT_PADINFO,
+@@ -937,6 +938,9 @@ struct ndis_tcp_lso_info {
+ #define NDIS_LSO_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
+               sizeof(struct ndis_tcp_lso_info))
++#define NDIS_HASH_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
++              sizeof(u32))
++
+ /* Format of Information buffer passed in a SetRequest for the OID */
+ /* OID_GEN_RNDIS_CONFIG_PARAMETER. */
+ struct rndis_config_parameter_info {
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 346f1aeb9c24..bd3b3acd04dc 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,
+       if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1)
+               return 0;
+-      if (netvsc_set_hash(&hash, skb))
++      if (netvsc_set_hash(&hash, skb)) {
+               q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
+                       ndev->real_num_tx_queues;
++              skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
++      }
+       return q_idx;
+ }
+@@ -385,6 +387,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+       struct ndis_tcp_lso_info *lso_info;
+       int  hdr_offset;
+       u32 net_trans_info;
++      u32 hash;
+       /* We will atmost need two pages to describe the rndis
+@@ -403,9 +406,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+       packet = kzalloc(sizeof(struct hv_netvsc_packet) +
+                        (num_data_pgs * sizeof(struct hv_page_buffer)) +
+                        sizeof(struct rndis_message) +
+-                       NDIS_VLAN_PPI_SIZE +
+-                       NDIS_CSUM_PPI_SIZE +
+-                       NDIS_LSO_PPI_SIZE, GFP_ATOMIC);
++                       NDIS_VLAN_PPI_SIZE + NDIS_CSUM_PPI_SIZE +
++                       NDIS_LSO_PPI_SIZE + NDIS_HASH_PPI_SIZE, GFP_ATOMIC);
+       if (!packet) {
+               /* out of memory, drop packet */
+               netdev_err(net, "unable to allocate hv_netvsc_packet\n");
+@@ -444,6 +446,14 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+       rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet);
++      hash = skb_get_hash_raw(skb);
++      if (hash != 0 && net->real_num_tx_queues > 1) {
++              rndis_msg_size += NDIS_HASH_PPI_SIZE;
++              ppi = init_ppi_data(rndis_msg, NDIS_HASH_PPI_SIZE,
++                                  NBL_HASH_VALUE);
++              *(u32 *)((void *)ppi + ppi->ppi_offset) = hash;
++      }
++
+       if (isvlan) {
+               struct ndis_pkt_8021q_info *vlan;
+-- 
+2.4.3
+