From a718d2df9ae5bb0e86aaad6715b8ec6fb31031bb Mon Sep 17 00:00:00 2001 From: Frank Du Date: Mon, 13 Nov 2023 15:37:37 +0800 Subject: [PATCH] LcoreMgr: add clean_pid_auto_check and clean_lcore support ./build/app/LcoreMgr --clean_pid_auto_check ./build/app/LcoreMgr --clean_lcore 30 Signed-off-by: Frank Du --- app/tools/lcore_shmem_mgr.c | 86 +++++++++++++++++++++++++++++++-- include/mtl_lcore_shm_api.h | 31 ++++++++++++ lib/src/mt_main.c | 31 +----------- lib/src/mt_sch.c | 94 +++++++++++++++++++++++++++++++++++-- lib/src/mt_util.c | 28 +++++++++++ lib/src/mt_util.h | 2 + 6 files changed, 235 insertions(+), 37 deletions(-) diff --git a/app/tools/lcore_shmem_mgr.c b/app/tools/lcore_shmem_mgr.c index 674ab5ae3..ace1acc16 100644 --- a/app/tools/lcore_shmem_mgr.c +++ b/app/tools/lcore_shmem_mgr.c @@ -2,14 +2,94 @@ * Copyright(c) 2023 Intel Corporation */ +#include +#include #include +#include #include "log.h" +enum lsm_args_cmd { + LSM_ARG_UNKNOWN = 0, + LSM_ARG_HELP = 0x100, /* start from end of ascii */ + LSM_ARG_INFO, + LSM_ARG_CLEAN_PID_AUTO_CHECK, + LSM_ARG_CLEAN_LCORE, + LSM_ARG_MAX, +}; + +/* +struct option { + const char *name; + int has_arg; + int *flag; + int val; +}; +*/ +static struct option lsm_args_options[] = { + {"help", no_argument, 0, LSM_ARG_HELP}, + {"info", no_argument, 0, LSM_ARG_INFO}, + {"clean_pid_auto_check", no_argument, 0, LSM_ARG_CLEAN_PID_AUTO_CHECK}, + {"clean_lcore", required_argument, 0, LSM_ARG_CLEAN_LCORE}, + {0, 0, 0, 0}, +}; + +static void lsm_print_help() { + printf("\n"); + printf("##### Usage: #####\n\n"); + + printf("Params:\n"); + printf(" --help: Print the help information\n"); + printf(" --info: Print lcore shared manager detail info\n"); + printf(" --info: Print lcore shared manager detail info\n"); + printf(" --clean_pid_auto_check: Clean the dead entries if PID is not active\n"); + printf(" --clean_lcore : Clean the entry by lcore ID\n"); + + printf("\n"); +} + int main(int argc, char** argv) { - MTL_MAY_UNUSED(argc); - MTL_MAY_UNUSED(argv); + int cmd = -1, opt_idx = 0; + int ret; + + while (1) { + cmd = getopt_long_only(argc, argv, "hv", lsm_args_options, &opt_idx); + if (cmd == -1) break; + + switch (cmd) { + case LSM_ARG_INFO: + mtl_lcore_shm_print(); + break; + case LSM_ARG_CLEAN_PID_AUTO_CHECK: + ret = mtl_lcore_shm_clean(MTL_LCORE_CLEAN_PID_AUTO_CHECK, NULL, 0); + if (ret > 0) + info("Total %d dead lcores detected and deleted\n", ret); + else if (ret == 0) + info("No dead lcores detected\n"); + else + err("Fail %d to clean shm by auto PID check\n", ret); + break; + case LSM_ARG_CLEAN_LCORE: + int lcore = atoi(optarg); + if (lcore < 0) { + err("lcore %d is not valid\n", lcore); + return -EIO; + } + struct mtl_lcore_clean_pid_info pid; + pid.lcore = lcore; + ret = mtl_lcore_shm_clean(MTL_LCORE_CLEAN_LCORE, &pid, sizeof(pid)); + if (ret >= 0) + info("Succ to delete lcore %d\n", lcore); + else + err("Fail %d to delete lcore %d\n", ret, lcore); + break; + break; + case LSM_ARG_HELP: + default: + lsm_print_help(); + return -1; + } + } - mtl_lcore_shm_print(); return 0; } \ No newline at end of file diff --git a/include/mtl_lcore_shm_api.h b/include/mtl_lcore_shm_api.h index c55002a7a..e1db99a5c 100644 --- a/include/mtl_lcore_shm_api.h +++ b/include/mtl_lcore_shm_api.h @@ -18,6 +18,22 @@ extern "C" { #endif +struct mtl_lcore_clean_pid_info { + uint32_t lcore; +}; + +/** lcore clean action */ +enum mtl_lcore_clean_action { + /** auto, no args. + * Remove lcore usage if the PID is inactive under the same hostname and user. + */ + MTL_LCORE_CLEAN_PID_AUTO_CHECK = 0, + /** clean as PID info, args to struct mtl_lcore_clean_pid_info */ + MTL_LCORE_CLEAN_LCORE, + /** max value of this enum */ + MTL_LCORE_CLEAN_MAX, +}; + /** * Print out the legacy lcore manager(shared memory) status. * @@ -27,6 +43,21 @@ extern "C" { */ int mtl_lcore_shm_print(void); +/** + * Clean the unused lcore from the legacy lcore manager(shared memory). + * @param action + * The action type. + * @param args + * The args to the action type. + * @param args_sz + * The size of the args. + * + * @return + * - 0 if successful. + * - <0: Error code if fail. + */ +int mtl_lcore_shm_clean(enum mtl_lcore_clean_action action, void* args, size_t args_sz); + #if defined(__cplusplus) } #endif diff --git a/lib/src/mt_main.c b/lib/src/mt_main.c index e1aa9a10b..ebe02c509 100644 --- a/lib/src/mt_main.c +++ b/lib/src/mt_main.c @@ -4,10 +4,6 @@ #include "mt_main.h" -#ifndef WINDOWSENV -#include -#endif - #include "datapath/mt_queue.h" #include "dev/mt_dev.h" #include "mt_admin.h" @@ -402,31 +398,6 @@ static int _mt_stop(struct mtl_main_impl* impl) { return 0; } -static int mt_user_info_init(struct mtl_main_impl* impl) { - int ret = -EIO; - struct mt_user_info* info = &impl->u_info; - -#ifdef WINDOWSENV /* todo */ - MTL_MAY_UNUSED(ret); - snprintf(info->hostname, sizeof(info->hostname), "%s", "unknow"); - snprintf(info->user, sizeof(info->user), "%s", "unknow"); -#else - ret = gethostname(info->hostname, sizeof(info->hostname)); - if (ret < 0) { - warn("%s, gethostname fail %d\n", __func__, ret); - snprintf(info->hostname, sizeof(info->hostname), "%s", "unknow"); - } - uid_t uid = getuid(); - struct passwd* user_info = getpwuid(uid); - snprintf(info->user, sizeof(info->user), "%s", - user_info ? user_info->pw_name : "unknow"); -#endif - - info->pid = getpid(); - - return 0; -} - mtl_handle mtl_init(struct mtl_init_params* p) { struct mtl_main_impl* impl = NULL; int socket[MTL_PORT_MAX], ret; @@ -493,7 +464,7 @@ mtl_handle mtl_init(struct mtl_init_params* p) { impl = mt_rte_zmalloc_socket(sizeof(*impl), socket[MTL_PORT_P]); if (!impl) goto err_exit; - mt_user_info_init(impl); + mt_user_info_init(&impl->u_info); #ifndef WINDOWSENV if (geteuid() == 0) diff --git a/lib/src/mt_sch.c b/lib/src/mt_sch.c index eab0f53ae..5ed908c41 100644 --- a/lib/src/mt_sch.c +++ b/lib/src/mt_sch.c @@ -4,8 +4,11 @@ #include "mt_sch.h" +#include + #include "mt_log.h" #include "mt_stat.h" +#include "mtl_lcore_shm_api.h" #include "st2110/st_rx_ancillary_session.h" #include "st2110/st_rx_audio_session.h" #include "st2110/st_rx_video_session.h" @@ -1038,12 +1041,95 @@ int mtl_lcore_shm_print(void) { for (int i = 0; i < RTE_MAX_LCORE; i++) { shm_entry = &lcore_shm->lcores_info[i]; - if (shm_entry->active) { - info("%s, lcore %d active on %s@%s with pid: %d\n", __func__, i, shm_entry->user, - shm_entry->hostname, (int)shm_entry->pid); - } + + if (!shm_entry->active) continue; + info("%s, lcore %d active on %s@%s with pid: %d\n", __func__, i, shm_entry->user, + shm_entry->hostname, (int)shm_entry->pid); } sch_lcore_shm_uinit(&lcore_mgr); return 0; } + +static int lcore_shm_clean_auto_pid(struct mt_lcore_mgr* lcore_mgr) { + struct mt_user_info u_info; + int clean = 0; + + memset(&u_info, 0, sizeof(u_info)); + mt_user_info_init(&u_info); + + struct mt_lcore_shm* lcore_shm = lcore_mgr->lcore_shm; + struct mt_lcore_shm_entry* shm_entry; + for (int i = 0; i < RTE_MAX_LCORE; i++) { + shm_entry = &lcore_shm->lcores_info[i]; + + if (!shm_entry->active) continue; + if (0 != strncmp(shm_entry->hostname, u_info.hostname, sizeof(shm_entry->hostname))) + continue; + if (0 != strncmp(shm_entry->user, u_info.user, sizeof(shm_entry->user))) continue; + /* now check if PID is active with zero signal */ + int result = kill(shm_entry->pid, 0); + if (0 == result) continue; + clean++; + notice("%s, delete dead lcore %d from the shared mem, PID %d\n", __func__, i, + (int)shm_entry->pid); + } + + return clean; +} + +static int lcore_shm_clean_id(struct mt_lcore_mgr* lcore_mgr, void* args, + size_t args_sz) { + struct mtl_lcore_clean_pid_info* info = args; + + if (!args) { + err("%s, NULL args\n", __func__); + return -EINVAL; + } + if (args_sz != sizeof(*info)) { + err("%s, error args_sz %" PRIu64 "\n", __func__, args_sz); + return -EINVAL; + } + uint32_t lcore = info->lcore; + if (lcore >= RTE_MAX_LCORE) { + err("%s, invalid lcore %u\n", __func__, lcore); + return -EINVAL; + } + + struct mt_lcore_shm* lcore_shm = lcore_mgr->lcore_shm; + struct mt_lcore_shm_entry* shm_entry = &lcore_shm->lcores_info[lcore]; + if (!shm_entry->active) { + err("%s, lcore %u is inactive\n", __func__, lcore); + return -EINVAL; + } + + shm_entry->active = false; + notice("%s, delete lcore %u from the shared mem, PID %d\n", __func__, lcore, + (int)shm_entry->pid); + return 0; +} + +int mtl_lcore_shm_clean(enum mtl_lcore_clean_action action, void* args, size_t args_sz) { + struct mt_lcore_mgr lcore_mgr; + + int ret = sch_lcore_shm_init(&lcore_mgr, false); + if (ret < 0) return ret; + + MTL_MAY_UNUSED(args); + MTL_MAY_UNUSED(args_sz); + switch (action) { + case MTL_LCORE_CLEAN_PID_AUTO_CHECK: + ret = lcore_shm_clean_auto_pid(&lcore_mgr); + break; + case MTL_LCORE_CLEAN_LCORE: + ret = lcore_shm_clean_id(&lcore_mgr, args, args_sz); + break; + default: + err("%s, unknown action %d\n", __func__, action); + ret = -EINVAL; + break; + } + + sch_lcore_shm_uinit(&lcore_mgr); + return ret; +} diff --git a/lib/src/mt_util.c b/lib/src/mt_util.c index 517b05eef..27d5687af 100644 --- a/lib/src/mt_util.c +++ b/lib/src/mt_util.c @@ -4,6 +4,10 @@ #include "mt_util.h" +#ifndef WINDOWSENV +#include +#endif + #include "datapath/mt_queue.h" #include "mt_log.h" #include "mt_main.h" @@ -879,3 +883,27 @@ const char* mt_native_afxdp_port2if(const char* port) { } return port + strlen(native_afxdp_port_prefix); } + +int mt_user_info_init(struct mt_user_info* info) { + int ret = -EIO; + +#ifdef WINDOWSENV /* todo */ + MTL_MAY_UNUSED(ret); + snprintf(info->hostname, sizeof(info->hostname), "%s", "unknow"); + snprintf(info->user, sizeof(info->user), "%s", "unknow"); +#else + ret = gethostname(info->hostname, sizeof(info->hostname)); + if (ret < 0) { + warn("%s, gethostname fail %d\n", __func__, ret); + snprintf(info->hostname, sizeof(info->hostname), "%s", "unknow"); + } + uid_t uid = getuid(); + struct passwd* user_info = getpwuid(uid); + snprintf(info->user, sizeof(info->user), "%s", + user_info ? user_info->pw_name : "unknow"); +#endif + + info->pid = getpid(); + + return 0; +} diff --git a/lib/src/mt_util.h b/lib/src/mt_util.h index 10391d97d..3df56425e 100644 --- a/lib/src/mt_util.h +++ b/lib/src/mt_util.h @@ -251,4 +251,6 @@ const char* mt_dpdk_afpkt_port2if(const char* port); const char* mt_kernel_port2if(const char* port); const char* mt_native_afxdp_port2if(const char* port); +int mt_user_info_init(struct mt_user_info* info); + #endif