From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BFE4541D3D; Fri, 10 Mar 2023 09:21:50 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C554C42D46; Fri, 10 Mar 2023 09:20:42 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 94A3740685 for ; Fri, 10 Mar 2023 09:20:28 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 32A7uId8021875 for ; Fri, 10 Mar 2023 00:20:28 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0220; bh=I0o7HE4dEvwmgtfFpIvw6QX8bKVmXCBaCVCOnFP9nZA=; b=FldAoTvJmfxrFTQ14yicbeQNWJa+zQ70EX78OG+oxltWHDpCwDQOtFfSpW8E/l6KScGW BUBy/Mz8uBgc91Slmv8+9wHGKuQJIezwbD8CTyiq8I9cIwAeeUTJgC/crIrajhk+hO32 IQoVJV1PsPX1GyFcmh3Olnkg2rSXzIXNdxcJ9TpSVFUH7a8VV6/PLL2Hjh5wqQXjv76j pyNhW2UQ4Cm6ovUIxg8NMajjAtA9sRXdNSz1E2jKTMoU8uCA4awyd3ot+xXuB5f4nhB6 a1XqnWP4WXTBFAhFLkMUM0RqEPbkxeYisGvGwHgoPOTx54QaA2B63qvuXT72ZxRVWov4 2g== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3p80k782tf-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Fri, 10 Mar 2023 00:20:27 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Fri, 10 Mar 2023 00:20:22 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.42 via Frontend Transport; Fri, 10 Mar 2023 00:20:22 -0800 Received: from ml-host-33.caveonetworks.com (unknown [10.110.143.233]) by maili.marvell.com (Postfix) with ESMTP id 0BCE15C6906; Fri, 10 Mar 2023 00:20:20 -0800 (PST) From: Srikanth Yalavarthi To: Srikanth Yalavarthi CC: , , , , , Subject: [PATCH v6 11/39] ml/cnxk: add functions to load and unload models Date: Fri, 10 Mar 2023 00:19:47 -0800 Message-ID: <20230310082015.20200-12-syalavarthi@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230310082015.20200-1-syalavarthi@marvell.com> References: <20221208200220.20267-1-syalavarthi@marvell.com> <20230310082015.20200-1-syalavarthi@marvell.com> MIME-Version: 1.0 Content-Type: text/plain X-Proofpoint-GUID: lRPtgXr40rSg1hUliyOP8FovqW0lMB1g X-Proofpoint-ORIG-GUID: lRPtgXr40rSg1hUliyOP8FovqW0lMB1g X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-03-10_02,2023-03-09_01,2023-02-09_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Added cnxk driver implementations to load and unload ML models. Enabled support in configure stage to allocate model handles array. Assign model ID and allocate resources per each model during load stage and release resources during model unload. Added internal structures to handle ML models. Signed-off-by: Srikanth Yalavarthi --- drivers/ml/cnxk/cn10k_ml_dev.h | 3 + drivers/ml/cnxk/cn10k_ml_model.c | 5 + drivers/ml/cnxk/cn10k_ml_model.h | 40 ++++++++ drivers/ml/cnxk/cn10k_ml_ops.c | 154 +++++++++++++++++++++++++++++++ drivers/ml/cnxk/cn10k_ml_ops.h | 5 + drivers/ml/cnxk/meson.build | 2 + 6 files changed, 209 insertions(+) create mode 100644 drivers/ml/cnxk/cn10k_ml_model.c create mode 100644 drivers/ml/cnxk/cn10k_ml_model.h diff --git a/drivers/ml/cnxk/cn10k_ml_dev.h b/drivers/ml/cnxk/cn10k_ml_dev.h index 00d23eb3ca..7cf6268115 100644 --- a/drivers/ml/cnxk/cn10k_ml_dev.h +++ b/drivers/ml/cnxk/cn10k_ml_dev.h @@ -214,6 +214,9 @@ struct cn10k_ml_dev { /* Firmware */ struct cn10k_ml_fw fw; + + /* Number of models loaded */ + uint16_t nb_models_loaded; }; uint64_t cn10k_ml_fw_flags_get(struct cn10k_ml_fw *fw); diff --git a/drivers/ml/cnxk/cn10k_ml_model.c b/drivers/ml/cnxk/cn10k_ml_model.c new file mode 100644 index 0000000000..39ed707396 --- /dev/null +++ b/drivers/ml/cnxk/cn10k_ml_model.c @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Marvell. + */ + +#include "cn10k_ml_model.h" diff --git a/drivers/ml/cnxk/cn10k_ml_model.h b/drivers/ml/cnxk/cn10k_ml_model.h new file mode 100644 index 0000000000..a9f7b169de --- /dev/null +++ b/drivers/ml/cnxk/cn10k_ml_model.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2022 Marvell. + */ + +#ifndef _CN10K_ML_MODEL_H_ +#define _CN10K_ML_MODEL_H_ + +#include + +#include + +#include "cn10k_ml_dev.h" + +/* Model state */ +enum cn10k_ml_model_state { + ML_CN10K_MODEL_STATE_LOADED, + ML_CN10K_MODEL_STATE_JOB_ACTIVE, + ML_CN10K_MODEL_STATE_STARTED, + ML_CN10K_MODEL_STATE_UNKNOWN, +}; + +/* Model Object */ +struct cn10k_ml_model { + /* Device reference */ + struct cn10k_ml_dev *mldev; + + /* Name */ + char name[RTE_ML_STR_MAX]; + + /* ID */ + uint16_t model_id; + + /* Spinlock, used to update model state */ + plt_spinlock_t lock; + + /* State */ + enum cn10k_ml_model_state state; +}; + +#endif /* _CN10K_ML_MODEL_H_ */ diff --git a/drivers/ml/cnxk/cn10k_ml_ops.c b/drivers/ml/cnxk/cn10k_ml_ops.c index 82670330d1..0955fa0d76 100644 --- a/drivers/ml/cnxk/cn10k_ml_ops.c +++ b/drivers/ml/cnxk/cn10k_ml_ops.c @@ -6,8 +6,12 @@ #include #include "cn10k_ml_dev.h" +#include "cn10k_ml_model.h" #include "cn10k_ml_ops.h" +/* ML model macros */ +#define CN10K_ML_MODEL_MEMZONE_NAME "ml_cn10k_model_mz" + static void qp_memzone_name_get(char *name, int size, int dev_id, int qp_id) { @@ -120,9 +124,11 @@ static int cn10k_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *conf) { struct rte_ml_dev_info dev_info; + struct cn10k_ml_model *model; struct cn10k_ml_dev *mldev; struct cn10k_ml_qp *qp; uint32_t mz_size; + uint16_t model_id; uint16_t qp_id; int ret; @@ -203,6 +209,48 @@ cn10k_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *c } dev->data->nb_queue_pairs = conf->nb_queue_pairs; + /* Allocate ML models */ + if (dev->data->models == NULL) { + mz_size = sizeof(dev->data->models[0]) * conf->nb_models; + dev->data->models = rte_zmalloc("cn10k_mldev_models", mz_size, RTE_CACHE_LINE_SIZE); + if (dev->data->models == NULL) { + dev->data->nb_models = 0; + plt_err("Failed to get memory for ml_models, nb_models %u", + conf->nb_models); + ret = -ENOMEM; + goto error; + } + } else { + /* Re-configure */ + void **models; + + /* Unload all models */ + for (model_id = 0; model_id < dev->data->nb_models; model_id++) { + model = dev->data->models[model_id]; + if (model != NULL) { + if (model->state == ML_CN10K_MODEL_STATE_LOADED) { + if (cn10k_ml_model_unload(dev, model_id) != 0) + plt_err("Could not unload model %u", model_id); + } + dev->data->models[model_id] = NULL; + } + } + + models = dev->data->models; + models = rte_realloc(models, sizeof(models[0]) * conf->nb_models, + RTE_CACHE_LINE_SIZE); + if (models == NULL) { + dev->data->nb_models = 0; + plt_err("Failed to realloc ml_models, nb_models = %u", conf->nb_models); + ret = -ENOMEM; + goto error; + } + memset(models, 0, sizeof(models[0]) * conf->nb_models); + dev->data->models = models; + } + dev->data->nb_models = conf->nb_models; + + mldev->nb_models_loaded = 0; mldev->state = ML_CN10K_DEV_STATE_CONFIGURED; return 0; @@ -211,14 +259,19 @@ cn10k_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *c if (dev->data->queue_pairs != NULL) rte_free(dev->data->queue_pairs); + if (dev->data->models != NULL) + rte_free(dev->data->models); + return ret; } static int cn10k_ml_dev_close(struct rte_ml_dev *dev) { + struct cn10k_ml_model *model; struct cn10k_ml_dev *mldev; struct cn10k_ml_qp *qp; + uint16_t model_id; uint16_t qp_id; if (dev == NULL) @@ -226,6 +279,21 @@ cn10k_ml_dev_close(struct rte_ml_dev *dev) mldev = dev->data->dev_private; + /* Unload all models */ + for (model_id = 0; model_id < dev->data->nb_models; model_id++) { + model = dev->data->models[model_id]; + if (model != NULL) { + if (model->state == ML_CN10K_MODEL_STATE_LOADED) { + if (cn10k_ml_model_unload(dev, model_id) != 0) + plt_err("Could not unload model %u", model_id); + } + dev->data->models[model_id] = NULL; + } + } + + if (dev->data->models) + rte_free(dev->data->models); + /* Destroy all queue pairs */ for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) { qp = dev->data->queue_pairs[qp_id]; @@ -337,6 +405,88 @@ cn10k_ml_dev_queue_pair_setup(struct rte_ml_dev *dev, uint16_t queue_pair_id, return 0; } +int +cn10k_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params, uint16_t *model_id) +{ + struct cn10k_ml_model *model; + struct cn10k_ml_dev *mldev; + + char str[RTE_MEMZONE_NAMESIZE]; + const struct plt_memzone *mz; + uint64_t mz_size; + uint16_t idx; + bool found; + + PLT_SET_USED(params); + + mldev = dev->data->dev_private; + + /* Find model ID */ + found = false; + for (idx = 0; idx < dev->data->nb_models; idx++) { + if (dev->data->models[idx] == NULL) { + found = true; + break; + } + } + + if (!found) { + plt_err("No slots available to load new model"); + return -ENOMEM; + } + + /* Compute memzone size */ + mz_size = PLT_ALIGN_CEIL(sizeof(struct cn10k_ml_model), ML_CN10K_ALIGN_SIZE); + + /* Allocate memzone for model object and model data */ + snprintf(str, RTE_MEMZONE_NAMESIZE, "%s_%u", CN10K_ML_MODEL_MEMZONE_NAME, idx); + mz = plt_memzone_reserve_aligned(str, mz_size, 0, ML_CN10K_ALIGN_SIZE); + if (!mz) { + plt_err("plt_memzone_reserve failed : %s", str); + return -ENOMEM; + } + + model = mz->addr; + model->mldev = mldev; + model->model_id = idx; + + plt_spinlock_init(&model->lock); + model->state = ML_CN10K_MODEL_STATE_LOADED; + dev->data->models[idx] = model; + mldev->nb_models_loaded++; + + *model_id = idx; + + return 0; +} + +int +cn10k_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id) +{ + char str[RTE_MEMZONE_NAMESIZE]; + struct cn10k_ml_model *model; + struct cn10k_ml_dev *mldev; + + mldev = dev->data->dev_private; + model = dev->data->models[model_id]; + + if (model == NULL) { + plt_err("Invalid model_id = %u", model_id); + return -EINVAL; + } + + if (model->state != ML_CN10K_MODEL_STATE_LOADED) { + plt_err("Cannot unload. Model in use."); + return -EBUSY; + } + + dev->data->models[model_id] = NULL; + mldev->nb_models_loaded--; + + snprintf(str, RTE_MEMZONE_NAMESIZE, "%s_%u", CN10K_ML_MODEL_MEMZONE_NAME, model_id); + return plt_memzone_free(plt_memzone_lookup(str)); +} + struct rte_ml_dev_ops cn10k_ml_ops = { /* Device control ops */ .dev_info_get = cn10k_ml_dev_info_get, @@ -348,4 +498,8 @@ struct rte_ml_dev_ops cn10k_ml_ops = { /* Queue-pair handling ops */ .dev_queue_pair_setup = cn10k_ml_dev_queue_pair_setup, .dev_queue_pair_release = cn10k_ml_dev_queue_pair_release, + + /* Model ops */ + .model_load = cn10k_ml_model_load, + .model_unload = cn10k_ml_model_unload, }; diff --git a/drivers/ml/cnxk/cn10k_ml_ops.h b/drivers/ml/cnxk/cn10k_ml_ops.h index 289c7c5587..d7842ecd73 100644 --- a/drivers/ml/cnxk/cn10k_ml_ops.h +++ b/drivers/ml/cnxk/cn10k_ml_ops.h @@ -53,4 +53,9 @@ struct cn10k_ml_qp { /* Device ops */ extern struct rte_ml_dev_ops cn10k_ml_ops; +/* Slow-path ops */ +int cn10k_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params, + uint16_t *model_id); +int cn10k_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id); + #endif /* _CN10K_ML_OPS_H_ */ diff --git a/drivers/ml/cnxk/meson.build b/drivers/ml/cnxk/meson.build index 7dc8a29a80..bf7a9c0225 100644 --- a/drivers/ml/cnxk/meson.build +++ b/drivers/ml/cnxk/meson.build @@ -10,11 +10,13 @@ endif driver_sdk_headers = files( 'cn10k_ml_dev.h', 'cn10k_ml_ops.h', + 'cn10k_ml_model.h', ) sources = files( 'cn10k_ml_dev.c', 'cn10k_ml_ops.c', + 'cn10k_ml_model.c', ) deps += ['mldev', 'common_cnxk', 'kvargs'] -- 2.17.1