|
@@ -841,6 +841,18 @@ static inline int netvsc_send_pkt(
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/* Move packet out of multi send data (msd), and clear msd */
|
|
|
+static inline void move_pkt_msd(struct hv_netvsc_packet **msd_send,
|
|
|
+ struct sk_buff **msd_skb,
|
|
|
+ struct multi_send_data *msdp)
|
|
|
+{
|
|
|
+ *msd_skb = msdp->skb;
|
|
|
+ *msd_send = msdp->pkt;
|
|
|
+ msdp->skb = NULL;
|
|
|
+ msdp->pkt = NULL;
|
|
|
+ msdp->count = 0;
|
|
|
+}
|
|
|
+
|
|
|
int netvsc_send(struct hv_device *device,
|
|
|
struct hv_netvsc_packet *packet,
|
|
|
struct rndis_message *rndis_msg,
|
|
@@ -855,6 +867,7 @@ int netvsc_send(struct hv_device *device,
|
|
|
unsigned int section_index = NETVSC_INVALID_INDEX;
|
|
|
struct multi_send_data *msdp;
|
|
|
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
|
|
|
+ struct sk_buff *msd_skb = NULL;
|
|
|
bool try_batch;
|
|
|
bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
|
|
|
|
|
@@ -897,10 +910,8 @@ int netvsc_send(struct hv_device *device,
|
|
|
net_device->send_section_size) {
|
|
|
section_index = netvsc_get_next_send_section(net_device);
|
|
|
if (section_index != NETVSC_INVALID_INDEX) {
|
|
|
- msd_send = msdp->pkt;
|
|
|
- msdp->pkt = NULL;
|
|
|
- msdp->count = 0;
|
|
|
- msd_len = 0;
|
|
|
+ move_pkt_msd(&msd_send, &msd_skb, msdp);
|
|
|
+ msd_len = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -919,31 +930,31 @@ int netvsc_send(struct hv_device *device,
|
|
|
packet->total_data_buflen += msd_len;
|
|
|
}
|
|
|
|
|
|
- if (msdp->pkt)
|
|
|
- dev_kfree_skb_any(skb);
|
|
|
+ if (msdp->skb)
|
|
|
+ dev_kfree_skb_any(msdp->skb);
|
|
|
|
|
|
if (xmit_more && !packet->cp_partial) {
|
|
|
+ msdp->skb = skb;
|
|
|
msdp->pkt = packet;
|
|
|
msdp->count++;
|
|
|
} else {
|
|
|
cur_send = packet;
|
|
|
+ msdp->skb = NULL;
|
|
|
msdp->pkt = NULL;
|
|
|
msdp->count = 0;
|
|
|
}
|
|
|
} else {
|
|
|
- msd_send = msdp->pkt;
|
|
|
- msdp->pkt = NULL;
|
|
|
- msdp->count = 0;
|
|
|
+ move_pkt_msd(&msd_send, &msd_skb, msdp);
|
|
|
cur_send = packet;
|
|
|
}
|
|
|
|
|
|
if (msd_send) {
|
|
|
- m_ret = netvsc_send_pkt(msd_send, net_device, pb, skb);
|
|
|
+ m_ret = netvsc_send_pkt(msd_send, net_device, NULL, msd_skb);
|
|
|
|
|
|
if (m_ret != 0) {
|
|
|
netvsc_free_send_slot(net_device,
|
|
|
msd_send->send_buf_index);
|
|
|
- dev_kfree_skb_any(skb);
|
|
|
+ dev_kfree_skb_any(msd_skb);
|
|
|
}
|
|
|
}
|
|
|
|