summaryrefslogtreecommitdiff
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
authorPaul Durrant <Paul.Durrant@citrix.com>2016-05-13 11:37:27 +0300
committerDavid S. Miller <davem@davemloft.net>2016-05-16 20:35:56 +0300
commit40d8abdee806d496a60ee607a6d01b1cd7fabaf0 (patch)
tree7a4bd1027e08d3a2a37a678ab7f3c58cc14b0be5 /drivers/net/xen-netback/interface.c
parent4e15ee2cb46fed730fe6f0195a86d44e5aeef129 (diff)
downloadlinux-40d8abdee806d496a60ee607a6d01b1cd7fabaf0.tar.xz
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.c24
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;