From 9f0c6e16e309076ef03bff9965e31d89cb841f9c Mon Sep 17 00:00:00 2001 From: Mike Pattrick Date: Thu, 8 Aug 2024 10:16:54 -0400 Subject: [PATCH] netdev-dpdk: Fix race condition in mempool information dump. Currently it is possible to call netdev-dpdk/get-mempool-info before a mempool as been created. This can happen because a device is added to the netdev_shash before a mempool is allocated for it, which results in a segmentation fault. Now we check for a NULL value before attempting to dereference it. Fixes: be4817331071 ("netdev-dpdk: Add debug appctl to get mempool information.") Signed-off-by: Mike Pattrick Signed-off-by: Ilya Maximets --- lib/netdev-dpdk.c | 25 +++++++++++++++++-------- tests/system-dpdk.at | 6 ++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 02cef6e4513..7cced0f2263 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -4637,10 +4637,11 @@ netdev_dpdk_get_mempool_info(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) { - size_t size; - FILE *stream; - char *response = NULL; struct netdev *netdev = NULL; + const char *error = NULL; + char *response = NULL; + FILE *stream; + size_t size; if (argc == 2) { netdev = netdev_from_name(argv[1]); @@ -4664,10 +4665,14 @@ netdev_dpdk_get_mempool_info(struct unixctl_conn *conn, ovs_mutex_lock(&dev->mutex); ovs_mutex_lock(&dpdk_mp_mutex); - rte_mempool_dump(stream, dev->dpdk_mp->mp); - fprintf(stream, " count: avail (%u), in use (%u)\n", - rte_mempool_avail_count(dev->dpdk_mp->mp), - rte_mempool_in_use_count(dev->dpdk_mp->mp)); + if (dev->dpdk_mp) { + rte_mempool_dump(stream, dev->dpdk_mp->mp); + fprintf(stream, " count: avail (%u), in use (%u)\n", + rte_mempool_avail_count(dev->dpdk_mp->mp), + rte_mempool_in_use_count(dev->dpdk_mp->mp)); + } else { + error = "Not allocated"; + } ovs_mutex_unlock(&dpdk_mp_mutex); ovs_mutex_unlock(&dev->mutex); @@ -4679,7 +4684,11 @@ netdev_dpdk_get_mempool_info(struct unixctl_conn *conn, fclose(stream); - unixctl_command_reply(conn, response); + if (error) { + unixctl_command_reply_error(conn, error); + } else { + unixctl_command_reply(conn, response); + } out: free(response); netdev_close(netdev); diff --git a/tests/system-dpdk.at b/tests/system-dpdk.at index 1c97bf77720..e79c755657a 100644 --- a/tests/system-dpdk.at +++ b/tests/system-dpdk.at @@ -88,6 +88,12 @@ ADD_VHOST_USER_CLIENT_PORT([br10], [dpdkvhostuserclient0], [$OVS_RUNDIR/dpdkvhos AT_CHECK([ovs-vsctl show], [], [stdout]) sleep 2 +dnl Check that no mempool was allocated. +AT_CHECK([ovs-appctl netdev-dpdk/get-mempool-info dpdkvhostuserclient0], [2], [], [dnl +Not allocated +ovs-appctl: ovs-vswitchd: server returned an error +]) + dnl Clean up AT_CHECK([ovs-vsctl del-port br10 dpdkvhostuserclient0], [], [stdout], [stderr]) OVS_DPDK_STOP_VSWITCHD(["dnl