diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
| -rw-r--r-- | drivers/net/virtio_net.c | 74 | 
1 files changed, 37 insertions, 37 deletions
| diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 8a58a2f013af..271d38c1d9f8 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -63,7 +63,7 @@ static const unsigned long guest_offloads[] = {  	VIRTIO_NET_F_GUEST_CSUM  }; -#define GUEST_OFFLOAD_LRO_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ +#define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \  				(1ULL << VIRTIO_NET_F_GUEST_TSO6) | \  				(1ULL << VIRTIO_NET_F_GUEST_ECN)  | \  				(1ULL << VIRTIO_NET_F_GUEST_UFO)) @@ -380,7 +380,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,  				   struct page *page, unsigned int offset,  				   unsigned int len, unsigned int truesize,  				   bool hdr_valid, unsigned int metasize, -				   bool whole_page) +				   unsigned int headroom)  {  	struct sk_buff *skb;  	struct virtio_net_hdr_mrg_rxbuf *hdr; @@ -398,28 +398,16 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,  	else  		hdr_padded_len = sizeof(struct padded_vnet_hdr); -	/* If whole_page, there is an offset between the beginning of the +	/* If headroom is not 0, there is an offset between the beginning of the  	 * data and the allocated space, otherwise the data and the allocated  	 * space are aligned.  	 *  	 * Buffers with headroom use PAGE_SIZE as alloc size, see  	 * add_recvbuf_mergeable() + get_mergeable_buf_len()  	 */ -	if (whole_page) { -		/* Buffers with whole_page use PAGE_SIZE as alloc size, -		 * see add_recvbuf_mergeable() + get_mergeable_buf_len() -		 */ -		truesize = PAGE_SIZE; - -		/* page maybe head page, so we should get the buf by p, not the -		 * page -		 */ -		tailroom = truesize - len - offset_in_page(p); -		buf = (char *)((unsigned long)p & PAGE_MASK); -	} else { -		tailroom = truesize - len; -		buf = p; -	} +	truesize = headroom ? PAGE_SIZE : truesize; +	tailroom = truesize - len - headroom; +	buf = p - headroom;  	len -= hdr_len;  	offset += hdr_padded_len; @@ -540,19 +528,20 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,   * functions to perfectly solve these three problems at the same time.   */  #define virtnet_xdp_get_sq(vi) ({                                       \ +	int cpu = smp_processor_id();                                   \  	struct netdev_queue *txq;                                       \  	typeof(vi) v = (vi);                                            \  	unsigned int qp;                                                \  									\  	if (v->curr_queue_pairs > nr_cpu_ids) {                         \  		qp = v->curr_queue_pairs - v->xdp_queue_pairs;          \ -		qp += smp_processor_id();                               \ +		qp += cpu;                                              \  		txq = netdev_get_tx_queue(v->dev, qp);                  \  		__netif_tx_acquire(txq);                                \  	} else {                                                        \ -		qp = smp_processor_id() % v->curr_queue_pairs;          \ +		qp = cpu % v->curr_queue_pairs;                         \  		txq = netdev_get_tx_queue(v->dev, qp);                  \ -		__netif_tx_lock(txq, raw_smp_processor_id());           \ +		__netif_tx_lock(txq, cpu);                              \  	}                                                               \  	v->sq + qp;                                                     \  }) @@ -978,7 +967,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,  				put_page(page);  				head_skb = page_to_skb(vi, rq, xdp_page, offset,  						       len, PAGE_SIZE, false, -						       metasize, true); +						       metasize, +						       VIRTIO_XDP_HEADROOM);  				return head_skb;  			}  			break; @@ -1029,7 +1019,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,  	rcu_read_unlock();  	head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog, -			       metasize, !!headroom); +			       metasize, headroom);  	curr_skb = head_skb;  	if (unlikely(!curr_skb)) @@ -1771,6 +1761,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,  {  	struct scatterlist *sgs[4], hdr, stat;  	unsigned out_num = 0, tmp; +	int ret;  	/* Caller should know better */  	BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)); @@ -1790,7 +1781,12 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,  	sgs[out_num] = &stat;  	BUG_ON(out_num + 1 > ARRAY_SIZE(sgs)); -	virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC); +	ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC); +	if (ret < 0) { +		dev_warn(&vi->vdev->dev, +			 "Failed to add sgs for command vq: %d\n.", ret); +		return false; +	}  	if (unlikely(!virtqueue_kick(vi->cvq)))  		return vi->ctrl->status == VIRTIO_NET_OK; @@ -2202,14 +2198,14 @@ static int virtnet_set_channels(struct net_device *dev,  	if (vi->rq[0].xdp_prog)  		return -EINVAL; -	get_online_cpus(); +	cpus_read_lock();  	err = _virtnet_set_queues(vi, queue_pairs);  	if (err) { -		put_online_cpus(); +		cpus_read_unlock();  		goto err;  	}  	virtnet_set_affinity(vi); -	put_online_cpus(); +	cpus_read_unlock();  	netif_set_real_num_tx_queues(dev, queue_pairs);  	netif_set_real_num_rx_queues(dev, queue_pairs); @@ -2325,7 +2321,9 @@ static int virtnet_get_link_ksettings(struct net_device *dev,  }  static int virtnet_set_coalesce(struct net_device *dev, -				struct ethtool_coalesce *ec) +				struct ethtool_coalesce *ec, +				struct kernel_ethtool_coalesce *kernel_coal, +				struct netlink_ext_ack *extack)  {  	struct virtnet_info *vi = netdev_priv(dev);  	int i, napi_weight; @@ -2346,7 +2344,9 @@ static int virtnet_set_coalesce(struct net_device *dev,  }  static int virtnet_get_coalesce(struct net_device *dev, -				struct ethtool_coalesce *ec) +				struct ethtool_coalesce *ec, +				struct kernel_ethtool_coalesce *kernel_coal, +				struct netlink_ext_ack *extack)  {  	struct ethtool_coalesce ec_default = {  		.cmd = ETHTOOL_GCOALESCE, @@ -2509,7 +2509,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,  	        virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||  		virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { -		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); +		NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");  		return -EOPNOTSUPP;  	} @@ -2640,15 +2640,15 @@ static int virtnet_set_features(struct net_device *dev,  	u64 offloads;  	int err; -	if ((dev->features ^ features) & NETIF_F_LRO) { +	if ((dev->features ^ features) & NETIF_F_GRO_HW) {  		if (vi->xdp_enabled)  			return -EBUSY; -		if (features & NETIF_F_LRO) +		if (features & NETIF_F_GRO_HW)  			offloads = vi->guest_offloads_capable;  		else  			offloads = vi->guest_offloads_capable & -				   ~GUEST_OFFLOAD_LRO_MASK; +				   ~GUEST_OFFLOAD_GRO_HW_MASK;  		err = virtnet_set_guest_offloads(vi, offloads);  		if (err) @@ -2964,9 +2964,9 @@ static int init_vqs(struct virtnet_info *vi)  	if (ret)  		goto err_free; -	get_online_cpus(); +	cpus_read_lock();  	virtnet_set_affinity(vi); -	put_online_cpus(); +	cpus_read_unlock();  	return 0; @@ -3128,9 +3128,9 @@ static int virtnet_probe(struct virtio_device *vdev)  		dev->features |= NETIF_F_RXCSUM;  	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||  	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) -		dev->features |= NETIF_F_LRO; +		dev->features |= NETIF_F_GRO_HW;  	if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) -		dev->hw_features |= NETIF_F_LRO; +		dev->hw_features |= NETIF_F_GRO_HW;  	dev->vlan_features = dev->features; |