From patchwork Wed Jun 28 12:42:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Traynor X-Patchwork-Id: 781661 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3wyMy76CzVz9s82 for ; Wed, 28 Jun 2017 22:47:27 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4597FB4C; Wed, 28 Jun 2017 12:43:37 +0000 (UTC) X-Original-To: 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 540A0AEF for ; Wed, 28 Jun 2017 12:43:35 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id C164E18F for ; Wed, 28 Jun 2017 12:43:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3CFF813A68; Wed, 28 Jun 2017 12:43:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3CFF813A68 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ktraynor@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3CFF813A68 Received: from ktraynor.remote.csb (ovpn-117-248.ams2.redhat.com [10.36.117.248]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3CC0388FF3; Wed, 28 Jun 2017 12:43:31 +0000 (UTC) From: Kevin Traynor To: dev@openvswitch.org, ian.stokes@intel.com, jan.scheurich@ericsson.com, bhanuprakash.bodireddy@intel.com, ciara.loftus@intel.com Date: Wed, 28 Jun 2017 13:42:51 +0100 Message-Id: <1498653773-13757-7-git-send-email-ktraynor@redhat.com> In-Reply-To: <1498653773-13757-1-git-send-email-ktraynor@redhat.com> References: <1494002063-12269-1-git-send-email-ktraynor@redhat.com> <1498653773-13757-1-git-send-email-ktraynor@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 28 Jun 2017 12:43:33 +0000 (UTC) X-Spam-Status: No, score=-6.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 6/8] dpif-netdev: Change rxq_scheduling to use rxq processing cycles. 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 Previously rxqs were assigned to pmds by round robin in port/queue order. Now that we have the processing cycles used for existing rxqs, use that information to try and produced a better balanced distribution of rxqs across pmds. i.e. given multiple pmds, the rxqs which have consumed the largest amount of processing cycles will be placed on different pmds. The rxqs are sorted by their processing cycles and assigned (in sorted order) round robin across pmds. Signed-off-by: Kevin Traynor --- Documentation/howto/dpdk.rst | 10 +++++++ lib/dpif-netdev.c | 67 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index 93248b4..e2779f3 100644 --- a/Documentation/howto/dpdk.rst +++ b/Documentation/howto/dpdk.rst @@ -119,4 +119,14 @@ After that PMD threads on cores where RX queues was pinned will become thread. +If pmd-rxq-affinity is not set for rxqs, they will be assigned to pmds +automatically. The processing cycles that have been required for each rxq +will be used where known to assign rxqs with the highest consumption of +processing cycles to different pmds. + +Rxq to pmds assignment takes place whenever there are configuration changes +or can be triggered by using:: + + $ ovs-appctl dpif-netdev/pmd-rxq-rebalance + QoS --- diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 6ccad13..77276ae 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -3296,8 +3296,29 @@ rr_numa_list_destroy(struct rr_numa_list *rr) } +/* Sort Rx Queues by the processing cycles they are consuming. */ +static int +rxq_cycle_sort(const void *a, const void *b) +{ + struct dp_netdev_rxq * qa; + struct dp_netdev_rxq * qb; + + qa = *(struct dp_netdev_rxq **) a; + qb = *(struct dp_netdev_rxq **) b; + + if (dp_netdev_rxq_get_cycles(qa, RXQ_CYCLES_PROC_LAST) >= + dp_netdev_rxq_get_cycles(qb, RXQ_CYCLES_PROC_LAST)) { + return -1; + } + + return 1; +} + /* Assign pmds to queues. If 'pinned' is true, assign pmds to pinned * queues and marks the pmds as isolated. Otherwise, assign non isolated * pmds to unpinned queues. * + * If 'pinned' is false queues will be sorted by processing cycles they are + * consuming and then assigned to pmds in round robin order. + * * The function doesn't touch the pmd threads, it just stores the assignment * in the 'pmd' member of each rxq. */ @@ -3307,18 +3328,14 @@ rxq_scheduling(struct dp_netdev *dp, bool pinned) OVS_REQUIRES(dp->port_mutex) struct dp_netdev_port *port; struct rr_numa_list rr; - - rr_numa_list_populate(dp, &rr); + struct dp_netdev_rxq ** rxqs = NULL; + int i, n_rxqs = 0; + struct rr_numa *numa = NULL; + int numa_id; HMAP_FOR_EACH (port, node, &dp->ports) { - struct rr_numa *numa; - int numa_id; - if (!netdev_is_pmd(port->netdev)) { continue; } - numa_id = netdev_get_numa_id(port->netdev); - numa = rr_numa_list_lookup(&rr, numa_id); - for (int qid = 0; qid < port->n_rxq; qid++) { struct dp_netdev_rxq *q = &port->rxqs[qid]; @@ -3338,17 +3355,39 @@ rxq_scheduling(struct dp_netdev *dp, bool pinned) OVS_REQUIRES(dp->port_mutex) } } else if (!pinned && q->core_id == OVS_CORE_UNSPEC) { - if (!numa) { - VLOG_WARN("There's no available (non isolated) pmd thread " - "on numa node %d. Queue %d on port \'%s\' will " - "not be polled.", - numa_id, qid, netdev_get_name(port->netdev)); + if (n_rxqs == 0) { + rxqs = xmalloc(sizeof *rxqs); } else { - q->pmd = rr_numa_get_pmd(numa); + rxqs = xrealloc(rxqs, sizeof *rxqs * (n_rxqs + 1)); } + /* Store the queue. */ + rxqs[n_rxqs++] = q; } } } + if (n_rxqs > 1) { + /* Sort the queues in order of the processing cycles + * they consumed during their last pmd interval. */ + qsort(rxqs, n_rxqs, sizeof *rxqs, rxq_cycle_sort); + } + + rr_numa_list_populate(dp, &rr); + /* Assign the sorted queues to pmds in round robin. */ + for (i = 0; i < n_rxqs; i++) { + numa_id = netdev_get_numa_id(rxqs[i]->port->netdev); + numa = rr_numa_list_lookup(&rr, numa_id); + if (!numa) { + VLOG_WARN("There's no available (non isolated) pmd thread " + "on numa node %d. Queue %d on port \'%s\' will " + "not be polled.", + numa_id, netdev_rxq_get_queue_id(rxqs[i]->rx), + netdev_get_name(rxqs[i]->port->netdev)); + continue; + } + rxqs[i]->pmd = rr_numa_get_pmd(numa); + } + rr_numa_list_destroy(&rr); + free(rxqs); }