[PATCH net-next] netvsc: Use the new in-place consumption APIs in the rx path

2016-06-09 Thread K. Y. Srinivasan
Use the new APIs for eliminating a copy on the receive path. These new APIs also
help in minimizing the number of memory barriers we end up issuing (in the
ringbuffer code) since we can better control when we want to expose the ring
state to the host.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
Tested-by: Dexuan Cui 
Tested-by: Simon Xiao 
---
 drivers/net/hyperv/netvsc.c |   88 +--
 1 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 719cb35..8cd4c19 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1141,6 +1141,39 @@ static inline void netvsc_receive_inband(struct 
hv_device *hdev,
}
 }
 
+static void netvsc_process_raw_pkt(struct hv_device *device,
+  struct vmbus_channel *channel,
+  struct netvsc_device *net_device,
+  struct net_device *ndev,
+  u64 request_id,
+  struct vmpacket_descriptor *desc)
+{
+   struct nvsp_message *nvmsg;
+
+   nvmsg = (struct nvsp_message *)((unsigned long)
+   desc + (desc->offset8 << 3));
+
+   switch (desc->type) {
+   case VM_PKT_COMP:
+   netvsc_send_completion(net_device, channel, device, desc);
+   break;
+
+   case VM_PKT_DATA_USING_XFER_PAGES:
+   netvsc_receive(net_device, channel, device, desc);
+   break;
+
+   case VM_PKT_DATA_INBAND:
+   netvsc_receive_inband(device, net_device, nvmsg);
+   break;
+
+   default:
+   netdev_err(ndev, "unhandled packet type %d, tid %llx\n",
+  desc->type, request_id);
+   break;
+   }
+}
+
+
 void netvsc_channel_cb(void *context)
 {
int ret;
@@ -1153,7 +1186,7 @@ void netvsc_channel_cb(void *context)
unsigned char *buffer;
int bufferlen = NETVSC_PACKET_SIZE;
struct net_device *ndev;
-   struct nvsp_message *nvmsg;
+   bool need_to_commit = false;
 
if (channel->primary_channel != NULL)
device = channel->primary_channel->device_obj;
@@ -1167,39 +1200,36 @@ void netvsc_channel_cb(void *context)
buffer = get_per_channel_state(channel);
 
do {
+   desc = get_next_pkt_raw(channel);
+   if (desc != NULL) {
+   netvsc_process_raw_pkt(device,
+  channel,
+  net_device,
+  ndev,
+  desc->trans_id,
+  desc);
+
+   put_pkt_raw(channel, desc);
+   need_to_commit = true;
+   continue;
+   }
+   if (need_to_commit) {
+   need_to_commit = false;
+   commit_rd_index(channel);
+   }
+
ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
   &bytes_recvd, &request_id);
if (ret == 0) {
if (bytes_recvd > 0) {
desc = (struct vmpacket_descriptor *)buffer;
-   nvmsg = (struct nvsp_message *)((unsigned long)
-desc + (desc->offset8 << 3));
-   switch (desc->type) {
-   case VM_PKT_COMP:
-   netvsc_send_completion(net_device,
-   channel,
-   device, desc);
-   break;
-
-   case VM_PKT_DATA_USING_XFER_PAGES:
-   netvsc_receive(net_device, channel,
-  device, desc);
-   break;
-
-   case VM_PKT_DATA_INBAND:
-   netvsc_receive_inband(device,
- net_device,
- nvmsg);
-   break;
-
-   default:
-   netdev_err(ndev,
-  "unhandled packet type %d, "
-  "tid %llx len %d\n",
-  desc-&

[PATCH net-next V5 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)

2016-04-19 Thread K. Y. Srinivasan
On Hyper-V, the VF/PF communication is a via software mediated path
as opposed to the hardware mailbox. Make the necessary
adjustments to support Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V2: Addressed most of the comments from
Alexander Duyck 
and Rustad, Mark D .

V3: Addressed additional comments from
Alexander Duyck 

V4: Addressed kbuild errors reported by:
kbuild test robot 

V5: Addressed additional comments from
Alexander Duyck 

 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 5 files changed, 266 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5ac60ee..3296d27 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -460,9 +460,13 @@ enum ixbgevf_state_t {
 
 enum ixgbevf_boards {
board_82599_vf,
+   board_82599_vf_hv,
board_X540_vf,
+   board_X540_vf_hv,
board_X550_vf,
+   board_X550_vf_hv,
board_X550EM_x_vf,
+   board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -477,6 +481,13 @@ extern const struct ixgbevf_info ixgbevf_X550_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
@@ -494,6 +505,7 @@ void ixgbevf_free_rx_resources(struct ixgbevf_ring *);
 void ixgbevf_free_tx_resources(struct ixgbevf_ring *);
 void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
 int ethtool_ioctl(struct ifreq *ifr);
+bool ixgbevf_on_hyperv(struct ixgbe_hw *hw);
 
 extern void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector);
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 007cbe0..c4bb480 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -62,10 +62,14 @@ static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-   [board_82599_vf] = &ixgbevf_82599_vf_info,
-   [board_X540_vf]  = &ixgbevf_X540_vf_info,
-   [board_X550_vf]  = &ixgbevf_X550_vf_info,
-   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_82599_vf]= &ixgbevf_82599_vf_info,
+   [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
+   [board_X540_vf] = &ixgbevf_X540_vf_info,
+   [board_X540_vf_hv]  = &ixgbevf_X540_vf_hv_info,
+   [board_X550_vf] = &ixgbevf_X550_vf_info,
+   [board_X550_vf_hv]  = &ixgbevf_X550_vf_hv_info,
+   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_X550EM_x_vf_hv]  = &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +82,13 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
/* required last entry */
{0, }
 };
@@ -1795,7 +1803,10 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter 
*adapter)
ixgbevf_setup_vfmrqc(adapter);
 
/* notify the PF of our intent to use this size of frame */
-   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   if (!ixgbevf_on_hyperv(hw))
+   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   else
+   ixgbevf_hv_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + 
ETH_FCS_LEN);
 
/* Setup the HW Rx Head and Tail Descriptor Pointers and

[PATCH net-next V5 1/2] ethernet: intel: Add the device ID's presented while running on Hyper-V

2016-04-19 Thread K. Y. Srinivasan
Intel SR-IOV cards present different ID when running on Hyper-V.
Add the device IDs presented while running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V5: No change from V1

 drivers/net/ethernet/intel/ixgbevf/defines.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h 
b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 5843458..1306a0d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF   0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF   0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV   0x152E
+#define IXGBE_DEV_ID_X540_VF_HV0x1530
+#define IXGBE_DEV_ID_X550_VF_HV0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK7
 #define IXGBE_VF_MAX_TX_QUEUES 8
 #define IXGBE_VF_MAX_RX_QUEUES 8
-- 
1.7.4.1



[PATCH net-next V5 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-19 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 6 files changed, 271 insertions(+), 7 deletions(-)

-- 
1.7.4.1



[PATCH net-next V4 1/2] ethernet: intel: Add the device ID's presented while running on Hyper-V

2016-04-19 Thread K. Y. Srinivasan
Intel SR-IOV cards present different ID when running on Hyper-V.
Add the device IDs presented while running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V4: No change from V1

 drivers/net/ethernet/intel/ixgbevf/defines.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h 
b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 5843458..1306a0d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF   0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF   0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV   0x152E
+#define IXGBE_DEV_ID_X540_VF_HV0x1530
+#define IXGBE_DEV_ID_X550_VF_HV0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK7
 #define IXGBE_VF_MAX_TX_QUEUES 8
 #define IXGBE_VF_MAX_RX_QUEUES 8
-- 
1.7.4.1



[PATCH net-next V4 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)

2016-04-19 Thread K. Y. Srinivasan
On Hyper-V, the VF/PF communication is a via software mediated path
as opposed to the hardware mailbox. Make the necessary
adjustments to support Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V2: Addressed most of the comments from
Alexander Duyck 
and Rustad, Mark D .

V3: Addressed additional comments from
Alexander Duyck 

V4: Addressed kbuild errors reported by:
kbuild test robot 


 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 5 files changed, 266 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5ac60ee..3296d27 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -460,9 +460,13 @@ enum ixbgevf_state_t {
 
 enum ixgbevf_boards {
board_82599_vf,
+   board_82599_vf_hv,
board_X540_vf,
+   board_X540_vf_hv,
board_X550_vf,
+   board_X550_vf_hv,
board_X550EM_x_vf,
+   board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -477,6 +481,13 @@ extern const struct ixgbevf_info ixgbevf_X550_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
@@ -494,6 +505,7 @@ void ixgbevf_free_rx_resources(struct ixgbevf_ring *);
 void ixgbevf_free_tx_resources(struct ixgbevf_ring *);
 void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
 int ethtool_ioctl(struct ifreq *ifr);
+bool ixgbevf_on_hyperv(struct ixgbe_hw *hw);
 
 extern void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector);
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 007cbe0..c4bb480 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -62,10 +62,14 @@ static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-   [board_82599_vf] = &ixgbevf_82599_vf_info,
-   [board_X540_vf]  = &ixgbevf_X540_vf_info,
-   [board_X550_vf]  = &ixgbevf_X550_vf_info,
-   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_82599_vf]= &ixgbevf_82599_vf_info,
+   [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
+   [board_X540_vf] = &ixgbevf_X540_vf_info,
+   [board_X540_vf_hv]  = &ixgbevf_X540_vf_hv_info,
+   [board_X550_vf] = &ixgbevf_X550_vf_info,
+   [board_X550_vf_hv]  = &ixgbevf_X550_vf_hv_info,
+   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_X550EM_x_vf_hv]  = &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +82,13 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
/* required last entry */
{0, }
 };
@@ -1795,7 +1803,10 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter 
*adapter)
ixgbevf_setup_vfmrqc(adapter);
 
/* notify the PF of our intent to use this size of frame */
-   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   if (!ixgbevf_on_hyperv(hw))
+   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   else
+   ixgbevf_hv_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + 
ETH_FCS_LEN);
 
/* Setup the HW Rx Head and Tail Descriptor Pointers and
 * the Base and Length of the Rx Descriptor Ring
@@ -2056,7 +

[PATCH net-next V4 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-19 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 6 files changed, 271 insertions(+), 7 deletions(-)

-- 
1.7.4.1



[PATCH net-next V3 1/2] ethernet: intel: Add the device ID's presented while running on Hyper-V

2016-04-19 Thread K. Y. Srinivasan
Intel SR-IOV cards present different ID when running on Hyper-V.
Add the device IDs presented while running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V2: No change from V1.
V3: No change from V2.

 drivers/net/ethernet/intel/ixgbevf/defines.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h 
b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 5843458..1306a0d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF   0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF   0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV   0x152E
+#define IXGBE_DEV_ID_X540_VF_HV0x1530
+#define IXGBE_DEV_ID_X550_VF_HV0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK7
 #define IXGBE_VF_MAX_TX_QUEUES 8
 #define IXGBE_VF_MAX_RX_QUEUES 8
-- 
1.7.4.1



[PATCH net-next V3 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)

2016-04-19 Thread K. Y. Srinivasan
On Hyper-V, the VF/PF communication is a via software mediated path
as opposed to the hardware mailbox. Make the necessary
adjustments to support Hyper-V.

Signed-off-by: K. Y. Srinivasan 
V2: Addressed most of the comments from
Alexander Duyck 
and Rustad, Mark D .

V3: Addressed additional comments from
Alexander Duyck 

---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 5 files changed, 266 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5ac60ee..3296d27 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -460,9 +460,13 @@ enum ixbgevf_state_t {
 
 enum ixgbevf_boards {
board_82599_vf,
+   board_82599_vf_hv,
board_X540_vf,
+   board_X540_vf_hv,
board_X550_vf,
+   board_X550_vf_hv,
board_X550EM_x_vf,
+   board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -477,6 +481,13 @@ extern const struct ixgbevf_info ixgbevf_X550_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
@@ -494,6 +505,7 @@ void ixgbevf_free_rx_resources(struct ixgbevf_ring *);
 void ixgbevf_free_tx_resources(struct ixgbevf_ring *);
 void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
 int ethtool_ioctl(struct ifreq *ifr);
+bool ixgbevf_on_hyperv(struct ixgbe_hw *hw);
 
 extern void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector);
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 007cbe0..c4bb480 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -62,10 +62,14 @@ static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-   [board_82599_vf] = &ixgbevf_82599_vf_info,
-   [board_X540_vf]  = &ixgbevf_X540_vf_info,
-   [board_X550_vf]  = &ixgbevf_X550_vf_info,
-   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_82599_vf]= &ixgbevf_82599_vf_info,
+   [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
+   [board_X540_vf] = &ixgbevf_X540_vf_info,
+   [board_X540_vf_hv]  = &ixgbevf_X540_vf_hv_info,
+   [board_X550_vf] = &ixgbevf_X550_vf_info,
+   [board_X550_vf_hv]  = &ixgbevf_X550_vf_hv_info,
+   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_X550EM_x_vf_hv]  = &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +82,13 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
/* required last entry */
{0, }
 };
@@ -1795,7 +1803,10 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter 
*adapter)
ixgbevf_setup_vfmrqc(adapter);
 
/* notify the PF of our intent to use this size of frame */
-   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   if (!ixgbevf_on_hyperv(hw))
+   ixgbevf_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
+   else
+   ixgbevf_hv_rlpml_set_vf(hw, netdev->mtu + ETH_HLEN + 
ETH_FCS_LEN);
 
/* Setup the HW Rx Head and Tail Descriptor Pointers and
 * the Base and Length of the Rx Descriptor Ring
@@ -2056,7 +2067,10 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter 
*adapter)

[PATCH net-next V3 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-19 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   31 +++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  216 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 6 files changed, 271 insertions(+), 7 deletions(-)

-- 
1.7.4.1



[PATCH net-next V2 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-17 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   16 ++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  201 +
 5 files changed, 242 insertions(+), 4 deletions(-)

-- 
1.7.4.1



[PATCH net-next V2 1/2] ethernet: intel: Add the device ID's presented while running on Hyper-V

2016-04-17 Thread K. Y. Srinivasan
Intel SR-IOV cards present different ID when running on Hyper-V.
Add the device IDs presented while running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V2: No change from V1.

 drivers/net/ethernet/intel/ixgbevf/defines.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h 
b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 5843458..1306a0d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF   0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF   0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV   0x152E
+#define IXGBE_DEV_ID_X540_VF_HV0x1530
+#define IXGBE_DEV_ID_X550_VF_HV0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK7
 #define IXGBE_VF_MAX_TX_QUEUES 8
 #define IXGBE_VF_MAX_RX_QUEUES 8
-- 
1.7.4.1



[PATCH net-next V2 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)

2016-04-17 Thread K. Y. Srinivasan
On Hyper-V, the VF/PF communication is a via software mediated path
as opposed to the hardware mailbox. Make the necessary
adjustments to support Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
V2: Addressed most of the comments from
Alexander Duyck 
and Rustad, Mark D .

 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   16 ++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  201 +
 4 files changed, 237 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5ac60ee..3296d27 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -460,9 +460,13 @@ enum ixbgevf_state_t {
 
 enum ixgbevf_boards {
board_82599_vf,
+   board_82599_vf_hv,
board_X540_vf,
+   board_X540_vf_hv,
board_X550_vf,
+   board_X550_vf_hv,
board_X550EM_x_vf,
+   board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -477,6 +481,13 @@ extern const struct ixgbevf_info ixgbevf_X550_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
@@ -494,6 +505,7 @@ void ixgbevf_free_rx_resources(struct ixgbevf_ring *);
 void ixgbevf_free_tx_resources(struct ixgbevf_ring *);
 void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
 int ethtool_ioctl(struct ifreq *ifr);
+bool ixgbevf_on_hyperv(struct ixgbe_hw *hw);
 
 extern void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector);
 
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 007cbe0..c761d80 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -62,10 +62,14 @@ static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-   [board_82599_vf] = &ixgbevf_82599_vf_info,
-   [board_X540_vf]  = &ixgbevf_X540_vf_info,
-   [board_X550_vf]  = &ixgbevf_X550_vf_info,
-   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_82599_vf]= &ixgbevf_82599_vf_info,
+   [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
+   [board_X540_vf] = &ixgbevf_X540_vf_info,
+   [board_X540_vf_hv]  = &ixgbevf_X540_vf_hv_info,
+   [board_X550_vf] = &ixgbevf_X550_vf_info,
+   [board_X550_vf_hv]  = &ixgbevf_X550_vf_hv_info,
+   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_X550EM_x_vf_hv]  = &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +82,13 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
/* required last entry */
{0, }
 };
diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c 
b/drivers/net/ethernet/intel/ixgbevf/mbx.c
index dc68fea..298a0da 100644
--- a/drivers/net/ethernet/intel/ixgbevf/mbx.c
+++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c
@@ -346,3 +346,15 @@ const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
.check_for_rst  = ixgbevf_check_for_rst_vf,
 };
 
+/**
+ * Mailbox operations when running on Hyper-V.
+ * On Hyper-V, PF/VF communiction is not through the
+ * hardware mailbox; this communication is through
+ * a software mediated path.
+ * Most mail box operations are noop while running on
+ * Hyper-V.
+ */
+const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {
+   .init_params= ixgbevf_init_mbx_params_vf,
+   .check_for_rst  = ixgbevf_check_for_rst_vf,
+};
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c 
b/drivers/net/ethernet/inte

[PATCH net-next V2 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-17 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   16 ++-
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  201 +
 5 files changed, 242 insertions(+), 4 deletions(-)

-- 
1.7.4.1



[PATCH net-next 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)

2016-04-14 Thread K. Y. Srinivasan
On Hyper-V, the VF/PF communication is a via software mediated path
as opposed to the hardware mailbox. Make the necessary
adjustments to support Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   11 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   56 ++---
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  138 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 5 files changed, 201 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 5ac60ee..f8d2a0b 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -460,9 +460,13 @@ enum ixbgevf_state_t {
 
 enum ixgbevf_boards {
board_82599_vf,
+   board_82599_vf_hv,
board_X540_vf,
+   board_X540_vf_hv,
board_X550_vf,
+   board_X550_vf_hv,
board_X550EM_x_vf,
+   board_X550EM_x_vf_hv,
 };
 
 enum ixgbevf_xcast_modes {
@@ -477,6 +481,13 @@ extern const struct ixgbevf_info ixgbevf_X550_vf_info;
 extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
 extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
 
+
+extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
+extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
+extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
+
 /* needed by ethtool.c */
 extern const char ixgbevf_driver_name[];
 extern const char ixgbevf_driver_version[];
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c 
b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 007cbe0..4a0ffac 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -49,6 +49,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ixgbevf.h"
 
@@ -62,10 +63,14 @@ static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
 
 static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
-   [board_82599_vf] = &ixgbevf_82599_vf_info,
-   [board_X540_vf]  = &ixgbevf_X540_vf_info,
-   [board_X550_vf]  = &ixgbevf_X550_vf_info,
-   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_82599_vf]= &ixgbevf_82599_vf_info,
+   [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
+   [board_X540_vf] = &ixgbevf_X540_vf_info,
+   [board_X540_vf_hv]  = &ixgbevf_X540_vf_hv_info,
+   [board_X550_vf] = &ixgbevf_X550_vf_info,
+   [board_X550_vf_hv]  = &ixgbevf_X550_vf_hv_info,
+   [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
+   [board_X550EM_x_vf_hv]  = &ixgbevf_X550EM_x_vf_hv_info,
 };
 
 /* ixgbevf_pci_tbl - PCI Device ID Table
@@ -78,9 +83,13 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
  */
 static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV), board_82599_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV), board_X540_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
+   {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
/* required last entry */
{0, }
 };
@@ -1809,12 +1818,13 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device 
*netdev,
 {
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
-   int err;
+   int err = 0;
 
spin_lock_bh(&adapter->mbx_lock);
 
/* add VID to filter table */
-   err = hw->mac.ops.set_vfta(hw, vid, 0, true);
+   if (hw->mac.ops.set_vfta)
+   err = hw->mac.ops.set_vfta(hw, vid, 0, true);
 
spin_unlock_bh(&adapter->mbx_lock);
 
@@ -1835,12 +1845,13 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device 
*netdev,
 {
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
-   int err;
+   int err = 0;
 
spin_lock_bh(&adapter->mbx_lock);
 
/* remove VID from filter table */
-   err = hw->mac.ops.set_vfta(hw, vid, 0, false);
+   if (hw->mac.ops.set_vfta)
+   err = hw->mac.ops.set_vfta(hw, vid, 0, false);
 
spin_unlock_bh(&adapter->mbx_lock);
 
@@ -1873,14 +1884,16 @@ static int ixgbevf_write_uc_addr_

[PATCH net-next 1/2] ethernet: intel: Add the device ID's presented while running on Hyper-V

2016-04-14 Thread K. Y. Srinivasan
Intel SR-IOV cards present different ID when running on Hyper-V.
Add the device IDs presented while running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/ethernet/intel/ixgbevf/defines.h |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/defines.h 
b/drivers/net/ethernet/intel/ixgbevf/defines.h
index 5843458..1306a0d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/defines.h
+++ b/drivers/net/ethernet/intel/ixgbevf/defines.h
@@ -33,6 +33,11 @@
 #define IXGBE_DEV_ID_X550_VF   0x1565
 #define IXGBE_DEV_ID_X550EM_X_VF   0x15A8
 
+#define IXGBE_DEV_ID_82599_VF_HV   0x152E
+#define IXGBE_DEV_ID_X540_VF_HV0x1530
+#define IXGBE_DEV_ID_X550_VF_HV0x1564
+#define IXGBE_DEV_ID_X550EM_X_VF_HV0x15A9
+
 #define IXGBE_VF_IRQ_CLEAR_MASK7
 #define IXGBE_VF_MAX_TX_QUEUES 8
 #define IXGBE_VF_MAX_RX_QUEUES 8
-- 
1.7.4.1



[PATCH net-next 0/2] ethernet: intel: Support Hyper-V hosts

2016-04-14 Thread K. Y. Srinivasan
Make adjustments to the Intel 10G VF driver to support
running on Hyper-V hosts.

K. Y. Srinivasan (2):
  ethernet: intel: Add the device ID's presented while running on
Hyper-V
  intel: ixgbevf: Support Windows hosts (Hyper-V)

 drivers/net/ethernet/intel/ixgbevf/defines.h  |5 +
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h  |   11 ++
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |   56 ++---
 drivers/net/ethernet/intel/ixgbevf/mbx.c  |   12 ++
 drivers/net/ethernet/intel/ixgbevf/vf.c   |  138 +
 drivers/net/ethernet/intel/ixgbevf/vf.h   |2 +
 6 files changed, 206 insertions(+), 18 deletions(-)

-- 
1.7.4.1



[PATCH net-next 1/1] hv_netvsc: Implement support for VF drivers on Hyper-V

2016-04-14 Thread K. Y. Srinivasan
Support VF drivers on Hyper-V. On Hyper-V, each VF instance presented to
the guest has an associated synthetic interface that shares the MAC address
with the VF instance. Typically these are bonded together to support
live migration. By default, the host delivers all the incoming packets
on the synthetic interface. Once the VF is up, we need to explicitly switch
the data path on the host to divert traffic onto the VF interface. Even after
switching the data path, broadcast and multicast packets are always delivered
on the synthetic interface and these will have to be injected back onto the
VF interface (if VF is up).
This patch implements the necessary support in netvsc to support Linux
VF drivers.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |   14 ++
 drivers/net/hyperv/netvsc.c   |   29 
 drivers/net/hyperv/netvsc_drv.c   |  312 +---
 drivers/net/hyperv/rndis_filter.c |6 +
 4 files changed, 335 insertions(+), 26 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 8b3bd8e..6700a4d 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -202,6 +202,8 @@ int rndis_filter_receive(struct hv_device *dev,
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
 
+void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf);
+
 #define NVSP_INVALID_PROTOCOL_VERSION  ((u32)0x)
 
 #define NVSP_PROTOCOL_VERSION_12
@@ -641,6 +643,12 @@ struct netvsc_reconfig {
u32 event;
 };
 
+struct garp_wrk {
+   struct work_struct dwrk;
+   struct net_device *netdev;
+   struct netvsc_device *netvsc_dev;
+};
+
 /* The context of the netvsc device  */
 struct net_device_context {
/* point back to our device context */
@@ -656,6 +664,7 @@ struct net_device_context {
 
struct work_struct work;
u32 msg_enable; /* debug level */
+   struct garp_wrk gwrk;
 
struct netvsc_stats __percpu *tx_stats;
struct netvsc_stats __percpu *rx_stats;
@@ -730,6 +739,11 @@ struct netvsc_device {
u32 vf_alloc;
/* Serial number of the VF to team with */
u32 vf_serial;
+   atomic_t open_cnt;
+   /* State to manage the associated VF interface. */
+   bool vf_inject;
+   struct net_device *vf_netdev;
+   atomic_t vf_use_cnt;
 };
 
 /* NdisInitialize message */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index ec313fc..eddce3c 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -33,6 +33,30 @@
 
 #include "hyperv_net.h"
 
+/*
+ * Switch the data path from the synthetic interface to the VF
+ * interface.
+ */
+void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf)
+{
+   struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
+   struct hv_device *dev = nv_dev->dev;
+
+   memset(init_pkt, 0, sizeof(struct nvsp_message));
+   init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH;
+   if (vf)
+   init_pkt->msg.v4_msg.active_dp.active_datapath =
+   NVSP_DATAPATH_VF;
+   else
+   init_pkt->msg.v4_msg.active_dp.active_datapath =
+   NVSP_DATAPATH_SYNTHETIC;
+
+   vmbus_sendpacket(dev->channel, init_pkt,
+  sizeof(struct nvsp_message),
+  (unsigned long)init_pkt,
+  VM_PKT_DATA_INBAND, 0);
+}
+
 
 static struct netvsc_device *alloc_net_device(struct hv_device *device)
 {
@@ -52,11 +76,16 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
init_waitqueue_head(&net_device->wait_drain);
net_device->start_remove = false;
net_device->destroy = false;
+   atomic_set(&net_device->open_cnt, 0);
+   atomic_set(&net_device->vf_use_cnt, 0);
net_device->dev = device;
net_device->ndev = ndev;
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
+   net_device->vf_netdev = NULL;
+   net_device->vf_inject = false;
+
hv_set_drvdata(device, net_device);
return net_device;
 }
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index b8121eb..bfdb568a 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -610,42 +610,24 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
schedule_delayed_work(&ndev_ctx->dwork, 0);
 }
 
-/*
- * netvsc_recv_callback -  Callback when we receive a packet from the
- * "wire" on the specified device.
- */
-int netvsc_recv_callback(struct hv_device *device_obj,
+
+static struct

[PATCH 1/1] hv_netvsc: Implement support for VF drivers on Hyper-V

2016-04-13 Thread K. Y. Srinivasan
Support VF drivers on Hyper-V. On Hyper-V, each VF instance presented to
the guest has an associated synthetic interface that shares the MAC address
with the VF instance. Typically these are bonded together to support
live migration. By default, the host delivers all the incoming packets
on the synthetic interface. Once the VF is up, we need to explicitly switch
the data path on the host to divert traffic onto the VF interface. Even after
switching the data path, broadcast and multicast packets are always delivered
on the synthetic interface and these will have to be injected back onto the
VF interface (if VF is up).
This patch implements the necessary support in netvsc to support Linux
VF drivers.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |   14 ++
 drivers/net/hyperv/netvsc.c |   29 
 drivers/net/hyperv/netvsc_drv.c |  309 +++
 3 files changed, 326 insertions(+), 26 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 8b3bd8e..6700a4d 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -202,6 +202,8 @@ int rndis_filter_receive(struct hv_device *dev,
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
 
+void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf);
+
 #define NVSP_INVALID_PROTOCOL_VERSION  ((u32)0x)
 
 #define NVSP_PROTOCOL_VERSION_12
@@ -641,6 +643,12 @@ struct netvsc_reconfig {
u32 event;
 };
 
+struct garp_wrk {
+   struct work_struct dwrk;
+   struct net_device *netdev;
+   struct netvsc_device *netvsc_dev;
+};
+
 /* The context of the netvsc device  */
 struct net_device_context {
/* point back to our device context */
@@ -656,6 +664,7 @@ struct net_device_context {
 
struct work_struct work;
u32 msg_enable; /* debug level */
+   struct garp_wrk gwrk;
 
struct netvsc_stats __percpu *tx_stats;
struct netvsc_stats __percpu *rx_stats;
@@ -730,6 +739,11 @@ struct netvsc_device {
u32 vf_alloc;
/* Serial number of the VF to team with */
u32 vf_serial;
+   atomic_t open_cnt;
+   /* State to manage the associated VF interface. */
+   bool vf_inject;
+   struct net_device *vf_netdev;
+   atomic_t vf_use_cnt;
 };
 
 /* NdisInitialize message */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index ec313fc..eddce3c 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -33,6 +33,30 @@
 
 #include "hyperv_net.h"
 
+/*
+ * Switch the data path from the synthetic interface to the VF
+ * interface.
+ */
+void netvsc_switch_datapath(struct netvsc_device *nv_dev, bool vf)
+{
+   struct nvsp_message *init_pkt = &nv_dev->channel_init_pkt;
+   struct hv_device *dev = nv_dev->dev;
+
+   memset(init_pkt, 0, sizeof(struct nvsp_message));
+   init_pkt->hdr.msg_type = NVSP_MSG4_TYPE_SWITCH_DATA_PATH;
+   if (vf)
+   init_pkt->msg.v4_msg.active_dp.active_datapath =
+   NVSP_DATAPATH_VF;
+   else
+   init_pkt->msg.v4_msg.active_dp.active_datapath =
+   NVSP_DATAPATH_SYNTHETIC;
+
+   vmbus_sendpacket(dev->channel, init_pkt,
+  sizeof(struct nvsp_message),
+  (unsigned long)init_pkt,
+  VM_PKT_DATA_INBAND, 0);
+}
+
 
 static struct netvsc_device *alloc_net_device(struct hv_device *device)
 {
@@ -52,11 +76,16 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
init_waitqueue_head(&net_device->wait_drain);
net_device->start_remove = false;
net_device->destroy = false;
+   atomic_set(&net_device->open_cnt, 0);
+   atomic_set(&net_device->vf_use_cnt, 0);
net_device->dev = device;
net_device->ndev = ndev;
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
+   net_device->vf_netdev = NULL;
+   net_device->vf_inject = false;
+
hv_set_drvdata(device, net_device);
return net_device;
 }
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index b8121eb..5669589 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -610,42 +610,24 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
schedule_delayed_work(&ndev_ctx->dwork, 0);
 }
 
-/*
- * netvsc_recv_callback -  Callback when we receive a packet from the
- * "wire" on the specified device.
- */
-int netvsc_recv_callback(struct hv_device *device_obj,
+
+static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
  

[PATCH net-next V3 15/17] hv_netvsc: Eliminate xmit_more from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate xmit_more from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |   13 -
 drivers/net/hyperv/netvsc_drv.c   |1 -
 drivers/net/hyperv/rndis_filter.c |2 --
 4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ddf51a0..96d34e2 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -131,7 +131,6 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-   u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
u8 rmsg_size; /* RNDIS header and PPI size */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 11b009e..cd5b65e 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -712,6 +712,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 + pend_size;
int i;
bool is_data_pkt = (skb != NULL) ? true : false;
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
u32 msg_size = 0;
u32 padding = 0;
u32 remain = packet->total_data_buflen % net_device->pkt_align;
@@ -719,7 +720,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
packet->page_buf_cnt;
 
/* Add padding */
-   if (is_data_pkt && packet->xmit_more && remain &&
+   if (is_data_pkt && xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
rndis_msg->msg_len += padding;
@@ -758,6 +759,7 @@ static inline int netvsc_send_pkt(
int ret;
struct hv_page_buffer *pgbuf;
u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
if (skb != NULL) {
@@ -789,7 +791,7 @@ static inline int netvsc_send_pkt(
 * unnecessarily.
 */
if (ring_avail < (RING_AVAIL_PERCENT_LOWATER + 1))
-   packet->xmit_more = false;
+   xmit_more = false;
 
if (packet->page_buf_cnt) {
pgbuf = packet->cp_partial ? (*pb) +
@@ -801,14 +803,14 @@ static inline int netvsc_send_pkt(
  sizeof(struct 
nvsp_message),
  req_id,
  
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
- !packet->xmit_more);
+ !xmit_more);
} else {
ret = vmbus_sendpacket_ctl(out_channel, &nvmsg,
   sizeof(struct nvsp_message),
   req_id,
   VM_PKT_DATA_INBAND,
   
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
-  !packet->xmit_more);
+  !xmit_more);
}
 
if (ret == 0) {
@@ -854,6 +856,7 @@ int netvsc_send(struct hv_device *device,
struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
bool try_batch;
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
net_device = get_outbound_net_device(device);
if (!net_device)
@@ -911,7 +914,7 @@ int netvsc_send(struct hv_device *device,
if (msdp->pkt)
dev_kfree_skb_any(skb);
 
-   if (packet->xmit_more && !packet->cp_partial) {
+   if (xmit_more && !packet->cp_partial) {
msdp->pkt = packet;
msdp->count++;
} else {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index bc4be1d..7520c52 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -471,7 +471,6 @@ check_size:
packet = (struct hv_netvsc_packet *)skb->cb;
 
packet->status = 0;
-   packet->xmit_more = skb->xmit_more;
 
packet->vlan_tci = skb->vlan_tci;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 6ba5adf..3c06aa7 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -236,8 +236,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
pb[0].len;
}
 
-   packet->xmit_more = f

[PATCH net-next V3 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient

2015-12-01 Thread K. Y. Srinivasan
Rearrange the elements of struct hv_negtvsc_packet for optimal layout -
eliminate unnecessary padding.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   18 ++
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 972e562..7435673 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -128,32 +128,34 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-
u8 is_data_pkt;
u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
-   u16 vlan_tci;
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 page_buf_cnt;
+   u8 pad0;
 
+   u16 vlan_tci;
u16 q_idx;
+   u32 send_buf_index;
+
+   u32 total_data_buflen;
+   u32 pad1;
+
struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-   u32 send_buf_index;
 
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u8 rmsg_size; /* RNDIS header and PPI size */
-   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
-
-   u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 06/17] hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate send_completion from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |3 +--
 drivers/net/hyperv/netvsc.c   |6 +++---
 drivers/net/hyperv/netvsc_drv.c   |2 +-
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 506d552..9a3c972 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -135,7 +135,7 @@ struct hv_netvsc_packet {
u8 rmsg_size; /* RNDIS header and PPI size */
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
-   u8 pad0;
+   u8 completion_func;
 
u16 vlan_tci;
u16 q_idx;
@@ -147,7 +147,6 @@ struct hv_netvsc_packet {
 
u64 send_completion_tid;
void *send_completion_ctx;
-   void (*send_completion)(void *context);
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 8fbf816..34c16d1 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,8 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   nvsc_packet->send_completion(nvsc_packet->
-send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet->
+  send_completion_ctx);
}
 
num_outstanding_sends =
@@ -775,7 +775,7 @@ static inline int netvsc_send_pkt(
nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
packet->total_data_buflen;
 
-   if (packet->send_completion)
+   if (packet->completion_func)
req_id = (ulong)packet;
else
req_id = 0;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c73afb1..6d71a1e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -488,7 +488,7 @@ check_size:
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
-   packet->send_completion = netvsc_xmit_completion;
+   packet->completion_func = 1;
packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index be0fa9c..c8af172 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -237,7 +237,7 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
packet->page_buf[0].len;
}
 
-   packet->send_completion = NULL;
+   packet->completion_func = 0;
packet->xmit_more = false;
 
ret = netvsc_send(dev->net_dev->dev, packet, NULL);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure

2015-12-01 Thread K. Y. Srinivasan
Eliminate the channel field in hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |   22 ++
 drivers/net/hyperv/netvsc.c   |   19 ---
 drivers/net/hyperv/netvsc_drv.c   |5 +++--
 drivers/net/hyperv/rndis_filter.c |   10 ++
 4 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7435673..ac24091 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -144,7 +144,6 @@ struct hv_netvsc_packet {
u32 total_data_buflen;
u32 pad1;
 
-   struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
@@ -199,7 +198,8 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
-   struct ndis_tcp_ip_checksum_info *csum_info);
+   struct ndis_tcp_ip_checksum_info *csum_info,
+   struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
@@ -207,12 +207,12 @@ int rndis_filter_device_add(struct hv_device *dev,
void *additional_info);
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
-   struct hv_netvsc_packet *pkt);
+   struct hv_netvsc_packet *pkt,
+   struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
 
-
 #define NVSP_INVALID_PROTOCOL_VERSION  ((u32)0x)
 
 #define NVSP_PROTOCOL_VERSION_12
@@ -1262,5 +1262,19 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
+static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
+   struct netvsc_device *net_device)
+
+{
+   struct vmbus_channel *out_channel;
+
+   out_channel = net_device->chn_table[packet->q_idx];
+   if (!out_channel) {
+   out_channel = net_device->dev->channel;
+   packet->q_idx = 0;
+   }
+   return out_channel;
+}
+
 
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 51e4c0f..52533ed 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -610,6 +610,7 @@ static inline void netvsc_free_send_slot(struct 
netvsc_device *net_device,
 }
 
 static void netvsc_send_completion(struct netvsc_device *net_device,
+  struct vmbus_channel *incoming_channel,
   struct hv_device *device,
   struct vmpacket_descriptor *packet)
 {
@@ -651,7 +652,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
-   channel = nvsc_packet->channel;
+   channel = incoming_channel;
nvsc_packet->send_completion(nvsc_packet->
 send_completion_ctx);
}
@@ -748,7 +749,7 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = packet->channel;
+   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
struct net_device *ndev = net_device->ndev;
u64 req_id;
@@ -857,13 +858,9 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = net_device->chn_table[q_idx];
-   if (!out_channel) {
-   out_channel = device->channel;
-   q_idx = 0;
-   packet->q_idx = 0;
-   }
-   packet->channel = out_channel;
+   out_channel = get_channel(packet, net_device);
+   q_idx = packet->q_idx;
+
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
 
@@ -1043,7 +1040,6 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
}
 
count = vmxferpage_packet->range_cnt;
-   netvsc_packet->channel = channel;
 
/* Each range represents 1 RNDIS pkt that co

[PATCH net-next V3 14/17] hv_netvsc: Eliminate completion_func from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate completion_func from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc_drv.c   |3 ---
 drivers/net/hyperv/rndis_filter.c |1 -
 3 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 65e340e..ddf51a0 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -137,7 +137,6 @@ struct hv_netvsc_packet {
u8 rmsg_size; /* RNDIS header and PPI size */
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
-   u8 completion_func;
 
u16 vlan_tci;
u16 q_idx;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index eb0c6fa..bc4be1d 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -483,9 +483,6 @@ check_size:
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
-   /* Set the completion routine */
-   packet->completion_func = 1;
-
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 0b98674..6ba5adf 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -236,7 +236,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
pb[0].len;
}
 
-   packet->completion_func = 0;
packet->xmit_more = false;
 
ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 04/17] hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet structure

2015-12-01 Thread K. Y. Srinivasan
Eliminate rndis_msg pointer from hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |8 +++-
 drivers/net/hyperv/netvsc.c   |   10 ++
 drivers/net/hyperv/netvsc_drv.c   |7 +++
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ac24091..7fa4f43 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -149,10 +149,6 @@ struct hv_netvsc_packet {
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-
-   /* This points to the memory after page_buf */
-   struct rndis_message *rndis_msg;
-
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
struct hv_page_buffer *page_buf;
@@ -189,10 +185,12 @@ struct rndis_device {
 
 
 /* Interface */
+struct rndis_message;
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet);
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
 void netvsc_xmit_completion(void *context);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 52533ed..2de9e7f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -706,7 +706,8 @@ static u32 netvsc_get_next_send_section(struct 
netvsc_device *net_device)
 static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
   unsigned int section_index,
   u32 pend_size,
-  struct hv_netvsc_packet *packet)
+  struct hv_netvsc_packet *packet,
+  struct rndis_message *rndis_msg)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
@@ -722,7 +723,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
if (packet->is_data_pkt && packet->xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
-   packet->rndis_msg->msg_len += padding;
+   rndis_msg->msg_len += padding;
packet->total_data_buflen += padding;
}
 
@@ -841,7 +842,8 @@ static inline int netvsc_send_pkt(
 }
 
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet)
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -897,7 +899,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet);
+   packet, rndis_msg);
 
packet->send_buf_index = section_index;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index e5f4eec..77c0849 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -482,10 +482,10 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   packet->rndis_msg = (struct rndis_message *)((unsigned long)packet +
+   rndis_msg = (struct rndis_message *)((unsigned long)packet +
sizeof(struct hv_netvsc_packet));
 
-   memset(packet->rndis_msg, 0, RNDIS_AND_PPI_SIZE);
+   memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
packet->send_completion = netvsc_xmit_completion;
@@ -495,7 +495,6 @@ check_size:
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
-   rndis_msg = packet->rndis_msg;
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
rndis_msg->msg_len = packet->total_data_buflen;
rndis_pkt = &rndis_msg->msg.pkt;
@@ -619,7 +618,7 @@ do_send:
packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
   skb, packet);
 
-   ret = netvsc_send(net_device_ctx->device_ctx, packet);
+   ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg);
 
 drop:
if (ret == 0) {
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c

[PATCH net-next V3 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminatte the data field from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |5 ++---
 drivers/net/hyperv/netvsc.c   |5 +++--
 drivers/net/hyperv/netvsc_drv.c   |3 ++-
 drivers/net/hyperv/rndis_filter.c |   11 +++
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7fa4f43..506d552 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -148,9 +148,6 @@ struct hv_netvsc_packet {
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
-
-   /* Points to the send/receive buffer where the ethernet frame is */
-   void *data;
struct hv_page_buffer *page_buf;
 };
 
@@ -196,6 +193,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
@@ -206,6 +204,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
struct hv_netvsc_packet *pkt,
+   void **data,
struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 2de9e7f..8fbf816 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1008,6 +1008,7 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
int i;
int count = 0;
struct net_device *ndev;
+   void *data;
 
ndev = net_device->ndev;
 
@@ -1047,13 +1048,13 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
netvsc_packet->status = NVSP_STAT_SUCCESS;
-   netvsc_packet->data = (void *)((unsigned long)net_device->
+   data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
vmxferpage_packet->ranges[i].byte_count;
 
/* Pass it to the upper layer */
-   rndis_filter_receive(device, netvsc_packet, channel);
+   rndis_filter_receive(device, netvsc_packet, &data, channel);
 
if (netvsc_packet->status != NVSP_STAT_SUCCESS)
status = NVSP_STAT_FAIL;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 77c0849..c73afb1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -685,6 +685,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
  */
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel)
 {
@@ -713,7 +714,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 * Copy to skb. This copy is needed here since the memory pointed by
 * hv_netvsc_packet cannot be deallocated
 */
-   memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
+   memcpy(skb_put(skb, packet->total_data_buflen), *data,
packet->total_data_buflen);
 
skb->protocol = eth_type_trans(skb, net);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 63584e7..be0fa9c 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -351,6 +351,7 @@ static inline void *rndis_get_ppi(struct rndis_packet 
*rpkt, u32 type)
 static void rndis_filter_receive_data(struct rndis_device *dev,
   struct rndis_message *msg,
   struct hv_netvsc_packet *pkt,
+  void **data,
   struct vmbus_channel *channel)
 {
struct rndis_packet *rndis_pkt;
@@ -383,7 +384,7 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
 * the data packet to the stack, without the rndis trailer padding
 */
pkt->total_data_buflen = rndis_pkt->data_len;
-   pkt->data = (void *)((unsigned long)pkt->data +

[PATCH net-next V3 00/17] hv_netvsc: Eliminate the additional head room

2015-12-01 Thread K. Y. Srinivasan
In an attempt to avoid having to allocate memory on the send path, the netvsc
driver was requesting additional head room so that both rndis header and the
netvsc packet (the state that had to persist) could be placed in the skb.
Since the amount of head room requested was exceeding the default head room
as set in LL_MAX_HEADER, we were forcing a reallocation of skb.

With this patch-set, I have reduced the size of the netvsc packet to less
than 20 bytes and with this reduction we don't need to ask for any additional
headroom. We place the rndis header in the skb head room and we place the
netvsc packet in control buffer area in the skb.

V2:  - Addressed  review comments:
 - Eliminated more fields from netvsc packet structure.

V3:  - Fixed a typo in patch: hv_netvsc: Don't ask for additional head room in 
the skb.
 
K. Y. Srinivasan (15):
  hv_netvsc: Resize some of the variables in hv_netvsc_packet
  hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient
  hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure
  hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet
structure
  hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet
  hv_netvsc: Don't ask for additional head room in the skb
  hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion_tid from struct hv_netvsc_packet
  hv_netvsc: Eliminate is_data_pkt from struct hv_netvsc_packet
  hv_netvsc: Eliminate completion_func from struct hv_netvsc_packet
  hv_netvsc: Eliminate xmit_more from struct hv_netvsc_packet
  hv_netvsc: Eliminate status from struct hv_netvsc_packet
  hv_netvsc: Eliminate vlan_tci from struct hv_netvsc_packet

Vitaly Kuznetsov (2):
  hv_netvsc: move subchannel existence check to netvsc_select_queue()
  hv_netvsc: remove locking in netvsc_send()

 drivers/net/hyperv/hyperv_net.h   |   48 +++--
 drivers/net/hyperv/netvsc.c   |  102 ++---
 drivers/net/hyperv/netvsc_drv.c   |   93 +-
 drivers/net/hyperv/rndis_filter.c |   66 
 include/linux/netdevice.h |4 +-
 5 files changed, 138 insertions(+), 175 deletions(-)

-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 10/17] hv_netvsc: remove locking in netvsc_send()

2015-12-01 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Packet scheduler guarantees there won't be multiple senders for the same
queue and as we use q_idx for multi_send_data the spinlock is redundant.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |8 
 2 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index a9d2bdc5..f5b2145 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -633,7 +633,6 @@ struct nvsp_message {
 #define RNDIS_PKT_ALIGN_DEFAULT 8
 
 struct multi_send_data {
-   spinlock_t lock; /* protect struct multi_send_data */
struct hv_netvsc_packet *pkt; /* netvsc pkt pending */
u32 count; /* counter of batched packets */
 };
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 419b055..081f14f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -38,7 +38,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
 {
struct netvsc_device *net_device;
struct net_device *ndev = hv_get_drvdata(device);
-   int i;
 
net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
if (!net_device)
@@ -58,9 +57,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
-   for (i = 0; i < num_online_cpus(); i++)
-   spin_lock_init(&net_device->msd[i].lock);
-
hv_set_drvdata(device, net_device);
return net_device;
 }
@@ -850,7 +846,6 @@ int netvsc_send(struct hv_device *device,
u16 q_idx = packet->q_idx;
u32 pktlen = packet->total_data_buflen, msd_len = 0;
unsigned int section_index = NETVSC_INVALID_INDEX;
-   unsigned long flag;
struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
bool try_batch;
@@ -867,7 +862,6 @@ int netvsc_send(struct hv_device *device,
msdp = &net_device->msd[q_idx];
 
/* batch packets in send buffer if possible */
-   spin_lock_irqsave(&msdp->lock, flag);
if (msdp->pkt)
msd_len = msdp->pkt->total_data_buflen;
 
@@ -927,8 +921,6 @@ int netvsc_send(struct hv_device *device,
cur_send = packet;
}
 
-   spin_unlock_irqrestore(&msdp->lock, flag);
-
if (msd_send) {
m_ret = netvsc_send_pkt(msd_send, net_device);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 08/17] hv_netvsc: Don't ask for additional head room in the skb

2015-12-01 Thread K. Y. Srinivasan
The rndis header is 116 bytes big and can be placed in the default
head room that will be available in the skb. Since the netvsc packet
is less than 48 bytes, we can use the skb control buffer
for the netvsc packet. With these changes we don't need to
ask for additional head room.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
V2: When HYPERV_NET is configured, set LL_MAX_HEADER to 128 - Vitaly 
Kuznetsov 
V2: Add a build time check on the skb control buffer - Florian Westphal 

V3: Fix a typo - David Miller

 drivers/net/hyperv/hyperv_net.h |3 +++
 drivers/net/hyperv/netvsc_drv.c |   30 +++---
 include/linux/netdevice.h   |4 +++-
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9504ca9..e15dc2c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -124,6 +124,9 @@ struct ndis_tcp_ip_checksum_info;
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
+ *
+ * The size of this structure is less than 48 bytes and we can now
+ * place this structure in the skb->cb field.
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 947b778..90cc8d9 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -432,7 +432,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct 
net_device *net)
u32 net_trans_info;
u32 hash;
u32 skb_length;
-   u32 pkt_sz;
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
 
@@ -460,16 +459,21 @@ check_size:
goto check_size;
}
 
-   pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
-
-   ret = skb_cow_head(skb, pkt_sz);
+   /*
+* Place the rndis header in the skb head room and
+* the skb->cb will be used for hv_netvsc_packet
+* structure.
+*/
+   ret = skb_cow_head(skb, RNDIS_AND_PPI_SIZE);
if (ret) {
netdev_err(net, "unable to alloc hv_netvsc_packet\n");
ret = -ENOMEM;
goto drop;
}
-   /* Use the headroom for building up the packet */
-   packet = (struct hv_netvsc_packet *)skb->head;
+   /* Use the skb control buffer for building up the packet */
+   BUILD_BUG_ON(sizeof(struct hv_netvsc_packet) >
+   FIELD_SIZEOF(struct sk_buff, cb));
+   packet = (struct hv_netvsc_packet *)skb->cb;
 
packet->status = 0;
packet->xmit_more = skb->xmit_more;
@@ -482,8 +486,7 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   rndis_msg = (struct rndis_message *)((unsigned long)packet +
-   sizeof(struct hv_netvsc_packet));
+   rndis_msg = (struct rndis_message *)skb->head;
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
@@ -1071,16 +1074,12 @@ static int netvsc_probe(struct hv_device *dev,
struct netvsc_device_info device_info;
struct netvsc_device *nvdev;
int ret;
-   u32 max_needed_headroom;
 
net = alloc_etherdev_mq(sizeof(struct net_device_context),
num_online_cpus());
if (!net)
return -ENOMEM;
 
-   max_needed_headroom = sizeof(struct hv_netvsc_packet) +
- RNDIS_AND_PPI_SIZE;
-
netif_carrier_off(net);
 
net_device_ctx = netdev_priv(net);
@@ -1116,13 +1115,6 @@ static int netvsc_probe(struct hv_device *dev,
net->ethtool_ops = ðtool_ops;
SET_NETDEV_DEV(net, &dev->device);
 
-   /*
-* Request additional head room in the skb.
-* We will use this space to build the rndis
-* heaser and other state we need to maintain.
-*/
-   net->needed_headroom = max_needed_headroom;
-
/* Notify the netvsc driver of the new device */
memset(&device_info, 0, sizeof(device_info));
device_info.ring_size = ring_size;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d208914..96975f8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -132,7 +132,9 @@ static inline bool dev_xmit_complete(int rc)
  * used.
  */
 
-#if defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
+#if defined(CONFIG_HYPERV_NET)
+# define LL_MAX_HEADER 128
+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
 # if defined(CONFIG_MAC80211_MESH)
 #  define LL_MAX_HEADER 128
 # else
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 13/17] hv_netvsc: Eliminate is_data_pkt from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate is_data_pkt from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |   14 --
 drivers/net/hyperv/netvsc_drv.c   |1 -
 drivers/net/hyperv/rndis_filter.c |1 -
 4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index baa40b1..65e340e 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -131,7 +131,6 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-   u8 is_data_pkt;
u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index d18e10c..11b009e 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -704,12 +704,14 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
   u32 pend_size,
   struct hv_netvsc_packet *packet,
   struct rndis_message *rndis_msg,
-  struct hv_page_buffer **pb)
+  struct hv_page_buffer **pb,
+  struct sk_buff *skb)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
 + pend_size;
int i;
+   bool is_data_pkt = (skb != NULL) ? true : false;
u32 msg_size = 0;
u32 padding = 0;
u32 remain = packet->total_data_buflen % net_device->pkt_align;
@@ -717,7 +719,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
packet->page_buf_cnt;
 
/* Add padding */
-   if (packet->is_data_pkt && packet->xmit_more && remain &&
+   if (is_data_pkt && packet->xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
rndis_msg->msg_len += padding;
@@ -758,7 +760,7 @@ static inline int netvsc_send_pkt(
u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
 
nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
-   if (packet->is_data_pkt) {
+   if (skb != NULL) {
/* 0 is RMC_DATA; */
nvmsg.msg.v1_msg.send_rndis_pkt.channel_type = 0;
} else {
@@ -868,7 +870,7 @@ int netvsc_send(struct hv_device *device,
if (msdp->pkt)
msd_len = msdp->pkt->total_data_buflen;
 
-   try_batch = packet->is_data_pkt && msd_len > 0 && msdp->count <
+   try_batch = (skb != NULL) && msd_len > 0 && msdp->count <
net_device->max_pkt;
 
if (try_batch && msd_len + pktlen + net_device->pkt_align <
@@ -880,7 +882,7 @@ int netvsc_send(struct hv_device *device,
section_index = msdp->pkt->send_buf_index;
packet->cp_partial = true;
 
-   } else if (packet->is_data_pkt && pktlen + net_device->pkt_align <
+   } else if ((skb != NULL) && pktlen + net_device->pkt_align <
   net_device->send_section_size) {
section_index = netvsc_get_next_send_section(net_device);
if (section_index != NETVSC_INVALID_INDEX) {
@@ -894,7 +896,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet, rndis_msg, pb);
+   packet, rndis_msg, pb, skb);
 
packet->send_buf_index = section_index;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 1532ae4..eb0c6fa 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -477,7 +477,6 @@ check_size:
 
packet->q_idx = skb_get_queue_mapping(skb);
 
-   packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
rndis_msg = (struct rndis_message *)skb->head;
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 53139f7..0b98674 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -215,7 +215,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
/* Setup the packet to send it */
packet = &req->pkt;
 
-   packet->is_data_pkt = false;
packet->total_data_buflen = req->request_msg.msg_len;
packet->page_buf_cnt = 1;
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH ney-next V3 12/17] hv_netvsc: Eliminate send_completion_tid from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate send_completion_tid from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |8 ++--
 drivers/net/hyperv/netvsc.c   |   28 ++--
 drivers/net/hyperv/netvsc_drv.c   |   14 ++
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index b541455..baa40b1 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -145,10 +145,6 @@ struct hv_netvsc_packet {
u32 send_buf_index;
 
u32 total_data_buflen;
-   u32 pad1;
-
-
-   u64 send_completion_tid;
 };
 
 struct netvsc_device_info {
@@ -188,10 +184,10 @@ int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
struct rndis_message *rndis_msg,
-   struct hv_page_buffer **page_buffer);
+   struct hv_page_buffer **page_buffer,
+   struct sk_buff *skb);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
-void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 18058a59..d18e10c 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -614,6 +614,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
struct hv_netvsc_packet *nvsc_packet;
struct net_device *ndev;
u32 send_index;
+   struct sk_buff *skb;
 
ndev = net_device->ndev;
 
@@ -639,17 +640,17 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
int queue_sends;
 
/* Get the send context */
-   nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
-   packet->trans_id;
+   skb = (struct sk_buff *)(unsigned long)packet->trans_id;
 
/* Notify the layer above us */
-   if (nvsc_packet) {
+   if (skb) {
+   nvsc_packet = (struct hv_netvsc_packet *) skb->cb;
send_index = nvsc_packet->send_buf_index;
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   netvsc_xmit_completion(nvsc_packet);
+   dev_kfree_skb_any(skb);
}
 
num_outstanding_sends =
@@ -744,7 +745,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 static inline int netvsc_send_pkt(
struct hv_netvsc_packet *packet,
struct netvsc_device *net_device,
-   struct hv_page_buffer **pb)
+   struct hv_page_buffer **pb,
+   struct sk_buff *skb)
 {
struct nvsp_message nvmsg;
u16 q_idx = packet->q_idx;
@@ -772,10 +774,7 @@ static inline int netvsc_send_pkt(
nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
packet->total_data_buflen;
 
-   if (packet->completion_func)
-   req_id = (ulong)packet;
-   else
-   req_id = 0;
+   req_id = (ulong)skb;
 
if (out_channel->rescind)
return -ENODEV;
@@ -841,7 +840,8 @@ static inline int netvsc_send_pkt(
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
struct rndis_message *rndis_msg,
-   struct hv_page_buffer **pb)
+   struct hv_page_buffer **pb,
+   struct sk_buff *skb)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -907,7 +907,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (msdp->pkt)
-   netvsc_xmit_completion(msdp->pkt);
+   dev_kfree_skb_any(skb);
 
if (packet->xmit_more && !packet->cp_partial) {
msdp->pkt = packet;
@@ -925,17 +925,17 @@ int netvsc_send(struct hv_device *device,
}
 
if (msd_send) {
-   m_ret = netvsc_send_pkt(msd_send, net_device, pb);
+   m_ret = netvsc_send_pkt(msd_send, net_device, pb, skb);
 
if (m_ret != 0) {
netvsc_free_send_slot(net_device,
  msd_send->send_buf_index);
-   netvsc_xmit_completion(msd_send);
+   dev_kfree_skb_any(skb);
   

[PATCH net-next V3 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue()

2015-12-01 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |   15 ---
 drivers/net/hyperv/netvsc.c |5 ++---
 drivers/net/hyperv/netvsc_drv.c |3 +++
 3 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index e15dc2c..a9d2bdc5 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -1260,19 +1260,4 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
-static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
-   struct netvsc_device *net_device)
-
-{
-   struct vmbus_channel *out_channel;
-
-   out_channel = net_device->chn_table[packet->q_idx];
-   if (!out_channel) {
-   out_channel = net_device->dev->channel;
-   packet->q_idx = 0;
-   }
-   return out_channel;
-}
-
-
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 0e0b723..419b055 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -749,8 +749,8 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
+   struct vmbus_channel *out_channel = net_device->chn_table[q_idx];
struct net_device *ndev = net_device->ndev;
u64 req_id;
int ret;
@@ -859,8 +859,7 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = get_channel(packet, net_device);
-   q_idx = packet->q_idx;
+   out_channel = net_device->chn_table[q_idx];
 
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 90cc8d9..da3a224 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -272,6 +272,9 @@ static u16 netvsc_select_queue(struct net_device *ndev, 
struct sk_buff *skb,
skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
}
 
+   if (!nvsc_dev->chn_table[q_idx])
+   q_idx = 0;
+
return q_idx;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 07/17] hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate send_completion_ctx from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |3 +--
 drivers/net/hyperv/netvsc_drv.c |1 -
 3 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9a3c972..9504ca9 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -146,7 +146,6 @@ struct hv_netvsc_packet {
 
 
u64 send_completion_tid;
-   void *send_completion_ctx;
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 34c16d1..0e0b723 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   netvsc_xmit_completion(nvsc_packet->
-  send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet);
}
 
num_outstanding_sends =
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6d71a1e..947b778 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -489,7 +489,6 @@ check_size:
 
/* Set the completion routine */
packet->completion_func = 1;
-   packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 17/17] hv_netvsc: Eliminate vlan_tci from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate vlan_tci from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |4 ++--
 drivers/net/hyperv/netvsc_drv.c   |   14 +++---
 drivers/net/hyperv/rndis_filter.c |7 +++
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 128b296..0c04362 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -136,7 +136,6 @@ struct hv_netvsc_packet {
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
 
-   u16 vlan_tci;
u16 q_idx;
u32 send_buf_index;
 
@@ -188,7 +187,8 @@ int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
-   struct vmbus_channel *channel);
+   struct vmbus_channel *channel,
+   u16 vlan_tci);
 void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 490672e..ba21272 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -470,7 +470,6 @@ check_size:
FIELD_SIZEOF(struct sk_buff, cb));
packet = (struct hv_netvsc_packet *)skb->cb;
 
-   packet->vlan_tci = skb->vlan_tci;
 
packet->q_idx = skb_get_queue_mapping(skb);
 
@@ -480,7 +479,7 @@ check_size:
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
-   isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
+   isvlan = skb->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
@@ -508,8 +507,8 @@ check_size:
IEEE_8021Q_INFO);
vlan = (struct ndis_pkt_8021q_info *)((void *)ppi +
ppi->ppi_offset);
-   vlan->vlanid = packet->vlan_tci & VLAN_VID_MASK;
-   vlan->pri = (packet->vlan_tci & VLAN_PRIO_MASK) >>
+   vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK;
+   vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >>
VLAN_PRIO_SHIFT;
}
 
@@ -676,7 +675,8 @@ int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
-   struct vmbus_channel *channel)
+   struct vmbus_channel *channel,
+   u16 vlan_tci)
 {
struct net_device *net;
struct net_device_context *net_device_ctx;
@@ -716,9 +716,9 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb->ip_summed = CHECKSUM_NONE;
}
 
-   if (packet->vlan_tci & VLAN_TAG_PRESENT)
+   if (vlan_tci & VLAN_TAG_PRESENT)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-  packet->vlan_tci);
+  vlan_tci);
 
skb_record_rx_queue(skb, channel->
offermsg.offer.sub_channel_index);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 28adf6a..a37bbda 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -354,6 +354,7 @@ static int rndis_filter_receive_data(struct rndis_device 
*dev,
u32 data_offset;
struct ndis_pkt_8021q_info *vlan;
struct ndis_tcp_ip_checksum_info *csum_info;
+   u16 vlan_tci = 0;
 
rndis_pkt = &msg->msg.pkt;
 
@@ -384,15 +385,13 @@ static int rndis_filter_receive_data(struct rndis_device 
*dev,
 
vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
if (vlan) {
-   pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
+   vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
(vlan->pri << VLAN_PRIO_SHIFT);
-   } else {
-   pkt->vlan_tci = 0;
}
 
csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
-   csum_info, channel);
+   csum_info, channel, vlan_tci);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 16/17] hv_netvsc: Eliminate status from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate status from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |6 ++
 drivers/net/hyperv/netvsc_drv.c   |8 ++--
 drivers/net/hyperv/rndis_filter.c |   20 +---
 4 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 96d34e2..128b296 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -130,7 +130,6 @@ struct ndis_tcp_ip_checksum_info;
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
-   u8 status;
u8 cp_partial; /* partial copy into send buffer */
 
u8 rmsg_size; /* RNDIS header and PPI size */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index cd5b65e..02bab9a 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1045,17 +1045,15 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
-   netvsc_packet->status = NVSP_STAT_SUCCESS;
data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
vmxferpage_packet->ranges[i].byte_count;
 
/* Pass it to the upper layer */
-   rndis_filter_receive(device, netvsc_packet, &data, channel);
+   status = rndis_filter_receive(device, netvsc_packet, &data,
+ channel);
 
-   if (netvsc_packet->status != NVSP_STAT_SUCCESS)
-   status = NVSP_STAT_FAIL;
}
 
netvsc_send_recv_completion(device, channel, net_device,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 7520c52..490672e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -470,8 +470,6 @@ check_size:
FIELD_SIZEOF(struct sk_buff, cb));
packet = (struct hv_netvsc_packet *)skb->cb;
 
-   packet->status = 0;
-
packet->vlan_tci = skb->vlan_tci;
 
packet->q_idx = skb_get_queue_mapping(skb);
@@ -687,8 +685,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 
net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
if (!net || net->reg_state != NETREG_REGISTERED) {
-   packet->status = NVSP_STAT_FAIL;
-   return 0;
+   return NVSP_STAT_FAIL;
}
net_device_ctx = netdev_priv(net);
rx_stats = this_cpu_ptr(net_device_ctx->rx_stats);
@@ -697,8 +694,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen);
if (unlikely(!skb)) {
++net->stats.rx_dropped;
-   packet->status = NVSP_STAT_FAIL;
-   return 0;
+   return NVSP_STAT_FAIL;
}
 
/*
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 3c06aa7..28adf6a 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -344,7 +344,7 @@ static inline void *rndis_get_ppi(struct rndis_packet 
*rpkt, u32 type)
return NULL;
 }
 
-static void rndis_filter_receive_data(struct rndis_device *dev,
+static int rndis_filter_receive_data(struct rndis_device *dev,
   struct rndis_message *msg,
   struct hv_netvsc_packet *pkt,
   void **data,
@@ -371,7 +371,7 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
   "overflow detected (got %u, min %u)"
   "...dropping this message!\n",
   pkt->total_data_buflen, rndis_pkt->data_len);
-   return;
+   return NVSP_STAT_FAIL;
}
 
/*
@@ -391,7 +391,8 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
}
 
csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
-   netvsc_recv_callback(dev->net_dev->dev, pkt, data, csum_info, channel);
+   return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
+   csum_info, channel);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
@@ -406,7 +407,7 @@ int rndis_filter_receive(struct hv_device *dev,
int ret = 0;
 
if (!net_dev) {
-   ret = -EINVAL;
+   ret = NVSP_STAT_FAIL;
goto exit;
}
 
@@ -416,7 +417,7 @@ int rndis_f

[PATCH net-next V3 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
As part of reducing the size of the hv_netvsc_packet, resize some of the
variables based on their usage.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   14 +++---
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 5fa98f5..972e562 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -127,11 +127,11 @@ struct ndis_tcp_ip_checksum_info;
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
-   u32 status;
+   u8 status;
 
-   bool is_data_pkt;
-   bool xmit_more; /* from skb */
-   bool cp_partial; /* partial copy into send buffer */
+   u8 is_data_pkt;
+   u8 xmit_more; /* from skb */
+   u8 cp_partial; /* partial copy into send buffer */
 
u16 vlan_tci;
 
@@ -147,13 +147,13 @@ struct hv_netvsc_packet {
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u32 rmsg_size; /* RNDIS header and PPI size */
-   u32 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
 
u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u32 page_buf_cnt;
+   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V3 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet

2015-12-01 Thread K. Y. Srinivasan
Eliminate page_buf from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |4 ++--
 drivers/net/hyperv/netvsc.c   |   25 ++---
 drivers/net/hyperv/netvsc_drv.c   |   11 ++-
 drivers/net/hyperv/rndis_filter.c |   26 +-
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index f5b2145..b541455 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -149,7 +149,6 @@ struct hv_netvsc_packet {
 
 
u64 send_completion_tid;
-   struct hv_page_buffer *page_buf;
 };
 
 struct netvsc_device_info {
@@ -188,7 +187,8 @@ int netvsc_device_add(struct hv_device *device, void 
*additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
-   struct rndis_message *rndis_msg);
+   struct rndis_message *rndis_msg,
+   struct hv_page_buffer **page_buffer);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
 void netvsc_xmit_completion(void *context);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 081f14f..18058a59 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -702,7 +702,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
   unsigned int section_index,
   u32 pend_size,
   struct hv_netvsc_packet *packet,
-  struct rndis_message *rndis_msg)
+  struct rndis_message *rndis_msg,
+  struct hv_page_buffer **pb)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
@@ -723,9 +724,9 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
}
 
for (i = 0; i < page_count; i++) {
-   char *src = phys_to_virt(packet->page_buf[i].pfn << PAGE_SHIFT);
-   u32 offset = packet->page_buf[i].offset;
-   u32 len = packet->page_buf[i].len;
+   char *src = phys_to_virt((*pb)[i].pfn << PAGE_SHIFT);
+   u32 offset = (*pb)[i].offset;
+   u32 len = (*pb)[i].len;
 
memcpy(dest, (src + offset), len);
msg_size += len;
@@ -742,7 +743,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 
 static inline int netvsc_send_pkt(
struct hv_netvsc_packet *packet,
-   struct netvsc_device *net_device)
+   struct netvsc_device *net_device,
+   struct hv_page_buffer **pb)
 {
struct nvsp_message nvmsg;
u16 q_idx = packet->q_idx;
@@ -789,8 +791,8 @@ static inline int netvsc_send_pkt(
packet->xmit_more = false;
 
if (packet->page_buf_cnt) {
-   pgbuf = packet->cp_partial ? packet->page_buf +
-   packet->rmsg_pgcnt : packet->page_buf;
+   pgbuf = packet->cp_partial ? (*pb) +
+   packet->rmsg_pgcnt : (*pb);
ret = vmbus_sendpacket_pagebuffer_ctl(out_channel,
  pgbuf,
  packet->page_buf_cnt,
@@ -838,7 +840,8 @@ static inline int netvsc_send_pkt(
 
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
-   struct rndis_message *rndis_msg)
+   struct rndis_message *rndis_msg,
+   struct hv_page_buffer **pb)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -891,7 +894,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet, rndis_msg);
+   packet, rndis_msg, pb);
 
packet->send_buf_index = section_index;
 
@@ -922,7 +925,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (msd_send) {
-   m_ret = netvsc_send_pkt(msd_send, net_device);
+   m_ret = netvsc_send_pkt(msd_send, net_device, pb);
 
if (m_ret != 0) {
netvsc_free_send_slot(net_device,
@@ -932,7 +935,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (cur_send)
-   ret = netvsc_send_pkt(cur_send, net_device);
+   ret = netvsc_send_pkt(cur_send, net_device, pb);

[PATCH net-next V2 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminatte the data field from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |5 ++---
 drivers/net/hyperv/netvsc.c   |5 +++--
 drivers/net/hyperv/netvsc_drv.c   |3 ++-
 drivers/net/hyperv/rndis_filter.c |   11 +++
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7fa4f43..506d552 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -148,9 +148,6 @@ struct hv_netvsc_packet {
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
-
-   /* Points to the send/receive buffer where the ethernet frame is */
-   void *data;
struct hv_page_buffer *page_buf;
 };
 
@@ -196,6 +193,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
@@ -206,6 +204,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
struct hv_netvsc_packet *pkt,
+   void **data,
struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 2de9e7f..8fbf816 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1008,6 +1008,7 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
int i;
int count = 0;
struct net_device *ndev;
+   void *data;
 
ndev = net_device->ndev;
 
@@ -1047,13 +1048,13 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
netvsc_packet->status = NVSP_STAT_SUCCESS;
-   netvsc_packet->data = (void *)((unsigned long)net_device->
+   data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
vmxferpage_packet->ranges[i].byte_count;
 
/* Pass it to the upper layer */
-   rndis_filter_receive(device, netvsc_packet, channel);
+   rndis_filter_receive(device, netvsc_packet, &data, channel);
 
if (netvsc_packet->status != NVSP_STAT_SUCCESS)
status = NVSP_STAT_FAIL;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 77c0849..c73afb1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -685,6 +685,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
  */
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel)
 {
@@ -713,7 +714,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 * Copy to skb. This copy is needed here since the memory pointed by
 * hv_netvsc_packet cannot be deallocated
 */
-   memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
+   memcpy(skb_put(skb, packet->total_data_buflen), *data,
packet->total_data_buflen);
 
skb->protocol = eth_type_trans(skb, net);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 63584e7..be0fa9c 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -351,6 +351,7 @@ static inline void *rndis_get_ppi(struct rndis_packet 
*rpkt, u32 type)
 static void rndis_filter_receive_data(struct rndis_device *dev,
   struct rndis_message *msg,
   struct hv_netvsc_packet *pkt,
+  void **data,
   struct vmbus_channel *channel)
 {
struct rndis_packet *rndis_pkt;
@@ -383,7 +384,7 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
 * the data packet to the stack, without the rndis trailer padding
 */
pkt->total_data_buflen = rndis_pkt->data_len;
-   pkt->data = (void *)((unsigned long)pkt->data +

[PATCH net-next V2 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue()

2015-11-28 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |   15 ---
 drivers/net/hyperv/netvsc.c |5 ++---
 drivers/net/hyperv/netvsc_drv.c |3 +++
 3 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index e15dc2c..a9d2bdc5 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -1260,19 +1260,4 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
-static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
-   struct netvsc_device *net_device)
-
-{
-   struct vmbus_channel *out_channel;
-
-   out_channel = net_device->chn_table[packet->q_idx];
-   if (!out_channel) {
-   out_channel = net_device->dev->channel;
-   packet->q_idx = 0;
-   }
-   return out_channel;
-}
-
-
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 0e0b723..419b055 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -749,8 +749,8 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
+   struct vmbus_channel *out_channel = net_device->chn_table[q_idx];
struct net_device *ndev = net_device->ndev;
u64 req_id;
int ret;
@@ -859,8 +859,7 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = get_channel(packet, net_device);
-   q_idx = packet->q_idx;
+   out_channel = net_device->chn_table[q_idx];
 
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 90cc8d9..da3a224 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -272,6 +272,9 @@ static u16 netvsc_select_queue(struct net_device *ndev, 
struct sk_buff *skb,
skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
}
 
+   if (!nvsc_dev->chn_table[q_idx])
+   q_idx = 0;
+
return q_idx;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 04/17] hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet structure

2015-11-28 Thread K. Y. Srinivasan
Eliminate rndis_msg pointer from hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |8 +++-
 drivers/net/hyperv/netvsc.c   |   10 ++
 drivers/net/hyperv/netvsc_drv.c   |7 +++
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ac24091..7fa4f43 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -149,10 +149,6 @@ struct hv_netvsc_packet {
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-
-   /* This points to the memory after page_buf */
-   struct rndis_message *rndis_msg;
-
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
struct hv_page_buffer *page_buf;
@@ -189,10 +185,12 @@ struct rndis_device {
 
 
 /* Interface */
+struct rndis_message;
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet);
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
 void netvsc_xmit_completion(void *context);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 52533ed..2de9e7f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -706,7 +706,8 @@ static u32 netvsc_get_next_send_section(struct 
netvsc_device *net_device)
 static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
   unsigned int section_index,
   u32 pend_size,
-  struct hv_netvsc_packet *packet)
+  struct hv_netvsc_packet *packet,
+  struct rndis_message *rndis_msg)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
@@ -722,7 +723,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
if (packet->is_data_pkt && packet->xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
-   packet->rndis_msg->msg_len += padding;
+   rndis_msg->msg_len += padding;
packet->total_data_buflen += padding;
}
 
@@ -841,7 +842,8 @@ static inline int netvsc_send_pkt(
 }
 
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet)
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -897,7 +899,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet);
+   packet, rndis_msg);
 
packet->send_buf_index = section_index;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index e5f4eec..77c0849 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -482,10 +482,10 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   packet->rndis_msg = (struct rndis_message *)((unsigned long)packet +
+   rndis_msg = (struct rndis_message *)((unsigned long)packet +
sizeof(struct hv_netvsc_packet));
 
-   memset(packet->rndis_msg, 0, RNDIS_AND_PPI_SIZE);
+   memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
packet->send_completion = netvsc_xmit_completion;
@@ -495,7 +495,6 @@ check_size:
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
-   rndis_msg = packet->rndis_msg;
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
rndis_msg->msg_len = packet->total_data_buflen;
rndis_pkt = &rndis_msg->msg.pkt;
@@ -619,7 +618,7 @@ do_send:
packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
   skb, packet);
 
-   ret = netvsc_send(net_device_ctx->device_ctx, packet);
+   ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg);
 
 drop:
if (ret == 0) {
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c

[PATCH net-next V2 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure

2015-11-28 Thread K. Y. Srinivasan
Eliminate the channel field in hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |   22 ++
 drivers/net/hyperv/netvsc.c   |   19 ---
 drivers/net/hyperv/netvsc_drv.c   |5 +++--
 drivers/net/hyperv/rndis_filter.c |   10 ++
 4 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7435673..ac24091 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -144,7 +144,6 @@ struct hv_netvsc_packet {
u32 total_data_buflen;
u32 pad1;
 
-   struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
@@ -199,7 +198,8 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
-   struct ndis_tcp_ip_checksum_info *csum_info);
+   struct ndis_tcp_ip_checksum_info *csum_info,
+   struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
@@ -207,12 +207,12 @@ int rndis_filter_device_add(struct hv_device *dev,
void *additional_info);
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
-   struct hv_netvsc_packet *pkt);
+   struct hv_netvsc_packet *pkt,
+   struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
 
-
 #define NVSP_INVALID_PROTOCOL_VERSION  ((u32)0x)
 
 #define NVSP_PROTOCOL_VERSION_12
@@ -1262,5 +1262,19 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
+static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
+   struct netvsc_device *net_device)
+
+{
+   struct vmbus_channel *out_channel;
+
+   out_channel = net_device->chn_table[packet->q_idx];
+   if (!out_channel) {
+   out_channel = net_device->dev->channel;
+   packet->q_idx = 0;
+   }
+   return out_channel;
+}
+
 
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 51e4c0f..52533ed 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -610,6 +610,7 @@ static inline void netvsc_free_send_slot(struct 
netvsc_device *net_device,
 }
 
 static void netvsc_send_completion(struct netvsc_device *net_device,
+  struct vmbus_channel *incoming_channel,
   struct hv_device *device,
   struct vmpacket_descriptor *packet)
 {
@@ -651,7 +652,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
-   channel = nvsc_packet->channel;
+   channel = incoming_channel;
nvsc_packet->send_completion(nvsc_packet->
 send_completion_ctx);
}
@@ -748,7 +749,7 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = packet->channel;
+   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
struct net_device *ndev = net_device->ndev;
u64 req_id;
@@ -857,13 +858,9 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = net_device->chn_table[q_idx];
-   if (!out_channel) {
-   out_channel = device->channel;
-   q_idx = 0;
-   packet->q_idx = 0;
-   }
-   packet->channel = out_channel;
+   out_channel = get_channel(packet, net_device);
+   q_idx = packet->q_idx;
+
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
 
@@ -1043,7 +1040,6 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
}
 
count = vmxferpage_packet->range_cnt;
-   netvsc_packet->channel = channel;
 
/* Each range represents 1 RNDIS pkt that co

[PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
As part of reducing the size of the hv_netvsc_packet, resize some of the
variables based on their usage.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   14 +++---
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 5fa98f5..972e562 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -127,11 +127,11 @@ struct ndis_tcp_ip_checksum_info;
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
-   u32 status;
+   u8 status;
 
-   bool is_data_pkt;
-   bool xmit_more; /* from skb */
-   bool cp_partial; /* partial copy into send buffer */
+   u8 is_data_pkt;
+   u8 xmit_more; /* from skb */
+   u8 cp_partial; /* partial copy into send buffer */
 
u16 vlan_tci;
 
@@ -147,13 +147,13 @@ struct hv_netvsc_packet {
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u32 rmsg_size; /* RNDIS header and PPI size */
-   u32 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
 
u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u32 page_buf_cnt;
+   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate page_buf from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |4 ++--
 drivers/net/hyperv/netvsc.c   |   25 ++---
 drivers/net/hyperv/netvsc_drv.c   |   11 ++-
 drivers/net/hyperv/rndis_filter.c |   26 +-
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index f5b2145..b541455 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -149,7 +149,6 @@ struct hv_netvsc_packet {
 
 
u64 send_completion_tid;
-   struct hv_page_buffer *page_buf;
 };
 
 struct netvsc_device_info {
@@ -188,7 +187,8 @@ int netvsc_device_add(struct hv_device *device, void 
*additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
-   struct rndis_message *rndis_msg);
+   struct rndis_message *rndis_msg,
+   struct hv_page_buffer **page_buffer);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
 void netvsc_xmit_completion(void *context);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 081f14f..18058a59 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -702,7 +702,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
   unsigned int section_index,
   u32 pend_size,
   struct hv_netvsc_packet *packet,
-  struct rndis_message *rndis_msg)
+  struct rndis_message *rndis_msg,
+  struct hv_page_buffer **pb)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
@@ -723,9 +724,9 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
}
 
for (i = 0; i < page_count; i++) {
-   char *src = phys_to_virt(packet->page_buf[i].pfn << PAGE_SHIFT);
-   u32 offset = packet->page_buf[i].offset;
-   u32 len = packet->page_buf[i].len;
+   char *src = phys_to_virt((*pb)[i].pfn << PAGE_SHIFT);
+   u32 offset = (*pb)[i].offset;
+   u32 len = (*pb)[i].len;
 
memcpy(dest, (src + offset), len);
msg_size += len;
@@ -742,7 +743,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 
 static inline int netvsc_send_pkt(
struct hv_netvsc_packet *packet,
-   struct netvsc_device *net_device)
+   struct netvsc_device *net_device,
+   struct hv_page_buffer **pb)
 {
struct nvsp_message nvmsg;
u16 q_idx = packet->q_idx;
@@ -789,8 +791,8 @@ static inline int netvsc_send_pkt(
packet->xmit_more = false;
 
if (packet->page_buf_cnt) {
-   pgbuf = packet->cp_partial ? packet->page_buf +
-   packet->rmsg_pgcnt : packet->page_buf;
+   pgbuf = packet->cp_partial ? (*pb) +
+   packet->rmsg_pgcnt : (*pb);
ret = vmbus_sendpacket_pagebuffer_ctl(out_channel,
  pgbuf,
  packet->page_buf_cnt,
@@ -838,7 +840,8 @@ static inline int netvsc_send_pkt(
 
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
-   struct rndis_message *rndis_msg)
+   struct rndis_message *rndis_msg,
+   struct hv_page_buffer **pb)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -891,7 +894,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet, rndis_msg);
+   packet, rndis_msg, pb);
 
packet->send_buf_index = section_index;
 
@@ -922,7 +925,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (msd_send) {
-   m_ret = netvsc_send_pkt(msd_send, net_device);
+   m_ret = netvsc_send_pkt(msd_send, net_device, pb);
 
if (m_ret != 0) {
netvsc_free_send_slot(net_device,
@@ -932,7 +935,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (cur_send)
-   ret = netvsc_send_pkt(cur_send, net_device);
+   ret = netvsc_send_pkt(cur_send, net_device, pb);

[PATCH net-next V2 14/17] hv_netvsc: Eliminate completion_func from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate completion_func from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc_drv.c   |3 ---
 drivers/net/hyperv/rndis_filter.c |1 -
 3 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 65e340e..ddf51a0 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -137,7 +137,6 @@ struct hv_netvsc_packet {
u8 rmsg_size; /* RNDIS header and PPI size */
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
-   u8 completion_func;
 
u16 vlan_tci;
u16 q_idx;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index eb0c6fa..bc4be1d 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -483,9 +483,6 @@ check_size:
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
-   /* Set the completion routine */
-   packet->completion_func = 1;
-
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 0b98674..6ba5adf 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -236,7 +236,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
pb[0].len;
}
 
-   packet->completion_func = 0;
packet->xmit_more = false;
 
ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 17/17] hv_netvsc: Eliminate vlan_tci from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate vlan_tci from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |4 ++--
 drivers/net/hyperv/netvsc_drv.c   |   14 +++---
 drivers/net/hyperv/rndis_filter.c |7 +++
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 128b296..0c04362 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -136,7 +136,6 @@ struct hv_netvsc_packet {
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
 
-   u16 vlan_tci;
u16 q_idx;
u32 send_buf_index;
 
@@ -188,7 +187,8 @@ int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
-   struct vmbus_channel *channel);
+   struct vmbus_channel *channel,
+   u16 vlan_tci);
 void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 490672e..ba21272 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -470,7 +470,6 @@ check_size:
FIELD_SIZEOF(struct sk_buff, cb));
packet = (struct hv_netvsc_packet *)skb->cb;
 
-   packet->vlan_tci = skb->vlan_tci;
 
packet->q_idx = skb_get_queue_mapping(skb);
 
@@ -480,7 +479,7 @@ check_size:
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
-   isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
+   isvlan = skb->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
@@ -508,8 +507,8 @@ check_size:
IEEE_8021Q_INFO);
vlan = (struct ndis_pkt_8021q_info *)((void *)ppi +
ppi->ppi_offset);
-   vlan->vlanid = packet->vlan_tci & VLAN_VID_MASK;
-   vlan->pri = (packet->vlan_tci & VLAN_PRIO_MASK) >>
+   vlan->vlanid = skb->vlan_tci & VLAN_VID_MASK;
+   vlan->pri = (skb->vlan_tci & VLAN_PRIO_MASK) >>
VLAN_PRIO_SHIFT;
}
 
@@ -676,7 +675,8 @@ int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
-   struct vmbus_channel *channel)
+   struct vmbus_channel *channel,
+   u16 vlan_tci)
 {
struct net_device *net;
struct net_device_context *net_device_ctx;
@@ -716,9 +716,9 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb->ip_summed = CHECKSUM_NONE;
}
 
-   if (packet->vlan_tci & VLAN_TAG_PRESENT)
+   if (vlan_tci & VLAN_TAG_PRESENT)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-  packet->vlan_tci);
+  vlan_tci);
 
skb_record_rx_queue(skb, channel->
offermsg.offer.sub_channel_index);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 28adf6a..a37bbda 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -354,6 +354,7 @@ static int rndis_filter_receive_data(struct rndis_device 
*dev,
u32 data_offset;
struct ndis_pkt_8021q_info *vlan;
struct ndis_tcp_ip_checksum_info *csum_info;
+   u16 vlan_tci = 0;
 
rndis_pkt = &msg->msg.pkt;
 
@@ -384,15 +385,13 @@ static int rndis_filter_receive_data(struct rndis_device 
*dev,
 
vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
if (vlan) {
-   pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
+   vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
(vlan->pri << VLAN_PRIO_SHIFT);
-   } else {
-   pkt->vlan_tci = 0;
}
 
csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
-   csum_info, channel);
+   csum_info, channel, vlan_tci);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 15/17] hv_netvsc: Eliminate xmit_more from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate xmit_more from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |   13 -
 drivers/net/hyperv/netvsc_drv.c   |1 -
 drivers/net/hyperv/rndis_filter.c |2 --
 4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ddf51a0..96d34e2 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -131,7 +131,6 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-   u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
u8 rmsg_size; /* RNDIS header and PPI size */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 11b009e..cd5b65e 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -712,6 +712,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 + pend_size;
int i;
bool is_data_pkt = (skb != NULL) ? true : false;
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
u32 msg_size = 0;
u32 padding = 0;
u32 remain = packet->total_data_buflen % net_device->pkt_align;
@@ -719,7 +720,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
packet->page_buf_cnt;
 
/* Add padding */
-   if (is_data_pkt && packet->xmit_more && remain &&
+   if (is_data_pkt && xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
rndis_msg->msg_len += padding;
@@ -758,6 +759,7 @@ static inline int netvsc_send_pkt(
int ret;
struct hv_page_buffer *pgbuf;
u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
if (skb != NULL) {
@@ -789,7 +791,7 @@ static inline int netvsc_send_pkt(
 * unnecessarily.
 */
if (ring_avail < (RING_AVAIL_PERCENT_LOWATER + 1))
-   packet->xmit_more = false;
+   xmit_more = false;
 
if (packet->page_buf_cnt) {
pgbuf = packet->cp_partial ? (*pb) +
@@ -801,14 +803,14 @@ static inline int netvsc_send_pkt(
  sizeof(struct 
nvsp_message),
  req_id,
  
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
- !packet->xmit_more);
+ !xmit_more);
} else {
ret = vmbus_sendpacket_ctl(out_channel, &nvmsg,
   sizeof(struct nvsp_message),
   req_id,
   VM_PKT_DATA_INBAND,
   
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED,
-  !packet->xmit_more);
+  !xmit_more);
}
 
if (ret == 0) {
@@ -854,6 +856,7 @@ int netvsc_send(struct hv_device *device,
struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
bool try_batch;
+   bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
 
net_device = get_outbound_net_device(device);
if (!net_device)
@@ -911,7 +914,7 @@ int netvsc_send(struct hv_device *device,
if (msdp->pkt)
dev_kfree_skb_any(skb);
 
-   if (packet->xmit_more && !packet->cp_partial) {
+   if (xmit_more && !packet->cp_partial) {
msdp->pkt = packet;
msdp->count++;
} else {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index bc4be1d..7520c52 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -471,7 +471,6 @@ check_size:
packet = (struct hv_netvsc_packet *)skb->cb;
 
packet->status = 0;
-   packet->xmit_more = skb->xmit_more;
 
packet->vlan_tci = skb->vlan_tci;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 6ba5adf..3c06aa7 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -236,8 +236,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
pb[0].len;
}
 
-   packet->xmit_more = f

[PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb

2015-11-28 Thread K. Y. Srinivasan
The rndis header is 116 bytes big and can be placed in the default
head room that will be available in the skb. Since the netvsc packet
is less than 48 bytes, we can use the skb control buffer
for the netvsc packet. With these changes we don't need to
ask for additional head room.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
v2: When HYPERV_NET is configured, set LL_MAX_HEADER to 128 - Vitaly 
Kuznetsov  
V2: Add a build time check on the skb control buffer - Florian Westphal 

 drivers/net/hyperv/hyperv_net.h |3 +++
 drivers/net/hyperv/netvsc_drv.c |   30 +++---
 include/linux/netdevice.h   |4 +++-
 3 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9504ca9..e15dc2c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -124,6 +124,9 @@ struct ndis_tcp_ip_checksum_info;
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
+ *
+ * The size of this structure is less than 48 bytes and we can now
+ * place this structure in the skb->cb field.
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 947b778..90cc8d9 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -432,7 +432,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct 
net_device *net)
u32 net_trans_info;
u32 hash;
u32 skb_length;
-   u32 pkt_sz;
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
 
@@ -460,16 +459,21 @@ check_size:
goto check_size;
}
 
-   pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
-
-   ret = skb_cow_head(skb, pkt_sz);
+   /*
+* Place the rndis header in the skb head room and
+* the skb->cb will be used for hv_netvsc_packet
+* structure.
+*/
+   ret = skb_cow_head(skb, RNDIS_AND_PPI_SIZE);
if (ret) {
netdev_err(net, "unable to alloc hv_netvsc_packet\n");
ret = -ENOMEM;
goto drop;
}
-   /* Use the headroom for building up the packet */
-   packet = (struct hv_netvsc_packet *)skb->head;
+   /* Use the skb control buffer for building up the packet */
+   BUILD_BUG_ON(sizeof(struct hv_netvsc_packet) >
+   FIELD_SIZEOF(struct sk_buff, cb));
+   packet = (struct hv_netvsc_packet *)skb->cb;
 
packet->status = 0;
packet->xmit_more = skb->xmit_more;
@@ -482,8 +486,7 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   rndis_msg = (struct rndis_message *)((unsigned long)packet +
-   sizeof(struct hv_netvsc_packet));
+   rndis_msg = (struct rndis_message *)skb->head;
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
@@ -1071,16 +1074,12 @@ static int netvsc_probe(struct hv_device *dev,
struct netvsc_device_info device_info;
struct netvsc_device *nvdev;
int ret;
-   u32 max_needed_headroom;
 
net = alloc_etherdev_mq(sizeof(struct net_device_context),
num_online_cpus());
if (!net)
return -ENOMEM;
 
-   max_needed_headroom = sizeof(struct hv_netvsc_packet) +
- RNDIS_AND_PPI_SIZE;
-
netif_carrier_off(net);
 
net_device_ctx = netdev_priv(net);
@@ -1116,13 +1115,6 @@ static int netvsc_probe(struct hv_device *dev,
net->ethtool_ops = ðtool_ops;
SET_NETDEV_DEV(net, &dev->device);
 
-   /*
-* Request additional head room in the skb.
-* We will use this space to build the rndis
-* heaser and other state we need to maintain.
-*/
-   net->needed_headroom = max_needed_headroom;
-
/* Notify the netvsc driver of the new device */
memset(&device_info, 0, sizeof(device_info));
device_info.ring_size = ring_size;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d208914..2e8d703 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -132,7 +132,9 @@ static inline bool dev_xmit_complete(int rc)
  * used.
  */
 
-#if defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
+#if defined(CONFIG_HYPERV_NET)
+# define LL_MAX_HEADER 128
+#elseif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
 # if defined(CONFIG_MAC80211_MESH)
 #  define LL_MAX_HEADER 128
 # else
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 16/17] hv_netvsc: Eliminate status from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate status from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |6 ++
 drivers/net/hyperv/netvsc_drv.c   |8 ++--
 drivers/net/hyperv/rndis_filter.c |   20 +---
 4 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 96d34e2..128b296 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -130,7 +130,6 @@ struct ndis_tcp_ip_checksum_info;
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
-   u8 status;
u8 cp_partial; /* partial copy into send buffer */
 
u8 rmsg_size; /* RNDIS header and PPI size */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index cd5b65e..02bab9a 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1045,17 +1045,15 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
-   netvsc_packet->status = NVSP_STAT_SUCCESS;
data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
vmxferpage_packet->ranges[i].byte_count;
 
/* Pass it to the upper layer */
-   rndis_filter_receive(device, netvsc_packet, &data, channel);
+   status = rndis_filter_receive(device, netvsc_packet, &data,
+ channel);
 
-   if (netvsc_packet->status != NVSP_STAT_SUCCESS)
-   status = NVSP_STAT_FAIL;
}
 
netvsc_send_recv_completion(device, channel, net_device,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 7520c52..490672e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -470,8 +470,6 @@ check_size:
FIELD_SIZEOF(struct sk_buff, cb));
packet = (struct hv_netvsc_packet *)skb->cb;
 
-   packet->status = 0;
-
packet->vlan_tci = skb->vlan_tci;
 
packet->q_idx = skb_get_queue_mapping(skb);
@@ -687,8 +685,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 
net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
if (!net || net->reg_state != NETREG_REGISTERED) {
-   packet->status = NVSP_STAT_FAIL;
-   return 0;
+   return NVSP_STAT_FAIL;
}
net_device_ctx = netdev_priv(net);
rx_stats = this_cpu_ptr(net_device_ctx->rx_stats);
@@ -697,8 +694,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen);
if (unlikely(!skb)) {
++net->stats.rx_dropped;
-   packet->status = NVSP_STAT_FAIL;
-   return 0;
+   return NVSP_STAT_FAIL;
}
 
/*
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 3c06aa7..28adf6a 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -344,7 +344,7 @@ static inline void *rndis_get_ppi(struct rndis_packet 
*rpkt, u32 type)
return NULL;
 }
 
-static void rndis_filter_receive_data(struct rndis_device *dev,
+static int rndis_filter_receive_data(struct rndis_device *dev,
   struct rndis_message *msg,
   struct hv_netvsc_packet *pkt,
   void **data,
@@ -371,7 +371,7 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
   "overflow detected (got %u, min %u)"
   "...dropping this message!\n",
   pkt->total_data_buflen, rndis_pkt->data_len);
-   return;
+   return NVSP_STAT_FAIL;
}
 
/*
@@ -391,7 +391,8 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
}
 
csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
-   netvsc_recv_callback(dev->net_dev->dev, pkt, data, csum_info, channel);
+   return netvsc_recv_callback(dev->net_dev->dev, pkt, data,
+   csum_info, channel);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
@@ -406,7 +407,7 @@ int rndis_filter_receive(struct hv_device *dev,
int ret = 0;
 
if (!net_dev) {
-   ret = -EINVAL;
+   ret = NVSP_STAT_FAIL;
goto exit;
}
 
@@ -416,7 +417,7 @@ int rndis_f

[PATCH net-next V2 10/17] hv_netvsc: remove locking in netvsc_send()

2015-11-28 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Packet scheduler guarantees there won't be multiple senders for the same
queue and as we use q_idx for multi_send_data the spinlock is redundant.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |8 
 2 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index a9d2bdc5..f5b2145 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -633,7 +633,6 @@ struct nvsp_message {
 #define RNDIS_PKT_ALIGN_DEFAULT 8
 
 struct multi_send_data {
-   spinlock_t lock; /* protect struct multi_send_data */
struct hv_netvsc_packet *pkt; /* netvsc pkt pending */
u32 count; /* counter of batched packets */
 };
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 419b055..081f14f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -38,7 +38,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
 {
struct netvsc_device *net_device;
struct net_device *ndev = hv_get_drvdata(device);
-   int i;
 
net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
if (!net_device)
@@ -58,9 +57,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
-   for (i = 0; i < num_online_cpus(); i++)
-   spin_lock_init(&net_device->msd[i].lock);
-
hv_set_drvdata(device, net_device);
return net_device;
 }
@@ -850,7 +846,6 @@ int netvsc_send(struct hv_device *device,
u16 q_idx = packet->q_idx;
u32 pktlen = packet->total_data_buflen, msd_len = 0;
unsigned int section_index = NETVSC_INVALID_INDEX;
-   unsigned long flag;
struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
bool try_batch;
@@ -867,7 +862,6 @@ int netvsc_send(struct hv_device *device,
msdp = &net_device->msd[q_idx];
 
/* batch packets in send buffer if possible */
-   spin_lock_irqsave(&msdp->lock, flag);
if (msdp->pkt)
msd_len = msdp->pkt->total_data_buflen;
 
@@ -927,8 +921,6 @@ int netvsc_send(struct hv_device *device,
cur_send = packet;
}
 
-   spin_unlock_irqrestore(&msdp->lock, flag);
-
if (msd_send) {
m_ret = netvsc_send_pkt(msd_send, net_device);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 12/17] hv_netvsc: Eliminate send_completion_tid from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate send_completion_tid from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |8 ++--
 drivers/net/hyperv/netvsc.c   |   28 ++--
 drivers/net/hyperv/netvsc_drv.c   |   14 ++
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index b541455..baa40b1 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -145,10 +145,6 @@ struct hv_netvsc_packet {
u32 send_buf_index;
 
u32 total_data_buflen;
-   u32 pad1;
-
-
-   u64 send_completion_tid;
 };
 
 struct netvsc_device_info {
@@ -188,10 +184,10 @@ int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
struct rndis_message *rndis_msg,
-   struct hv_page_buffer **page_buffer);
+   struct hv_page_buffer **page_buffer,
+   struct sk_buff *skb);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
-void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
void **data,
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 18058a59..d18e10c 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -614,6 +614,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
struct hv_netvsc_packet *nvsc_packet;
struct net_device *ndev;
u32 send_index;
+   struct sk_buff *skb;
 
ndev = net_device->ndev;
 
@@ -639,17 +640,17 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
int queue_sends;
 
/* Get the send context */
-   nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
-   packet->trans_id;
+   skb = (struct sk_buff *)(unsigned long)packet->trans_id;
 
/* Notify the layer above us */
-   if (nvsc_packet) {
+   if (skb) {
+   nvsc_packet = (struct hv_netvsc_packet *) skb->cb;
send_index = nvsc_packet->send_buf_index;
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   netvsc_xmit_completion(nvsc_packet);
+   dev_kfree_skb_any(skb);
}
 
num_outstanding_sends =
@@ -744,7 +745,8 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
 static inline int netvsc_send_pkt(
struct hv_netvsc_packet *packet,
struct netvsc_device *net_device,
-   struct hv_page_buffer **pb)
+   struct hv_page_buffer **pb,
+   struct sk_buff *skb)
 {
struct nvsp_message nvmsg;
u16 q_idx = packet->q_idx;
@@ -772,10 +774,7 @@ static inline int netvsc_send_pkt(
nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
packet->total_data_buflen;
 
-   if (packet->completion_func)
-   req_id = (ulong)packet;
-   else
-   req_id = 0;
+   req_id = (ulong)skb;
 
if (out_channel->rescind)
return -ENODEV;
@@ -841,7 +840,8 @@ static inline int netvsc_send_pkt(
 int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet,
struct rndis_message *rndis_msg,
-   struct hv_page_buffer **pb)
+   struct hv_page_buffer **pb,
+   struct sk_buff *skb)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -907,7 +907,7 @@ int netvsc_send(struct hv_device *device,
}
 
if (msdp->pkt)
-   netvsc_xmit_completion(msdp->pkt);
+   dev_kfree_skb_any(skb);
 
if (packet->xmit_more && !packet->cp_partial) {
msdp->pkt = packet;
@@ -925,17 +925,17 @@ int netvsc_send(struct hv_device *device,
}
 
if (msd_send) {
-   m_ret = netvsc_send_pkt(msd_send, net_device, pb);
+   m_ret = netvsc_send_pkt(msd_send, net_device, pb, skb);
 
if (m_ret != 0) {
netvsc_free_send_slot(net_device,
  msd_send->send_buf_index);
-   netvsc_xmit_completion(msd_send);
+   dev_kfree_skb_any(skb);
   

[PATCH net-next V2 13/17] hv_netvsc: Eliminate is_data_pkt from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate is_data_pkt from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 -
 drivers/net/hyperv/netvsc.c   |   14 --
 drivers/net/hyperv/netvsc_drv.c   |1 -
 drivers/net/hyperv/rndis_filter.c |1 -
 4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index baa40b1..65e340e 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -131,7 +131,6 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-   u8 is_data_pkt;
u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index d18e10c..11b009e 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -704,12 +704,14 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
   u32 pend_size,
   struct hv_netvsc_packet *packet,
   struct rndis_message *rndis_msg,
-  struct hv_page_buffer **pb)
+  struct hv_page_buffer **pb,
+  struct sk_buff *skb)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
 + pend_size;
int i;
+   bool is_data_pkt = (skb != NULL) ? true : false;
u32 msg_size = 0;
u32 padding = 0;
u32 remain = packet->total_data_buflen % net_device->pkt_align;
@@ -717,7 +719,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
packet->page_buf_cnt;
 
/* Add padding */
-   if (packet->is_data_pkt && packet->xmit_more && remain &&
+   if (is_data_pkt && packet->xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
rndis_msg->msg_len += padding;
@@ -758,7 +760,7 @@ static inline int netvsc_send_pkt(
u32 ring_avail = hv_ringbuf_avail_percent(&out_channel->outbound);
 
nvmsg.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
-   if (packet->is_data_pkt) {
+   if (skb != NULL) {
/* 0 is RMC_DATA; */
nvmsg.msg.v1_msg.send_rndis_pkt.channel_type = 0;
} else {
@@ -868,7 +870,7 @@ int netvsc_send(struct hv_device *device,
if (msdp->pkt)
msd_len = msdp->pkt->total_data_buflen;
 
-   try_batch = packet->is_data_pkt && msd_len > 0 && msdp->count <
+   try_batch = (skb != NULL) && msd_len > 0 && msdp->count <
net_device->max_pkt;
 
if (try_batch && msd_len + pktlen + net_device->pkt_align <
@@ -880,7 +882,7 @@ int netvsc_send(struct hv_device *device,
section_index = msdp->pkt->send_buf_index;
packet->cp_partial = true;
 
-   } else if (packet->is_data_pkt && pktlen + net_device->pkt_align <
+   } else if ((skb != NULL) && pktlen + net_device->pkt_align <
   net_device->send_section_size) {
section_index = netvsc_get_next_send_section(net_device);
if (section_index != NETVSC_INVALID_INDEX) {
@@ -894,7 +896,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet, rndis_msg, pb);
+   packet, rndis_msg, pb, skb);
 
packet->send_buf_index = section_index;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 1532ae4..eb0c6fa 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -477,7 +477,6 @@ check_size:
 
packet->q_idx = skb_get_queue_mapping(skb);
 
-   packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
rndis_msg = (struct rndis_message *)skb->head;
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 53139f7..0b98674 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -215,7 +215,6 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
/* Setup the packet to send it */
packet = &req->pkt;
 
-   packet->is_data_pkt = false;
packet->total_data_buflen = req->request_msg.msg_len;
packet->page_buf_cnt = 1;
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 07/17] hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate send_completion_ctx from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |3 +--
 drivers/net/hyperv/netvsc_drv.c |1 -
 3 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9a3c972..9504ca9 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -146,7 +146,6 @@ struct hv_netvsc_packet {
 
 
u64 send_completion_tid;
-   void *send_completion_ctx;
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 34c16d1..0e0b723 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   netvsc_xmit_completion(nvsc_packet->
-  send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet);
}
 
num_outstanding_sends =
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6d71a1e..947b778 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -489,7 +489,6 @@ check_size:
 
/* Set the completion routine */
packet->completion_func = 1;
-   packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient

2015-11-28 Thread K. Y. Srinivasan
Rearrange the elements of struct hv_negtvsc_packet for optimal layout -
eliminate unnecessary padding.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   18 ++
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 972e562..7435673 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -128,32 +128,34 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-
u8 is_data_pkt;
u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
-   u16 vlan_tci;
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 page_buf_cnt;
+   u8 pad0;
 
+   u16 vlan_tci;
u16 q_idx;
+   u32 send_buf_index;
+
+   u32 total_data_buflen;
+   u32 pad1;
+
struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-   u32 send_buf_index;
 
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u8 rmsg_size; /* RNDIS header and PPI size */
-   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
-
-   u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 06/17] hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet

2015-11-28 Thread K. Y. Srinivasan
Eliminate send_completion from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |3 +--
 drivers/net/hyperv/netvsc.c   |6 +++---
 drivers/net/hyperv/netvsc_drv.c   |2 +-
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 506d552..9a3c972 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -135,7 +135,7 @@ struct hv_netvsc_packet {
u8 rmsg_size; /* RNDIS header and PPI size */
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
-   u8 pad0;
+   u8 completion_func;
 
u16 vlan_tci;
u16 q_idx;
@@ -147,7 +147,6 @@ struct hv_netvsc_packet {
 
u64 send_completion_tid;
void *send_completion_ctx;
-   void (*send_completion)(void *context);
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 8fbf816..34c16d1 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,8 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   nvsc_packet->send_completion(nvsc_packet->
-send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet->
+  send_completion_ctx);
}
 
num_outstanding_sends =
@@ -775,7 +775,7 @@ static inline int netvsc_send_pkt(
nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
packet->total_data_buflen;
 
-   if (packet->send_completion)
+   if (packet->completion_func)
req_id = (ulong)packet;
else
req_id = 0;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c73afb1..6d71a1e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -488,7 +488,7 @@ check_size:
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
-   packet->send_completion = netvsc_xmit_completion;
+   packet->completion_func = 1;
packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index be0fa9c..c8af172 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -237,7 +237,7 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
packet->page_buf[0].len;
}
 
-   packet->send_completion = NULL;
+   packet->completion_func = 0;
packet->xmit_more = false;
 
ret = netvsc_send(dev->net_dev->dev, packet, NULL);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next V2 00/17] hv_netvsc: Eliminate the additional head room

2015-11-28 Thread K. Y. Srinivasan
In an attempt to avoid having to allocate memory on the send path, the netvsc
driver was requesting additional head room so that both rndis header and the
netvsc packet (the state that had to persist) could be placed in the skb.
Since the amount of head room requested was exceeding the default head room
as set in LL_MAX_HEADER, we were forcing a reallocation of skb.

With this patch-set, I have reduced the size of the netvsc packet to less
than 20 bytes and with this reduction we don't need to ask for any additional
headroom. We place the rndis header in the skb head room and we place the
netvsc packet in control buffer area in the skb.

V2:  - Addressed  review comments:
 - Eliminated more fields from netvsc packet structure.

K. Y. Srinivasan (15):
  hv_netvsc: Resize some of the variables in hv_netvsc_packet
  hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient
  hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure
  hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet
structure
  hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet
  hv_netvsc: Don't ask for additional head room in the skb
  hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion_tid from struct hv_netvsc_packet
  hv_netvsc: Eliminate is_data_pkt from struct hv_netvsc_packet
  hv_netvsc: Eliminate completion_func from struct hv_netvsc_packet
  hv_netvsc: Eliminate xmit_more from struct hv_netvsc_packet
  hv_netvsc: Eliminate status from struct hv_netvsc_packet
  hv_netvsc: Eliminate vlan_tci from struct hv_netvsc_packet

Vitaly Kuznetsov (2):
  hv_netvsc: move subchannel existence check to netvsc_select_queue()
  hv_netvsc: remove locking in netvsc_send()

 drivers/net/hyperv/hyperv_net.h   |   48 +++--
 drivers/net/hyperv/netvsc.c   |  102 ++---
 drivers/net/hyperv/netvsc_drv.c   |   93 +-
 drivers/net/hyperv/rndis_filter.c |   66 
 include/linux/netdevice.h |4 +-
 5 files changed, 138 insertions(+), 175 deletions(-)

-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 03/10] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure

2015-11-23 Thread K. Y. Srinivasan
Eliminate the channel field in hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |   22 ++
 drivers/net/hyperv/netvsc.c   |   19 ---
 drivers/net/hyperv/netvsc_drv.c   |5 +++--
 drivers/net/hyperv/rndis_filter.c |   10 ++
 4 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7435673..ac24091 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -144,7 +144,6 @@ struct hv_netvsc_packet {
u32 total_data_buflen;
u32 pad1;
 
-   struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
@@ -199,7 +198,8 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
-   struct ndis_tcp_ip_checksum_info *csum_info);
+   struct ndis_tcp_ip_checksum_info *csum_info,
+   struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
 int rndis_filter_open(struct hv_device *dev);
 int rndis_filter_close(struct hv_device *dev);
@@ -207,12 +207,12 @@ int rndis_filter_device_add(struct hv_device *dev,
void *additional_info);
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
-   struct hv_netvsc_packet *pkt);
+   struct hv_netvsc_packet *pkt,
+   struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
 int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac);
 
-
 #define NVSP_INVALID_PROTOCOL_VERSION  ((u32)0x)
 
 #define NVSP_PROTOCOL_VERSION_12
@@ -1262,5 +1262,19 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
+static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
+   struct netvsc_device *net_device)
+
+{
+   struct vmbus_channel *out_channel;
+
+   out_channel = net_device->chn_table[packet->q_idx];
+   if (!out_channel) {
+   out_channel = net_device->dev->channel;
+   packet->q_idx = 0;
+   }
+   return out_channel;
+}
+
 
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 51e4c0f..52533ed 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -610,6 +610,7 @@ static inline void netvsc_free_send_slot(struct 
netvsc_device *net_device,
 }
 
 static void netvsc_send_completion(struct netvsc_device *net_device,
+  struct vmbus_channel *incoming_channel,
   struct hv_device *device,
   struct vmpacket_descriptor *packet)
 {
@@ -651,7 +652,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
if (send_index != NETVSC_INVALID_INDEX)
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
-   channel = nvsc_packet->channel;
+   channel = incoming_channel;
nvsc_packet->send_completion(nvsc_packet->
 send_completion_ctx);
}
@@ -748,7 +749,7 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = packet->channel;
+   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
struct net_device *ndev = net_device->ndev;
u64 req_id;
@@ -857,13 +858,9 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = net_device->chn_table[q_idx];
-   if (!out_channel) {
-   out_channel = device->channel;
-   q_idx = 0;
-   packet->q_idx = 0;
-   }
-   packet->channel = out_channel;
+   out_channel = get_channel(packet, net_device);
+   q_idx = packet->q_idx;
+
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
 
@@ -1043,7 +1040,6 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
}
 
count = vmxferpage_packet->range_cnt;
-   netvsc_packet->channel = channel;
 
/* Each range represents 1 RNDIS pkt that co

[PATCH net-next 04/10] hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet structure

2015-11-23 Thread K. Y. Srinivasan
Eliminate rndis_msg pointer from hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |8 +++-
 drivers/net/hyperv/netvsc.c   |   10 ++
 drivers/net/hyperv/netvsc_drv.c   |7 +++
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ac24091..7fa4f43 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -149,10 +149,6 @@ struct hv_netvsc_packet {
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-
-   /* This points to the memory after page_buf */
-   struct rndis_message *rndis_msg;
-
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
struct hv_page_buffer *page_buf;
@@ -189,10 +185,12 @@ struct rndis_device {
 
 
 /* Interface */
+struct rndis_message;
 int netvsc_device_add(struct hv_device *device, void *additional_info);
 int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet);
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
struct rndis_message *resp);
 void netvsc_xmit_completion(void *context);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 52533ed..2de9e7f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -706,7 +706,8 @@ static u32 netvsc_get_next_send_section(struct 
netvsc_device *net_device)
 static u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
   unsigned int section_index,
   u32 pend_size,
-  struct hv_netvsc_packet *packet)
+  struct hv_netvsc_packet *packet,
+  struct rndis_message *rndis_msg)
 {
char *start = net_device->send_buf;
char *dest = start + (section_index * net_device->send_section_size)
@@ -722,7 +723,7 @@ static u32 netvsc_copy_to_send_buf(struct netvsc_device 
*net_device,
if (packet->is_data_pkt && packet->xmit_more && remain &&
!packet->cp_partial) {
padding = net_device->pkt_align - remain;
-   packet->rndis_msg->msg_len += padding;
+   rndis_msg->msg_len += padding;
packet->total_data_buflen += padding;
}
 
@@ -841,7 +842,8 @@ static inline int netvsc_send_pkt(
 }
 
 int netvsc_send(struct hv_device *device,
-   struct hv_netvsc_packet *packet)
+   struct hv_netvsc_packet *packet,
+   struct rndis_message *rndis_msg)
 {
struct netvsc_device *net_device;
int ret = 0, m_ret = 0;
@@ -897,7 +899,7 @@ int netvsc_send(struct hv_device *device,
if (section_index != NETVSC_INVALID_INDEX) {
netvsc_copy_to_send_buf(net_device,
section_index, msd_len,
-   packet);
+   packet, rndis_msg);
 
packet->send_buf_index = section_index;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index e5f4eec..77c0849 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -482,10 +482,10 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   packet->rndis_msg = (struct rndis_message *)((unsigned long)packet +
+   rndis_msg = (struct rndis_message *)((unsigned long)packet +
sizeof(struct hv_netvsc_packet));
 
-   memset(packet->rndis_msg, 0, RNDIS_AND_PPI_SIZE);
+   memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
packet->send_completion = netvsc_xmit_completion;
@@ -495,7 +495,6 @@ check_size:
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
/* Add the rndis header */
-   rndis_msg = packet->rndis_msg;
rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
rndis_msg->msg_len = packet->total_data_buflen;
rndis_pkt = &rndis_msg->msg.pkt;
@@ -619,7 +618,7 @@ do_send:
packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
   skb, packet);
 
-   ret = netvsc_send(net_device_ctx->device_ctx, packet);
+   ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg);
 
 drop:
if (ret == 0) {
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c

[PATCH net-next 08/10] hv_netvsc: Don't ask for additional head room in the skb

2015-11-23 Thread K. Y. Srinivasan
The rndis header is 116 bytes big and can be placed in the default
head room that will be available in the skb. Since the netvsc packet
is less than 48 bytes, we can use the skb control buffer
for the netvsc packet. With these changes we don't need to
ask for additional head room.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |3 +++
 drivers/net/hyperv/netvsc_drv.c |   28 +---
 2 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9504ca9..e15dc2c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -124,6 +124,9 @@ struct ndis_tcp_ip_checksum_info;
 /*
  * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
  * within the RNDIS
+ *
+ * The size of this structure is less than 48 bytes and we can now
+ * place this structure in the skb->cb field.
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 947b778..9b6c507 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -432,7 +432,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct 
net_device *net)
u32 net_trans_info;
u32 hash;
u32 skb_length;
-   u32 pkt_sz;
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
 
@@ -460,16 +459,19 @@ check_size:
goto check_size;
}
 
-   pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
-
-   ret = skb_cow_head(skb, pkt_sz);
+   /*
+* Place the rndis header in the skb head room and
+* the skb->cb will be used for hv_netvsc_packet
+* structure.
+*/
+   ret = skb_cow_head(skb, RNDIS_AND_PPI_SIZE);
if (ret) {
netdev_err(net, "unable to alloc hv_netvsc_packet\n");
ret = -ENOMEM;
goto drop;
}
-   /* Use the headroom for building up the packet */
-   packet = (struct hv_netvsc_packet *)skb->head;
+   /* Use the skb control buffer for building up the packet */
+   packet = (struct hv_netvsc_packet *)skb->cb;
 
packet->status = 0;
packet->xmit_more = skb->xmit_more;
@@ -482,8 +484,7 @@ check_size:
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
 
-   rndis_msg = (struct rndis_message *)((unsigned long)packet +
-   sizeof(struct hv_netvsc_packet));
+   rndis_msg = (struct rndis_message *)skb->head;
 
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
@@ -1071,16 +1072,12 @@ static int netvsc_probe(struct hv_device *dev,
struct netvsc_device_info device_info;
struct netvsc_device *nvdev;
int ret;
-   u32 max_needed_headroom;
 
net = alloc_etherdev_mq(sizeof(struct net_device_context),
num_online_cpus());
if (!net)
return -ENOMEM;
 
-   max_needed_headroom = sizeof(struct hv_netvsc_packet) +
- RNDIS_AND_PPI_SIZE;
-
netif_carrier_off(net);
 
net_device_ctx = netdev_priv(net);
@@ -1116,13 +1113,6 @@ static int netvsc_probe(struct hv_device *dev,
net->ethtool_ops = ðtool_ops;
SET_NETDEV_DEV(net, &dev->device);
 
-   /*
-* Request additional head room in the skb.
-* We will use this space to build the rndis
-* heaser and other state we need to maintain.
-*/
-   net->needed_headroom = max_needed_headroom;
-
/* Notify the netvsc driver of the new device */
memset(&device_info, 0, sizeof(device_info));
device_info.ring_size = ring_size;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 06/10] hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet

2015-11-23 Thread K. Y. Srinivasan
Eliminate send_completion from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |3 +--
 drivers/net/hyperv/netvsc.c   |6 +++---
 drivers/net/hyperv/netvsc_drv.c   |2 +-
 drivers/net/hyperv/rndis_filter.c |2 +-
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 506d552..9a3c972 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -135,7 +135,7 @@ struct hv_netvsc_packet {
u8 rmsg_size; /* RNDIS header and PPI size */
u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
u8 page_buf_cnt;
-   u8 pad0;
+   u8 completion_func;
 
u16 vlan_tci;
u16 q_idx;
@@ -147,7 +147,6 @@ struct hv_netvsc_packet {
 
u64 send_completion_tid;
void *send_completion_ctx;
-   void (*send_completion)(void *context);
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 8fbf816..34c16d1 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,8 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   nvsc_packet->send_completion(nvsc_packet->
-send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet->
+  send_completion_ctx);
}
 
num_outstanding_sends =
@@ -775,7 +775,7 @@ static inline int netvsc_send_pkt(
nvmsg.msg.v1_msg.send_rndis_pkt.send_buf_section_size =
packet->total_data_buflen;
 
-   if (packet->send_completion)
+   if (packet->completion_func)
req_id = (ulong)packet;
else
req_id = 0;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c73afb1..6d71a1e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -488,7 +488,7 @@ check_size:
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
 
/* Set the completion routine */
-   packet->send_completion = netvsc_xmit_completion;
+   packet->completion_func = 1;
packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index be0fa9c..c8af172 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -237,7 +237,7 @@ static int rndis_filter_send_request(struct rndis_device 
*dev,
packet->page_buf[0].len;
}
 
-   packet->send_completion = NULL;
+   packet->completion_func = 0;
packet->xmit_more = false;
 
ret = netvsc_send(dev->net_dev->dev, packet, NULL);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 10/10] hv_netvsc: remove locking in netvsc_send()

2015-11-23 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Packet scheduler guarantees there won't be multiple senders for the same
queue and as we use q_idx for multi_send_data the spinlock is redundant.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |8 
 2 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index a9d2bdc5..f5b2145 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -633,7 +633,6 @@ struct nvsp_message {
 #define RNDIS_PKT_ALIGN_DEFAULT 8
 
 struct multi_send_data {
-   spinlock_t lock; /* protect struct multi_send_data */
struct hv_netvsc_packet *pkt; /* netvsc pkt pending */
u32 count; /* counter of batched packets */
 };
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 419b055..081f14f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -38,7 +38,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
 {
struct netvsc_device *net_device;
struct net_device *ndev = hv_get_drvdata(device);
-   int i;
 
net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
if (!net_device)
@@ -58,9 +57,6 @@ static struct netvsc_device *alloc_net_device(struct 
hv_device *device)
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
 
-   for (i = 0; i < num_online_cpus(); i++)
-   spin_lock_init(&net_device->msd[i].lock);
-
hv_set_drvdata(device, net_device);
return net_device;
 }
@@ -850,7 +846,6 @@ int netvsc_send(struct hv_device *device,
u16 q_idx = packet->q_idx;
u32 pktlen = packet->total_data_buflen, msd_len = 0;
unsigned int section_index = NETVSC_INVALID_INDEX;
-   unsigned long flag;
struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
bool try_batch;
@@ -867,7 +862,6 @@ int netvsc_send(struct hv_device *device,
msdp = &net_device->msd[q_idx];
 
/* batch packets in send buffer if possible */
-   spin_lock_irqsave(&msdp->lock, flag);
if (msdp->pkt)
msd_len = msdp->pkt->total_data_buflen;
 
@@ -927,8 +921,6 @@ int netvsc_send(struct hv_device *device,
cur_send = packet;
}
 
-   spin_unlock_irqrestore(&msdp->lock, flag);
-
if (msd_send) {
m_ret = netvsc_send_pkt(msd_send, net_device);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 07/10] hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet

2015-11-23 Thread K. Y. Srinivasan
Eliminate send_completion_ctx from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |3 +--
 drivers/net/hyperv/netvsc_drv.c |1 -
 3 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 9a3c972..9504ca9 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -146,7 +146,6 @@ struct hv_netvsc_packet {
 
 
u64 send_completion_tid;
-   void *send_completion_ctx;
struct hv_page_buffer *page_buf;
 };
 
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 34c16d1..0e0b723 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -653,8 +653,7 @@ static void netvsc_send_completion(struct netvsc_device 
*net_device,
netvsc_free_send_slot(net_device, send_index);
q_idx = nvsc_packet->q_idx;
channel = incoming_channel;
-   netvsc_xmit_completion(nvsc_packet->
-  send_completion_ctx);
+   netvsc_xmit_completion(nvsc_packet);
}
 
num_outstanding_sends =
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 6d71a1e..947b778 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -489,7 +489,6 @@ check_size:
 
/* Set the completion routine */
packet->completion_func = 1;
-   packet->send_completion_ctx = packet;
packet->send_completion_tid = (unsigned long)skb;
 
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 09/10] hv_netvsc: move subchannel existence check to netvsc_select_queue()

2015-11-23 Thread K. Y. Srinivasan
From: Vitaly Kuznetsov 

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h |   15 ---
 drivers/net/hyperv/netvsc.c |5 ++---
 drivers/net/hyperv/netvsc_drv.c |3 +++
 3 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index e15dc2c..a9d2bdc5 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -1260,19 +1260,4 @@ struct rndis_message {
 #define TRANSPORT_INFO_IPV6_TCP ((INFO_IPV6 << 16) | INFO_TCP)
 #define TRANSPORT_INFO_IPV6_UDP ((INFO_IPV6 << 16) | INFO_UDP)
 
-static inline struct vmbus_channel *get_channel(struct hv_netvsc_packet 
*packet,
-   struct netvsc_device *net_device)
-
-{
-   struct vmbus_channel *out_channel;
-
-   out_channel = net_device->chn_table[packet->q_idx];
-   if (!out_channel) {
-   out_channel = net_device->dev->channel;
-   packet->q_idx = 0;
-   }
-   return out_channel;
-}
-
-
 #endif /* _HYPERV_NET_H */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 0e0b723..419b055 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -749,8 +749,8 @@ static inline int netvsc_send_pkt(
struct netvsc_device *net_device)
 {
struct nvsp_message nvmsg;
-   struct vmbus_channel *out_channel = get_channel(packet, net_device);
u16 q_idx = packet->q_idx;
+   struct vmbus_channel *out_channel = net_device->chn_table[q_idx];
struct net_device *ndev = net_device->ndev;
u64 req_id;
int ret;
@@ -859,8 +859,7 @@ int netvsc_send(struct hv_device *device,
if (!net_device)
return -ENODEV;
 
-   out_channel = get_channel(packet, net_device);
-   q_idx = packet->q_idx;
+   out_channel = net_device->chn_table[q_idx];
 
packet->send_buf_index = NETVSC_INVALID_INDEX;
packet->cp_partial = false;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 9b6c507..83b457e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -272,6 +272,9 @@ static u16 netvsc_select_queue(struct net_device *ndev, 
struct sk_buff *skb,
skb_set_hash(skb, hash, PKT_HASH_TYPE_L3);
}
 
+   if (!nvsc_dev->chn_table[q_idx])
+   q_idx = 0;
+
return q_idx;
 }
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 02/10] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient

2015-11-23 Thread K. Y. Srinivasan
Rearrange the elements of struct hv_negtvsc_packet for optimal layout -
eliminate unnecessary padding.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   18 ++
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 972e562..7435673 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -128,32 +128,34 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u8 status;
-
u8 is_data_pkt;
u8 xmit_more; /* from skb */
u8 cp_partial; /* partial copy into send buffer */
 
-   u16 vlan_tci;
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 page_buf_cnt;
+   u8 pad0;
 
+   u16 vlan_tci;
u16 q_idx;
+   u32 send_buf_index;
+
+   u32 total_data_buflen;
+   u32 pad1;
+
struct vmbus_channel *channel;
 
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
 
-   u32 send_buf_index;
 
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u8 rmsg_size; /* RNDIS header and PPI size */
-   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
-
-   u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 01/10] hv_netvsc: Resize some of the variables in hv_netvsc_packet

2015-11-23 Thread K. Y. Srinivasan
As part of reducing the size of the hv_netvsc_packet, resize some of the
variables based on their usage.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h |   14 +++---
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 5fa98f5..972e562 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -127,11 +127,11 @@ struct ndis_tcp_ip_checksum_info;
  */
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
-   u32 status;
+   u8 status;
 
-   bool is_data_pkt;
-   bool xmit_more; /* from skb */
-   bool cp_partial; /* partial copy into send buffer */
+   u8 is_data_pkt;
+   u8 xmit_more; /* from skb */
+   u8 cp_partial; /* partial copy into send buffer */
 
u16 vlan_tci;
 
@@ -147,13 +147,13 @@ struct hv_netvsc_packet {
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
 
-   u32 rmsg_size; /* RNDIS header and PPI size */
-   u32 rmsg_pgcnt; /* page count of RNDIS header and PPI */
+   u8 rmsg_size; /* RNDIS header and PPI size */
+   u8 rmsg_pgcnt; /* page count of RNDIS header and PPI */
 
u32 total_data_buflen;
/* Points to the send/receive buffer where the ethernet frame is */
void *data;
-   u32 page_buf_cnt;
+   u8 page_buf_cnt;
struct hv_page_buffer *page_buf;
 };
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 05/10] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet

2015-11-23 Thread K. Y. Srinivasan
Eliminatte the data field from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Haiyang Zhang 
---
 drivers/net/hyperv/hyperv_net.h   |5 ++---
 drivers/net/hyperv/netvsc.c   |5 +++--
 drivers/net/hyperv/netvsc_drv.c   |3 ++-
 drivers/net/hyperv/rndis_filter.c |   11 +++
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 7fa4f43..506d552 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -148,9 +148,6 @@ struct hv_netvsc_packet {
u64 send_completion_tid;
void *send_completion_ctx;
void (*send_completion)(void *context);
-
-   /* Points to the send/receive buffer where the ethernet frame is */
-   void *data;
struct hv_page_buffer *page_buf;
 };
 
@@ -196,6 +193,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
 void netvsc_xmit_completion(void *context);
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel);
 void netvsc_channel_cb(void *context);
@@ -206,6 +204,7 @@ int rndis_filter_device_add(struct hv_device *dev,
 void rndis_filter_device_remove(struct hv_device *dev);
 int rndis_filter_receive(struct hv_device *dev,
struct hv_netvsc_packet *pkt,
+   void **data,
struct vmbus_channel *channel);
 
 int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 2de9e7f..8fbf816 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1008,6 +1008,7 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
int i;
int count = 0;
struct net_device *ndev;
+   void *data;
 
ndev = net_device->ndev;
 
@@ -1047,13 +1048,13 @@ static void netvsc_receive(struct netvsc_device 
*net_device,
for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
netvsc_packet->status = NVSP_STAT_SUCCESS;
-   netvsc_packet->data = (void *)((unsigned long)net_device->
+   data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
vmxferpage_packet->ranges[i].byte_count;
 
/* Pass it to the upper layer */
-   rndis_filter_receive(device, netvsc_packet, channel);
+   rndis_filter_receive(device, netvsc_packet, &data, channel);
 
if (netvsc_packet->status != NVSP_STAT_SUCCESS)
status = NVSP_STAT_FAIL;
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 77c0849..c73afb1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -685,6 +685,7 @@ void netvsc_linkstatus_callback(struct hv_device 
*device_obj,
  */
 int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
+   void **data,
struct ndis_tcp_ip_checksum_info *csum_info,
struct vmbus_channel *channel)
 {
@@ -713,7 +714,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 * Copy to skb. This copy is needed here since the memory pointed by
 * hv_netvsc_packet cannot be deallocated
 */
-   memcpy(skb_put(skb, packet->total_data_buflen), packet->data,
+   memcpy(skb_put(skb, packet->total_data_buflen), *data,
packet->total_data_buflen);
 
skb->protocol = eth_type_trans(skb, net);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 63584e7..be0fa9c 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -351,6 +351,7 @@ static inline void *rndis_get_ppi(struct rndis_packet 
*rpkt, u32 type)
 static void rndis_filter_receive_data(struct rndis_device *dev,
   struct rndis_message *msg,
   struct hv_netvsc_packet *pkt,
+  void **data,
   struct vmbus_channel *channel)
 {
struct rndis_packet *rndis_pkt;
@@ -383,7 +384,7 @@ static void rndis_filter_receive_data(struct rndis_device 
*dev,
 * the data packet to the stack, without the rndis trailer padding
 */
pkt->total_data_buflen = rndis_pkt->data_len;
-   pkt->data = (void *)((unsigned long)pkt->data +

[PATCH net-next 00/10] hv_netvsc: Eliminate the additional head room

2015-11-23 Thread K. Y. Srinivasan
In an attempt to avoid having to allocate memory on the send path, the netvsc
driver was requesting additional head room so that both rndis header and the
netvsc packet (the state that had to persist) could be placed in the skb.
Since the amount of head room requested was exceeding the default head room
as set in LL_MAX_HEADER, we were forcing a reallocation of skb.

With this patch-set, I have reduced the size of the netvsc packet to
40 bytes and with this reduction we don't need to ask for any additional
headroom. We place the rndis header in the skb head room and we place the
netvsc packet in control buffer area in the skb.

K. Y. Srinivasan (8):
  hv_netvsc: Resize some of the variables in hv_netvsc_packet
  hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient
  hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure
  hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet
structure
  hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet
  hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet
  hv_netvsc: Don't ask for additional head room in the skb

Vitaly Kuznetsov (2):
  hv_netvsc: move subchannel existence check to netvsc_select_queue()
  hv_netvsc: remove locking in netvsc_send()

 drivers/net/hyperv/hyperv_net.h   |   48 +---
 drivers/net/hyperv/netvsc.c   |   42 
 drivers/net/hyperv/netvsc_drv.c   |   47 +++
 drivers/net/hyperv/rndis_filter.c |   21 ++--
 4 files changed, 72 insertions(+), 86 deletions(-)

-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 net-next 1/1] hv_netvsc: Wait for sub-channels to be processed during probe

2015-07-22 Thread K. Y. Srinivasan
The current code returns from probe without waiting for the proper handling
of subchannels that may be requested. If the netvsc driver were to be rapidly
loaded/unloaded, we can  trigger a panic as the unload will be tearing
down state that may not have been fully setup yet. We fix this issue by making
sure that we return from the probe call only after ensuring that the
sub-channel offers in flight are properly handled.

Reviewed-and-tested-by: Haiyang Zhang 
---
V2: Introduce timed wait - Vitaly Kuznetsov 
v2: Fix the sub-channel accounting - Dexuan Cui 

 drivers/net/hyperv/hyperv_net.h   |2 ++
 drivers/net/hyperv/rndis_filter.c |   28 
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 26cd14c..925b75d 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -671,6 +671,8 @@ struct netvsc_device {
u32 send_table[VRSS_SEND_TAB_SIZE];
u32 max_chn;
u32 num_chn;
+   spinlock_t sc_lock; /* Protects num_sc_offered variable */
+   u32 num_sc_offered;
atomic_t queue_sends[NR_CPUS];
 
/* Holds rndis device info */
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 2e40417..9b8263d 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -984,9 +984,16 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
struct netvsc_device *nvscdev;
u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
int ret;
+   unsigned long flags;
 
nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
 
+   spin_lock_irqsave(&nvscdev->sc_lock, flags);
+   nvscdev->num_sc_offered--;
+   spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
+   if (nvscdev->num_sc_offered == 0)
+   complete(&nvscdev->channel_init_wait);
+
if (chn_index >= nvscdev->num_chn)
return;
 
@@ -1015,8 +1022,10 @@ int rndis_filter_device_add(struct hv_device *dev,
u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
u32 mtu, size;
u32 num_rss_qs;
+   u32 sc_delta;
const struct cpumask *node_cpu_mask;
u32 num_possible_rss_qs;
+   unsigned long flags;
 
rndis_device = get_rndis_device();
if (!rndis_device)
@@ -1039,6 +1048,8 @@ int rndis_filter_device_add(struct hv_device *dev,
net_device->max_chn = 1;
net_device->num_chn = 1;
 
+   spin_lock_init(&net_device->sc_lock);
+
net_device->extension = rndis_device;
rndis_device->net_dev = net_device;
 
@@ -1116,6 +1127,9 @@ int rndis_filter_device_add(struct hv_device *dev,
num_possible_rss_qs = cpumask_weight(node_cpu_mask);
net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
 
+   num_rss_qs = net_device->num_chn - 1;
+   net_device->num_sc_offered = num_rss_qs;
+
if (net_device->num_chn == 1)
goto out;
 
@@ -1157,11 +1171,25 @@ int rndis_filter_device_add(struct hv_device *dev,
 
ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
 
+   /*
+* Wait for the host to send us the sub-channel offers.
+*/
+   spin_lock_irqsave(&net_device->sc_lock, flags);
+   sc_delta = num_rss_qs - (net_device->num_chn - 1);
+   net_device->num_sc_offered -= sc_delta;
+   spin_unlock_irqrestore(&net_device->sc_lock, flags);
+
+   while (net_device->num_sc_offered != 0) {
+   t = wait_for_completion_timeout(&net_device->channel_init_wait, 
10*HZ);
+   if (t == 0)
+   WARN(1, "Netvsc: Waiting for sub-channel processing");
+   }
 out:
if (ret) {
net_device->max_chn = 1;
net_device->num_chn = 1;
}
+
return 0; /* return 0 because primary channel can be used alone */
 
 err_dev_remv:
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 1/1] hv_netvsc: Wait for sub-channels to be processed during probe

2015-07-16 Thread K. Y. Srinivasan
The current code returns from probe without waiting for the proper handling
of subchannels that may be requested. If the netvsc driver were to be rapidly
loaded/unloaded, we can  trigger a panic as the unload will be tearing
down state that may not have been fully setup yet. We fix this issue by making
sure that we return from the probe call only after ensuring that the
sub-channel offers in flight are properly handled.

Signed-off-by: K. Y. Srinivasan 
Reviewed-and-tested-by: Haiyang Zhang offermsg.offer.sub_channel_index;
int ret;
+   unsigned long flags;
 
nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
 
+   spin_lock_irqsave(&nvscdev->sc_lock, flags);
+   nvscdev->num_sc_offered--;
+   spin_unlock_irqrestore(&nvscdev->sc_lock, flags);
+   if (nvscdev->num_sc_offered == 0)
+   complete(&nvscdev->channel_init_wait);
+
if (chn_index >= nvscdev->num_chn)
return;
 
@@ -1015,8 +1022,10 @@ int rndis_filter_device_add(struct hv_device *dev,
u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
u32 mtu, size;
u32 num_rss_qs;
+   u32 sc_delta;
const struct cpumask *node_cpu_mask;
u32 num_possible_rss_qs;
+   unsigned long flags;
 
rndis_device = get_rndis_device();
if (!rndis_device)
@@ -1039,6 +1048,8 @@ int rndis_filter_device_add(struct hv_device *dev,
net_device->max_chn = 1;
net_device->num_chn = 1;
 
+   spin_lock_init(&net_device->sc_lock);
+
net_device->extension = rndis_device;
rndis_device->net_dev = net_device;
 
@@ -1116,6 +1127,9 @@ int rndis_filter_device_add(struct hv_device *dev,
num_possible_rss_qs = cpumask_weight(node_cpu_mask);
net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
 
+   num_rss_qs = net_device->num_chn - 1;
+   net_device->num_sc_offered = num_rss_qs;
+
if (net_device->num_chn == 1)
goto out;
 
@@ -1157,11 +1171,22 @@ int rndis_filter_device_add(struct hv_device *dev,
 
ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
 
+   /*
+* Wait for the host to send us the sub-channel offers.
+*/
+   spin_lock_irqsave(&net_device->sc_lock, flags);
+   sc_delta = net_device->num_chn - 1 - num_rss_qs;
+   net_device->num_sc_offered -= sc_delta;
+   spin_unlock_irqrestore(&net_device->sc_lock, flags);
+
+   if (net_device->num_sc_offered != 0)
+   wait_for_completion(&net_device->channel_init_wait);
 out:
if (ret) {
net_device->max_chn = 1;
net_device->num_chn = 1;
}
+
return 0; /* return 0 because primary channel can be used alone */
 
 err_dev_remv:
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 2/2] hv_netvsc: Allocate the sendbuf in a NUMA aware way

2015-05-28 Thread K. Y. Srinivasan
Allocate the send buffer in a NUMA aware way.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/netvsc.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index d187965..06de98a 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -326,7 +326,9 @@ static int netvsc_init_buf(struct hv_device *device)
 
/* Now setup the send buffer.
 */
-   net_device->send_buf = vzalloc(net_device->send_buf_size);
+   net_device->send_buf = vzalloc_node(net_device->send_buf_size, node);
+   if (!net_device->send_buf)
+   net_device->send_buf = vzalloc(net_device->send_buf_size);
if (!net_device->send_buf) {
netdev_err(ndev, "unable to allocate send "
   "buffer of size %d\n", net_device->send_buf_size);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 net-next 1/2] hv_netvsc: Allocate the receive buffer from the correct NUMA node

2015-05-28 Thread K. Y. Srinivasan
Allocate the receive bufer from the NUMA node assigned to the primary
channel.

Signed-off-by: K. Y. Srinivasan 
---
V2: Specify the tree for this patch.

 drivers/net/hyperv/netvsc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index b024968..d187965 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -227,13 +227,18 @@ static int netvsc_init_buf(struct hv_device *device)
struct netvsc_device *net_device;
struct nvsp_message *init_packet;
struct net_device *ndev;
+   int node;
 
net_device = get_outbound_net_device(device);
if (!net_device)
return -ENODEV;
ndev = net_device->ndev;
 
-   net_device->recv_buf = vzalloc(net_device->recv_buf_size);
+   node = cpu_to_node(device->channel->target_cpu);
+   net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node);
+   if (!net_device->recv_buf)
+   net_device->recv_buf = vzalloc(net_device->recv_buf_size);
+
if (!net_device->recv_buf) {
netdev_err(ndev, "unable to allocate receive "
"buffer of size %d\n", net_device->recv_buf_size);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 0/2] hv_netvsc: Implement NUMA aware memory allocation

2015-05-28 Thread K. Y. Srinivasan
Allocate both receive buffer and send buffer from the NUMA node assigned to the
primary channel.

K. Y. Srinivasan (2):
  hv_netvsc: Allocate the receive buffer from the correct NUMA node
  hv_netvsc: Allocate the sendbuf in a NUMA aware way

 drivers/net/hyperv/netvsc.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/1] hv_netvsc: Allocate the receive buffer from the correct NUMA node

2015-05-28 Thread K. Y. Srinivasan
Allocate the receive bufer from the NUMA node assigned to the primary
channel.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/netvsc.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index b024968..d187965 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -227,13 +227,18 @@ static int netvsc_init_buf(struct hv_device *device)
struct netvsc_device *net_device;
struct nvsp_message *init_packet;
struct net_device *ndev;
+   int node;
 
net_device = get_outbound_net_device(device);
if (!net_device)
return -ENODEV;
ndev = net_device->ndev;
 
-   net_device->recv_buf = vzalloc(net_device->recv_buf_size);
+   node = cpu_to_node(device->channel->target_cpu);
+   net_device->recv_buf = vzalloc_node(net_device->recv_buf_size, node);
+   if (!net_device->recv_buf)
+   net_device->recv_buf = vzalloc(net_device->recv_buf_size);
+
if (!net_device->recv_buf) {
netdev_err(ndev, "unable to allocate receive "
"buffer of size %d\n", net_device->recv_buf_size);
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 net-next 1/1] hv_netvsc: Properly size the vrss queues

2015-05-27 Thread K. Y. Srinivasan
The current algorithm for deciding on the number of VRSS channels is
not optimal since we open up the min of number of CPUs online and the
number of VRSS channels the host is offering. So on a 32 VCPU guest
we could potentially open 32 VRSS subchannels. Experimentation has
shown that it is best to limit the number of VRSS channels to the number
of CPUs within a NUMA node.

Here is the new algorithm for deciding on the number of sub-channels we
would open up:
1) Pick the minimum of what the host is offering and what the driver
   in the guest is specifying as the default value.
2) Pick the minimum of (1) and the numbers of CPUs in the NUMA
   node the primary channel is bound to.


Signed-off-by: K. Y. Srinivasan 
---
V2: Got rid of the module parameter (Dave Miller)

 drivers/net/hyperv/hyperv_net.h   |1 +
 drivers/net/hyperv/netvsc_drv.c   |4 
 drivers/net/hyperv/rndis_filter.c |   16 ++--
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ddcc7f8..dd45440 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -161,6 +161,7 @@ struct netvsc_device_info {
unsigned char mac_adr[ETH_ALEN];
bool link_state;/* 0 - link up, 1 - link down */
int  ring_size;
+   u32  max_num_vrss_chns;
 };
 
 enum rndis_device_state {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index d9c88bc..358475e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -46,6 +46,8 @@ static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
 
+static int max_num_vrss_chns = 8;
+
 static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_LINK | NETIF_MSG_IFUP |
NETIF_MSG_IFDOWN | NETIF_MSG_RX_ERR |
@@ -755,6 +757,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int 
mtu)
ndevctx->device_ctx = hdev;
hv_set_drvdata(hdev, ndev);
device_info.ring_size = ring_size;
+   device_info.max_num_vrss_chns = max_num_vrss_chns;
rndis_filter_device_add(hdev, &device_info);
netif_tx_wake_all_queues(ndev);
 
@@ -975,6 +978,7 @@ static int netvsc_probe(struct hv_device *dev,
 
/* Notify the netvsc driver of the new device */
device_info.ring_size = ring_size;
+   device_info.max_num_vrss_chns = max_num_vrss_chns;
ret = rndis_filter_device_add(dev, &device_info);
if (ret != 0) {
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 9118cea..006c1b8 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1013,6 +1013,9 @@ int rndis_filter_device_add(struct hv_device *dev,
struct ndis_recv_scale_cap rsscap;
u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
u32 mtu, size;
+   u32 num_rss_qs;
+   const struct cpumask *node_cpu_mask;
+   u32 num_possible_rss_qs;
 
rndis_device = get_rndis_device();
if (!rndis_device)
@@ -1100,9 +1103,18 @@ int rndis_filter_device_add(struct hv_device *dev,
if (ret || rsscap.num_recv_que < 2)
goto out;
 
+   num_rss_qs = min(device_info->max_num_vrss_chns, rsscap.num_recv_que);
+
net_device->max_chn = rsscap.num_recv_que;
-   net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
-  num_online_cpus() : rsscap.num_recv_que;
+
+   /*
+* We will limit the VRSS channels to the number CPUs in the NUMA node
+* the primary channel is currently bound to.
+*/
+   node_cpu_mask = cpumask_of_node(cpu_to_node(dev->channel->target_cpu));
+   num_possible_rss_qs = cpumask_weight(node_cpu_mask);
+   net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
+
if (net_device->num_chn == 1)
goto out;
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next 1/1] hv_netvsc: Properly size the vrss queues

2015-05-26 Thread K. Y. Srinivasan
The current algorithm for deciding on the number of VRSS channels is
not optimal since we open up the min of number of CPUs online and the
number of VRSS channels the host is offering. So on a 32 VCPU guest
we could potentially open 32 VRSS subchannels. Experimentation has
shown that it is best to limit the number of VRSS channels to the number
of CPUs within a NUMA node. As part of this work introduce a module
parameter to control the number of sub-channels we would open up as well.
Here is the new algorithm for deciding on the number of sub-channels we
would open up:
1) Pick the minimum of what the host is offering and what the driver
   in the guest is specifying via the module parameter.
2) Pick the minimum of (1) and the numbers of CPUs in the NUMA
   node the primary channel is bound to.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/hyperv_net.h   |1 +
 drivers/net/hyperv/netvsc_drv.c   |6 ++
 drivers/net/hyperv/rndis_filter.c |   16 ++--
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index ddcc7f8..dd45440 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -161,6 +161,7 @@ struct netvsc_device_info {
unsigned char mac_adr[ETH_ALEN];
bool link_state;/* 0 - link up, 1 - link down */
int  ring_size;
+   u32  max_num_vrss_chns;
 };
 
 enum rndis_device_state {
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index d9c88bc..feb94e2 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -46,6 +46,10 @@ static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
 
+static int max_num_vrss_chns = 8;
+module_param(max_num_vrss_chns, int, S_IRUGO);
+MODULE_PARM_DESC(num_vrss_chns, "Maximum VRSS channels we would open by 
default");
+
 static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
NETIF_MSG_LINK | NETIF_MSG_IFUP |
NETIF_MSG_IFDOWN | NETIF_MSG_RX_ERR |
@@ -755,6 +759,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int 
mtu)
ndevctx->device_ctx = hdev;
hv_set_drvdata(hdev, ndev);
device_info.ring_size = ring_size;
+   device_info.max_num_vrss_chns = max_num_vrss_chns;
rndis_filter_device_add(hdev, &device_info);
netif_tx_wake_all_queues(ndev);
 
@@ -975,6 +980,7 @@ static int netvsc_probe(struct hv_device *dev,
 
/* Notify the netvsc driver of the new device */
device_info.ring_size = ring_size;
+   device_info.max_num_vrss_chns = max_num_vrss_chns;
ret = rndis_filter_device_add(dev, &device_info);
if (ret != 0) {
netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
index 9118cea..006c1b8 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1013,6 +1013,9 @@ int rndis_filter_device_add(struct hv_device *dev,
struct ndis_recv_scale_cap rsscap;
u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
u32 mtu, size;
+   u32 num_rss_qs;
+   const struct cpumask *node_cpu_mask;
+   u32 num_possible_rss_qs;
 
rndis_device = get_rndis_device();
if (!rndis_device)
@@ -1100,9 +1103,18 @@ int rndis_filter_device_add(struct hv_device *dev,
if (ret || rsscap.num_recv_que < 2)
goto out;
 
+   num_rss_qs = min(device_info->max_num_vrss_chns, rsscap.num_recv_que);
+
net_device->max_chn = rsscap.num_recv_que;
-   net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
-  num_online_cpus() : rsscap.num_recv_que;
+
+   /*
+* We will limit the VRSS channels to the number CPUs in the NUMA node
+* the primary channel is currently bound to.
+*/
+   node_cpu_mask = cpumask_of_node(cpu_to_node(dev->channel->target_cpu));
+   num_possible_rss_qs = cpumask_weight(node_cpu_mask);
+   net_device->num_chn = min(num_possible_rss_qs, num_rss_qs);
+
if (net_device->num_chn == 1)
goto out;
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 net 1/1] hv_netvsc: Fix a bug in netvsc_start_xmit()

2015-04-28 Thread K. Y. Srinivasan
Commit b08cc79155fc26d0d112b1470d1ece5034651a4b eliminated memory
allocation in the packet send path:

"hv_netvsc: Eliminate memory allocation in the packet send path

The network protocol used to communicate with the host is the remote ndis 
(rndis)
protocol. We need to decorate each outgoing packet with a rndis header and
additional rndis state (rndis per-packet state). To manage this state, we
currently allocate memory in the transmit path. Eliminate this allocation by
requesting additional head room in the skb."

This commit introduced a bug since it did not account for the case if the skb
was cloned. Fix this bug.


Signed-off-by: K. Y. Srinivasan 
---
V2: Used skb_cow_head() based on Dave Miller's feedback
V2: Fixed up the commit log based on feedback from Sergei Shtylyov

 drivers/net/hyperv/hyperv_net.h |1 -
 drivers/net/hyperv/netvsc.c |5 -
 drivers/net/hyperv/netvsc_drv.c |   27 +++
 3 files changed, 7 insertions(+), 26 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index a10b316..ae04eb5 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -128,7 +128,6 @@ struct ndis_tcp_ip_checksum_info;
 struct hv_netvsc_packet {
/* Bookkeeping stuff */
u32 status;
-   bool part_of_skb;
 
bool is_data_pkt;
bool xmit_more; /* from skb */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 2e8ad06..6d0ac8f 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -889,11 +889,6 @@ int netvsc_send(struct hv_device *device,
} else {
packet->page_buf_cnt = 0;
packet->total_data_buflen += msd_len;
-   if (!packet->part_of_skb) {
-   skb = (struct sk_buff *)(unsigned long)packet->
-  send_completion_tid;
-   packet->send_completion_tid = 0;
-   }
}
 
if (msdp->pkt)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index a3a9d38..19037a6 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -235,9 +235,6 @@ void netvsc_xmit_completion(void *context)
struct sk_buff *skb = (struct sk_buff *)
(unsigned long)packet->send_completion_tid;
 
-   if (!packet->part_of_skb)
-   kfree(packet);
-
if (skb)
dev_kfree_skb_any(skb);
 }
@@ -389,7 +386,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct 
net_device *net)
u32 net_trans_info;
u32 hash;
u32 skb_length;
-   u32 head_room;
u32 pkt_sz;
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
 
@@ -402,7 +398,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct 
net_device *net)
 
 check_size:
skb_length = skb->len;
-   head_room = skb_headroom(skb);
num_data_pgs = netvsc_get_slots(skb) + 2;
if (num_data_pgs > MAX_PAGE_BUFFER_COUNT && linear) {
net_alert_ratelimited("packet too big: %u pages (%u bytes)\n",
@@ -421,20 +416,14 @@ check_size:
 
pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
 
-   if (head_room < pkt_sz) {
-   packet = kmalloc(pkt_sz, GFP_ATOMIC);
-   if (!packet) {
-   /* out of memory, drop packet */
-   netdev_err(net, "unable to alloc hv_netvsc_packet\n");
-   ret = -ENOMEM;
-   goto drop;
-   }
-   packet->part_of_skb = false;
-   } else {
-   /* Use the headroom for building up the packet */
-   packet = (struct hv_netvsc_packet *)skb->head;
-   packet->part_of_skb = true;
+   ret = skb_cow_head(skb, pkt_sz);
+   if (ret) {
+   netdev_err(net, "unable to alloc hv_netvsc_packet\n");
+   ret = -ENOMEM;
+   goto drop;
}
+   /* Use the headroom for building up the packet */
+   packet = (struct hv_netvsc_packet *)skb->head;
 
packet->status = 0;
packet->xmit_more = skb->xmit_more;
@@ -591,8 +580,6 @@ drop:
net->stats.tx_bytes += skb_length;
net->stats.tx_packets++;
} else {
-   if (packet && !packet->part_of_skb)
-   kfree(packet);
if (ret != -EAGAIN) {
dev_kfree_skb_any(skb);
net->stats.tx_dropped++;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net 1/1] hv_netvsc: Fix a bug in netvsc_start_xmit()

2015-04-27 Thread K. Y. Srinivasan
Commit commit b08cc79155fc26d0d112b1470d1ece5034651a4b eliminated memory
allocation in the packet send path. This commit introduced a bug since it
did not account for the case if the skb was cloned. Fix this bug by
using the pre-reserved head room only if the skb is not cloned.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/net/hyperv/netvsc_drv.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index a3a9d38..7eb0251 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -421,7 +421,7 @@ check_size:
 
pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE;
 
-   if (head_room < pkt_sz) {
+   if (skb->cloned ||  head_room < pkt_sz) {
packet = kmalloc(pkt_sz, GFP_ATOMIC);
if (!packet) {
/* out of memory, drop packet */
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html