linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next V2 00/17] hv_netvsc: Eliminate the additional head room
@ 2015-11-28 20:20 K. Y. Srinivasan
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
  0 siblings, 1 reply; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: 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


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet
  2015-11-28 20:20 [PATCH net-next V2 00/17] hv_netvsc: Eliminate the additional head room K. Y. Srinivasan
@ 2015-11-28 20:20 ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient K. Y. Srinivasan
                     ` (15 more replies)
  0 siblings, 16 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: 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 <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure K. Y. Srinivasan
                     ` (14 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Rearrange the elements of struct hv_negtvsc_packet for optimal layout -
eliminate unnecessary padding.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 04/17] hv_netvsc: Eliminate rndis_msg pointer from " K. Y. Srinivasan
                     ` (13 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate the channel field in hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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)0xFFFFFFFF)
 
 #define NVSP_PROTOCOL_VERSION_1		2
@@ -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 contains 1 ethernet frame */
 	for (i = 0; i < count; i++) {
@@ -1055,7 +1051,7 @@ static void netvsc_receive(struct netvsc_device *net_device,
 					vmxferpage_packet->ranges[i].byte_count;
 
 		/* Pass it to the upper layer */
-		rndis_filter_receive(device, netvsc_packet);
+		rndis_filter_receive(device, netvsc_packet, channel);
 
 		if (netvsc_packet->status != NVSP_STAT_SUCCESS)
 			status = NVSP_STAT_FAIL;
@@ -1150,6 +1146,7 @@ void netvsc_channel_cb(void *context)
 				switch (desc->type) {
 				case VM_PKT_COMP:
 					netvsc_send_completion(net_device,
+								channel,
 								device, desc);
 					break;
 
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 409b48e..e5f4eec 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -686,7 +686,8 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
  */
 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)
 {
 	struct net_device *net;
 	struct net_device_context *net_device_ctx;
@@ -732,7 +733,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 				       packet->vlan_tci);
 
-	skb_record_rx_queue(skb, packet->channel->
+	skb_record_rx_queue(skb, channel->
 			    offermsg.offer.sub_channel_index);
 
 	u64_stats_update_begin(&rx_stats->syncp);
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 5931a79..1b04d78 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -350,7 +350,8 @@ 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)
+				   struct hv_netvsc_packet *pkt,
+				   struct vmbus_channel *channel)
 {
 	struct rndis_packet *rndis_pkt;
 	u32 data_offset;
@@ -393,11 +394,12 @@ 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, csum_info);
+	netvsc_recv_callback(dev->net_dev->dev, pkt, csum_info, channel);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
-				struct hv_netvsc_packet	*pkt)
+				struct hv_netvsc_packet	*pkt,
+				struct vmbus_channel *channel)
 {
 	struct netvsc_device *net_dev = hv_get_drvdata(dev);
 	struct rndis_device *rndis_dev;
@@ -436,7 +438,7 @@ int rndis_filter_receive(struct hv_device *dev,
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
 		/* data msg */
-		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
+		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt, channel);
 		break;
 
 	case RNDIS_MSG_INIT_C:
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 04/17] hv_netvsc: Eliminate rndis_msg pointer from hv_netvsc_packet structure
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet K. Y. Srinivasan
                     ` (12 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate rndis_msg pointer from hv_netvsc_packet structure.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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
index 1b04d78..63584e7 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -240,7 +240,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
 	packet->send_completion = NULL;
 	packet->xmit_more = false;
 
-	ret = netvsc_send(dev->net_dev->dev, packet);
+	ret = netvsc_send(dev->net_dev->dev, packet, NULL);
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (2 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 04/17] hv_netvsc: Eliminate rndis_msg pointer from " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 06/17] hv_netvsc: Eliminate send_completion " K. Y. Srinivasan
                     ` (11 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminatte the data field from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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 + data_offset);
+	*data = (void *)((unsigned long)(*data) + data_offset);
 
 	vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
 	if (vlan) {
@@ -394,11 +395,12 @@ 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, csum_info, channel);
+	netvsc_recv_callback(dev->net_dev->dev, pkt, data, csum_info, channel);
 }
 
 int rndis_filter_receive(struct hv_device *dev,
 				struct hv_netvsc_packet	*pkt,
+				void **data,
 				struct vmbus_channel *channel)
 {
 	struct netvsc_device *net_dev = hv_get_drvdata(dev);
@@ -430,7 +432,7 @@ int rndis_filter_receive(struct hv_device *dev,
 		goto exit;
 	}
 
-	rndis_msg = pkt->data;
+	rndis_msg = *data;
 
 	if (netif_msg_rx_err(net_dev->nd_ctx))
 		dump_rndis_message(dev, rndis_msg);
@@ -438,7 +440,8 @@ int rndis_filter_receive(struct hv_device *dev,
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
 		/* data msg */
-		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt, channel);
+		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt,
+					  data, channel);
 		break;
 
 	case RNDIS_MSG_INIT_C:
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 06/17] hv_netvsc: Eliminate send_completion from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (3 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 07/17] hv_netvsc: Eliminate send_completion_ctx " K. Y. Srinivasan
                     ` (10 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate send_completion from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 07/17] hv_netvsc: Eliminate send_completion_ctx from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (4 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 06/17] hv_netvsc: Eliminate send_completion " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb K. Y. Srinivasan
                     ` (9 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate send_completion_ctx from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (5 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 07/17] hv_netvsc: Eliminate send_completion_ctx " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-12-01 20:41     ` David Miller
  2015-11-28 20:20   ` [PATCH net-next V2 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue() K. Y. Srinivasan
                     ` (8 subsequent siblings)
  15 siblings, 1 reply; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: 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 <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
	v2: When HYPERV_NET is configured, set LL_MAX_HEADER to 128 - Vitaly Kuznetsov <vkuznets@redhat.com> 
	V2: Add a build time check on the skb control buffer - Florian Westphal <fw@strlen.de>
 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 = &ethtool_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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue()
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (6 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 10/17] hv_netvsc: remove locking in netvsc_send() K. Y. Srinivasan
                     ` (7 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang
  Cc: Vitaly Kuznetsov, K. Y. Srinivasan

From: Vitaly Kuznetsov <vkuznets@redhat.com>

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 10/17] hv_netvsc: remove locking in netvsc_send()
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (7 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue() K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet K. Y. Srinivasan
                     ` (6 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang
  Cc: Vitaly Kuznetsov, K. Y. Srinivasan

From: Vitaly Kuznetsov <vkuznets@redhat.com>

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 <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (8 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 10/17] hv_netvsc: remove locking in netvsc_send() K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 12/17] hv_netvsc: Eliminate send_completion_tid " K. Y. Srinivasan
                     ` (5 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate page_buf from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 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);
 
 	if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
 		netvsc_free_send_slot(net_device, section_index);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index da3a224..1906f2f 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -323,9 +323,10 @@ static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
 }
 
 static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
-			   struct hv_netvsc_packet *packet)
+			   struct hv_netvsc_packet *packet,
+			   struct hv_page_buffer **page_buf)
 {
-	struct hv_page_buffer *pb = packet->page_buf;
+	struct hv_page_buffer *pb = *page_buf;
 	u32 slots_used = 0;
 	char *data = skb->data;
 	int frags = skb_shinfo(skb)->nr_frags;
@@ -436,6 +437,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
 	u32 hash;
 	u32 skb_length;
 	struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
+	struct hv_page_buffer *pb = page_buf;
 	struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
 
 	/* We will atmost need two pages to describe the rndis
@@ -482,7 +484,6 @@ check_size:
 	packet->xmit_more = skb->xmit_more;
 
 	packet->vlan_tci = skb->vlan_tci;
-	packet->page_buf = page_buf;
 
 	packet->q_idx = skb_get_queue_mapping(skb);
 
@@ -621,9 +622,9 @@ do_send:
 	rndis_msg->msg_len += rndis_msg_size;
 	packet->total_data_buflen = rndis_msg->msg_len;
 	packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
-					       skb, packet);
+					       skb, packet, &pb);
 
-	ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg);
+	ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg, &pb);
 
 drop:
 	if (ret == 0) {
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index c8af172..6ff2253 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -210,6 +210,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
 	int ret;
 	struct hv_netvsc_packet *packet;
 	struct hv_page_buffer page_buf[2];
+	struct hv_page_buffer *pb = page_buf;
 
 	/* Setup the packet to send it */
 	packet = &req->pkt;
@@ -217,30 +218,29 @@ static int rndis_filter_send_request(struct rndis_device *dev,
 	packet->is_data_pkt = false;
 	packet->total_data_buflen = req->request_msg.msg_len;
 	packet->page_buf_cnt = 1;
-	packet->page_buf = page_buf;
 
-	packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
+	pb[0].pfn = virt_to_phys(&req->request_msg) >>
 					PAGE_SHIFT;
-	packet->page_buf[0].len = req->request_msg.msg_len;
-	packet->page_buf[0].offset =
+	pb[0].len = req->request_msg.msg_len;
+	pb[0].offset =
 		(unsigned long)&req->request_msg & (PAGE_SIZE - 1);
 
 	/* Add one page_buf when request_msg crossing page boundary */
-	if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
+	if (pb[0].offset + pb[0].len > PAGE_SIZE) {
 		packet->page_buf_cnt++;
-		packet->page_buf[0].len = PAGE_SIZE -
-			packet->page_buf[0].offset;
-		packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
-			+ packet->page_buf[0].len) >> PAGE_SHIFT;
-		packet->page_buf[1].offset = 0;
-		packet->page_buf[1].len = req->request_msg.msg_len -
-			packet->page_buf[0].len;
+		pb[0].len = PAGE_SIZE -
+			pb[0].offset;
+		pb[1].pfn = virt_to_phys((void *)&req->request_msg
+			+ pb[0].len) >> PAGE_SHIFT;
+		pb[1].offset = 0;
+		pb[1].len = req->request_msg.msg_len -
+			pb[0].len;
 	}
 
 	packet->completion_func = 0;
 	packet->xmit_more = false;
 
-	ret = netvsc_send(dev->net_dev->dev, packet, NULL);
+	ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb);
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 12/17] hv_netvsc: Eliminate send_completion_tid from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (9 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 13/17] hv_netvsc: Eliminate is_data_pkt " K. Y. Srinivasan
                     ` (4 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate send_completion_tid from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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);
 		}
 	}
 
 	if (cur_send)
-		ret = netvsc_send_pkt(cur_send, net_device, pb);
+		ret = netvsc_send_pkt(cur_send, net_device, pb, skb);
 
 	if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
 		netvsc_free_send_slot(net_device, section_index);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 1906f2f..1532ae4 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -278,16 +278,6 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
 	return q_idx;
 }
 
-void netvsc_xmit_completion(void *context)
-{
-	struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
-	struct sk_buff *skb = (struct sk_buff *)
-		(unsigned long)packet->send_completion_tid;
-
-	if (skb)
-		dev_kfree_skb_any(skb);
-}
-
 static u32 fill_pg_buf(struct page *page, u32 offset, u32 len,
 			struct hv_page_buffer *pb)
 {
@@ -496,7 +486,6 @@ check_size:
 
 	/* Set the completion routine */
 	packet->completion_func = 1;
-	packet->send_completion_tid = (unsigned long)skb;
 
 	isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
 
@@ -624,7 +613,8 @@ do_send:
 	packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
 					       skb, packet, &pb);
 
-	ret = netvsc_send(net_device_ctx->device_ctx, packet, rndis_msg, &pb);
+	ret = netvsc_send(net_device_ctx->device_ctx, packet,
+			  rndis_msg, &pb, skb);
 
 drop:
 	if (ret == 0) {
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 6ff2253..53139f7 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -240,7 +240,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
 	packet->completion_func = 0;
 	packet->xmit_more = false;
 
-	ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb);
+	ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 13/17] hv_netvsc: Eliminate is_data_pkt from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (10 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 12/17] hv_netvsc: Eliminate send_completion_tid " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 14/17] hv_netvsc: Eliminate completion_func " K. Y. Srinivasan
                     ` (3 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate is_data_pkt from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 14/17] hv_netvsc: Eliminate completion_func from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (11 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 13/17] hv_netvsc: Eliminate is_data_pkt " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 15/17] hv_netvsc: Eliminate xmit_more " K. Y. Srinivasan
                     ` (2 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate completion_func from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 15/17] hv_netvsc: Eliminate xmit_more from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (12 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 14/17] hv_netvsc: Eliminate completion_func " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 16/17] hv_netvsc: Eliminate status " K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 17/17] hv_netvsc: Eliminate vlan_tci " K. Y. Srinivasan
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate xmit_more from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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 = false;
-
 	ret = netvsc_send(dev->net_dev->dev, packet, NULL, &pb, NULL);
 	return ret;
 }
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 16/17] hv_netvsc: Eliminate status from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (13 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 15/17] hv_netvsc: Eliminate xmit_more " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  2015-11-28 20:20   ` [PATCH net-next V2 17/17] hv_netvsc: Eliminate vlan_tci " K. Y. Srinivasan
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate status from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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_filter_receive(struct hv_device *dev,
 	if (!net_dev->extension) {
 		netdev_err(ndev, "got rndis message but no rndis device - "
 			  "dropping this message!\n");
-		ret = -ENODEV;
+		ret = NVSP_STAT_FAIL;
 		goto exit;
 	}
 
@@ -424,7 +425,7 @@ int rndis_filter_receive(struct hv_device *dev,
 	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
 		netdev_err(ndev, "got rndis message but rndis device "
 			   "uninitialized...dropping this message!\n");
-		ret = -ENODEV;
+		ret = NVSP_STAT_FAIL;
 		goto exit;
 	}
 
@@ -436,8 +437,8 @@ int rndis_filter_receive(struct hv_device *dev,
 	switch (rndis_msg->ndis_msg_type) {
 	case RNDIS_MSG_PACKET:
 		/* data msg */
-		rndis_filter_receive_data(rndis_dev, rndis_msg, pkt,
-					  data, channel);
+		ret = rndis_filter_receive_data(rndis_dev, rndis_msg, pkt,
+						data, channel);
 		break;
 
 	case RNDIS_MSG_INIT_C:
@@ -460,9 +461,6 @@ int rndis_filter_receive(struct hv_device *dev,
 	}
 
 exit:
-	if (ret != 0)
-		pkt->status = NVSP_STAT_FAIL;
-
 	return ret;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH net-next V2 17/17] hv_netvsc: Eliminate vlan_tci from struct hv_netvsc_packet
  2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
                     ` (14 preceding siblings ...)
  2015-11-28 20:20   ` [PATCH net-next V2 16/17] hv_netvsc: Eliminate status " K. Y. Srinivasan
@ 2015-11-28 20:20   ` K. Y. Srinivasan
  15 siblings, 0 replies; 20+ messages in thread
From: K. Y. Srinivasan @ 2015-11-28 20:20 UTC (permalink / raw)
  To: davem, netdev, linux-kernel, devel, olaf, apw, jasowang; +Cc: K. Y. Srinivasan

Eliminate vlan_tci from struct hv_netvsc_packet.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
 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


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb
  2015-11-28 20:20   ` [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb K. Y. Srinivasan
@ 2015-12-01 20:41     ` David Miller
  2015-12-01 20:48       ` KY Srinivasan
  0 siblings, 1 reply; 20+ messages in thread
From: David Miller @ 2015-12-01 20:41 UTC (permalink / raw)
  To: kys; +Cc: netdev, linux-kernel, devel, olaf, apw, jasowang

From: "K. Y. Srinivasan" <kys@microsoft.com>
Date: Sat, 28 Nov 2015 12:20:36 -0800

> +#elseif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)

The correct CPP directive is "#elif".

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb
  2015-12-01 20:41     ` David Miller
@ 2015-12-01 20:48       ` KY Srinivasan
  0 siblings, 0 replies; 20+ messages in thread
From: KY Srinivasan @ 2015-12-01 20:48 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-kernel, devel, olaf, apw, jasowang



> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Tuesday, December 1, 2015 12:42 PM
> To: KY Srinivasan <kys@microsoft.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; olaf@aepfle.de; apw@canonical.com;
> jasowang@redhat.com
> Subject: Re: [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional
> head room in the skb
> 
> From: "K. Y. Srinivasan" <kys@microsoft.com>
> Date: Sat, 28 Nov 2015 12:20:36 -0800
> 
> > +#elseif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
> 
> The correct CPP directive is "#elif".

Thanks David, I will fix the typo and resubmit.

K. Y

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-12-01 20:48 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-28 20:20 [PATCH net-next V2 00/17] hv_netvsc: Eliminate the additional head room K. Y. Srinivasan
2015-11-28 20:20 ` [PATCH net-next V2 01/17] hv_netvsc: Resize some of the variables in hv_netvsc_packet K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 02/17] hv_netvsc: Rearrange the hv_negtvsc_packet to be space efficient K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 03/17] hv_netvsc: Eliminate the channel field in hv_netvsc_packet structure K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 04/17] hv_netvsc: Eliminate rndis_msg pointer from " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 05/17] hv_netvsc: Eliminatte the data field from struct hv_netvsc_packet K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 06/17] hv_netvsc: Eliminate send_completion " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 07/17] hv_netvsc: Eliminate send_completion_ctx " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 08/17] hv_netvsc: Don't ask for additional head room in the skb K. Y. Srinivasan
2015-12-01 20:41     ` David Miller
2015-12-01 20:48       ` KY Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 09/17] hv_netvsc: move subchannel existence check to netvsc_select_queue() K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 10/17] hv_netvsc: remove locking in netvsc_send() K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 11/17] hv_netvsc: Eliminate page_buf from struct hv_netvsc_packet K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 12/17] hv_netvsc: Eliminate send_completion_tid " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 13/17] hv_netvsc: Eliminate is_data_pkt " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 14/17] hv_netvsc: Eliminate completion_func " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 15/17] hv_netvsc: Eliminate xmit_more " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 16/17] hv_netvsc: Eliminate status " K. Y. Srinivasan
2015-11-28 20:20   ` [PATCH net-next V2 17/17] hv_netvsc: Eliminate vlan_tci " K. Y. Srinivasan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).