From patchwork Thu Jun 18 16:53:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Van Haaren, Harry" X-Patchwork-Id: 1312323 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49np1N4NM8z9sRR for ; Fri, 19 Jun 2020 02:54:00 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id CDB84266D9; Thu, 18 Jun 2020 16:53:58 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id einUoJiAWoRA; Thu, 18 Jun 2020 16:53:49 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 0915024E91; Thu, 18 Jun 2020 16:53:48 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E3125C0894; Thu, 18 Jun 2020 16:53:47 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id EA64EC016E for ; Thu, 18 Jun 2020 16:53:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id DA73888AA9 for ; Thu, 18 Jun 2020 16:53:46 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HRTKhYRpCEgA for ; Thu, 18 Jun 2020 16:53:44 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by whitealder.osuosl.org (Postfix) with ESMTPS id 4838F88AAF for ; Thu, 18 Jun 2020 16:53:43 +0000 (UTC) IronPort-SDR: dSa3cSlEWS4x/F/TL2ZM1fuSuO0ZAdgS9KMAWFlUFoQTPOfnQcW72i0VmhI3aDcEfsi50Sy/nr jZEbCHNyszmA== X-IronPort-AV: E=McAfee;i="6000,8403,9656"; a="141724089" X-IronPort-AV: E=Sophos;i="5.75,251,1589266800"; d="scan'208";a="141724089" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2020 09:53:43 -0700 IronPort-SDR: 6dKy93xaivFrTWGCj7Cu+gLsKwufjkClsIxBV5hq0SFruPrPfevzfuK5danY1UKj4/7XhGXeit Nzn6lPwNAVDw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,251,1589266800"; d="scan'208";a="299760727" Received: from silpixa00399779.ir.intel.com (HELO silpixa00399779.ger.corp.intel.com) ([10.237.222.209]) by fmsmga004.fm.intel.com with ESMTP; 18 Jun 2020 09:53:41 -0700 From: Harry van Haaren To: ovs-dev@openvswitch.org Date: Thu, 18 Jun 2020 17:53:49 +0100 Message-Id: <20200618165354.87787-3-harry.van.haaren@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200618165354.87787-1-harry.van.haaren@intel.com> References: <20200610104839.54608-1-harry.van.haaren@intel.com> <20200618165354.87787-1-harry.van.haaren@intel.com> Cc: i.maximets@ovn.org Subject: [ovs-dev] [PATCH v4 2/7] dpif-netdev: add subtable lookup prio set command. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This commit adds a command for the dpif-netdev to set a specific lookup function to a particular priority level. The command enables runtime switching of the dpcls subtable lookup implementation. Selection is performed based on a priority. Higher priorities take precedence, eg; priotity 5 will be selected instead of a priority 3. If lookup functions have the same priority, the first one in the list is selected. The two options available are 'autovalidator' and 'generic'. The below command will set a new priority for the given function: $ ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 2 The autovalidator implementation can be selected at runtime now: $ ovs-appctl dpif-netdev/subtable-lookup-prio-set autovalidator 5 Signed-off-by: Harry van Haaren Acked-by: William Tu --- v4: - Align prio-set command in code (William Tu) - Improve commit title & update commit message (William Tu) v3 - Add automatic reprobe after changing priorities --- Refactored from previous 1-second timeout based reprobe WIP-hack - Add VLOG entries for changed dpcls and subtable counts --- Also return the updated counts to the issuing command for visibility - Clarify command by adding "prio" to the name --- New command name is "dpif-netdev/subtable-lookup-prio-set" --- Please note this new command change - previous command is now invalid --- lib/dpif-netdev.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index d3f80c997..f7cc85145 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -258,6 +258,7 @@ struct dp_packet_flow_map { static void dpcls_init(struct dpcls *); static void dpcls_destroy(struct dpcls *); static void dpcls_sort_subtable_vector(struct dpcls *); +static uint32_t dpcls_subtable_lookup_reprobe(struct dpcls *cls); static void dpcls_insert(struct dpcls *, struct dpcls_rule *, const struct netdev_flow_key *mask); static void dpcls_remove(struct dpcls *, struct dpcls_rule *); @@ -860,6 +861,9 @@ dpif_netdev_xps_revalidate_pmd(const struct dp_netdev_pmd_thread *pmd, bool purge); static int dpif_netdev_xps_get_tx_qid(const struct dp_netdev_pmd_thread *pmd, struct tx_port *tx); +static inline struct dpcls * +dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd, + odp_port_t in_port); static inline bool emc_entry_alive(struct emc_entry *ce); static void emc_clear_entry(struct emc_entry *ce); @@ -1260,6 +1264,97 @@ sorted_poll_thread_list(struct dp_netdev *dp, *n = k; } +static void +dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux OVS_UNUSED) +{ + /* This function requires 2 parameters (argv[1] and argv[2]) to execute. + * argv[1] is subtable name + * argv[2] is priority + * argv[3] is the datapath name (optional if only 1 datapath exists) + */ + const char *func_name = argv[1]; + + errno = 0; + char *err_char; + uint32_t new_prio = strtoul(argv[2], &err_char, 10); + if (errno != 0 || new_prio > UINT8_MAX) { + unixctl_command_reply_error(conn, + "error converting priority, use integer in range 0-255\n"); + return; + } + + int32_t err = dpcls_subtable_set_prio(func_name, new_prio); + if (err) { + unixctl_command_reply_error(conn, + "error, subtable lookup function not found\n"); + return; + } + + /* argv[3] is optional datapath instance. If no datapath name is provided + * and only one datapath exists, the one existing datapath is reprobed. + */ + ovs_mutex_lock(&dp_netdev_mutex); + struct dp_netdev *dp = NULL; + + if (argc == 4) { + dp = shash_find_data(&dp_netdevs, argv[3]); + } else if (shash_count(&dp_netdevs) == 1) { + dp = shash_first(&dp_netdevs)->data; + } + + if (!dp) { + ovs_mutex_unlock(&dp_netdev_mutex); + unixctl_command_reply_error(conn, + "please specify an existing datapath"); + return; + } + + /* Get PMD threads list, required to get DPCLS instances */ + size_t n; + uint32_t lookup_dpcls_changed = 0; + uint32_t lookup_subtable_changed = 0; + struct dp_netdev_pmd_thread **pmd_list; + sorted_poll_thread_list(dp, &pmd_list, &n); + + /* take port mutex as HMAP iters over them */ + ovs_mutex_lock(&dp->port_mutex); + + for (size_t i = 0; i < n; i++) { + struct dp_netdev_pmd_thread *pmd = pmd_list[i]; + if (pmd->core_id == NON_PMD_CORE_ID) { + continue; + } + + struct dp_netdev_port *port = NULL; + HMAP_FOR_EACH (port, node, &dp->ports) { + odp_port_t in_port = port->port_no; + struct dpcls *cls = dp_netdev_pmd_lookup_dpcls(pmd, in_port); + if (!cls) { + continue; + } + uint32_t subtbl_changes = dpcls_subtable_lookup_reprobe(cls); + if (subtbl_changes) { + lookup_dpcls_changed++; + lookup_subtable_changed += subtbl_changes; + } + } + } + + /* release port mutex before netdev mutex */ + ovs_mutex_unlock(&dp->port_mutex); + ovs_mutex_unlock(&dp_netdev_mutex); + + struct ds reply = DS_EMPTY_INITIALIZER; + ds_put_format(&reply, + "Lookup priority change affected %d dpcls ports and %d subtables.\n", + lookup_dpcls_changed, lookup_subtable_changed); + const char *reply_str = ds_cstr(&reply); + unixctl_command_reply(conn, reply_str); + VLOG_INFO("%s", reply_str); + ds_destroy(&reply); +} + static void dpif_netdev_pmd_rebalance(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) @@ -1429,6 +1524,10 @@ dpif_netdev_init(void) "[-us usec] [-q qlen]", 0, 10, pmd_perf_log_set_cmd, NULL); + unixctl_command_register("dpif-netdev/subtable-lookup-prio-set", + "[lookup_func] [prio] [dp]", + 2, 3, dpif_netdev_subtable_lookup_set, + NULL); return 0; } @@ -8089,6 +8188,28 @@ dpcls_find_subtable(struct dpcls *cls, const struct netdev_flow_key *mask) return dpcls_create_subtable(cls, mask); } +/* Checks for the best available implementation for each subtable lookup + * function, and assigns it as the lookup function pointer for each subtable. + * Returns the number of subtables that have changed lookup implementation. + */ +static uint32_t +dpcls_subtable_lookup_reprobe(struct dpcls *cls) +{ + struct pvector *pvec = &cls->subtables; + uint32_t subtables_changed = 0; + struct dpcls_subtable *subtable = NULL; + + PVECTOR_FOR_EACH (subtable, pvec) { + uint32_t u0_bits = subtable->mf_bits_set_unit0; + uint32_t u1_bits = subtable->mf_bits_set_unit1; + void *old_func = subtable->lookup_func; + subtable->lookup_func = dpcls_subtable_get_best_impl(u0_bits, u1_bits); + subtables_changed += (old_func != subtable->lookup_func); + } + pvector_publish(pvec); + + return subtables_changed; +} /* Periodically sort the dpcls subtable vectors according to hit counts */ static void