Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1524858/?format=api
http://patchwork.ozlabs.org/api/patches/1524858/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/163091843101.96839.16631709571000877173.stgit@ebuild/", "project": { "id": 47, "url": "http://patchwork.ozlabs.org/api/projects/47/?format=api", "name": "Open vSwitch", "link_name": "openvswitch", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "git@github.com:openvswitch/ovs.git", "webscm_url": "https://github.com/openvswitch/ovs", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<163091843101.96839.16631709571000877173.stgit@ebuild>", "list_archive_url": null, "date": "2021-09-06T08:53:58", "name": "[ovs-dev,v6,2/2] dpctl: dpif: allow viewing and configuring dp cache sizes", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "a95e31f3970753850e80ca55c14abdf41e7dcbfe", "submitter": { "id": 70613, "url": "http://patchwork.ozlabs.org/api/people/70613/?format=api", "name": "Eelco Chaudron", "email": "echaudro@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/163091843101.96839.16631709571000877173.stgit@ebuild/mbox/", "series": [ { "id": 261091, "url": "http://patchwork.ozlabs.org/api/series/261091/?format=api", "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=261091", "date": "2021-09-06T08:53:28", "name": "dpctl: cache visibility/configuration enhancements", "version": 6, "mbox": "http://patchwork.ozlabs.org/series/261091/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1524858/comments/", "check": "success", "checks": "http://patchwork.ozlabs.org/api/patches/1524858/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "ovs-dev@lists.linuxfoundation.org" ], "Authentication-Results": [ "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=a0I7i6nA;\n\tdkim-atps=neutral", "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN>)", "relay.mimecast.com;\n auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=echaudro@redhat.com" ], "Received": [ "from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4H32JY4hb9z9sRN\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 6 Sep 2021 18:54:21 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id BF7E74041A;\n\tMon, 6 Sep 2021 08:54:18 +0000 (UTC)", "from smtp2.osuosl.org ([127.0.0.1])\n\tby localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 8zjEhPFE7UuU; Mon, 6 Sep 2021 08:54:17 +0000 (UTC)", "from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id 0ACE2403F0;\n\tMon, 6 Sep 2021 08:54:16 +0000 (UTC)", "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id CE49AC001C;\n\tMon, 6 Sep 2021 08:54:15 +0000 (UTC)", "from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 6E891C001B\n for <dev@openvswitch.org>; Mon, 6 Sep 2021 08:54:14 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp2.osuosl.org (Postfix) with ESMTP id E4E5640445\n for <dev@openvswitch.org>; Mon, 6 Sep 2021 08:54:08 +0000 (UTC)", "from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id jVZj_dqGctHS for <dev@openvswitch.org>;\n Mon, 6 Sep 2021 08:54:07 +0000 (UTC)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp2.osuosl.org (Postfix) with ESMTPS id 163324043C\n for <dev@openvswitch.org>; Mon, 6 Sep 2021 08:54:06 +0000 (UTC)", "from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com\n [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id\n us-mta-244-yp0odMNaNv66wFPlUzRf1A-1; Mon, 06 Sep 2021 04:54:02 -0400", "from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com\n [10.5.11.22])\n (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n (No client certificate requested)\n by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6A15710866B9;\n Mon, 6 Sep 2021 08:54:01 +0000 (UTC)", "from ebuild.redhat.com (unknown [10.39.194.213])\n by smtp.corp.redhat.com (Postfix) with ESMTP id 8198B10016F4;\n Mon, 6 Sep 2021 08:54:00 +0000 (UTC)" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "domain auto-whitelisted by SQLgrey-1.8.0", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1630918446;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=fCdaO5IPmFdFSj4SZrJIhiqMIZCGewKi6ghQSuAYzAI=;\n b=a0I7i6nAGuNjZn2qIxY/pIoAs8nqugtlZzwRZI15j/JQBOvsUEckcoNQ9OMUIwzfoEQoU8\n zYYvTaeY6w/xecOzwAJSGaEoemCZPkiuV3MM9DrCeePfZgUcpIqsFC1o0m3Xq71cu3srO+\n Y/6Da9hYFtAy4zYuy9TQRl3wcCQM97E=", "X-MC-Unique": "yp0odMNaNv66wFPlUzRf1A-1", "From": "Eelco Chaudron <echaudro@redhat.com>", "To": "dev@openvswitch.org", "Date": "Mon, 6 Sep 2021 10:53:58 +0200", "Message-Id": "<163091843101.96839.16631709571000877173.stgit@ebuild>", "In-Reply-To": "<163091839517.96839.8006181203263313854.stgit@ebuild>", "References": "<163091839517.96839.8006181203263313854.stgit@ebuild>", "User-Agent": "StGit/0.21", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 2.84 on 10.5.11.22", "X-Mimecast-Spam-Score": "0", "X-Mimecast-Originator": "redhat.com", "Cc": "fbl@sysclose.org", "Subject": "[ovs-dev] [PATCH v6 2/2] dpctl: dpif: allow viewing and configuring\n\tdp cache sizes", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "ovs-dev-bounces@openvswitch.org", "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>" }, "content": "This patch adds a general way of viewing/configuring datapath\ncache sizes. With an implementation for the netlink interface.\n\nThe ovs-dpctl/ovs-appctl show commands will display the\ncurrent cache sizes configured:\n\novs-dpctl show\nsystem@ovs-system:\n lookups: hit:25 missed:63 lost:0\n flows: 0\n masks: hit:282 total:0 hit/pkt:3.20\n cache: hit:4 hit rate:4.54%\n caches:\n masks-cache: size: 256\n port 0: ovs-system (internal)\n port 1: br-int (internal)\n port 2: genev_sys_6081 (geneve: packet_type=ptap)\n port 3: br-ex (internal)\n port 4: eth2\n port 5: sw0p1 (internal)\n port 6: sw0p3 (internal)\n\nA specific cache can be configured as follows:\n\novs-appctl dpctl/cache-set-size DP CACHE SIZE\novs-dpctl cache-set-size DP CACHE SIZE\n\nFor example to disable the cache do:\n\n$ ovs-dpctl cache-set-size system@ovs-system masks-cache 0\nSetting cache size successful, new size 0.\n\nSigned-off-by: Eelco Chaudron <echaudro@redhat.com>\nAcked-by: Paolo Valerio <pvalerio@redhat.com>\nAcked-by: Flavio Leitner <fbl@sysclose.org>\n\nv2: - Changed precision to 2 digits\n - Handle missing kernel feature at netlink level\nv3: - Rebase on the latest master branch\nv4: - Fixed commit message\n - Fix issue with resetting user_features\nv5: - Include the actual resetting user_features fix\nv6: - Rebase on the latest master branch\n - Add ACK's\n---\n datapath/linux/compat/include/linux/openvswitch.h | 2 \n lib/dpctl.c | 120 +++++++++++++++++++++\n lib/dpctl.man | 14 ++\n lib/dpif-netdev.c | 4 +\n lib/dpif-netlink.c | 117 ++++++++++++++++++++\n lib/dpif-provider.h | 20 ++++\n lib/dpif.c | 32 ++++++\n lib/dpif.h | 7 +\n tests/system-traffic.at | 36 ++++++\n utilities/ovs-dpctl.c | 4 +\n 10 files changed, 355 insertions(+), 1 deletion(-)", "diff": "diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h\nindex a3f5fb919..936644192 100644\n--- a/datapath/linux/compat/include/linux/openvswitch.h\n+++ b/datapath/linux/compat/include/linux/openvswitch.h\n@@ -107,7 +107,7 @@ enum ovs_datapath_attr {\n \tOVS_DP_ATTR_MEGAFLOW_STATS,\t/* struct ovs_dp_megaflow_stats */\n \tOVS_DP_ATTR_USER_FEATURES,\t/* OVS_DP_F_* */\n \tOVS_DP_ATTR_PAD,\n-\tOVS_DP_ATTR_PAD2,\n+\tOVS_DP_ATTR_MASKS_CACHE_SIZE,\n \tOVS_DP_ATTR_PER_CPU_PIDS,\t/* Netlink PIDS to receive upcalls */\n \t__OVS_DP_ATTR_MAX\n };\ndiff --git a/lib/dpctl.c b/lib/dpctl.c\nindex acc677974..6cba8db51 100644\n--- a/lib/dpctl.c\n+++ b/lib/dpctl.c\n@@ -591,6 +591,36 @@ compare_port_nos(const void *a_, const void *b_)\n return a < b ? -1 : a > b;\n }\n \n+static void\n+show_dpif_cache__(struct dpif *dpif, struct dpctl_params *dpctl_p)\n+{\n+ uint32_t nr_caches;\n+ int error = dpif_cache_get_supported_levels(dpif, &nr_caches);\n+\n+ if (error || nr_caches == 0) {\n+ return;\n+ }\n+\n+ dpctl_print(dpctl_p, \" caches:\\n\");\n+ for (int i = 0; i < nr_caches; i++) {\n+ const char *name;\n+ uint32_t size;\n+\n+ if (dpif_cache_get_name(dpif, i, &name) ||\n+ dpif_cache_get_size(dpif, i, &size)) {\n+ continue;\n+ }\n+ dpctl_print(dpctl_p, \" %s: size: %u\\n\", name, size);\n+ }\n+}\n+\n+static void\n+show_dpif_cache(struct dpif *dpif, struct dpctl_params *dpctl_p)\n+{\n+ dpctl_print(dpctl_p, \"%s:\\n\", dpif_name(dpif));\n+ show_dpif_cache__(dpif, dpctl_p);\n+}\n+\n static void\n show_dpif(struct dpif *dpif, struct dpctl_params *dpctl_p)\n {\n@@ -623,6 +653,8 @@ show_dpif(struct dpif *dpif, struct dpctl_params *dpctl_p)\n }\n }\n \n+ show_dpif_cache__(dpif, dpctl_p);\n+\n odp_port_t *port_nos = NULL;\n size_t allocated_port_nos = 0, n_port_nos = 0;\n DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {\n@@ -2409,6 +2441,92 @@ dpctl_ct_ipf_get_status(int argc, const char *argv[],\n return error;\n }\n \n+static int\n+dpctl_cache_get_size(int argc, const char *argv[],\n+ struct dpctl_params *dpctl_p)\n+{\n+ int error;\n+\n+ if (argc > 1) {\n+ struct dpif *dpif;\n+\n+ error = parsed_dpif_open(argv[1], false, &dpif);\n+ if (!error) {\n+ show_dpif_cache(dpif, dpctl_p);\n+ dpif_close(dpif);\n+ } else {\n+ dpctl_error(dpctl_p, error, \"Opening datapath %s failed\", argv[1]);\n+ }\n+ } else {\n+ error = dps_for_each(dpctl_p, show_dpif_cache);\n+ }\n+\n+ return error;\n+}\n+\n+static int\n+dpctl_cache_set_size(int argc, const char *argv[],\n+ struct dpctl_params *dpctl_p)\n+{\n+ int i, error = EINVAL;\n+ uint32_t nr_caches, size;\n+ struct dpif *dpif;\n+\n+ if (argc != 4) {\n+ dpctl_error(dpctl_p, error, \"Invalid number of arguments\");\n+ return error;\n+ }\n+\n+ if (!ovs_scan(argv[3], \"%\"SCNu32, &size)) {\n+ dpctl_error(dpctl_p, error, \"size is malformed\");\n+ return error;\n+ }\n+\n+ error = parsed_dpif_open(argv[1], false, &dpif);\n+ if (error) {\n+ dpctl_error(dpctl_p, error, \"Opening datapath %s failed\",\n+ argv[1]);\n+ return error;\n+ }\n+\n+ error = dpif_cache_get_supported_levels(dpif, &nr_caches);\n+ if (error || nr_caches == 0) {\n+ dpctl_error(dpctl_p, error, \"Setting caches not supported\");\n+ goto exit;\n+ }\n+\n+ for (i = 0; i < nr_caches; i++) {\n+ const char *name;\n+\n+ if (dpif_cache_get_name(dpif, i, &name)) {\n+ continue;\n+ }\n+ if (!strcmp(argv[2], name)) {\n+ break;\n+ }\n+ }\n+\n+ if (i == nr_caches) {\n+ error = EINVAL;\n+ dpctl_error(dpctl_p, error, \"Cache name \\\"%s\\\" not found on dpif\",\n+ argv[2]);\n+ goto exit;\n+ }\n+\n+ error = dpif_cache_set_size(dpif, i, size);\n+ if (!error) {\n+ dpif_cache_get_size(dpif, i, &size);\n+ dpctl_print(dpctl_p, \"Setting cache size successful, new size %u\\n\",\n+ size);\n+ } else {\n+ dpctl_error(dpctl_p, error, \"Setting cache size failed\");\n+ }\n+\n+exit:\n+ dpif_close(dpif);\n+ return error;\n+}\n+\n /* Undocumented commands for unit testing. */\n \n static int\n@@ -2710,6 +2828,8 @@ static const struct dpctl_command all_commands[] = {\n 0, 4, dpctl_dump_conntrack, DP_RO },\n { \"flush-conntrack\", \"[dp] [zone=N] [ct-tuple]\", 0, 3,\n dpctl_flush_conntrack, DP_RW },\n+ { \"cache-get-size\", \"[dp]\", 0, 1, dpctl_cache_get_size, DP_RO },\n+ { \"cache-set-size\", \"dp cache <size>\", 3, 3, dpctl_cache_set_size, DP_RW },\n { \"ct-stats-show\", \"[dp] [zone=N]\",\n 0, 3, dpctl_ct_stats_show, DP_RO },\n { \"ct-bkts\", \"[dp] [gt=N]\", 0, 2, dpctl_ct_bkts, DP_RO },\ndiff --git a/lib/dpctl.man b/lib/dpctl.man\nindex 81046ef39..c1361f217 100644\n--- a/lib/dpctl.man\n+++ b/lib/dpctl.man\n@@ -226,6 +226,20 @@ Fetches the flow from \\fIdp\\fR's flow table with unique identifier \\fIufid\\fR.\n .\n .IP \"\\*(DX\\fBdel\\-flows\\fR [\\fIdp\\fR]\"\n Deletes all flow entries from datapath \\fIdp\\fR's flow table.\n+.SS \"DATAPATH FLOW CACHE COMMANDS\"\n+The following commands are useful for debugging and configuring\n+the datapath flow cache settings.\n+.\n+.TP\n+\\*(DX\\fBcache\\-get\\-size\\fR [\\fIdp\\fR]\n+Prints the current cache setting to the console.\n+.\n+.TP\n+\\*(DX\\fBcache\\-set\\-size\\fR \\fIdp\\fR \\fIcache\\fR \\fIsize\\fR\n+Set the \\fIdp\\fR's specific \\fIcache\\fR to the given \\fIsize\\fR.\n+The cache name can be found by using the \\fBcache\\-get\\-size\\fR\n+command.\n+.\n .SS \"CONNECTION TRACKING TABLE COMMANDS\"\n The following commands are useful for debugging and configuring\n the connection tracking table in the datapath.\ndiff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c\nindex 0d0623013..642204b54 100644\n--- a/lib/dpif-netdev.c\n+++ b/lib/dpif-netdev.c\n@@ -8791,6 +8791,10 @@ const struct dpif_class dpif_netdev_class = {\n dpif_netdev_bond_add,\n dpif_netdev_bond_del,\n dpif_netdev_bond_stats_get,\n+ NULL, /* cache_get_supported_levels */\n+ NULL, /* cache_get_name */\n+ NULL, /* cache_get_size */\n+ NULL, /* cache_set_size */\n };\n \n static void\ndiff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c\nindex 70751e634..18bd1125a 100644\n--- a/lib/dpif-netlink.c\n+++ b/lib/dpif-netlink.c\n@@ -98,6 +98,7 @@ struct dpif_netlink_dp {\n const char *name; /* OVS_DP_ATTR_NAME. */\n const uint32_t *upcall_pid; /* OVS_DP_ATTR_UPCALL_PID. */\n uint32_t user_features; /* OVS_DP_ATTR_USER_FEATURES */\n+ uint32_t cache_size; /* OVS_DP_ATTR_MASKS_CACHE_SIZE */\n const struct ovs_dp_stats *stats; /* OVS_DP_ATTR_STATS. */\n const struct ovs_dp_megaflow_stats *megaflow_stats;\n /* OVS_DP_ATTR_MEGAFLOW_STATS.*/\n@@ -4270,6 +4271,104 @@ probe_broken_meters(struct dpif *dpif)\n }\n return broken_meters;\n }\n+\n+\n+static int\n+dpif_netlink_cache_get_supported_levels(struct dpif *dpif_, uint32_t *levels)\n+{\n+ int error;\n+ struct ofpbuf *buf;\n+ struct dpif_netlink_dp dp;\n+\n+ /* If available, in the kernel we support one level of cache.\n+ * Unfortunately, there is no way to detect if the older kernel module has\n+ * the cache feature. For now, we only report the cache information if the\n+ * kernel module reports the OVS_DP_ATTR_MASKS_CACHE_SIZE attribute. */\n+\n+ *levels = 0;\n+ error = dpif_netlink_dp_get(dpif_, &dp, &buf);\n+ if (!error) {\n+\n+ if (dp.cache_size != UINT32_MAX) {\n+ *levels = 1;\n+ }\n+ ofpbuf_delete(buf);\n+ }\n+\n+ return error;\n+}\n+\n+static int\n+dpif_netlink_cache_get_name(struct dpif *dpif_ OVS_UNUSED, uint32_t level,\n+ const char **name)\n+{\n+ if (level != 0) {\n+ return EINVAL;\n+ }\n+\n+ *name = \"masks-cache\";\n+ return 0;\n+}\n+\n+static int\n+dpif_netlink_cache_get_size(struct dpif *dpif_, uint32_t level, uint32_t *size)\n+{\n+ int error;\n+ struct ofpbuf *buf;\n+ struct dpif_netlink_dp dp;\n+\n+ if (level != 0) {\n+ return EINVAL;\n+ }\n+\n+ error = dpif_netlink_dp_get(dpif_, &dp, &buf);\n+ if (!error) {\n+\n+ ofpbuf_delete(buf);\n+\n+ if (dp.cache_size == UINT32_MAX) {\n+ return EOPNOTSUPP;\n+ }\n+ *size = dp.cache_size;\n+ }\n+ return error;\n+}\n+\n+static int\n+dpif_netlink_cache_set_size(struct dpif *dpif_, uint32_t level, uint32_t size)\n+{\n+ int error;\n+ struct ofpbuf *bufp;\n+ struct dpif_netlink_dp request, reply;\n+ struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);\n+\n+ size = ROUND_UP_POW2(size);\n+\n+ if (level != 0) {\n+ return EINVAL;\n+ }\n+\n+ dpif_netlink_dp_init(&request);\n+ request.cmd = OVS_DP_CMD_SET;\n+ request.name = dpif_->base_name;\n+ request.dp_ifindex = dpif->dp_ifindex;\n+ request.cache_size = size;\n+ /* We need to set the dpif user_features, as the kernel module assumes the\n+ * OVS_DP_ATTR_USER_FEATURES attribute is always present. If not, it will\n+ * reset all the features. */\n+ request.user_features = dpif->user_features;\n+\n+ error = dpif_netlink_dp_transact(&request, &reply, &bufp);\n+ if (!error) {\n+ ofpbuf_delete(bufp);\n+ if (reply.cache_size != size) {\n+ return EINVAL;\n+ }\n+ }\n+\n+ return error;\n+}\n+\n \f\n const struct dpif_class dpif_netlink_class = {\n \"system\",\n@@ -4349,6 +4448,10 @@ const struct dpif_class dpif_netlink_class = {\n NULL, /* bond_add */\n NULL, /* bond_del */\n NULL, /* bond_stats_get */\n+ dpif_netlink_cache_get_supported_levels,\n+ dpif_netlink_cache_get_name,\n+ dpif_netlink_cache_get_size,\n+ dpif_netlink_cache_set_size,\n };\n \n static int\n@@ -4612,6 +4715,9 @@ dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf\n [OVS_DP_ATTR_USER_FEATURES] = {\n .type = NL_A_U32,\n .optional = true },\n+ [OVS_DP_ATTR_MASKS_CACHE_SIZE] = {\n+ .type = NL_A_U32,\n+ .optional = true },\n };\n \n dpif_netlink_dp_init(dp);\n@@ -4644,6 +4750,12 @@ dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf\n dp->user_features = nl_attr_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);\n }\n \n+ if (a[OVS_DP_ATTR_MASKS_CACHE_SIZE]) {\n+ dp->cache_size = nl_attr_get_u32(a[OVS_DP_ATTR_MASKS_CACHE_SIZE]);\n+ } else {\n+ dp->cache_size = UINT32_MAX;\n+ }\n+\n return 0;\n }\n \n@@ -4677,6 +4789,10 @@ dpif_netlink_dp_to_ofpbuf(const struct dpif_netlink_dp *dp, struct ofpbuf *buf)\n sizeof *dp->upcall_pids * dp->n_upcall_pids);\n }\n \n+ if (dp->cache_size != UINT32_MAX) {\n+ nl_msg_put_u32(buf, OVS_DP_ATTR_MASKS_CACHE_SIZE, dp->cache_size);\n+ }\n+\n /* Skip OVS_DP_ATTR_STATS since we never have a reason to serialize it. */\n }\n \n@@ -4685,6 +4801,7 @@ static void\n dpif_netlink_dp_init(struct dpif_netlink_dp *dp)\n {\n memset(dp, 0, sizeof *dp);\n+ dp->cache_size = UINT32_MAX;\n }\n \n static void\ndiff --git a/lib/dpif-provider.h b/lib/dpif-provider.h\nindex 7e11b9697..27e3a7658 100644\n--- a/lib/dpif-provider.h\n+++ b/lib/dpif-provider.h\n@@ -635,6 +635,26 @@ struct dpif_class {\n * sufficient to store BOND_BUCKETS number of elements. */\n int (*bond_stats_get)(struct dpif *dpif, uint32_t bond_id,\n uint64_t *n_bytes);\n+\n+ /* Cache configuration\n+ *\n+ * Multiple levels of cache can exist in a given datapath implementation.\n+ * An API has been provided to get the number of supported caches, which\n+ * can then be used to get/set specific configuration. Cache level is 0\n+ * indexed, i.e. if 1 level is supported, the level value to use is 0.\n+ *\n+ * Get the number of cache levels supported. */\n+ int (*cache_get_supported_levels)(struct dpif *dpif, uint32_t *levels);\n+\n+ /* Get the cache name for the given level. */\n+ int (*cache_get_name)(struct dpif *dpif, uint32_t level,\n+ const char **name);\n+\n+ /* Get currently configured cache size. */\n+ int (*cache_get_size)(struct dpif *dpif, uint32_t level, uint32_t *size);\n+\n+ /* Set cache size. */\n+ int (*cache_set_size)(struct dpif *dpif, uint32_t level, uint32_t size);\n };\n \n extern const struct dpif_class dpif_netlink_class;\ndiff --git a/lib/dpif.c b/lib/dpif.c\nindex 8c4aed47b..0b94d6ff0 100644\n--- a/lib/dpif.c\n+++ b/lib/dpif.c\n@@ -2058,3 +2058,35 @@ dpif_get_n_offloaded_flows(struct dpif *dpif, uint64_t *n_flows)\n }\n return n_devs ? 0 : EOPNOTSUPP;\n }\n+\n+int\n+dpif_cache_get_supported_levels(struct dpif *dpif, uint32_t *levels)\n+{\n+ return dpif->dpif_class->cache_get_supported_levels\n+ ? dpif->dpif_class->cache_get_supported_levels(dpif, levels)\n+ : EOPNOTSUPP;\n+}\n+\n+int\n+dpif_cache_get_name(struct dpif *dpif, uint32_t level, const char **name)\n+{\n+ return dpif->dpif_class->cache_get_name\n+ ? dpif->dpif_class->cache_get_name(dpif, level, name)\n+ : EOPNOTSUPP;\n+}\n+\n+int\n+dpif_cache_get_size(struct dpif *dpif, uint32_t level, uint32_t *size)\n+{\n+ return dpif->dpif_class->cache_get_size\n+ ? dpif->dpif_class->cache_get_size(dpif, level, size)\n+ : EOPNOTSUPP;\n+}\n+\n+int\n+dpif_cache_set_size(struct dpif *dpif, uint32_t level, uint32_t size)\n+{\n+ return dpif->dpif_class->cache_set_size\n+ ? dpif->dpif_class->cache_set_size(dpif, level, size)\n+ : EOPNOTSUPP;\n+}\ndiff --git a/lib/dpif.h b/lib/dpif.h\nindex b32ae5fc7..8febfb9f6 100644\n--- a/lib/dpif.h\n+++ b/lib/dpif.h\n@@ -908,6 +908,13 @@ int dpif_bond_del(struct dpif *, uint32_t bond_id);\n int dpif_bond_stats_get(struct dpif *, uint32_t bond_id, uint64_t *n_bytes);\n bool dpif_supports_lb_output_action(const struct dpif *);\n \n+\f\n+/* Cache */\n+int dpif_cache_get_supported_levels(struct dpif *dpif, uint32_t *levels);\n+int dpif_cache_get_name(struct dpif *dpif, uint32_t level, const char **name);\n+int dpif_cache_get_size(struct dpif *dpif, uint32_t level, uint32_t *size);\n+int dpif_cache_set_size(struct dpif *dpif, uint32_t level, uint32_t size);\n+\n \f\n /* Miscellaneous. */\n \ndiff --git a/tests/system-traffic.at b/tests/system-traffic.at\nindex f400cfabc..662ad2a8f 100644\n--- a/tests/system-traffic.at\n+++ b/tests/system-traffic.at\n@@ -1454,6 +1454,42 @@ AT_CHECK([ovs-ofctl dump-flows br0 | grep \"in_port=4\" | ofctl_strip], [0], [dnl\n OVS_TRAFFIC_VSWITCHD_STOP\n AT_CLEANUP\n \n+AT_SETUP([datapath - configure cache size])\n+\n+OVS_TRAFFIC_VSWITCHD_START()\n+OVS_CHECK_KERNEL_EXCL(3, 10, 5, 8)\n+\n+AT_CHECK([ovs-dpctl cache-get-size one-bad-dp], [1], [], [dnl\n+ovs-dpctl: Opening datapath one-bad-dp failed (No such device)\n+])\n+AT_CHECK([ovs-dpctl cache-get-size | grep masks-cache | tr -d [[:blank:]]], [0], [dnl\n+masks-cache:size:256\n+])\n+AT_CHECK([ovs-dpctl cache-set-size one-bad-dp masks-cache 0], [1], [], [dnl\n+ovs-dpctl: Opening datapath one-bad-dp failed (No such device)\n+])\n+AT_CHECK([ovs-dpctl cache-set-size system@ovs-system dummy-cache 0], [1], [], [dnl\n+ovs-dpctl: Cache name \"dummy-cache\" not found on dpif (Invalid argument)\n+])\n+AT_CHECK([ovs-dpctl cache-set-size system@ovs-system masks-cache 80000], [1], [], [dnl\n+ovs-dpctl: Setting cache size failed (Numerical result out of range)\n+])\n+AT_CHECK([ovs-dpctl cache-set-size system@ovs-system masks-cache 0], [0], [dnl\n+Setting cache size successful, new size 0\n+])\n+AT_CHECK([ovs-dpctl cache-get-size | grep masks-cache | tr -d [[:blank:]]], [0], [dnl\n+masks-cache:size:0\n+])\n+AT_CHECK([ovs-dpctl cache-set-size system@ovs-system masks-cache 256], [0], [dnl\n+Setting cache size successful, new size 256\n+])\n+AT_CHECK([ovs-dpctl cache-get-size | grep masks-cache | tr -d [[:blank:]]], [0], [dnl\n+masks-cache:size:256\n+])\n+\n+OVS_TRAFFIC_VSWITCHD_STOP\n+AT_CLEANUP\n+\n AT_BANNER([conntrack])\n \n AT_SETUP([conntrack - controller])\ndiff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c\nindex f616995c3..56d7a942b 100644\n--- a/utilities/ovs-dpctl.c\n+++ b/utilities/ovs-dpctl.c\n@@ -198,6 +198,10 @@ usage(void *userdata OVS_UNUSED)\n \" del-flow [DP] FLOW delete FLOW from DP\\n\"\n \" del-flows [DP] [FILE] \" \\\n \"delete all or specified flows from DP\\n\"\n+ \" cache-get-size [DP] \" \\\n+ \"Show the current size for all caches\\n\"\n+ \" cache-set-size DP CACHE SIZE \" \\\n+ \"Set cache size for a specific cache\\n\"\n \" dump-conntrack [DP] [zone=ZONE] \" \\\n \"display conntrack entries for ZONE\\n\"\n \" flush-conntrack [DP] [zone=ZONE] [ct-tuple]\" \\\n", "prefixes": [ "ovs-dev", "v6", "2/2" ] }{ "id": 1524858, "url": "