From patchwork Tue Jul 25 02:53:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zhaozhanxu X-Patchwork-Id: 793160 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=163.com header.i=@163.com header.b="ewLh+8A0"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xGjsH1S3Fz9s4q for ; Tue, 25 Jul 2017 13:09:55 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 0704FAA5; Tue, 25 Jul 2017 03:09:16 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 7E16CA7A for ; Tue, 25 Jul 2017 03:09:12 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from m50-134.163.com (m50-134.163.com [123.125.50.134]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 7B56242B for ; Tue, 25 Jul 2017 03:09:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id; bh=56qC0814fi5dez+N9y szUWQP7ATBkPLN9H3qRJSopuU=; b=ewLh+8A0OE8mL5pqryuNNu4KGjkmrA1Xsu AOHopxoXQkbTAVfXiRMoVzeNxzoAbC6mupjiqWBCmKY41YKjC0q5zc693sZ32cUQ NQrBZgPP0RoqZo8VCXrv5cgyNSuER8ScxeWr2BpVRXaht3dAkhqVthuPnna1kEt2 Ds/5Hr3gM= Received: from localhost.localdomain (unknown [107.155.53.100]) by smtp4 (Coremail) with SMTP id DtGowADn3k_BsnZZ5WQVBQ--.789S5; Tue, 25 Jul 2017 10:54:06 +0800 (CST) From: zhaozhanxu To: ovs-dev@openvswitch.org Date: Tue, 25 Jul 2017 10:53:47 +0800 Message-Id: <1500951228-18646-4-git-send-email-zhaozhanxu@163.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500951228-18646-1-git-send-email-zhaozhanxu@163.com> References: <1500951228-18646-1-git-send-email-zhaozhanxu@163.com> X-CM-TRANSID: DtGowADn3k_BsnZZ5WQVBQ--.789S5 X-Coremail-Antispam: 1Uf129KBjvJXoW3Jr4xJrW3GFW8Jr1ktry5urg_yoWxKr4xpF WUGasxZw4IqrsxWrW7JFy7WrnI9r18Ca17GryfG3sxZF90vw1Y9r1kWFyUZr4fGrykAa17 tw4Y9FZrKa18trJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UIsj8UUUUU= X-Originating-IP: [107.155.53.100] X-CM-SenderInfo: p2kd06xkdq53i6rwjhhfrp/1tbiLQ8gqFSITKVPNgAAsm X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: zhaozhanxu Subject: [ovs-dev] [PATCH v2 3/4] netdev-dpdk.c: Support to show multi-queue qos info for dpdk datapath X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch support command `ovs-appctl -t ovs-vswitchd qos/show vhost-user0` to show QoS and its queues information. It adds some functions whitch is pointed by `get_queue_stats`, `queue_dump_start`, `queue_dump_next` and `queue_dump_done` of structure `netdev_class` to show queue information. Signed-off-by: zhaozhanxu --- lib/netdev-dpdk.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 5 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 85f077e..641ddfa 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -284,6 +284,10 @@ struct dpdk_qos_ops { */ int (*qos_queue_get)(struct smap *details, uint32_t queue_id, const struct qos_conf *conf); + + /* Retrieves statistics of QoS Queue configuration into 'details'. */ + int (*qos_queue_get_stats)(const struct qos_conf *conf, uint32_t queue_id, + struct netdev_queue_stats *stats); }; /* dpdk_qos_ops for each type of user space QoS implementation */ @@ -3079,6 +3083,28 @@ netdev_dpdk_delete_queue(struct netdev *netdev, uint32_t queue_id) return 0; } +static int +netdev_dpdk_get_queue_stats(const struct netdev *netdev, uint32_t queue_id, + struct netdev_queue_stats *stats) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct qos_conf *qos_conf; + int error = 0; + + ovs_mutex_lock(&dev->mutex); + + qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf); + if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get_stats) { + qos_conf->ops->qos_queue_get_stats(qos_conf, queue_id, stats); + } else { + error = EOPNOTSUPP; + } + + ovs_mutex_unlock(&dev->mutex); + + return error; +} + /* egress-policer details */ struct egress_policer { @@ -3088,13 +3114,100 @@ struct egress_policer { struct hmap queue; }; +struct egress_queue_stats { + uint64_t tx_bytes; + uint64_t tx_packets; + uint64_t tx_errors; + + long long int created; +}; + struct egress_queue_policer { struct hmap_node hmap_node; uint32_t queue_id; struct rte_meter_srtcm_params app_srtcm_params; struct rte_meter_srtcm egress_meter; + struct egress_queue_stats stats; +}; + +struct netdev_dpdk_queue_state { + uint32_t *queues; + size_t cur_queue; + size_t n_queues; }; +static int +netdev_dpdk_queue_dump_start(const struct netdev *netdev, void **statep) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct qos_conf *qos_conf; + int error = 0; + + ovs_mutex_lock(&dev->mutex); + + qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf); + if (qos_conf) { + struct netdev_dpdk_queue_state *state; + struct egress_policer *policer = + CONTAINER_OF(qos_conf, struct egress_policer, qos_conf); + + *statep = state = xmalloc(sizeof *state); + state->n_queues = hmap_count(&policer->queue); + state->cur_queue = 0; + state->queues = xmalloc(state->n_queues * sizeof *state->queues); + + uint32_t i = 0; + struct egress_queue_policer *queue_policer; + HMAP_FOR_EACH (queue_policer, hmap_node, &policer->queue) { + state->queues[i++] = queue_policer->queue_id; + } + } else { + error = EOPNOTSUPP; + } + + ovs_mutex_unlock(&dev->mutex); + + return error; +} + +static int +netdev_dpdk_queue_dump_next(const struct netdev *netdev, void *state_, + uint32_t *queue_idp, struct smap *details) +{ + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct netdev_dpdk_queue_state *state = state_; + struct qos_conf *qos_conf; + int error = EOF; + + ovs_mutex_lock(&dev->mutex); + + while (state->cur_queue < state->n_queues) { + uint32_t queue_id = state->queues[state->cur_queue++]; + + qos_conf = ovsrcu_get_protected(struct qos_conf *, &dev->qos_conf); + if (qos_conf && qos_conf->ops && qos_conf->ops->qos_queue_get) { + *queue_idp = queue_id; + error = qos_conf->ops->qos_queue_get(details, queue_id, qos_conf); + break; + } + } + + ovs_mutex_unlock(&dev->mutex); + + return error; +} + +static int +netdev_dpdk_queue_dump_done(const struct netdev *netdev OVS_UNUSED, + void *state_) +{ + struct netdev_dpdk_queue_state *state = state_; + + free(state->queues); + free(state); + return 0; +} + static struct egress_queue_policer * egress_policer_qos_find_queue(struct egress_policer *policer, uint32_t queue_id); @@ -3185,7 +3298,11 @@ egress_policer_pkt_handle(struct egress_policer *policer, if (queue_policer) { if (rte_meter_srtcm_color_blind_check(&queue_policer->egress_meter, time, pkt_len) != e_RTE_METER_GREEN) { + queue_policer->stats.tx_errors ++; return false; + } else { + queue_policer->stats.tx_bytes += pkt_len; + queue_policer->stats.tx_packets ++; } } @@ -3246,6 +3363,8 @@ egress_policer_qos_queue_construct(const struct smap *details, hmap_insert(&policer->queue, &queue_policer->hmap_node, hash_2words(queue_id, 0)); queue_policer->queue_id = queue_id; + memset(&queue_policer->stats, 0, sizeof queue_policer->stats); + queue_policer->stats.created = rte_rdtsc(); } egress_policer_details_to_param(details, &queue_policer->app_srtcm_params); err = rte_meter_srtcm_config(&queue_policer->egress_meter, @@ -3291,6 +3410,31 @@ egress_policer_qos_queue_get(struct smap *details, uint32_t queue_id, return 0; } +static int +egress_policer_qos_queue_get_stats(const struct qos_conf *conf, + uint32_t queue_id, + struct netdev_queue_stats *stats) +{ + struct egress_policer *policer = + CONTAINER_OF(conf, struct egress_policer, qos_conf); + + struct egress_queue_policer *queue_policer; + queue_policer = egress_policer_qos_find_queue(policer, queue_id); + if (!queue_policer) { + stats->tx_bytes = UINT64_MAX; + stats->tx_packets = UINT64_MAX; + stats->tx_errors = UINT64_MAX; + stats->created = LLONG_MIN; + return -1; + } else { + stats->tx_bytes = queue_policer->stats.tx_bytes; + stats->tx_packets = queue_policer->stats.tx_packets; + stats->tx_errors = queue_policer->stats.tx_errors; + stats->created = queue_policer->stats.created; + return 0; + } +} + static const struct dpdk_qos_ops egress_policer_ops = { "egress-policer", /* qos_name */ egress_policer_qos_construct, @@ -3300,7 +3444,8 @@ static const struct dpdk_qos_ops egress_policer_ops = { egress_policer_run, egress_policer_qos_queue_construct, egress_policer_qos_queue_destruct, - egress_policer_qos_queue_get + egress_policer_qos_queue_get, + egress_policer_qos_queue_get_stats }; static int @@ -3485,10 +3630,10 @@ unlock: netdev_dpdk_get_queue, \ netdev_dpdk_set_queue, \ netdev_dpdk_delete_queue, \ - NULL, /* get_queue_stats */ \ - NULL, /* queue_dump_start */ \ - NULL, /* queue_dump_next */ \ - NULL, /* queue_dump_done */ \ + netdev_dpdk_get_queue_stats, \ + netdev_dpdk_queue_dump_start, \ + netdev_dpdk_queue_dump_next, \ + netdev_dpdk_queue_dump_done, \ NULL, /* dump_queue_stats */ \ \ NULL, /* set_in4 */ \