From 45124b06374eebfec91047401c2e84d6ee46d80d 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 6c22afbceae..3134eb42d34 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -3834,10 +3834,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]); @@ -3861,10 +3862,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); @@ -3876,7 +3881,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 52eaae8b72b..e8829d01e12 100644 --- a/tests/system-dpdk.at +++ b/tests/system-dpdk.at @@ -82,6 +82,12 @@ AT_CHECK([grep "VHOST_CONFIG: vhost-user client: socket created" ovs-vswitchd.lo AT_CHECK([grep "vHost User device 'dpdkvhostuserclient0' created in 'client' mode, using client socket" ovs-vswitchd.log], [], [stdout]) AT_CHECK([grep "VHOST_CONFIG: $OVS_RUNDIR/dpdkvhostclient0: reconnecting..." ovs-vswitchd.log], [], [stdout]) +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_VSWITCHD_STOP("m4_join([], [SYSTEM_DPDK_ALLOWED_LOGS], [