diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
| -rw-r--r-- | drivers/net/xen-netfront.c | 34 | 
1 files changed, 22 insertions, 12 deletions
| diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 922ce0abf5cf..73f596a90c69 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -87,6 +87,7 @@ struct netfront_cb {  /* IRQ name is queue name with "-tx" or "-rx" appended */  #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) +static DECLARE_WAIT_QUEUE_HEAD(module_load_q);  static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);  struct netfront_stats { @@ -545,7 +546,8 @@ static int xennet_count_skb_slots(struct sk_buff *skb)  }  static u16 xennet_select_queue(struct net_device *dev, struct sk_buff *skb, -			       void *accel_priv, select_queue_fallback_t fallback) +			       struct net_device *sb_dev, +			       select_queue_fallback_t fallback)  {  	unsigned int num_queues = dev->real_num_tx_queues;  	u32 hash; @@ -893,7 +895,6 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,  				  struct sk_buff *skb,  				  struct sk_buff_head *list)  { -	struct skb_shared_info *shinfo = skb_shinfo(skb);  	RING_IDX cons = queue->rx.rsp_cons;  	struct sk_buff *nskb; @@ -902,15 +903,16 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,  			RING_GET_RESPONSE(&queue->rx, ++cons);  		skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; -		if (shinfo->nr_frags == MAX_SKB_FRAGS) { +		if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {  			unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;  			BUG_ON(pull_to <= skb_headlen(skb));  			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));  		} -		BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS); +		BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS); -		skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag), +		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, +				skb_frag_page(nfrag),  				rx->offset, rx->status, PAGE_SIZE);  		skb_shinfo(nskb)->nr_frags = 0; @@ -1330,6 +1332,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)  	netif_carrier_off(netdev);  	xenbus_switch_state(dev, XenbusStateInitialising); +	wait_event(module_load_q, +			   xenbus_read_driver_state(dev->otherend) != +			   XenbusStateClosed && +			   xenbus_read_driver_state(dev->otherend) != +			   XenbusStateUnknown);  	return netdev;   exit: @@ -1597,14 +1604,16 @@ static int xennet_init_queue(struct netfront_queue *queue)  {  	unsigned short i;  	int err = 0; +	char *devid;  	spin_lock_init(&queue->tx_lock);  	spin_lock_init(&queue->rx_lock);  	timer_setup(&queue->rx_refill_timer, rx_refill_timeout, 0); -	snprintf(queue->name, sizeof(queue->name), "%s-q%u", -		 queue->info->netdev->name, queue->id); +	devid = strrchr(queue->info->xbdev->nodename, '/') + 1; +	snprintf(queue->name, sizeof(queue->name), "vif%s-q%u", +		 devid, queue->id);  	/* Initialise tx_skbs as a free chain containing every entry. */  	queue->tx_skb_freelist = 0; @@ -1810,7 +1819,7 @@ static int talk_to_netback(struct xenbus_device *dev,  	err = xen_net_read_mac(dev, info->netdev->dev_addr);  	if (err) {  		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); -		goto out; +		goto out_unlocked;  	}  	rtnl_lock(); @@ -1925,6 +1934,7 @@ abort_transaction_no_dev_fatal:  	xennet_destroy_queues(info);   out:  	rtnl_unlock(); +out_unlocked:  	device_unregister(&dev->dev);  	return err;  } @@ -1950,10 +1960,6 @@ static int xennet_connect(struct net_device *dev)  	/* talk_to_netback() sets the correct number of queues */  	num_queues = dev->real_num_tx_queues; -	rtnl_lock(); -	netdev_update_features(dev); -	rtnl_unlock(); -  	if (dev->reg_state == NETREG_UNINITIALIZED) {  		err = register_netdev(dev);  		if (err) { @@ -1963,6 +1969,10 @@ static int xennet_connect(struct net_device *dev)  		}  	} +	rtnl_lock(); +	netdev_update_features(dev); +	rtnl_unlock(); +  	/*  	 * All public and private state should now be sane.  Get  	 * ready to start sending and receiving packets and give the driver |