diff options
| author | Paul Durrant <Paul.Durrant@citrix.com> | 2016-05-13 09:37:27 +0100 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-05-16 13:35:56 -0400 | 
| commit | 40d8abdee806d496a60ee607a6d01b1cd7fabaf0 (patch) | |
| tree | 7a4bd1027e08d3a2a37a678ab7f3c58cc14b0be5 /drivers/net/xen-netback/interface.c | |
| parent | 4e15ee2cb46fed730fe6f0195a86d44e5aeef129 (diff) | |
| download | blackbird-op-linux-40d8abdee806d496a60ee607a6d01b1cd7fabaf0.tar.gz blackbird-op-linux-40d8abdee806d496a60ee607a6d01b1cd7fabaf0.zip | |
xen-netback: add control protocol implementation
My recent patch to include/xen/interface/io/netif.h defines a new shared
ring (in addition to the rx and tx rings) for passing control messages
from a VM frontend driver to a backend driver.
A previous patch added the necessary boilerplate for mapping the control
ring from the frontend, should it be created. This patch adds
implementations for each of the defined protocol messages.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 24 | 
1 files changed, 24 insertions, 0 deletions
| diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 78a10d2af101..5a39cdbc217c 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -151,6 +151,24 @@ void xenvif_wake_queue(struct xenvif_queue *queue)  	netif_tx_wake_queue(netdev_get_tx_queue(dev, id));  } +static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, +			       void *accel_priv, +			       select_queue_fallback_t fallback) +{ +	struct xenvif *vif = netdev_priv(dev); +	unsigned int size = vif->hash.size; + +	if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) +		return fallback(dev, skb) % 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[skb_get_hash_raw(skb) % size]; +} +  static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)  {  	struct xenvif *vif = netdev_priv(dev); @@ -395,6 +413,7 @@ static const struct ethtool_ops xenvif_ethtool_ops = {  };  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, @@ -563,6 +582,8 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,  	vif->ctrl_irq = err; +	xenvif_init_hash(vif); +  	task = kthread_create(xenvif_ctrl_kthread, (void *)vif,  			      "%s-control", dev->name);  	if (IS_ERR(task)) { @@ -579,6 +600,7 @@ int xenvif_connect_ctrl(struct xenvif *vif, grant_ref_t ring_ref,  	return 0;  err_deinit: +	xenvif_deinit_hash(vif);  	unbind_from_irqhandler(vif->ctrl_irq, vif);  	vif->ctrl_irq = 0; @@ -749,6 +771,8 @@ void xenvif_disconnect_ctrl(struct xenvif *vif)  		vif->ctrl_task = NULL;  	} +	xenvif_deinit_hash(vif); +  	if (vif->ctrl_irq) {  		unbind_from_irqhandler(vif->ctrl_irq, vif);  		vif->ctrl_irq = 0; | 

