[ovs-dev] [PATCH v2 6/7] netdev-dummy: Add multiqueue support to dummy-pmd.
Ilya Maximets
i.maximets at samsung.com
Fri May 27 13:32:53 UTC 2016
All previous multi-open logic preserved for rx queues.
Also, added new optional parameter '--qid' for 'netdev-dummy/receive'
in order to allow user to choose id of rx queue to which packet will
be sent.
Ex.:
ovs-appctl netdev-dummy/receive p1 --qid 3 'in_port(1) ...'
Signed-off-by: Ilya Maximets <i.maximets at samsung.com>
---
lib/netdev-dummy.c | 127 +++++++++++++++++++++++++++++++++++++++++---------
tests/ofproto-dpif.at | 6 +--
2 files changed, 109 insertions(+), 24 deletions(-)
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index f0d5626..216956a 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -118,6 +118,12 @@ struct netdev_dummy {
struct in_addr address, netmask;
struct in6_addr ipv6, ipv6_mask;
struct ovs_list rxes OVS_GUARDED; /* List of child "netdev_rxq_dummy"s. */
+
+ /* The following properties are for dummy-pmd and they cannot be changed
+ * when a device is running, so we remember the request and update them
+ * next time netdev_dummy_reconfigure() is called. */
+ int requested_n_txq;
+ int requested_n_rxq;
};
/* Max 'recv_queue_len' in struct netdev_dummy. */
@@ -133,7 +139,8 @@ struct netdev_rxq_dummy {
static unixctl_cb_func netdev_dummy_set_admin_state;
static int netdev_dummy_construct(struct netdev *);
-static void netdev_dummy_queue_packet(struct netdev_dummy *, struct dp_packet *);
+static void netdev_dummy_queue_packet(struct netdev_dummy *,
+ struct dp_packet *, int);
static void dummy_packet_stream_close(struct dummy_packet_stream *);
@@ -260,7 +267,7 @@ dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
if (retval == n && dp_packet_size(&s->rxbuf) > 2) {
dp_packet_pull(&s->rxbuf, 2);
netdev_dummy_queue_packet(dev,
- dp_packet_clone(&s->rxbuf));
+ dp_packet_clone(&s->rxbuf), 0);
dp_packet_clear(&s->rxbuf);
}
} else if (retval != -EAGAIN) {
@@ -661,6 +668,8 @@ netdev_dummy_construct(struct netdev *netdev_)
netdev->mtu = 1500;
netdev->flags = 0;
netdev->ifindex = -EOPNOTSUPP;
+ netdev->requested_n_rxq = netdev_->n_rxq;
+ netdev->requested_n_txq = netdev_->n_txq;
dummy_packet_conn_init(&netdev->conn);
@@ -700,9 +709,9 @@ netdev_dummy_dealloc(struct netdev *netdev_)
}
static int
-netdev_dummy_get_config(const struct netdev *netdev_, struct smap *args)
+netdev_dummy_get_config(const struct netdev *dev, struct smap *args)
{
- struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+ struct netdev_dummy *netdev = netdev_dummy_cast(dev);
ovs_mutex_lock(&netdev->mutex);
@@ -712,6 +721,16 @@ netdev_dummy_get_config(const struct netdev *netdev_, struct smap *args)
dummy_packet_conn_get_config(&netdev->conn, args);
+ /* 'dummy-pmd' specific config. */
+ if (!dev->netdev_class->is_pmd) {
+ goto exit;
+ }
+ smap_add_format(args, "requested_rx_queues", "%d", netdev->requested_n_rxq);
+ smap_add_format(args, "configured_rx_queues", "%d", dev->n_rxq);
+ smap_add_format(args, "requested_tx_queues", "%d", netdev->requested_n_txq);
+ smap_add_format(args, "configured_tx_queues", "%d", dev->n_txq);
+
+exit:
ovs_mutex_unlock(&netdev->mutex);
return 0;
}
@@ -798,6 +817,7 @@ netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
{
struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
const char *pcap;
+ int new_n_rxq;
ovs_mutex_lock(&netdev->mutex);
netdev->ifindex = smap_get_int(args, "ifindex", -EOPNOTSUPP);
@@ -826,8 +846,21 @@ netdev_dummy_set_config(struct netdev *netdev_, const struct smap *args)
}
}
- ovs_mutex_unlock(&netdev->mutex);
+ netdev_change_seq_changed(netdev_);
+
+ /* 'dummy-pmd' specific config. */
+ if (!netdev_->netdev_class->is_pmd) {
+ goto exit;
+ }
+
+ new_n_rxq = MAX(smap_get_int(args, "n_rxq", netdev->requested_n_rxq), 1);
+ if (new_n_rxq != netdev->requested_n_rxq) {
+ netdev->requested_n_rxq = new_n_rxq;
+ netdev_request_reconfigure(netdev_);
+ }
+exit:
+ ovs_mutex_unlock(&netdev->mutex);
return 0;
}
@@ -837,6 +870,41 @@ netdev_dummy_get_numa_id(const struct netdev *netdev_ OVS_UNUSED)
return 0;
}
+/* Requests the number of tx queues for the dummy PMD interface. */
+static int
+netdev_dummy_set_tx_multiq(struct netdev *netdev_, unsigned int n_txq)
+{
+ struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
+
+ if (netdev_->n_txq == n_txq) {
+ goto out;
+ }
+
+ netdev->requested_n_txq = n_txq;
+ netdev_request_reconfigure(netdev_);
+
+out:
+ ovs_mutex_unlock(&netdev->mutex);
+ return 0;
+}
+
+/* Sets the number of tx queues and rx queues for the dummy PMD interface. */
+static int
+netdev_dummy_reconfigure(struct netdev *netdev_)
+{
+ struct netdev_dummy *netdev = netdev_dummy_cast(netdev_);
+
+ ovs_mutex_lock(&netdev->mutex);
+
+ netdev_->n_txq = netdev->requested_n_txq;
+ netdev_->n_rxq = netdev->requested_n_rxq;
+
+ ovs_mutex_unlock(&netdev->mutex);
+ return 0;
+}
+
static struct netdev_rxq *
netdev_dummy_rxq_alloc(void)
{
@@ -1000,7 +1068,7 @@ netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED,
struct dp_packet *reply = dp_packet_new(0);
compose_arp(reply, ARP_OP_REPLY, dev->hwaddr, flow.dl_src,
false, flow.nw_dst, flow.nw_src);
- netdev_dummy_queue_packet(dev, reply);
+ netdev_dummy_queue_packet(dev, reply, 0);
}
}
@@ -1227,7 +1295,7 @@ netdev_dummy_update_flags(struct netdev *netdev_,
/* Helper functions. */
-#define NETDEV_DUMMY_CLASS(NAME, PMD) \
+#define NETDEV_DUMMY_CLASS(NAME, PMD, TX_MULTIQ, RECOFIGURE) \
{ \
NAME, \
PMD, /* is_pmd */ \
@@ -1246,7 +1314,7 @@ netdev_dummy_update_flags(struct netdev *netdev_,
NULL, /* push header */ \
NULL, /* pop header */ \
netdev_dummy_get_numa_id, \
- NULL, /* set_tx_multiq */ \
+ TX_MULTIQ, \
\
netdev_dummy_send, /* send */ \
NULL, /* send_wait */ \
@@ -1286,7 +1354,7 @@ netdev_dummy_update_flags(struct netdev *netdev_,
NULL, /* arp_lookup */ \
\
netdev_dummy_update_flags, \
- NULL, /* reconfigure */ \
+ RECOFIGURE, \
\
netdev_dummy_rxq_alloc, \
netdev_dummy_rxq_construct, \
@@ -1298,9 +1366,12 @@ netdev_dummy_update_flags(struct netdev *netdev_,
}
static const struct netdev_class dummy_class =
- NETDEV_DUMMY_CLASS("dummy", false);
+ NETDEV_DUMMY_CLASS("dummy", false, NULL, NULL);
+
static const struct netdev_class dummy_pmd_class =
- NETDEV_DUMMY_CLASS("dummy-pmd", true);
+ NETDEV_DUMMY_CLASS("dummy-pmd", true,
+ netdev_dummy_set_tx_multiq,
+ netdev_dummy_reconfigure);
static void
pkt_list_delete(struct ovs_list *l)
@@ -1365,7 +1436,8 @@ netdev_dummy_queue_packet__(struct netdev_rxq_dummy *rx, struct dp_packet *packe
}
static void
-netdev_dummy_queue_packet(struct netdev_dummy *dummy, struct dp_packet *packet)
+netdev_dummy_queue_packet(struct netdev_dummy *dummy, struct dp_packet *packet,
+ int queue_id)
OVS_REQUIRES(dummy->mutex)
{
struct netdev_rxq_dummy *rx, *prev;
@@ -1376,7 +1448,8 @@ netdev_dummy_queue_packet(struct netdev_dummy *dummy, struct dp_packet *packet)
}
prev = NULL;
LIST_FOR_EACH (rx, node, &dummy->rxes) {
- if (rx->recv_queue_len < NETDEV_DUMMY_MAX_QUEUE) {
+ if (rx->up.queue_id == queue_id &&
+ rx->recv_queue_len < NETDEV_DUMMY_MAX_QUEUE) {
if (prev) {
netdev_dummy_queue_packet__(prev, dp_packet_clone(packet));
}
@@ -1396,16 +1469,27 @@ netdev_dummy_receive(struct unixctl_conn *conn,
{
struct netdev_dummy *dummy_dev;
struct netdev *netdev;
- int i;
+ int i, k = 1, rx_qid = 0;
- netdev = netdev_from_name(argv[1]);
+ netdev = netdev_from_name(argv[k++]);
if (!netdev || !is_dummy_class(netdev->netdev_class)) {
unixctl_command_reply_error(conn, "no such dummy netdev");
- goto exit;
+ goto exit_netdev;
}
dummy_dev = netdev_dummy_cast(netdev);
- for (i = 2; i < argc; i++) {
+ ovs_mutex_lock(&dummy_dev->mutex);
+
+ if (argc > k + 1 && !strcmp(argv[k], "--qid")) {
+ rx_qid = strtol(argv[k + 1], NULL, 10);
+ if (rx_qid < 0 || rx_qid >= netdev->n_rxq) {
+ unixctl_command_reply_error(conn, "bad rx queue id.");
+ goto exit;
+ }
+ k += 2;
+ }
+
+ for (i = k; i < argc; i++) {
struct dp_packet *packet;
packet = eth_from_packet_or_flow(argv[i]);
@@ -1414,14 +1498,14 @@ netdev_dummy_receive(struct unixctl_conn *conn,
goto exit;
}
- ovs_mutex_lock(&dummy_dev->mutex);
- netdev_dummy_queue_packet(dummy_dev, packet);
- ovs_mutex_unlock(&dummy_dev->mutex);
+ netdev_dummy_queue_packet(dummy_dev, packet, rx_qid);
}
unixctl_command_reply(conn, NULL);
exit:
+ ovs_mutex_unlock(&dummy_dev->mutex);
+exit_netdev:
netdev_close(netdev);
}
@@ -1624,7 +1708,8 @@ netdev_dummy_override(const char *type)
void
netdev_dummy_register(enum dummy_level level)
{
- unixctl_command_register("netdev-dummy/receive", "name packet|flow...",
+ unixctl_command_register("netdev-dummy/receive",
+ "name [--qid queue_id] packet|flow...",
2, INT_MAX, netdev_dummy_receive, NULL);
unixctl_command_register("netdev-dummy/set-admin-state",
"[netdev] up|down", 1, 2,
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 1c081d5..a523e87 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -6011,12 +6011,12 @@ OVS_VSWITCHD_START([add-br br1 -- set bridge br1 datapath-type=dummy])
add_pmd_of_ports br0 1 2
add_of_ports br1 3
-AT_CHECK([ovs-appctl dpif/show], [0], [dnl
+AT_CHECK([ovs-appctl dpif/show | sed 's/\(dummy-pmd: \).*)/\1<cleared>)/'], [0], [dnl
dummy at ovs-dummy: hit:0 missed:0
br0:
br0 65534/100: (dummy)
- p1 1/1: (dummy-pmd)
- p2 2/2: (dummy-pmd)
+ p1 1/1: (dummy-pmd: <cleared>)
+ p2 2/2: (dummy-pmd: <cleared>)
br1:
br1 65534/101: (dummy)
p3 3/3: (dummy)
--
2.5.0
More information about the dev
mailing list