Skip to content

Commit

Permalink
netdev-dummy: Add multiqueue support to dummy-pmd.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Daniele Di Proietto <[email protected]>
  • Loading branch information
igsilya authored and ddiproietto committed Jun 7, 2016
1 parent 868dae9 commit 9a81a63
Showing 1 changed file with 106 additions and 21 deletions.
127 changes: 106 additions & 21 deletions lib/netdev-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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 *);

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -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 (!netdev_is_pmd(dev)) {
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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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)
{
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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 */ \
Expand All @@ -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 */ \
Expand Down Expand Up @@ -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, \
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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));
}
Expand All @@ -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]);
Expand All @@ -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);
}

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 9a81a63

Please sign in to comment.