|
@@ -433,7 +433,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
|
|
u32 net_trans_info;
|
|
u32 net_trans_info;
|
|
u32 hash;
|
|
u32 hash;
|
|
u32 skb_length;
|
|
u32 skb_length;
|
|
- u32 pkt_sz;
|
|
|
|
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
|
|
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
|
|
struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
|
|
struct netvsc_stats *tx_stats = this_cpu_ptr(net_device_ctx->tx_stats);
|
|
|
|
|
|
@@ -461,16 +460,21 @@ check_size:
|
|
goto 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) {
|
|
if (ret) {
|
|
netdev_err(net, "unable to alloc hv_netvsc_packet\n");
|
|
netdev_err(net, "unable to alloc hv_netvsc_packet\n");
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
goto drop;
|
|
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->status = 0;
|
|
packet->xmit_more = skb->xmit_more;
|
|
packet->xmit_more = skb->xmit_more;
|
|
@@ -483,8 +487,7 @@ check_size:
|
|
packet->is_data_pkt = true;
|
|
packet->is_data_pkt = true;
|
|
packet->total_data_buflen = skb->len;
|
|
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);
|
|
memset(rndis_msg, 0, RNDIS_AND_PPI_SIZE);
|
|
|
|
|
|
@@ -1118,16 +1121,12 @@ static int netvsc_probe(struct hv_device *dev,
|
|
struct netvsc_device_info device_info;
|
|
struct netvsc_device_info device_info;
|
|
struct netvsc_device *nvdev;
|
|
struct netvsc_device *nvdev;
|
|
int ret;
|
|
int ret;
|
|
- u32 max_needed_headroom;
|
|
|
|
|
|
|
|
net = alloc_etherdev_mq(sizeof(struct net_device_context),
|
|
net = alloc_etherdev_mq(sizeof(struct net_device_context),
|
|
num_online_cpus());
|
|
num_online_cpus());
|
|
if (!net)
|
|
if (!net)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
- max_needed_headroom = sizeof(struct hv_netvsc_packet) +
|
|
|
|
- RNDIS_AND_PPI_SIZE;
|
|
|
|
-
|
|
|
|
netif_carrier_off(net);
|
|
netif_carrier_off(net);
|
|
|
|
|
|
net_device_ctx = netdev_priv(net);
|
|
net_device_ctx = netdev_priv(net);
|
|
@@ -1166,13 +1165,6 @@ static int netvsc_probe(struct hv_device *dev,
|
|
net->ethtool_ops = ðtool_ops;
|
|
net->ethtool_ops = ðtool_ops;
|
|
SET_NETDEV_DEV(net, &dev->device);
|
|
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 */
|
|
/* Notify the netvsc driver of the new device */
|
|
memset(&device_info, 0, sizeof(device_info));
|
|
memset(&device_info, 0, sizeof(device_info));
|
|
device_info.ring_size = ring_size;
|
|
device_info.ring_size = ring_size;
|