Commit c85e4924 authored by Haiyang Zhang's avatar Haiyang Zhang Committed by David S. Miller

hv_netvsc: Fix book keeping of skb during batching process

Since eliminating send_completion_tid from struct hv_netvsc_packet, we
haven't add proper book keeping for the skb of the batched packet. This
patch fixes this issue and allows the previous skb is properly freed.
Otherwise, a panic may happen.
Thanks to Simon Xiao <sixiao@microsoft.com> for bisecting and analysis.
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 757647e1
...@@ -624,6 +624,7 @@ struct nvsp_message { ...@@ -624,6 +624,7 @@ struct nvsp_message {
#define RNDIS_PKT_ALIGN_DEFAULT 8 #define RNDIS_PKT_ALIGN_DEFAULT 8
struct multi_send_data { struct multi_send_data {
struct sk_buff *skb; /* skb containing the pkt */
struct hv_netvsc_packet *pkt; /* netvsc pkt pending */ struct hv_netvsc_packet *pkt; /* netvsc pkt pending */
u32 count; /* counter of batched packets */ u32 count; /* counter of batched packets */
}; };
......
...@@ -841,6 +841,18 @@ static inline int netvsc_send_pkt( ...@@ -841,6 +841,18 @@ static inline int netvsc_send_pkt(
return ret; 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, int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet, struct hv_netvsc_packet *packet,
struct rndis_message *rndis_msg, struct rndis_message *rndis_msg,
...@@ -855,6 +867,7 @@ int netvsc_send(struct hv_device *device, ...@@ -855,6 +867,7 @@ int netvsc_send(struct hv_device *device,
unsigned int section_index = NETVSC_INVALID_INDEX; unsigned int section_index = NETVSC_INVALID_INDEX;
struct multi_send_data *msdp; struct multi_send_data *msdp;
struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
struct sk_buff *msd_skb = NULL;
bool try_batch; bool try_batch;
bool xmit_more = (skb != NULL) ? skb->xmit_more : false; bool xmit_more = (skb != NULL) ? skb->xmit_more : false;
...@@ -897,9 +910,7 @@ int netvsc_send(struct hv_device *device, ...@@ -897,9 +910,7 @@ int netvsc_send(struct hv_device *device,
net_device->send_section_size) { net_device->send_section_size) {
section_index = netvsc_get_next_send_section(net_device); section_index = netvsc_get_next_send_section(net_device);
if (section_index != NETVSC_INVALID_INDEX) { if (section_index != NETVSC_INVALID_INDEX) {
msd_send = msdp->pkt; move_pkt_msd(&msd_send, &msd_skb, msdp);
msdp->pkt = NULL;
msdp->count = 0;
msd_len = 0; msd_len = 0;
} }
} }
...@@ -919,31 +930,31 @@ int netvsc_send(struct hv_device *device, ...@@ -919,31 +930,31 @@ int netvsc_send(struct hv_device *device,
packet->total_data_buflen += msd_len; packet->total_data_buflen += msd_len;
} }
if (msdp->pkt) if (msdp->skb)
dev_kfree_skb_any(skb); dev_kfree_skb_any(msdp->skb);
if (xmit_more && !packet->cp_partial) { if (xmit_more && !packet->cp_partial) {
msdp->skb = skb;
msdp->pkt = packet; msdp->pkt = packet;
msdp->count++; msdp->count++;
} else { } else {
cur_send = packet; cur_send = packet;
msdp->skb = NULL;
msdp->pkt = NULL; msdp->pkt = NULL;
msdp->count = 0; msdp->count = 0;
} }
} else { } else {
msd_send = msdp->pkt; move_pkt_msd(&msd_send, &msd_skb, msdp);
msdp->pkt = NULL;
msdp->count = 0;
cur_send = packet; cur_send = packet;
} }
if (msd_send) { 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) { if (m_ret != 0) {
netvsc_free_send_slot(net_device, netvsc_free_send_slot(net_device,
msd_send->send_buf_index); msd_send->send_buf_index);
dev_kfree_skb_any(skb); dev_kfree_skb_any(msd_skb);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment