get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/132780/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 132780,
    "url": "http://patches.dpdk.org/api/patches/132780/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231017165951.27299-10-syalavarthi@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20231017165951.27299-10-syalavarthi@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231017165951.27299-10-syalavarthi@marvell.com",
    "date": "2023-10-17T16:59:22",
    "name": "[v4,09/34] ml/cnxk: update model load and unload functions",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "ecccf1ed64e3082532a2cefaf6ca0a6a97c5d6c8",
    "submitter": {
        "id": 2480,
        "url": "http://patches.dpdk.org/api/people/2480/?format=api",
        "name": "Srikanth Yalavarthi",
        "email": "syalavarthi@marvell.com"
    },
    "delegate": {
        "id": 310,
        "url": "http://patches.dpdk.org/api/users/310/?format=api",
        "username": "jerin",
        "first_name": "Jerin",
        "last_name": "Jacob",
        "email": "jerinj@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20231017165951.27299-10-syalavarthi@marvell.com/mbox/",
    "series": [
        {
            "id": 29890,
            "url": "http://patches.dpdk.org/api/series/29890/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29890",
            "date": "2023-10-17T16:59:13",
            "name": "Implementation of revised ml/cnxk driver",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/29890/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/132780/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/132780/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id E9E144318E;\n\tTue, 17 Oct 2023 19:02:14 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 65D1D42E38;\n\tTue, 17 Oct 2023 19:00:25 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 552AE42DF1\n for <dev@dpdk.org>; Tue, 17 Oct 2023 19:00:13 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 39HCUgW8018897 for <dev@dpdk.org>; Tue, 17 Oct 2023 10:00:12 -0700",
            "from dc5-exch02.marvell.com ([199.233.59.182])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3tstb3s9m1-5\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Tue, 17 Oct 2023 10:00:12 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Tue, 17 Oct 2023 10:00:05 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Tue, 17 Oct 2023 10:00:05 -0700",
            "from ml-host-33.caveonetworks.com (unknown [10.110.143.233])\n by maili.marvell.com (Postfix) with ESMTP id 6A74D5B6944;\n Tue, 17 Oct 2023 10:00:05 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=6Ch3TSIf1/iuOybC3KiKb9ip5/z8fAwPMRUqA/YzwDY=;\n b=B7QQpbxUt2gvGsr5gRPLrIywjz56Wp9K8xHb9fHj3xRfkuNFparQtHsGcemUG6t6GN6T\n hSQBWfqU7DLtO0WCPhSHY342ca0MTmPXeRCyMBQLd3JoFbiG+DcSJ/xrerJyuRR1Y9ZW\n VDvCj2brMx1C/7dMezG2ObjYzcfBTysGq2TSq2Z521hqnTUTT8QNydPqpbBrvPxEi1+S\n gYGxvJuNXFplUvWK8IOCOpqA30tCx7fsNsq8DCTFGWw/bndRfKRLdMA5wOeC4qjhYtQy\n sdli43nQsxOteNkQb9nWSkgLxRT9dZHj3GnUJqEXe7ekcicqBzAyPc4hZiMzxV/f7uog +w==",
        "From": "Srikanth Yalavarthi <syalavarthi@marvell.com>",
        "To": "Srikanth Yalavarthi <syalavarthi@marvell.com>",
        "CC": "<dev@dpdk.org>, <sshankarnara@marvell.com>, <aprabhu@marvell.com>,\n <ptakkar@marvell.com>",
        "Subject": "[PATCH v4 09/34] ml/cnxk: update model load and unload functions",
        "Date": "Tue, 17 Oct 2023 09:59:22 -0700",
        "Message-ID": "<20231017165951.27299-10-syalavarthi@marvell.com>",
        "X-Mailer": "git-send-email 2.42.0",
        "In-Reply-To": "<20231017165951.27299-1-syalavarthi@marvell.com>",
        "References": "<20230830155927.3566-1-syalavarthi@marvell.com>\n <20231017165951.27299-1-syalavarthi@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "rDhrx48_l0a3BwZXoB6ySryc6OpDXqa6",
        "X-Proofpoint-GUID": "rDhrx48_l0a3BwZXoB6ySryc6OpDXqa6",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.272,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26\n definitions=2023-10-17_03,2023-10-17_01,2023-05-22_02",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Implemented cnxk wrapper functions to load and unload\nML models. Wrapper functions would invoke the cn10k\nmodel load and unload functions.\n\nSigned-off-by: Srikanth Yalavarthi <syalavarthi@marvell.com>\n---\n drivers/ml/cnxk/cn10k_ml_model.c | 244 ++++++++++++-------------\n drivers/ml/cnxk/cn10k_ml_model.h |  26 ++-\n drivers/ml/cnxk/cn10k_ml_ops.c   | 296 ++++++++++++++++++-------------\n drivers/ml/cnxk/cn10k_ml_ops.h   |  12 +-\n drivers/ml/cnxk/cnxk_ml_dev.h    |  15 ++\n drivers/ml/cnxk/cnxk_ml_ops.c    | 144 ++++++++++++++-\n drivers/ml/cnxk/cnxk_ml_ops.h    |   2 +\n 7 files changed, 462 insertions(+), 277 deletions(-)",
    "diff": "diff --git a/drivers/ml/cnxk/cn10k_ml_model.c b/drivers/ml/cnxk/cn10k_ml_model.c\nindex 5d37e9bf8a..69a60b9b90 100644\n--- a/drivers/ml/cnxk/cn10k_ml_model.c\n+++ b/drivers/ml/cnxk/cn10k_ml_model.c\n@@ -316,42 +316,31 @@ cn10k_ml_layer_addr_update(struct cnxk_ml_layer *layer, uint8_t *buffer, uint8_t\n {\n \tstruct cn10k_ml_model_metadata *metadata;\n \tstruct cn10k_ml_layer_addr *addr;\n-\tsize_t model_data_size;\n \tuint8_t *dma_addr_load;\n-\tuint8_t *dma_addr_run;\n \tint fpos;\n \n \tmetadata = &layer->glow.metadata;\n \taddr = &layer->glow.addr;\n-\tmodel_data_size = metadata->init_model.file_size + metadata->main_model.file_size +\n-\t\t\t  metadata->finish_model.file_size + metadata->weights_bias.file_size;\n \n \t/* Base address */\n \taddr->base_dma_addr_load = base_dma_addr;\n-\taddr->base_dma_addr_run = PLT_PTR_ADD(addr->base_dma_addr_load, model_data_size);\n \n \t/* Init section */\n \tdma_addr_load = addr->base_dma_addr_load;\n-\tdma_addr_run = addr->base_dma_addr_run;\n \tfpos = sizeof(struct cn10k_ml_model_metadata);\n \taddr->init_load_addr = dma_addr_load;\n-\taddr->init_run_addr = dma_addr_run;\n \trte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->init_model.file_size);\n \n \t/* Main section */\n \tdma_addr_load += metadata->init_model.file_size;\n-\tdma_addr_run += metadata->init_model.file_size;\n \tfpos += metadata->init_model.file_size;\n \taddr->main_load_addr = dma_addr_load;\n-\taddr->main_run_addr = dma_addr_run;\n \trte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->main_model.file_size);\n \n \t/* Finish section */\n \tdma_addr_load += metadata->main_model.file_size;\n-\tdma_addr_run += metadata->main_model.file_size;\n \tfpos += metadata->main_model.file_size;\n \taddr->finish_load_addr = dma_addr_load;\n-\taddr->finish_run_addr = dma_addr_run;\n \trte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->finish_model.file_size);\n \n \t/* Weights and Bias section */\n@@ -363,140 +352,146 @@ cn10k_ml_layer_addr_update(struct cnxk_ml_layer *layer, uint8_t *buffer, uint8_t\n }\n \n void\n-cn10k_ml_layer_info_update(struct cnxk_ml_layer *layer)\n+cn10k_ml_layer_io_info_set(struct cnxk_ml_io_info *io_info,\n+\t\t\t   struct cn10k_ml_model_metadata *metadata)\n {\n-\tstruct cn10k_ml_model_metadata *metadata;\n \tuint8_t i;\n \tuint8_t j;\n \n-\tmetadata = &layer->glow.metadata;\n-\n \t/* Inputs */\n-\tlayer->info.nb_inputs = metadata->model.num_input;\n-\tlayer->info.total_input_sz_d = 0;\n-\tlayer->info.total_input_sz_q = 0;\n+\tio_info->nb_inputs = metadata->model.num_input;\n+\tio_info->total_input_sz_d = 0;\n+\tio_info->total_input_sz_q = 0;\n \tfor (i = 0; i < metadata->model.num_input; i++) {\n \t\tif (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {\n-\t\t\tstrncpy(layer->info.input[i].name, (char *)metadata->input1[i].input_name,\n+\t\t\tstrncpy(io_info->input[i].name, (char *)metadata->input1[i].input_name,\n \t\t\t\tMRVL_ML_INPUT_NAME_LEN);\n-\t\t\tlayer->info.input[i].dtype = metadata->input1[i].input_type;\n-\t\t\tlayer->info.input[i].qtype = metadata->input1[i].model_input_type;\n-\t\t\tlayer->info.input[i].nb_dims = 4;\n-\t\t\tlayer->info.input[i].shape[0] = metadata->input1[i].shape.w;\n-\t\t\tlayer->info.input[i].shape[1] = metadata->input1[i].shape.x;\n-\t\t\tlayer->info.input[i].shape[2] = metadata->input1[i].shape.y;\n-\t\t\tlayer->info.input[i].shape[3] = metadata->input1[i].shape.z;\n-\t\t\tlayer->info.input[i].nb_elements =\n+\t\t\tio_info->input[i].dtype = metadata->input1[i].input_type;\n+\t\t\tio_info->input[i].qtype = metadata->input1[i].model_input_type;\n+\t\t\tio_info->input[i].nb_dims = 4;\n+\t\t\tio_info->input[i].shape[0] = metadata->input1[i].shape.w;\n+\t\t\tio_info->input[i].shape[1] = metadata->input1[i].shape.x;\n+\t\t\tio_info->input[i].shape[2] = metadata->input1[i].shape.y;\n+\t\t\tio_info->input[i].shape[3] = metadata->input1[i].shape.z;\n+\t\t\tio_info->input[i].nb_elements =\n \t\t\t\tmetadata->input1[i].shape.w * metadata->input1[i].shape.x *\n \t\t\t\tmetadata->input1[i].shape.y * metadata->input1[i].shape.z;\n-\t\t\tlayer->info.input[i].sz_d =\n-\t\t\t\tlayer->info.input[i].nb_elements *\n+\t\t\tio_info->input[i].sz_d =\n+\t\t\t\tio_info->input[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->input1[i].input_type);\n-\t\t\tlayer->info.input[i].sz_q =\n-\t\t\t\tlayer->info.input[i].nb_elements *\n+\t\t\tio_info->input[i].sz_q =\n+\t\t\t\tio_info->input[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->input1[i].model_input_type);\n-\t\t\tlayer->info.input[i].scale = metadata->input1[i].qscale;\n+\t\t\tio_info->input[i].scale = metadata->input1[i].qscale;\n \n-\t\t\tlayer->info.total_input_sz_d += layer->info.input[i].sz_d;\n-\t\t\tlayer->info.total_input_sz_q += layer->info.input[i].sz_q;\n+\t\t\tio_info->total_input_sz_d += io_info->input[i].sz_d;\n+\t\t\tio_info->total_input_sz_q += io_info->input[i].sz_q;\n \n \t\t\tplt_ml_dbg(\n-\t\t\t\t\"index = %u, input1[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u\",\n-\t\t\t\tlayer->index, i, metadata->input1[i].shape.w,\n+\t\t\t\t\"layer_name = %s, input1[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u\",\n+\t\t\t\tmetadata->model.name, i, metadata->input1[i].shape.w,\n \t\t\t\tmetadata->input1[i].shape.x, metadata->input1[i].shape.y,\n-\t\t\t\tmetadata->input1[i].shape.z, layer->info.input[i].sz_d,\n-\t\t\t\tlayer->info.input[i].sz_q);\n+\t\t\t\tmetadata->input1[i].shape.z, io_info->input[i].sz_d,\n+\t\t\t\tio_info->input[i].sz_q);\n \t\t} else {\n \t\t\tj = i - MRVL_ML_NUM_INPUT_OUTPUT_1;\n \n-\t\t\tstrncpy(layer->info.input[i].name, (char *)metadata->input2[j].input_name,\n+\t\t\tstrncpy(io_info->input[i].name, (char *)metadata->input2[j].input_name,\n \t\t\t\tMRVL_ML_INPUT_NAME_LEN);\n-\t\t\tlayer->info.input[i].dtype = metadata->input2[j].input_type;\n-\t\t\tlayer->info.input[i].qtype = metadata->input2[j].model_input_type;\n-\t\t\tlayer->info.input[i].nb_dims = 4;\n-\t\t\tlayer->info.input[i].shape[0] = metadata->input2[j].shape.w;\n-\t\t\tlayer->info.input[i].shape[1] = metadata->input2[j].shape.x;\n-\t\t\tlayer->info.input[i].shape[2] = metadata->input2[j].shape.y;\n-\t\t\tlayer->info.input[i].shape[3] = metadata->input2[j].shape.z;\n-\t\t\tlayer->info.input[i].nb_elements =\n+\t\t\tio_info->input[i].dtype = metadata->input2[j].input_type;\n+\t\t\tio_info->input[i].qtype = metadata->input2[j].model_input_type;\n+\t\t\tio_info->input[i].nb_dims = 4;\n+\t\t\tio_info->input[i].shape[0] = metadata->input2[j].shape.w;\n+\t\t\tio_info->input[i].shape[1] = metadata->input2[j].shape.x;\n+\t\t\tio_info->input[i].shape[2] = metadata->input2[j].shape.y;\n+\t\t\tio_info->input[i].shape[3] = metadata->input2[j].shape.z;\n+\t\t\tio_info->input[i].nb_elements =\n \t\t\t\tmetadata->input2[j].shape.w * metadata->input2[j].shape.x *\n \t\t\t\tmetadata->input2[j].shape.y * metadata->input2[j].shape.z;\n-\t\t\tlayer->info.input[i].sz_d =\n-\t\t\t\tlayer->info.input[i].nb_elements *\n+\t\t\tio_info->input[i].sz_d =\n+\t\t\t\tio_info->input[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->input2[j].input_type);\n-\t\t\tlayer->info.input[i].sz_q =\n-\t\t\t\tlayer->info.input[i].nb_elements *\n+\t\t\tio_info->input[i].sz_q =\n+\t\t\t\tio_info->input[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->input2[j].model_input_type);\n-\t\t\tlayer->info.input[i].scale = metadata->input2[j].qscale;\n+\t\t\tio_info->input[i].scale = metadata->input2[j].qscale;\n \n-\t\t\tlayer->info.total_input_sz_d += layer->info.input[i].sz_d;\n-\t\t\tlayer->info.total_input_sz_q += layer->info.input[i].sz_q;\n+\t\t\tio_info->total_input_sz_d += io_info->input[i].sz_d;\n+\t\t\tio_info->total_input_sz_q += io_info->input[i].sz_q;\n \n \t\t\tplt_ml_dbg(\n-\t\t\t\t\"index = %u, input2[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u\",\n-\t\t\t\tlayer->index, j, metadata->input2[j].shape.w,\n+\t\t\t\t\"layer_name = %s, input2[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u\",\n+\t\t\t\tmetadata->model.name, j, metadata->input2[j].shape.w,\n \t\t\t\tmetadata->input2[j].shape.x, metadata->input2[j].shape.y,\n-\t\t\t\tmetadata->input2[j].shape.z, layer->info.input[i].sz_d,\n-\t\t\t\tlayer->info.input[i].sz_q);\n+\t\t\t\tmetadata->input2[j].shape.z, io_info->input[i].sz_d,\n+\t\t\t\tio_info->input[i].sz_q);\n \t\t}\n \t}\n \n \t/* Outputs */\n-\tlayer->info.nb_outputs = metadata->model.num_output;\n-\tlayer->info.total_output_sz_q = 0;\n-\tlayer->info.total_output_sz_d = 0;\n+\tio_info->nb_outputs = metadata->model.num_output;\n+\tio_info->total_output_sz_q = 0;\n+\tio_info->total_output_sz_d = 0;\n \tfor (i = 0; i < metadata->model.num_output; i++) {\n \t\tif (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {\n-\t\t\tstrncpy(layer->info.output[i].name,\n-\t\t\t\t(char *)metadata->output1[i].output_name, MRVL_ML_OUTPUT_NAME_LEN);\n-\t\t\tlayer->info.output[i].dtype = metadata->output1[i].output_type;\n-\t\t\tlayer->info.output[i].qtype = metadata->output1[i].model_output_type;\n-\t\t\tlayer->info.output[i].nb_dims = 1;\n-\t\t\tlayer->info.output[i].shape[0] = metadata->output1[i].size;\n-\t\t\tlayer->info.output[i].nb_elements = metadata->output1[i].size;\n-\t\t\tlayer->info.output[i].sz_d =\n-\t\t\t\tlayer->info.output[i].nb_elements *\n+\t\t\tstrncpy(io_info->output[i].name, (char *)metadata->output1[i].output_name,\n+\t\t\t\tMRVL_ML_OUTPUT_NAME_LEN);\n+\t\t\tio_info->output[i].dtype = metadata->output1[i].output_type;\n+\t\t\tio_info->output[i].qtype = metadata->output1[i].model_output_type;\n+\t\t\tio_info->output[i].nb_dims = 1;\n+\t\t\tio_info->output[i].shape[0] = metadata->output1[i].size;\n+\t\t\tio_info->output[i].nb_elements = metadata->output1[i].size;\n+\t\t\tio_info->output[i].sz_d =\n+\t\t\t\tio_info->output[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->output1[i].output_type);\n-\t\t\tlayer->info.output[i].sz_q =\n-\t\t\t\tlayer->info.output[i].nb_elements *\n+\t\t\tio_info->output[i].sz_q =\n+\t\t\t\tio_info->output[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->output1[i].model_output_type);\n-\t\t\tlayer->info.output[i].scale = metadata->output1[i].dscale;\n+\t\t\tio_info->output[i].scale = metadata->output1[i].dscale;\n \n-\t\t\tlayer->info.total_output_sz_q += layer->info.output[i].sz_q;\n-\t\t\tlayer->info.total_output_sz_d += layer->info.output[i].sz_d;\n+\t\t\tio_info->total_output_sz_q += io_info->output[i].sz_q;\n+\t\t\tio_info->total_output_sz_d += io_info->output[i].sz_d;\n \n-\t\t\tplt_ml_dbg(\"index = %u, output1[%u] - sz_d = %u, sz_q = %u\", layer->index,\n-\t\t\t\t   i, layer->info.output[i].sz_d, layer->info.output[i].sz_q);\n+\t\t\tplt_ml_dbg(\"layer_name = %s, output1[%u] - sz_d = %u, sz_q = %u\",\n+\t\t\t\t   metadata->model.name, i, io_info->output[i].sz_d,\n+\t\t\t\t   io_info->output[i].sz_q);\n \t\t} else {\n \t\t\tj = i - MRVL_ML_NUM_INPUT_OUTPUT_1;\n \n-\t\t\tstrncpy(layer->info.output[i].name,\n-\t\t\t\t(char *)metadata->output2[j].output_name, MRVL_ML_OUTPUT_NAME_LEN);\n-\t\t\tlayer->info.output[i].dtype = metadata->output2[j].output_type;\n-\t\t\tlayer->info.output[i].qtype = metadata->output2[j].model_output_type;\n-\t\t\tlayer->info.output[i].nb_dims = 1;\n-\t\t\tlayer->info.output[i].shape[0] = metadata->output2[j].size;\n-\t\t\tlayer->info.output[i].nb_elements = metadata->output2[j].size;\n-\t\t\tlayer->info.output[i].sz_d =\n-\t\t\t\tlayer->info.output[i].nb_elements *\n+\t\t\tstrncpy(io_info->output[i].name, (char *)metadata->output2[j].output_name,\n+\t\t\t\tMRVL_ML_OUTPUT_NAME_LEN);\n+\t\t\tio_info->output[i].dtype = metadata->output2[j].output_type;\n+\t\t\tio_info->output[i].qtype = metadata->output2[j].model_output_type;\n+\t\t\tio_info->output[i].nb_dims = 1;\n+\t\t\tio_info->output[i].shape[0] = metadata->output2[j].size;\n+\t\t\tio_info->output[i].nb_elements = metadata->output2[j].size;\n+\t\t\tio_info->output[i].sz_d =\n+\t\t\t\tio_info->output[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->output2[j].output_type);\n-\t\t\tlayer->info.output[i].sz_q =\n-\t\t\t\tlayer->info.output[i].nb_elements *\n+\t\t\tio_info->output[i].sz_q =\n+\t\t\t\tio_info->output[i].nb_elements *\n \t\t\t\trte_ml_io_type_size_get(metadata->output2[j].model_output_type);\n-\t\t\tlayer->info.output[i].scale = metadata->output2[j].dscale;\n+\t\t\tio_info->output[i].scale = metadata->output2[j].dscale;\n \n-\t\t\tlayer->info.total_output_sz_q += layer->info.output[i].sz_q;\n-\t\t\tlayer->info.total_output_sz_d += layer->info.output[i].sz_d;\n+\t\t\tio_info->total_output_sz_q += io_info->output[i].sz_q;\n+\t\t\tio_info->total_output_sz_d += io_info->output[i].sz_d;\n \n-\t\t\tplt_ml_dbg(\"index = %u, output2[%u] - sz_d = %u, sz_q = %u\", layer->index,\n-\t\t\t\t   j, layer->info.output[i].sz_d, layer->info.output[i].sz_q);\n+\t\t\tplt_ml_dbg(\"layer_name = %s, output2[%u] - sz_d = %u, sz_q = %u\",\n+\t\t\t\t   metadata->model.name, j, io_info->output[i].sz_d,\n+\t\t\t\t   io_info->output[i].sz_q);\n \t\t}\n \t}\n }\n \n+struct cnxk_ml_io_info *\n+cn10k_ml_model_io_info_get(struct cnxk_ml_model *model, uint16_t layer_id)\n+{\n+\treturn &model->layer[layer_id].info;\n+}\n+\n int\n-cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_id, uint8_t *buffer,\n-\t\t\t       uint16_t *wb_pages, uint16_t *scratch_pages)\n+cn10k_ml_model_ocm_pages_count(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_layer *layer,\n+\t\t\t       uint8_t *buffer, uint16_t *wb_pages, uint16_t *scratch_pages)\n {\n \tstruct cn10k_ml_model_metadata *metadata;\n \tstruct cn10k_ml_ocm *ocm;\n@@ -504,7 +499,7 @@ cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_\n \tuint64_t wb_size;\n \n \tmetadata = (struct cn10k_ml_model_metadata *)buffer;\n-\tocm = &cn10k_mldev->ocm;\n+\tocm = &cnxk_mldev->cn10k_mldev.ocm;\n \n \t/* Assume wb_size is zero for non-relocatable models */\n \tif (metadata->model.ocm_relocatable)\n@@ -516,7 +511,7 @@ cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_\n \t\t*wb_pages = wb_size / ocm->page_size + 1;\n \telse\n \t\t*wb_pages = wb_size / ocm->page_size;\n-\tplt_ml_dbg(\"model_id = %u, wb_size = %\" PRIu64 \", wb_pages = %u\", model_id, wb_size,\n+\tplt_ml_dbg(\"index = %u, wb_size = %\" PRIu64 \", wb_pages = %u\", layer->index, wb_size,\n \t\t   *wb_pages);\n \n \tscratch_size = ocm->size_per_tile - metadata->model.ocm_tmp_range_floor;\n@@ -524,15 +519,15 @@ cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_\n \t\t*scratch_pages = scratch_size / ocm->page_size + 1;\n \telse\n \t\t*scratch_pages = scratch_size / ocm->page_size;\n-\tplt_ml_dbg(\"model_id = %u, scratch_size = %\" PRIu64 \", scratch_pages = %u\", model_id,\n+\tplt_ml_dbg(\"index = %u, scratch_size = %\" PRIu64 \", scratch_pages = %u\", layer->index,\n \t\t   scratch_size, *scratch_pages);\n \n \t/* Check if the model can be loaded on OCM */\n-\tif ((*wb_pages + *scratch_pages) > cn10k_mldev->ocm.num_pages) {\n+\tif ((*wb_pages + *scratch_pages) > ocm->num_pages) {\n \t\tplt_err(\"Cannot create the model, OCM relocatable = %u\",\n \t\t\tmetadata->model.ocm_relocatable);\n \t\tplt_err(\"wb_pages (%u) + scratch_pages (%u) > %u\", *wb_pages, *scratch_pages,\n-\t\t\tcn10k_mldev->ocm.num_pages);\n+\t\t\tocm->num_pages);\n \t\treturn -ENOMEM;\n \t}\n \n@@ -540,28 +535,25 @@ cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_\n \t * prevent the library from allocating the remaining space on the tile to other models.\n \t */\n \tif (!metadata->model.ocm_relocatable)\n-\t\t*scratch_pages = PLT_MAX(PLT_U64_CAST(*scratch_pages),\n-\t\t\t\t\t PLT_U64_CAST(cn10k_mldev->ocm.num_pages));\n+\t\t*scratch_pages =\n+\t\t\tPLT_MAX(PLT_U64_CAST(*scratch_pages), PLT_U64_CAST(ocm->num_pages));\n \n \treturn 0;\n }\n \n void\n-cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cnxk_ml_model *model)\n+cn10k_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model *model,\n+\t\t\tstruct cnxk_ml_io_info *io_info, struct cn10k_ml_model_metadata *metadata)\n {\n-\tstruct cn10k_ml_model_metadata *metadata;\n-\tstruct cnxk_ml_dev *cnxk_mldev;\n \tstruct rte_ml_model_info *info;\n \tstruct rte_ml_io_info *output;\n \tstruct rte_ml_io_info *input;\n-\tstruct cnxk_ml_layer *layer;\n \tuint8_t i;\n \n-\tcnxk_mldev = dev->data->dev_private;\n \tmetadata = &model->glow.metadata;\n \tinfo = PLT_PTR_CAST(model->info);\n \tinput = PLT_PTR_ADD(info, sizeof(struct rte_ml_model_info));\n-\toutput = PLT_PTR_ADD(input, metadata->model.num_input * sizeof(struct rte_ml_io_info));\n+\toutput = PLT_PTR_ADD(input, ML_CNXK_MODEL_MAX_INPUT_OUTPUT * sizeof(struct rte_ml_io_info));\n \n \t/* Set model info */\n \tmemset(info, 0, sizeof(struct rte_ml_model_info));\n@@ -570,39 +562,37 @@ cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cnxk_ml_model *model)\n \t\t metadata->model.version[1], metadata->model.version[2],\n \t\t metadata->model.version[3]);\n \tinfo->model_id = model->model_id;\n-\tinfo->device_id = dev->data->dev_id;\n+\tinfo->device_id = cnxk_mldev->mldev->data->dev_id;\n \tinfo->io_layout = RTE_ML_IO_LAYOUT_PACKED;\n \tinfo->min_batches = model->batch_size;\n \tinfo->max_batches =\n \t\tcnxk_mldev->cn10k_mldev.fw.req->cn10k_req.jd.fw_load.cap.s.max_num_batches /\n \t\tmodel->batch_size;\n-\tinfo->nb_inputs = metadata->model.num_input;\n+\tinfo->nb_inputs = io_info->nb_inputs;\n \tinfo->input_info = input;\n-\tinfo->nb_outputs = metadata->model.num_output;\n+\tinfo->nb_outputs = io_info->nb_outputs;\n \tinfo->output_info = output;\n \tinfo->wb_size = metadata->weights_bias.file_size;\n \n \t/* Set input info */\n-\tlayer = &model->layer[0];\n \tfor (i = 0; i < info->nb_inputs; i++) {\n-\t\trte_memcpy(input[i].name, layer->info.input[i].name, MRVL_ML_INPUT_NAME_LEN);\n-\t\tinput[i].nb_dims = layer->info.input[i].nb_dims;\n-\t\tinput[i].shape = &layer->info.input[i].shape[0];\n-\t\tinput[i].type = layer->info.input[i].qtype;\n-\t\tinput[i].nb_elements = layer->info.input[i].nb_elements;\n-\t\tinput[i].size = layer->info.input[i].nb_elements *\n-\t\t\t\trte_ml_io_type_size_get(layer->info.input[i].qtype);\n+\t\trte_memcpy(input[i].name, io_info->input[i].name, MRVL_ML_INPUT_NAME_LEN);\n+\t\tinput[i].nb_dims = io_info->input[i].nb_dims;\n+\t\tinput[i].shape = &io_info->input[i].shape[0];\n+\t\tinput[i].type = io_info->input[i].qtype;\n+\t\tinput[i].nb_elements = io_info->input[i].nb_elements;\n+\t\tinput[i].size = io_info->input[i].nb_elements *\n+\t\t\t\trte_ml_io_type_size_get(io_info->input[i].qtype);\n \t}\n \n \t/* Set output info */\n-\tlayer = &model->layer[0];\n \tfor (i = 0; i < info->nb_outputs; i++) {\n-\t\trte_memcpy(output[i].name, layer->info.output[i].name, MRVL_ML_INPUT_NAME_LEN);\n-\t\toutput[i].nb_dims = layer->info.output[i].nb_dims;\n-\t\toutput[i].shape = &layer->info.output[i].shape[0];\n-\t\toutput[i].type = layer->info.output[i].qtype;\n-\t\toutput[i].nb_elements = layer->info.output[i].nb_elements;\n-\t\toutput[i].size = layer->info.output[i].nb_elements *\n-\t\t\t\t rte_ml_io_type_size_get(layer->info.output[i].qtype);\n+\t\trte_memcpy(output[i].name, io_info->output[i].name, MRVL_ML_INPUT_NAME_LEN);\n+\t\toutput[i].nb_dims = io_info->output[i].nb_dims;\n+\t\toutput[i].shape = &io_info->output[i].shape[0];\n+\t\toutput[i].type = io_info->output[i].qtype;\n+\t\toutput[i].nb_elements = io_info->output[i].nb_elements;\n+\t\toutput[i].size = io_info->output[i].nb_elements *\n+\t\t\t\t rte_ml_io_type_size_get(io_info->output[i].qtype);\n \t}\n }\ndiff --git a/drivers/ml/cnxk/cn10k_ml_model.h b/drivers/ml/cnxk/cn10k_ml_model.h\nindex 5c32f48c68..b891c9d627 100644\n--- a/drivers/ml/cnxk/cn10k_ml_model.h\n+++ b/drivers/ml/cnxk/cn10k_ml_model.h\n@@ -9,9 +9,11 @@\n \n #include <roc_api.h>\n \n-#include \"cn10k_ml_dev.h\"\n #include \"cn10k_ml_ocm.h\"\n \n+#include \"cnxk_ml_io.h\"\n+\n+struct cnxk_ml_dev;\n struct cnxk_ml_model;\n struct cnxk_ml_layer;\n struct cnxk_ml_req;\n@@ -366,27 +368,15 @@ struct cn10k_ml_layer_addr {\n \t/* Base DMA address for load */\n \tvoid *base_dma_addr_load;\n \n-\t/* Base DMA address for run */\n-\tvoid *base_dma_addr_run;\n-\n \t/* Init section load address */\n \tvoid *init_load_addr;\n \n-\t/* Init section run address */\n-\tvoid *init_run_addr;\n-\n \t/* Main section load address */\n \tvoid *main_load_addr;\n \n-\t/* Main section run address */\n-\tvoid *main_run_addr;\n-\n \t/* Finish section load address */\n \tvoid *finish_load_addr;\n \n-\t/* Finish section run address */\n-\tvoid *finish_run_addr;\n-\n \t/* Weights and Bias base address */\n \tvoid *wb_base_addr;\n \n@@ -462,9 +452,13 @@ int cn10k_ml_model_metadata_check(uint8_t *buffer, uint64_t size);\n void cn10k_ml_model_metadata_update(struct cn10k_ml_model_metadata *metadata);\n void cn10k_ml_layer_addr_update(struct cnxk_ml_layer *layer, uint8_t *buffer,\n \t\t\t\tuint8_t *base_dma_addr);\n-void cn10k_ml_layer_info_update(struct cnxk_ml_layer *layer);\n-int cn10k_ml_model_ocm_pages_count(struct cn10k_ml_dev *cn10k_mldev, uint16_t model_id,\n+void cn10k_ml_layer_io_info_set(struct cnxk_ml_io_info *io_info,\n+\t\t\t\tstruct cn10k_ml_model_metadata *metadata);\n+struct cnxk_ml_io_info *cn10k_ml_model_io_info_get(struct cnxk_ml_model *model, uint16_t layer_id);\n+int cn10k_ml_model_ocm_pages_count(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_layer *layer,\n \t\t\t\t   uint8_t *buffer, uint16_t *wb_pages, uint16_t *scratch_pages);\n-void cn10k_ml_model_info_set(struct rte_ml_dev *dev, struct cnxk_ml_model *model);\n+void cn10k_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model *model,\n+\t\t\t     struct cnxk_ml_io_info *io_info,\n+\t\t\t     struct cn10k_ml_model_metadata *metadata);\n \n #endif /* _CN10K_ML_MODEL_H_ */\ndiff --git a/drivers/ml/cnxk/cn10k_ml_ops.c b/drivers/ml/cnxk/cn10k_ml_ops.c\nindex e3c688a55f..ad2effb904 100644\n--- a/drivers/ml/cnxk/cn10k_ml_ops.c\n+++ b/drivers/ml/cnxk/cn10k_ml_ops.c\n@@ -15,6 +15,9 @@\n /* ML model macros */\n #define CN10K_ML_MODEL_MEMZONE_NAME \"ml_cn10k_model_mz\"\n \n+/* ML layer macros */\n+#define CN10K_ML_LAYER_MEMZONE_NAME \"ml_cn10k_layer_mz\"\n+\n /* Debug print width */\n #define STR_LEN\t  12\n #define FIELD_LEN 16\n@@ -273,7 +276,7 @@ cn10k_ml_prep_sp_job_descriptor(struct cn10k_ml_dev *cn10k_mldev, struct cnxk_ml\n \t\treq->cn10k_req.jd.model_start.extended_args = PLT_U64_CAST(\n \t\t\troc_ml_addr_ap2mlip(&cn10k_mldev->roc, &req->cn10k_req.extended_args));\n \t\treq->cn10k_req.jd.model_start.model_dst_ddr_addr =\n-\t\t\tPLT_U64_CAST(roc_ml_addr_ap2mlip(&cn10k_mldev->roc, addr->init_run_addr));\n+\t\t\tPLT_U64_CAST(roc_ml_addr_ap2mlip(&cn10k_mldev->roc, addr->init_load_addr));\n \t\treq->cn10k_req.jd.model_start.model_init_offset = 0x0;\n \t\treq->cn10k_req.jd.model_start.model_main_offset = metadata->init_model.file_size;\n \t\treq->cn10k_req.jd.model_start.model_finish_offset =\n@@ -1261,85 +1264,171 @@ cn10k_ml_dev_selftest(struct rte_ml_dev *dev)\n }\n \n int\n-cn10k_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params, uint16_t *model_id)\n+cn10k_ml_layer_load(void *device, uint16_t model_id, const char *layer_name, uint8_t *buffer,\n+\t\t    size_t size, uint16_t *index)\n {\n \tstruct cn10k_ml_model_metadata *metadata;\n \tstruct cnxk_ml_dev *cnxk_mldev;\n \tstruct cnxk_ml_model *model;\n+\tstruct cnxk_ml_layer *layer;\n \n \tchar str[RTE_MEMZONE_NAMESIZE];\n \tconst struct plt_memzone *mz;\n-\tsize_t model_scratch_size;\n-\tsize_t model_stats_size;\n-\tsize_t model_data_size;\n-\tsize_t model_info_size;\n+\tsize_t layer_object_size = 0;\n+\tsize_t layer_scratch_size;\n+\tsize_t layer_xstats_size;\n \tuint8_t *base_dma_addr;\n \tuint16_t scratch_pages;\n+\tuint16_t layer_id = 0;\n \tuint16_t wb_pages;\n \tuint64_t mz_size;\n \tuint16_t idx;\n-\tbool found;\n \tint qp_id;\n \tint ret;\n \n-\tret = cn10k_ml_model_metadata_check(params->addr, params->size);\n+\tPLT_SET_USED(size);\n+\tPLT_SET_USED(layer_name);\n+\n+\tcnxk_mldev = (struct cnxk_ml_dev *)device;\n+\tif (cnxk_mldev == NULL) {\n+\t\tplt_err(\"Invalid device = %p\", device);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmodel = cnxk_mldev->mldev->data->models[model_id];\n+\tif (model == NULL) {\n+\t\tplt_err(\"Invalid model_id = %u\", model_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tlayer = &model->layer[layer_id];\n+\n+\tret = cn10k_ml_model_metadata_check(buffer, size);\n \tif (ret != 0)\n \t\treturn ret;\n \n-\tcnxk_mldev = dev->data->dev_private;\n-\n-\t/* Find model ID */\n-\tfound = false;\n-\tfor (idx = 0; idx < dev->data->nb_models; idx++) {\n-\t\tif (dev->data->models[idx] == NULL) {\n-\t\t\tfound = true;\n+\t/* Get index */\n+\tfor (idx = 0; idx < cnxk_mldev->max_nb_layers; idx++) {\n+\t\tif (!cnxk_mldev->index_map[idx].active) {\n+\t\t\tlayer->index = idx;\n \t\t\tbreak;\n \t\t}\n \t}\n \n-\tif (!found) {\n-\t\tplt_err(\"No slots available to load new model\");\n-\t\treturn -ENOMEM;\n+\tif (idx >= cnxk_mldev->max_nb_layers) {\n+\t\tplt_err(\"No slots available for model layers, model_id = %u, layer_id = %u\",\n+\t\t\tmodel->model_id, layer_id);\n+\t\treturn -1;\n \t}\n \n+\tlayer->model = model;\n+\n \t/* Get WB and scratch pages, check if model can be loaded. */\n-\tret = cn10k_ml_model_ocm_pages_count(&cnxk_mldev->cn10k_mldev, idx, params->addr, &wb_pages,\n-\t\t\t\t\t     &scratch_pages);\n+\tret = cn10k_ml_model_ocm_pages_count(cnxk_mldev, layer, buffer, &wb_pages, &scratch_pages);\n \tif (ret < 0)\n \t\treturn ret;\n \n-\t/* Compute memzone size */\n-\tmetadata = (struct cn10k_ml_model_metadata *)params->addr;\n-\tmodel_data_size = metadata->init_model.file_size + metadata->main_model.file_size +\n-\t\t\t  metadata->finish_model.file_size + metadata->weights_bias.file_size;\n-\tmodel_scratch_size = PLT_ALIGN_CEIL(metadata->model.ddr_scratch_range_end -\n+\t/* Compute layer memzone size */\n+\tmetadata = (struct cn10k_ml_model_metadata *)buffer;\n+\tlayer_object_size = metadata->init_model.file_size + metadata->main_model.file_size +\n+\t\t\t    metadata->finish_model.file_size + metadata->weights_bias.file_size;\n+\tlayer_object_size = PLT_ALIGN_CEIL(layer_object_size, ML_CN10K_ALIGN_SIZE);\n+\tlayer_scratch_size = PLT_ALIGN_CEIL(metadata->model.ddr_scratch_range_end -\n \t\t\t\t\t\t    metadata->model.ddr_scratch_range_start + 1,\n \t\t\t\t\t    ML_CN10K_ALIGN_SIZE);\n-\tmodel_data_size = PLT_ALIGN_CEIL(model_data_size, ML_CN10K_ALIGN_SIZE);\n-\tmodel_info_size = sizeof(struct rte_ml_model_info) +\n-\t\t\t  metadata->model.num_input * sizeof(struct rte_ml_io_info) +\n-\t\t\t  metadata->model.num_output * sizeof(struct rte_ml_io_info);\n-\tmodel_info_size = PLT_ALIGN_CEIL(model_info_size, ML_CN10K_ALIGN_SIZE);\n-\tmodel_stats_size = (dev->data->nb_queue_pairs + 1) * sizeof(struct cn10k_ml_layer_xstats);\n-\n-\tmz_size = PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_model), ML_CN10K_ALIGN_SIZE) +\n-\t\t  2 * model_data_size + model_scratch_size + model_info_size +\n-\t\t  PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_req), ML_CN10K_ALIGN_SIZE) +\n-\t\t  model_stats_size;\n+\tlayer_xstats_size = (cnxk_mldev->mldev->data->nb_queue_pairs + 1) *\n+\t\t\t    sizeof(struct cn10k_ml_layer_xstats);\n \n-\t/* Allocate memzone for model object and model data */\n-\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u\", CN10K_ML_MODEL_MEMZONE_NAME, idx);\n+\t/* Allocate memzone for model data */\n+\tmz_size = layer_object_size + layer_scratch_size +\n+\t\t  PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_req), ML_CN10K_ALIGN_SIZE) +\n+\t\t  layer_xstats_size;\n+\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u_%u\", CN10K_ML_LAYER_MEMZONE_NAME,\n+\t\t model->model_id, layer_id);\n \tmz = plt_memzone_reserve_aligned(str, mz_size, 0, ML_CN10K_ALIGN_SIZE);\n \tif (!mz) {\n \t\tplt_err(\"plt_memzone_reserve failed : %s\", str);\n \t\treturn -ENOMEM;\n \t}\n \n-\tmodel = mz->addr;\n-\tmodel->cnxk_mldev = cnxk_mldev;\n-\tmodel->model_id = idx;\n-\tdev->data->models[idx] = model;\n+\t/* Copy metadata to internal buffer */\n+\trte_memcpy(&layer->glow.metadata, buffer, sizeof(struct cn10k_ml_model_metadata));\n+\tcn10k_ml_model_metadata_update(&layer->glow.metadata);\n+\n+\t/* Set layer name */\n+\trte_memcpy(layer->name, layer->glow.metadata.model.name, MRVL_ML_MODEL_NAME_LEN);\n+\n+\t/* Enable support for batch_size of 256 */\n+\tif (layer->glow.metadata.model.batch_size == 0)\n+\t\tlayer->batch_size = 256;\n+\telse\n+\t\tlayer->batch_size = layer->glow.metadata.model.batch_size;\n+\n+\t/* Set DMA base address */\n+\tbase_dma_addr = mz->addr;\n+\tcn10k_ml_layer_addr_update(layer, buffer, base_dma_addr);\n+\n+\t/* Set scratch base address */\n+\tlayer->glow.addr.scratch_base_addr = PLT_PTR_ADD(base_dma_addr, layer_object_size);\n+\n+\t/* Update internal I/O data structure */\n+\tcn10k_ml_layer_io_info_set(&layer->info, &layer->glow.metadata);\n+\n+\t/* Initialize model_mem_map */\n+\tmemset(&layer->glow.ocm_map, 0, sizeof(struct cn10k_ml_ocm_layer_map));\n+\tlayer->glow.ocm_map.ocm_reserved = false;\n+\tlayer->glow.ocm_map.tilemask = 0;\n+\tlayer->glow.ocm_map.wb_page_start = -1;\n+\tlayer->glow.ocm_map.wb_pages = wb_pages;\n+\tlayer->glow.ocm_map.scratch_pages = scratch_pages;\n+\n+\t/* Set slow-path request address and state */\n+\tlayer->glow.req = PLT_PTR_ADD(mz->addr, layer_object_size + layer_scratch_size);\n+\n+\t/* Reset burst and sync stats */\n+\tlayer->glow.burst_xstats = PLT_PTR_ADD(\n+\t\tlayer->glow.req, PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_req), ML_CN10K_ALIGN_SIZE));\n+\tfor (qp_id = 0; qp_id < cnxk_mldev->mldev->data->nb_queue_pairs + 1; qp_id++) {\n+\t\tlayer->glow.burst_xstats[qp_id].hw_latency_tot = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].hw_latency_min = UINT64_MAX;\n+\t\tlayer->glow.burst_xstats[qp_id].hw_latency_max = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].fw_latency_tot = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].fw_latency_min = UINT64_MAX;\n+\t\tlayer->glow.burst_xstats[qp_id].fw_latency_max = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].hw_reset_count = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].fw_reset_count = 0;\n+\t\tlayer->glow.burst_xstats[qp_id].dequeued_count = 0;\n+\t}\n+\n+\tlayer->glow.sync_xstats =\n+\t\tPLT_PTR_ADD(layer->glow.burst_xstats, cnxk_mldev->mldev->data->nb_queue_pairs *\n+\t\t\t\t\t\t\t      sizeof(struct cn10k_ml_layer_xstats));\n+\n+\t/* Update xstats names */\n+\tcn10k_ml_xstats_model_name_update(cnxk_mldev->mldev, idx);\n+\n+\tlayer->state = ML_CNXK_LAYER_STATE_LOADED;\n+\tcnxk_mldev->index_map[idx].model_id = model->model_id;\n+\tcnxk_mldev->index_map[idx].layer_id = layer_id;\n+\tcnxk_mldev->index_map[idx].active = true;\n+\t*index = idx;\n+\n+\treturn 0;\n+}\n+\n+int\n+cn10k_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_model_params *params,\n+\t\t    struct cnxk_ml_model *model)\n+{\n+\tstruct cnxk_ml_layer *layer;\n+\tint ret;\n+\n+\t/* Metadata check */\n+\tret = cn10k_ml_model_metadata_check(params->addr, params->size);\n+\tif (ret != 0)\n+\t\treturn ret;\n \n+\t/* Copy metadata to internal buffer */\n \trte_memcpy(&model->glow.metadata, params->addr, sizeof(struct cn10k_ml_model_metadata));\n \tcn10k_ml_model_metadata_update(&model->glow.metadata);\n \n@@ -1358,99 +1447,62 @@ cn10k_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params,\n \t */\n \tmodel->nb_layers = 1;\n \n-\t/* Copy metadata to internal buffer */\n-\trte_memcpy(&model->layer[0].glow.metadata, params->addr,\n-\t\t   sizeof(struct cn10k_ml_model_metadata));\n-\tcn10k_ml_model_metadata_update(&model->layer[0].glow.metadata);\n-\tmodel->layer[0].model = model;\n-\n-\t/* Set DMA base address */\n-\tbase_dma_addr = PLT_PTR_ADD(\n-\t\tmz->addr, PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_model), ML_CN10K_ALIGN_SIZE));\n-\tcn10k_ml_layer_addr_update(&model->layer[0], params->addr, base_dma_addr);\n-\tmodel->layer[0].glow.addr.scratch_base_addr =\n-\t\tPLT_PTR_ADD(base_dma_addr, 2 * model_data_size);\n-\n-\t/* Copy data from load to run. run address to be used by MLIP */\n-\trte_memcpy(model->layer[0].glow.addr.base_dma_addr_run,\n-\t\t   model->layer[0].glow.addr.base_dma_addr_load, model_data_size);\n-\n-\t/* Update internal I/O data structure */\n-\tcn10k_ml_layer_info_update(&model->layer[0]);\n-\n-\t/* Initialize model_mem_map */\n-\tmemset(&model->layer[0].glow.ocm_map, 0, sizeof(struct cn10k_ml_ocm_layer_map));\n-\tmodel->layer[0].glow.ocm_map.ocm_reserved = false;\n-\tmodel->layer[0].glow.ocm_map.tilemask = 0;\n-\tmodel->layer[0].glow.ocm_map.wb_page_start = -1;\n-\tmodel->layer[0].glow.ocm_map.wb_pages = wb_pages;\n-\tmodel->layer[0].glow.ocm_map.scratch_pages = scratch_pages;\n-\n-\t/* Set model info */\n-\tmodel->info = PLT_PTR_ADD(model->layer[0].glow.addr.scratch_base_addr, model_scratch_size);\n-\tcn10k_ml_model_info_set(dev, model);\n-\n-\t/* Set slow-path request address and state */\n-\tmodel->layer[0].glow.req = PLT_PTR_ADD(model->info, model_info_size);\n-\n-\t/* Reset burst and sync stats */\n-\tmodel->layer[0].glow.burst_xstats =\n-\t\tPLT_PTR_ADD(model->layer[0].glow.req,\n-\t\t\t    PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_req), ML_CN10K_ALIGN_SIZE));\n-\tfor (qp_id = 0; qp_id < dev->data->nb_queue_pairs + 1; qp_id++) {\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].hw_latency_tot = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].hw_latency_min = UINT64_MAX;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].hw_latency_max = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].fw_latency_tot = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].fw_latency_min = UINT64_MAX;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].fw_latency_max = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].hw_reset_count = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].fw_reset_count = 0;\n-\t\tmodel->layer[0].glow.burst_xstats[qp_id].dequeued_count = 0;\n+\t/* Load layer and get the index */\n+\tlayer = &model->layer[0];\n+\tret = cn10k_ml_layer_load(cnxk_mldev, model->model_id, NULL, params->addr, params->size,\n+\t\t\t\t  &layer->index);\n+\tif (ret != 0) {\n+\t\tplt_err(\"Model layer load failed: model_id = %u, layer_id = %u\", model->model_id,\n+\t\t\t0);\n+\t\treturn ret;\n \t}\n \n-\tmodel->layer[0].glow.sync_xstats =\n-\t\tPLT_PTR_ADD(model->layer[0].glow.burst_xstats,\n-\t\t\t    dev->data->nb_queue_pairs * sizeof(struct cn10k_ml_layer_xstats));\n-\n-\tplt_spinlock_init(&model->lock);\n-\tmodel->state = ML_CNXK_MODEL_STATE_LOADED;\n-\tdev->data->models[idx] = model;\n-\tcnxk_mldev->nb_models_loaded++;\n-\n-\t/* Update xstats names */\n-\tcn10k_ml_xstats_model_name_update(dev, idx);\n-\n-\t*model_id = idx;\n+\tcn10k_ml_model_info_set(cnxk_mldev, model, &model->layer[0].info, &model->glow.metadata);\n \n \treturn 0;\n }\n \n int\n-cn10k_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id)\n+cn10k_ml_layer_unload(void *device, uint16_t model_id, const char *layer_name)\n {\n-\tchar str[RTE_MEMZONE_NAMESIZE];\n-\tstruct cnxk_ml_model *model;\n \tstruct cnxk_ml_dev *cnxk_mldev;\n+\tstruct cnxk_ml_model *model;\n+\tstruct cnxk_ml_layer *layer;\n \n-\tcnxk_mldev = dev->data->dev_private;\n-\tmodel = dev->data->models[model_id];\n+\tchar str[RTE_MEMZONE_NAMESIZE];\n+\tuint16_t layer_id = 0;\n+\tint ret;\n \n+\tPLT_SET_USED(layer_name);\n+\n+\tcnxk_mldev = (struct cnxk_ml_dev *)device;\n+\tif (cnxk_mldev == NULL) {\n+\t\tplt_err(\"Invalid device = %p\", device);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmodel = cnxk_mldev->mldev->data->models[model_id];\n \tif (model == NULL) {\n \t\tplt_err(\"Invalid model_id = %u\", model_id);\n \t\treturn -EINVAL;\n \t}\n \n-\tif (model->state != ML_CNXK_MODEL_STATE_LOADED) {\n-\t\tplt_err(\"Cannot unload. Model in use.\");\n-\t\treturn -EBUSY;\n-\t}\n+\tlayer = &model->layer[layer_id];\n \n-\tdev->data->models[model_id] = NULL;\n-\tcnxk_mldev->nb_models_unloaded++;\n+\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u_%u\", CN10K_ML_LAYER_MEMZONE_NAME,\n+\t\t model->model_id, layer_id);\n+\tret = plt_memzone_free(plt_memzone_lookup(str));\n \n-\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u\", CN10K_ML_MODEL_MEMZONE_NAME, model_id);\n-\treturn plt_memzone_free(plt_memzone_lookup(str));\n+\tlayer->state = ML_CNXK_LAYER_STATE_UNKNOWN;\n+\tcnxk_mldev->index_map[layer->index].active = false;\n+\n+\treturn ret;\n+}\n+\n+int\n+cn10k_ml_model_unload(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model *model)\n+{\n+\treturn cn10k_ml_layer_unload(cnxk_mldev, model->model_id, NULL);\n }\n \n int\n@@ -1748,7 +1800,6 @@ int\n cn10k_ml_model_params_update(struct rte_ml_dev *dev, uint16_t model_id, void *buffer)\n {\n \tstruct cnxk_ml_model *model;\n-\tsize_t size;\n \n \tmodel = dev->data->models[model_id];\n \n@@ -1762,19 +1813,10 @@ cn10k_ml_model_params_update(struct rte_ml_dev *dev, uint16_t model_id, void *bu\n \telse if (model->state != ML_CNXK_MODEL_STATE_LOADED)\n \t\treturn -EBUSY;\n \n-\tsize = model->layer[0].glow.metadata.init_model.file_size +\n-\t       model->layer[0].glow.metadata.main_model.file_size +\n-\t       model->layer[0].glow.metadata.finish_model.file_size +\n-\t       model->layer[0].glow.metadata.weights_bias.file_size;\n-\n \t/* Update model weights & bias */\n \trte_memcpy(model->layer[0].glow.addr.wb_load_addr, buffer,\n \t\t   model->layer[0].glow.metadata.weights_bias.file_size);\n \n-\t/* Copy data from load to run. run address to be used by MLIP */\n-\trte_memcpy(model->layer[0].glow.addr.base_dma_addr_run,\n-\t\t   model->layer[0].glow.addr.base_dma_addr_load, size);\n-\n \treturn 0;\n }\n \ndiff --git a/drivers/ml/cnxk/cn10k_ml_ops.h b/drivers/ml/cnxk/cn10k_ml_ops.h\nindex 2d0a49d5cd..677219dfdf 100644\n--- a/drivers/ml/cnxk/cn10k_ml_ops.h\n+++ b/drivers/ml/cnxk/cn10k_ml_ops.h\n@@ -12,6 +12,7 @@\n \n struct cnxk_ml_dev;\n struct cnxk_ml_qp;\n+struct cnxk_ml_model;\n \n /* Firmware version string length */\n #define MLDEV_FIRMWARE_VERSION_LENGTH 32\n@@ -311,9 +312,9 @@ int cn10k_ml_dev_xstats_reset(struct rte_ml_dev *dev, enum rte_ml_dev_xstats_mod\n \t\t\t      int32_t model_id, const uint16_t stat_ids[], uint16_t nb_ids);\n \n /* Slow-path ops */\n-int cn10k_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params,\n-\t\t\tuint16_t *model_id);\n-int cn10k_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id);\n+int cn10k_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_model_params *params,\n+\t\t\tstruct cnxk_ml_model *model);\n+int cn10k_ml_model_unload(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model *model);\n int cn10k_ml_model_start(struct rte_ml_dev *dev, uint16_t model_id);\n int cn10k_ml_model_stop(struct rte_ml_dev *dev, uint16_t model_id);\n int cn10k_ml_model_info_get(struct rte_ml_dev *dev, uint16_t model_id,\n@@ -339,4 +340,9 @@ __rte_hot int cn10k_ml_inference_sync(struct rte_ml_dev *dev, struct rte_ml_op *\n /* Misc ops */\n void cn10k_ml_qp_initialize(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_qp *qp);\n \n+/* Layer ops */\n+int cn10k_ml_layer_load(void *device, uint16_t model_id, const char *layer_name, uint8_t *buffer,\n+\t\t\tsize_t size, uint16_t *index);\n+int cn10k_ml_layer_unload(void *device, uint16_t model_id, const char *layer_name);\n+\n #endif /* _CN10K_ML_OPS_H_ */\ndiff --git a/drivers/ml/cnxk/cnxk_ml_dev.h b/drivers/ml/cnxk/cnxk_ml_dev.h\nindex 02605fa28f..1590249abd 100644\n--- a/drivers/ml/cnxk/cnxk_ml_dev.h\n+++ b/drivers/ml/cnxk/cnxk_ml_dev.h\n@@ -31,6 +31,18 @@ enum cnxk_ml_dev_state {\n \tML_CNXK_DEV_STATE_CLOSED\n };\n \n+/* Index to model and layer ID map */\n+struct cnxk_ml_index_map {\n+\t/* Model ID */\n+\tuint16_t model_id;\n+\n+\t/* Layer ID */\n+\tuint16_t layer_id;\n+\n+\t/* Layer status */\n+\tbool active;\n+};\n+\n /* Device private data */\n struct cnxk_ml_dev {\n \t/* RTE device */\n@@ -56,6 +68,9 @@ struct cnxk_ml_dev {\n \n \t/* Maximum number of layers */\n \tuint64_t max_nb_layers;\n+\n+\t/* Index map */\n+\tstruct cnxk_ml_index_map *index_map;\n };\n \n #endif /* _CNXK_ML_DEV_H_ */\ndiff --git a/drivers/ml/cnxk/cnxk_ml_ops.c b/drivers/ml/cnxk/cnxk_ml_ops.c\nindex aa56dd2276..1d8b84269d 100644\n--- a/drivers/ml/cnxk/cnxk_ml_ops.c\n+++ b/drivers/ml/cnxk/cnxk_ml_ops.c\n@@ -10,6 +10,9 @@\n #include \"cnxk_ml_model.h\"\n #include \"cnxk_ml_ops.h\"\n \n+/* ML model macros */\n+#define CNXK_ML_MODEL_MEMZONE_NAME \"ml_cnxk_model_mz\"\n+\n static void\n qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)\n {\n@@ -137,6 +140,7 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *co\n \tuint16_t model_id;\n \tuint32_t mz_size;\n \tuint16_t qp_id;\n+\tuint64_t i;\n \tint ret;\n \n \tif (dev == NULL)\n@@ -240,7 +244,7 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *co\n \t\t\t\t\t\tplt_err(\"Could not stop model %u\", model_id);\n \t\t\t\t}\n \t\t\t\tif (model->state == ML_CNXK_MODEL_STATE_LOADED) {\n-\t\t\t\t\tif (cn10k_ml_model_unload(dev, model_id) != 0)\n+\t\t\t\t\tif (cnxk_ml_model_unload(dev, model_id) != 0)\n \t\t\t\t\t\tplt_err(\"Could not unload model %u\", model_id);\n \t\t\t\t}\n \t\t\t\tdev->data->models[model_id] = NULL;\n@@ -271,6 +275,23 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const struct rte_ml_dev_config *co\n \tcnxk_mldev->max_nb_layers =\n \t\tcnxk_mldev->cn10k_mldev.fw.req->cn10k_req.jd.fw_load.cap.s.max_models;\n \n+\t/* Allocate and initialize index_map */\n+\tif (cnxk_mldev->index_map == NULL) {\n+\t\tcnxk_mldev->index_map =\n+\t\t\trte_zmalloc(\"cnxk_ml_index_map\",\n+\t\t\t\t    sizeof(struct cnxk_ml_index_map) * cnxk_mldev->max_nb_layers,\n+\t\t\t\t    RTE_CACHE_LINE_SIZE);\n+\t\tif (cnxk_mldev->index_map == NULL) {\n+\t\t\tplt_err(\"Failed to get memory for index_map, nb_layers %\" PRIu64,\n+\t\t\t\tcnxk_mldev->max_nb_layers);\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto error;\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < cnxk_mldev->max_nb_layers; i++)\n+\t\tcnxk_mldev->index_map[i].active = false;\n+\n \tcnxk_mldev->nb_models_loaded = 0;\n \tcnxk_mldev->nb_models_started = 0;\n \tcnxk_mldev->nb_models_stopped = 0;\n@@ -303,6 +324,9 @@ cnxk_ml_dev_close(struct rte_ml_dev *dev)\n \tif (cn10k_ml_dev_close(cnxk_mldev) != 0)\n \t\tplt_err(\"Failed to close CN10K ML Device\");\n \n+\tif (cnxk_mldev->index_map)\n+\t\trte_free(cnxk_mldev->index_map);\n+\n \t/* Stop and unload all models */\n \tfor (model_id = 0; model_id < dev->data->nb_models; model_id++) {\n \t\tmodel = dev->data->models[model_id];\n@@ -312,7 +336,7 @@ cnxk_ml_dev_close(struct rte_ml_dev *dev)\n \t\t\t\t\tplt_err(\"Could not stop model %u\", model_id);\n \t\t\t}\n \t\t\tif (model->state == ML_CNXK_MODEL_STATE_LOADED) {\n-\t\t\t\tif (cn10k_ml_model_unload(dev, model_id) != 0)\n+\t\t\t\tif (cnxk_ml_model_unload(dev, model_id) != 0)\n \t\t\t\t\tplt_err(\"Could not unload model %u\", model_id);\n \t\t\t}\n \t\t\tdev->data->models[model_id] = NULL;\n@@ -428,6 +452,118 @@ cnxk_ml_dev_queue_pair_setup(struct rte_ml_dev *dev, uint16_t queue_pair_id,\n \treturn 0;\n }\n \n+static int\n+cnxk_ml_model_load(struct rte_ml_dev *dev, struct rte_ml_model_params *params, uint16_t *model_id)\n+{\n+\tstruct rte_ml_dev_info dev_info;\n+\tstruct cnxk_ml_dev *cnxk_mldev;\n+\tstruct cnxk_ml_model *model;\n+\n+\tchar str[RTE_MEMZONE_NAMESIZE];\n+\tconst struct plt_memzone *mz;\n+\tuint64_t model_info_size;\n+\tuint16_t lcl_model_id;\n+\tuint64_t mz_size;\n+\tbool found;\n+\tint ret;\n+\n+\tif (dev == NULL)\n+\t\treturn -EINVAL;\n+\n+\tcnxk_mldev = dev->data->dev_private;\n+\n+\t/* Find model ID */\n+\tfound = false;\n+\tfor (lcl_model_id = 0; lcl_model_id < dev->data->nb_models; lcl_model_id++) {\n+\t\tif (dev->data->models[lcl_model_id] == NULL) {\n+\t\t\tfound = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (!found) {\n+\t\tplt_err(\"No slots available to load new model\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\t/* Compute memzone size */\n+\tcnxk_ml_dev_info_get(dev, &dev_info);\n+\tmz_size = PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_model), dev_info.align_size);\n+\tmodel_info_size = sizeof(struct rte_ml_model_info) +\n+\t\t\t  ML_CNXK_MODEL_MAX_INPUT_OUTPUT * sizeof(struct rte_ml_io_info) +\n+\t\t\t  ML_CNXK_MODEL_MAX_INPUT_OUTPUT * sizeof(struct rte_ml_io_info);\n+\tmodel_info_size = PLT_ALIGN_CEIL(model_info_size, dev_info.align_size);\n+\tmz_size += model_info_size;\n+\n+\t/* Allocate memzone for model object */\n+\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u\", CNXK_ML_MODEL_MEMZONE_NAME, lcl_model_id);\n+\tmz = plt_memzone_reserve_aligned(str, mz_size, 0, dev_info.align_size);\n+\tif (!mz) {\n+\t\tplt_err(\"Failed to allocate memory for cnxk_ml_model: %s\", str);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmodel = mz->addr;\n+\tmodel->cnxk_mldev = cnxk_mldev;\n+\tmodel->model_id = lcl_model_id;\n+\tmodel->info = PLT_PTR_ADD(\n+\t\tmodel, PLT_ALIGN_CEIL(sizeof(struct cnxk_ml_model), dev_info.align_size));\n+\tdev->data->models[lcl_model_id] = model;\n+\n+\tret = cn10k_ml_model_load(cnxk_mldev, params, model);\n+\tif (ret != 0)\n+\t\tgoto error;\n+\n+\tplt_spinlock_init(&model->lock);\n+\tmodel->state = ML_CNXK_MODEL_STATE_LOADED;\n+\tcnxk_mldev->nb_models_loaded++;\n+\n+\t*model_id = lcl_model_id;\n+\n+\treturn 0;\n+\n+error:\n+\trte_memzone_free(mz);\n+\n+\treturn ret;\n+}\n+\n+int\n+cnxk_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id)\n+{\n+\tstruct cnxk_ml_dev *cnxk_mldev;\n+\tstruct cnxk_ml_model *model;\n+\n+\tchar str[RTE_MEMZONE_NAMESIZE];\n+\tint ret;\n+\n+\tif (dev == NULL)\n+\t\treturn -EINVAL;\n+\n+\tcnxk_mldev = dev->data->dev_private;\n+\n+\tmodel = dev->data->models[model_id];\n+\tif (model == NULL) {\n+\t\tplt_err(\"Invalid model_id = %u\", model_id);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (model->state != ML_CNXK_MODEL_STATE_LOADED) {\n+\t\tplt_err(\"Cannot unload. Model in use.\");\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tret = cn10k_ml_model_unload(cnxk_mldev, model);\n+\tif (ret != 0)\n+\t\treturn ret;\n+\n+\tdev->data->models[model_id] = NULL;\n+\tcnxk_mldev->nb_models_unloaded++;\n+\n+\tsnprintf(str, RTE_MEMZONE_NAMESIZE, \"%s_%u\", CNXK_ML_MODEL_MEMZONE_NAME, model_id);\n+\treturn plt_memzone_free(plt_memzone_lookup(str));\n+}\n+\n struct rte_ml_dev_ops cnxk_ml_ops = {\n \t/* Device control ops */\n \t.dev_info_get = cnxk_ml_dev_info_get,\n@@ -451,8 +587,8 @@ struct rte_ml_dev_ops cnxk_ml_ops = {\n \t.dev_xstats_reset = cn10k_ml_dev_xstats_reset,\n \n \t/* Model ops */\n-\t.model_load = cn10k_ml_model_load,\n-\t.model_unload = cn10k_ml_model_unload,\n+\t.model_load = cnxk_ml_model_load,\n+\t.model_unload = cnxk_ml_model_unload,\n \t.model_start = cn10k_ml_model_start,\n \t.model_stop = cn10k_ml_model_stop,\n \t.model_info_get = cn10k_ml_model_info_get,\ndiff --git a/drivers/ml/cnxk/cnxk_ml_ops.h b/drivers/ml/cnxk/cnxk_ml_ops.h\nindex a925c07580..bc14f6e5b9 100644\n--- a/drivers/ml/cnxk/cnxk_ml_ops.h\n+++ b/drivers/ml/cnxk/cnxk_ml_ops.h\n@@ -62,4 +62,6 @@ struct cnxk_ml_qp {\n \n extern struct rte_ml_dev_ops cnxk_ml_ops;\n \n+int cnxk_ml_model_unload(struct rte_ml_dev *dev, uint16_t model_id);\n+\n #endif /* _CNXK_ML_OPS_H_ */\n",
    "prefixes": [
        "v4",
        "09/34"
    ]
}