857 lines · 21.6 KB · C
RawDownload
/* * Network-device interface management. * * Copyright (c) 2004-2005, Keir Fraser * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "common.h" #include <linux/kthread.h>#include <linux/sched/task.h>#include <linux/ethtool.h>#include <linux/rtnetlink.h>#include <linux/if_vlan.h>#include <linux/vmalloc.h> #include <xen/events.h>#include <asm/xen/hypercall.h>#include <xen/balloon.h> /* Number of bytes allowed on the internal guest Rx queue. */#define XENVIF_RX_QUEUE_BYTES (XEN_NETIF_RX_RING_SIZE/2 * PAGE_SIZE) /* This function is used to set SKBFL_ZEROCOPY_ENABLE as well as * increasing the inflight counter. We need to increase the inflight * counter because core driver calls into xenvif_zerocopy_callback * which calls xenvif_skb_zerocopy_complete. */void xenvif_skb_zerocopy_prepare(struct xenvif_queue *queue,				 struct sk_buff *skb){	skb_shinfo(skb)->flags |= SKBFL_ZEROCOPY_ENABLE;	atomic_inc(&queue->inflight_packets);} void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue){	atomic_dec(&queue->inflight_packets); 	/* Wake the dealloc thread _after_ decrementing inflight_packets so	 * that if kthread_stop() has already been called, the dealloc thread	 * does not wait forever with nothing to wake it.	 */	wake_up(&queue->dealloc_wq);} static int xenvif_schedulable(struct xenvif *vif){	return netif_running(vif->dev) &&		test_bit(VIF_STATUS_CONNECTED, &vif->status) &&		!vif->disabled;} static bool xenvif_handle_tx_interrupt(struct xenvif_queue *queue){	bool rc; 	rc = RING_HAS_UNCONSUMED_REQUESTS(&queue->tx);	if (rc)		napi_schedule(&queue->napi);	return rc;} static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id){	struct xenvif_queue *queue = dev_id;	int old; 	old = atomic_fetch_or(NETBK_TX_EOI, &queue->eoi_pending);	WARN(old & NETBK_TX_EOI, "Interrupt while EOI pending\n"); 	if (!xenvif_handle_tx_interrupt(queue)) {		atomic_andnot(NETBK_TX_EOI, &queue->eoi_pending);		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);	} 	return IRQ_HANDLED;} static int xenvif_poll(struct napi_struct *napi, int budget){	struct xenvif_queue *queue =		container_of(napi, struct xenvif_queue, napi);	int work_done; 	/* This vif is rogue, we pretend we've there is nothing to do	 * for this vif to deschedule it from NAPI. But this interface	 * will be turned off in thread context later.	 */	if (unlikely(queue->vif->disabled)) {		napi_complete(napi);		return 0;	} 	work_done = xenvif_tx_action(queue, budget); 	if (work_done < budget) {		napi_complete_done(napi, work_done);		/* If the queue is rate-limited, it shall be		 * rescheduled in the timer callback.		 */		if (likely(!queue->rate_limited))			xenvif_napi_schedule_or_enable_events(queue);	} 	return work_done;} static bool xenvif_handle_rx_interrupt(struct xenvif_queue *queue){	bool rc; 	rc = xenvif_have_rx_work(queue, false);	if (rc)		xenvif_kick_thread(queue);	return rc;} static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id){	struct xenvif_queue *queue = dev_id;	int old; 	old = atomic_fetch_or(NETBK_RX_EOI, &queue->eoi_pending);	WARN(old & NETBK_RX_EOI, "Interrupt while EOI pending\n"); 	if (!xenvif_handle_rx_interrupt(queue)) {		atomic_andnot(NETBK_RX_EOI, &queue->eoi_pending);		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);	} 	return IRQ_HANDLED;} irqreturn_t xenvif_interrupt(int irq, void *dev_id){	struct xenvif_queue *queue = dev_id;	int old;	bool has_rx, has_tx; 	old = atomic_fetch_or(NETBK_COMMON_EOI, &queue->eoi_pending);	WARN(old, "Interrupt while EOI pending\n"); 	has_tx = xenvif_handle_tx_interrupt(queue);	has_rx = xenvif_handle_rx_interrupt(queue); 	if (!has_rx && !has_tx) {		atomic_andnot(NETBK_COMMON_EOI, &queue->eoi_pending);		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);	} 	return IRQ_HANDLED;} static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb,			       struct net_device *sb_dev){	struct xenvif *vif = netdev_priv(dev);	unsigned int size = vif->hash.size;	unsigned int num_queues; 	/* If queues are not set up internally - always return 0	 * as the packet going to be dropped anyway */	num_queues = READ_ONCE(vif->num_queues);	if (num_queues < 1)		return 0; 	if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)		return netdev_pick_tx(dev, skb, NULL) %		       dev->real_num_tx_queues; 	xenvif_set_skb_hash(vif, skb); 	if (size == 0)		return skb_get_hash_raw(skb) % dev->real_num_tx_queues; 	return vif->hash.mapping[vif->hash.mapping_sel]				[skb_get_hash_raw(skb) % size];} static netdev_tx_txenvif_start_xmit(struct sk_buff *skb, struct net_device *dev){	struct xenvif *vif = netdev_priv(dev);	struct xenvif_queue *queue = NULL;	unsigned int num_queues;	u16 index;	struct xenvif_rx_cb *cb; 	BUG_ON(skb->dev != dev); 	/* Drop the packet if queues are not set up.	 * This handler should be called inside an RCU read section	 * so we don't need to enter it here explicitly.	 */	num_queues = READ_ONCE(vif->num_queues);	if (num_queues < 1)		goto drop; 	/* Obtain the queue to be used to transmit this packet */	index = skb_get_queue_mapping(skb);	if (index >= num_queues) {		pr_warn_ratelimited("Invalid queue %hu for packet on interface %s\n",				    index, vif->dev->name);		index %= num_queues;	}	queue = &vif->queues[index]; 	/* Drop the packet if queue is not ready */	if (queue->task == NULL ||	    queue->dealloc_task == NULL ||	    !xenvif_schedulable(vif))		goto drop; 	if (vif->multicast_control && skb->pkt_type == PACKET_MULTICAST) {		struct ethhdr *eth = (struct ethhdr *)skb->data; 		if (!xenvif_mcast_match(vif, eth->h_dest))			goto drop;	} 	cb = XENVIF_RX_CB(skb);	cb->expires = jiffies + vif->drain_timeout; 	/* If there is no hash algorithm configured then make sure there	 * is no hash information in the socket buffer otherwise it	 * would be incorrectly forwarded to the frontend.	 */	if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)		skb_clear_hash(skb); 	/* timestamp packet in software */	skb_tx_timestamp(skb); 	if (!xenvif_rx_queue_tail(queue, skb))		goto drop; 	xenvif_kick_thread(queue); 	return NETDEV_TX_OK;  drop:	vif->dev->stats.tx_dropped++;	dev_kfree_skb_any(skb);	return NETDEV_TX_OK;} static struct net_device_stats *xenvif_get_stats(struct net_device *dev){	struct xenvif *vif = netdev_priv(dev);	struct xenvif_queue *queue = NULL;	unsigned int num_queues;	u64 rx_bytes = 0;	u64 rx_packets = 0;	u64 tx_bytes = 0;	u64 tx_packets = 0;	unsigned int index; 	rcu_read_lock();	num_queues = READ_ONCE(vif->num_queues); 	/* Aggregate tx and rx stats from each queue */	for (index = 0; index < num_queues; ++index) {		queue = &vif->queues[index];		rx_bytes += queue->stats.rx_bytes;		rx_packets += queue->stats.rx_packets;		tx_bytes += queue->stats.tx_bytes;		tx_packets += queue->stats.tx_packets;	} 	rcu_read_unlock(); 	vif->dev->stats.rx_bytes = rx_bytes;	vif->dev->stats.rx_packets = rx_packets;	vif->dev->stats.tx_bytes = tx_bytes;	vif->dev->stats.tx_packets = tx_packets; 	return &vif->dev->stats;} static void xenvif_up(struct xenvif *vif){	struct xenvif_queue *queue = NULL;	unsigned int num_queues = vif->num_queues;	unsigned int queue_index; 	for (queue_index = 0; queue_index < num_queues; ++queue_index) {		queue = &vif->queues[queue_index];		napi_enable(&queue->napi);		enable_irq(queue->tx_irq);		if (queue->tx_irq != queue->rx_irq)			enable_irq(queue->rx_irq);		xenvif_napi_schedule_or_enable_events(queue);	}} static void xenvif_down(struct xenvif *vif){	struct xenvif_queue *queue = NULL;	unsigned int num_queues = vif->num_queues;	unsigned int queue_index; 	for (queue_index = 0; queue_index < num_queues; ++queue_index) {		queue = &vif->queues[queue_index];		disable_irq(queue->tx_irq);		if (queue->tx_irq != queue->rx_irq)			disable_irq(queue->rx_irq);		napi_disable(&queue->napi);		timer_delete_sync(&queue->credit_timeout);	}} static int xenvif_open(struct net_device *dev){	struct xenvif *vif = netdev_priv(dev);	if (test_bit(VIF_STATUS_CONNECTED, &vif->status))		xenvif_up(vif);	netif_tx_start_all_queues(dev);	return 0;} static int xenvif_close(struct net_device *dev){	struct xenvif *vif = netdev_priv(dev);	if (test_bit(VIF_STATUS_CONNECTED, &vif->status))		xenvif_down(vif);	netif_tx_stop_all_queues(dev);	return 0;} static int xenvif_change_mtu(struct net_device *dev, int mtu){	struct xenvif *vif = netdev_priv(dev);	int max = vif->can_sg ? ETH_MAX_MTU - VLAN_ETH_HLEN : ETH_DATA_LEN; 	if (mtu > max)		return -EINVAL;	WRITE_ONCE(dev->mtu, mtu);	return 0;} static netdev_features_t xenvif_fix_features(struct net_device *dev,	netdev_features_t features){	struct xenvif *vif = netdev_priv(dev); 	if (!vif->can_sg)		features &= ~NETIF_F_SG;	if (~(vif->gso_mask) & GSO_BIT(TCPV4))		features &= ~NETIF_F_TSO;	if (~(vif->gso_mask) & GSO_BIT(TCPV6))		features &= ~NETIF_F_TSO6;	if (!vif->ip_csum)		features &= ~NETIF_F_IP_CSUM;	if (!vif->ipv6_csum)		features &= ~NETIF_F_IPV6_CSUM; 	return features;} static const struct xenvif_stat {	char name[ETH_GSTRING_LEN];	u16 offset;} xenvif_stats[] = {	{		"rx_gso_checksum_fixup",		offsetof(struct xenvif_stats, rx_gso_checksum_fixup)	},	/* If (sent != success + fail), there are probably packets never	 * freed up properly!	 */	{		"tx_zerocopy_sent",		offsetof(struct xenvif_stats, tx_zerocopy_sent),	},	{		"tx_zerocopy_success",		offsetof(struct xenvif_stats, tx_zerocopy_success),	},	{		"tx_zerocopy_fail",		offsetof(struct xenvif_stats, tx_zerocopy_fail)	},	/* Number of packets exceeding MAX_SKB_FRAG slots. You should use	 * a guest with the same MAX_SKB_FRAG	 */	{		"tx_frag_overflow",		offsetof(struct xenvif_stats, tx_frag_overflow)	},}; static int xenvif_get_sset_count(struct net_device *dev, int string_set){	switch (string_set) {	case ETH_SS_STATS:		return ARRAY_SIZE(xenvif_stats);	default:		return -EINVAL;	}} static void xenvif_get_ethtool_stats(struct net_device *dev,				     struct ethtool_stats *stats, u64 * data){	struct xenvif *vif = netdev_priv(dev);	unsigned int num_queues;	int i;	unsigned int queue_index; 	rcu_read_lock();	num_queues = READ_ONCE(vif->num_queues); 	for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) {		unsigned long accum = 0;		for (queue_index = 0; queue_index < num_queues; ++queue_index) {			void *vif_stats = &vif->queues[queue_index].stats;			accum += *(unsigned long *)(vif_stats + xenvif_stats[i].offset);		}		data[i] = accum;	} 	rcu_read_unlock();} static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data){	int i; 	switch (stringset) {	case ETH_SS_STATS:		for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++)			memcpy(data + i * ETH_GSTRING_LEN,			       xenvif_stats[i].name, ETH_GSTRING_LEN);		break;	}} static const struct ethtool_ops xenvif_ethtool_ops = {	.get_link	= ethtool_op_get_link,	.get_ts_info 	= ethtool_op_get_ts_info,	.get_sset_count = xenvif_get_sset_count,	.get_ethtool_stats = xenvif_get_ethtool_stats,	.get_strings = xenvif_get_strings,}; static const struct net_device_ops xenvif_netdev_ops = {	.ndo_select_queue = xenvif_select_queue,	.ndo_start_xmit	= xenvif_start_xmit,	.ndo_get_stats	= xenvif_get_stats,	.ndo_open	= xenvif_open,	.ndo_stop	= xenvif_close,	.ndo_change_mtu	= xenvif_change_mtu,	.ndo_fix_features = xenvif_fix_features,	.ndo_set_mac_address = eth_mac_addr,	.ndo_validate_addr   = eth_validate_addr,}; struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,			    unsigned int handle){	static const u8 dummy_addr[ETH_ALEN] = {		0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,	};	int err;	struct net_device *dev;	struct xenvif *vif;	char name[IFNAMSIZ] = {}; 	snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);	/* Allocate a netdev with the max. supported number of queues.	 * When the guest selects the desired number, it will be updated	 * via netif_set_real_num_*_queues().	 */	dev = alloc_netdev_mq(sizeof(struct xenvif), name, NET_NAME_UNKNOWN,			      ether_setup, xenvif_max_queues);	if (dev == NULL) {

Lines 1–500 of 857.