diff options
author | Eelco Chaudron <echaudro@redhat.com> | 2021-09-06 10:53:58 +0200 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2021-11-08 21:48:05 +0100 |
commit | 9b20df73a600b00b236c85856b5c92cf9b624e82 (patch) | |
tree | d93550ac28848dfe1849ffea8ebdedee2b5ba71d /lib/dpif-netlink.c | |
parent | efd55eb34cf246d7b65bdae633d9369391dfb5af (diff) | |
download | openvswitch-9b20df73a600b00b236c85856b5c92cf9b624e82.tar.gz |
dpctl: dpif: Allow viewing and configuring dp cache sizes.
This patch adds a general way of viewing/configuring datapath
cache sizes. With an implementation for the netlink interface.
The ovs-dpctl/ovs-appctl show commands will display the
current cache sizes configured:
$ ovs-dpctl show
system@ovs-system:
lookups: hit:25 missed:63 lost:0
flows: 0
masks: hit:282 total:0 hit/pkt:3.20
cache: hit:4 hit-rate:4.54%
caches:
masks-cache: size:256
port 0: ovs-system (internal)
port 1: br-int (internal)
port 2: genev_sys_6081 (geneve: packet_type=ptap)
port 3: br-ex (internal)
port 4: eth2
port 5: sw0p1 (internal)
port 6: sw0p3 (internal)
A specific cache can be configured as follows:
$ ovs-appctl dpctl/cache-set-size DP CACHE SIZE
$ ovs-dpctl cache-set-size DP CACHE SIZE
For example to disable the cache do:
$ ovs-dpctl cache-set-size system@ovs-system masks-cache 0
Setting cache size successful, new size 0.
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Paolo Valerio <pvalerio@redhat.com>
Acked-by: Flavio Leitner <fbl@sysclose.org>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib/dpif-netlink.c')
-rw-r--r-- | lib/dpif-netlink.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index b5d436e66..18cdfe6e5 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -100,6 +100,7 @@ struct dpif_netlink_dp { const char *name; /* OVS_DP_ATTR_NAME. */ const uint32_t *upcall_pid; /* OVS_DP_ATTR_UPCALL_PID. */ uint32_t user_features; /* OVS_DP_ATTR_USER_FEATURES */ + uint32_t cache_size; /* OVS_DP_ATTR_MASKS_CACHE_SIZE */ const struct ovs_dp_stats *stats; /* OVS_DP_ATTR_STATS. */ const struct ovs_dp_megaflow_stats *megaflow_stats; /* OVS_DP_ATTR_MEGAFLOW_STATS.*/ @@ -4298,6 +4299,104 @@ probe_broken_meters(struct dpif *dpif) } return broken_meters; } + + +static int +dpif_netlink_cache_get_supported_levels(struct dpif *dpif_, uint32_t *levels) +{ + struct dpif_netlink_dp dp; + struct ofpbuf *buf; + int error; + + /* If available, in the kernel we support one level of cache. + * Unfortunately, there is no way to detect if the older kernel module has + * the cache feature. For now, we only report the cache information if the + * kernel module reports the OVS_DP_ATTR_MASKS_CACHE_SIZE attribute. */ + + *levels = 0; + error = dpif_netlink_dp_get(dpif_, &dp, &buf); + if (!error) { + + if (dp.cache_size != UINT32_MAX) { + *levels = 1; + } + ofpbuf_delete(buf); + } + + return error; +} + +static int +dpif_netlink_cache_get_name(struct dpif *dpif_ OVS_UNUSED, uint32_t level, + const char **name) +{ + if (level != 0) { + return EINVAL; + } + + *name = "masks-cache"; + return 0; +} + +static int +dpif_netlink_cache_get_size(struct dpif *dpif_, uint32_t level, uint32_t *size) +{ + struct dpif_netlink_dp dp; + struct ofpbuf *buf; + int error; + + if (level != 0) { + return EINVAL; + } + + error = dpif_netlink_dp_get(dpif_, &dp, &buf); + if (!error) { + + ofpbuf_delete(buf); + + if (dp.cache_size == UINT32_MAX) { + return EOPNOTSUPP; + } + *size = dp.cache_size; + } + return error; +} + +static int +dpif_netlink_cache_set_size(struct dpif *dpif_, uint32_t level, uint32_t size) +{ + struct dpif_netlink *dpif = dpif_netlink_cast(dpif_); + struct dpif_netlink_dp request, reply; + struct ofpbuf *bufp; + int error; + + size = ROUND_UP_POW2(size); + + if (level != 0) { + return EINVAL; + } + + dpif_netlink_dp_init(&request); + request.cmd = OVS_DP_CMD_SET; + request.name = dpif_->base_name; + request.dp_ifindex = dpif->dp_ifindex; + request.cache_size = size; + /* We need to set the dpif user_features, as the kernel module assumes the + * OVS_DP_ATTR_USER_FEATURES attribute is always present. If not, it will + * reset all the features. */ + request.user_features = dpif->user_features; + + error = dpif_netlink_dp_transact(&request, &reply, &bufp); + if (!error) { + ofpbuf_delete(bufp); + if (reply.cache_size != size) { + return EINVAL; + } + } + + return error; +} + const struct dpif_class dpif_netlink_class = { "system", @@ -4377,6 +4476,10 @@ const struct dpif_class dpif_netlink_class = { NULL, /* bond_add */ NULL, /* bond_del */ NULL, /* bond_stats_get */ + dpif_netlink_cache_get_supported_levels, + dpif_netlink_cache_get_name, + dpif_netlink_cache_get_size, + dpif_netlink_cache_set_size, }; static int @@ -4640,6 +4743,9 @@ dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf [OVS_DP_ATTR_USER_FEATURES] = { .type = NL_A_U32, .optional = true }, + [OVS_DP_ATTR_MASKS_CACHE_SIZE] = { + .type = NL_A_U32, + .optional = true }, }; dpif_netlink_dp_init(dp); @@ -4672,6 +4778,12 @@ dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf dp->user_features = nl_attr_get_u32(a[OVS_DP_ATTR_USER_FEATURES]); } + if (a[OVS_DP_ATTR_MASKS_CACHE_SIZE]) { + dp->cache_size = nl_attr_get_u32(a[OVS_DP_ATTR_MASKS_CACHE_SIZE]); + } else { + dp->cache_size = UINT32_MAX; + } + return 0; } @@ -4705,6 +4817,10 @@ dpif_netlink_dp_to_ofpbuf(const struct dpif_netlink_dp *dp, struct ofpbuf *buf) sizeof *dp->upcall_pids * dp->n_upcall_pids); } + if (dp->cache_size != UINT32_MAX) { + nl_msg_put_u32(buf, OVS_DP_ATTR_MASKS_CACHE_SIZE, dp->cache_size); + } + /* Skip OVS_DP_ATTR_STATS since we never have a reason to serialize it. */ } @@ -4713,6 +4829,7 @@ static void dpif_netlink_dp_init(struct dpif_netlink_dp *dp) { memset(dp, 0, sizeof *dp); + dp->cache_size = UINT32_MAX; } static void |