diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
| -rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 47 | 
1 files changed, 21 insertions, 26 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index a3a9d3898a6e..5993c7e2d723 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -40,18 +40,21 @@  #include "hyperv_net.h" -struct net_device_context { -	/* point back to our device context */ -	struct hv_device *device_ctx; -	struct delayed_work dwork; -	struct work_struct work; -};  #define RING_SIZE_MIN 64  static int ring_size = 128;  module_param(ring_size, int, S_IRUGO);  MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); +static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | +				NETIF_MSG_LINK | NETIF_MSG_IFUP | +				NETIF_MSG_IFDOWN | NETIF_MSG_RX_ERR | +				NETIF_MSG_TX_ERR; + +static int debug = -1; +module_param(debug, int, S_IRUGO); +MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); +  static void do_set_multicast(struct work_struct *w)  {  	struct net_device_context *ndevctx = @@ -235,9 +238,6 @@ void netvsc_xmit_completion(void *context)  	struct sk_buff *skb = (struct sk_buff *)  		(unsigned long)packet->send_completion_tid; -	if (!packet->part_of_skb) -		kfree(packet); -  	if (skb)  		dev_kfree_skb_any(skb);  } @@ -389,7 +389,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)  	u32 net_trans_info;  	u32 hash;  	u32 skb_length; -	u32 head_room;  	u32 pkt_sz;  	struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT]; @@ -402,7 +401,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)  check_size:  	skb_length = skb->len; -	head_room = skb_headroom(skb);  	num_data_pgs = netvsc_get_slots(skb) + 2;  	if (num_data_pgs > MAX_PAGE_BUFFER_COUNT && linear) {  		net_alert_ratelimited("packet too big: %u pages (%u bytes)\n", @@ -421,20 +419,14 @@ check_size:  	pkt_sz = sizeof(struct hv_netvsc_packet) + RNDIS_AND_PPI_SIZE; -	if (head_room < pkt_sz) { -		packet = kmalloc(pkt_sz, GFP_ATOMIC); -		if (!packet) { -			/* out of memory, drop packet */ -			netdev_err(net, "unable to alloc hv_netvsc_packet\n"); -			ret = -ENOMEM; -			goto drop; -		} -		packet->part_of_skb = false; -	} else { -		/* Use the headroom for building up the packet */ -		packet = (struct hv_netvsc_packet *)skb->head; -		packet->part_of_skb = true; +	ret = skb_cow_head(skb, pkt_sz); +	if (ret) { +		netdev_err(net, "unable to alloc hv_netvsc_packet\n"); +		ret = -ENOMEM; +		goto drop;  	} +	/* Use the headroom for building up the packet */ +	packet = (struct hv_netvsc_packet *)skb->head;  	packet->status = 0;  	packet->xmit_more = skb->xmit_more; @@ -591,8 +583,6 @@ drop:  		net->stats.tx_bytes += skb_length;  		net->stats.tx_packets++;  	} else { -		if (packet && !packet->part_of_skb) -			kfree(packet);  		if (ret != -EAGAIN) {  			dev_kfree_skb_any(skb);  			net->stats.tx_dropped++; @@ -888,6 +878,11 @@ static int netvsc_probe(struct hv_device *dev,  	net_device_ctx = netdev_priv(net);  	net_device_ctx->device_ctx = dev; +	net_device_ctx->msg_enable = netif_msg_init(debug, default_msg); +	if (netif_msg_probe(net_device_ctx)) +		netdev_dbg(net, "netvsc msg_enable: %d\n", +			   net_device_ctx->msg_enable); +  	hv_set_drvdata(dev, net);  	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);  	INIT_WORK(&net_device_ctx->work, do_set_multicast);  |