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.maxim...@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@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev