get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 97450,
    "url": "http://patches.dpdk.org/api/patches/97450/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru/",
    "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": "<20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru",
    "date": "2021-08-27T06:57:11",
    "name": "[32/38] net/sfc: maintain controller to EFX interface mapping",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "725ea9feecef998c6d0e3bf9558c591fd709e563",
    "submitter": {
        "id": 2013,
        "url": "http://patches.dpdk.org/api/people/2013/?format=api",
        "name": "Andrew Rybchenko",
        "email": "Andrew.Rybchenko@oktetlabs.ru"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru/mbox/",
    "series": [
        {
            "id": 18492,
            "url": "http://patches.dpdk.org/api/series/18492/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=18492",
            "date": "2021-08-27T06:56:39",
            "name": "net/sfc: support port representors",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/18492/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/97450/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/97450/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 A9308A0C55;\n\tFri, 27 Aug 2021 09:01:12 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 32D68412E2;\n\tFri, 27 Aug 2021 08:59:07 +0200 (CEST)",
            "from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113])\n by mails.dpdk.org (Postfix) with ESMTP id 8DE9B412E2\n for <dev@dpdk.org>; Fri, 27 Aug 2021 08:59:05 +0200 (CEST)",
            "by shelob.oktetlabs.ru (Postfix, from userid 122)\n id 659467F6E4; Fri, 27 Aug 2021 09:59:05 +0300 (MSK)",
            "from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17])\n by shelob.oktetlabs.ru (Postfix) with ESMTP id 5D48D7F6F3;\n Fri, 27 Aug 2021 09:57:36 +0300 (MSK)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=0.8 required=5.0 tests=ALL_TRUSTED,\n DKIM_ADSP_DISCARD,\n URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2",
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 5D48D7F6F3",
        "Authentication-Results": "shelob.oktetlabs.ru/5D48D7F6F3; dkim=none;\n dkim-atps=neutral",
        "From": "Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>",
        "To": "dev@dpdk.org",
        "Cc": "Viacheslav Galaktionov <viacheslav.galaktionov@oktetlabs.ru>,\n Andy Moreton <amoreton@xilinx.com>",
        "Date": "Fri, 27 Aug 2021 09:57:11 +0300",
        "Message-Id": "<20210827065717.1838258-33-andrew.rybchenko@oktetlabs.ru>",
        "X-Mailer": "git-send-email 2.30.2",
        "In-Reply-To": "<20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru>",
        "References": "<20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 32/38] net/sfc: maintain controller to EFX\n interface mapping",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Viacheslav Galaktionov <viacheslav.galaktionov@oktetlabs.ru>\n\nNewer hardware may have arbitrarily complex controller configurations,\nand for this reason the mapping has been made dynamic: it is represented\nwith a dynamic array that is indexed by controller numbers and each\nelement contains an EFX interface number. Since the number of controllers\nis expected to be small, this approach should not hurt the performance.\n\nSigned-off-by: Viacheslav Galaktionov <viacheslav.galaktionov@oktetlabs.ru>\nSigned-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\n---\n drivers/net/sfc/sfc_ethdev.c | 184 +++++++++++++++++++++++++++++++++++\n drivers/net/sfc/sfc_switch.c |  57 +++++++++++\n drivers/net/sfc/sfc_switch.h |   8 ++\n 3 files changed, 249 insertions(+)",
    "diff": "diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c\nindex 8f9afb2c67..8536a2b111 100644\n--- a/drivers/net/sfc/sfc_ethdev.c\n+++ b/drivers/net/sfc/sfc_ethdev.c\n@@ -30,6 +30,7 @@\n #include \"sfc_dp_rx.h\"\n #include \"sfc_repr.h\"\n #include \"sfc_sw_stats.h\"\n+#include \"sfc_switch.h\"\n \n #define SFC_XSTAT_ID_INVALID_VAL  UINT64_MAX\n #define SFC_XSTAT_ID_INVALID_NAME '\\0'\n@@ -1862,6 +1863,177 @@ sfc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t ethdev_qid)\n \treturn sap->dp_rx->intr_disable(rxq_info->dp);\n }\n \n+struct sfc_mport_journal_ctx {\n+\tstruct sfc_adapter\t\t*sa;\n+\tuint16_t\t\t\tswitch_domain_id;\n+\tuint32_t\t\t\tmcdi_handle;\n+\tbool\t\t\t\tcontrollers_assigned;\n+\tefx_pcie_interface_t\t\t*controllers;\n+\tsize_t\t\t\t\tnb_controllers;\n+};\n+\n+static int\n+sfc_journal_ctx_add_controller(struct sfc_mport_journal_ctx *ctx,\n+\t\t\t       efx_pcie_interface_t intf)\n+{\n+\tefx_pcie_interface_t *new_controllers;\n+\tsize_t i, target;\n+\tsize_t new_size;\n+\n+\tif (ctx->controllers == NULL) {\n+\t\tctx->controllers = rte_malloc(\"sfc_controller_mapping\",\n+\t\t\t\t\t      sizeof(ctx->controllers[0]), 0);\n+\t\tif (ctx->controllers == NULL)\n+\t\t\treturn ENOMEM;\n+\n+\t\tctx->controllers[0] = intf;\n+\t\tctx->nb_controllers = 1;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tfor (i = 0; i < ctx->nb_controllers; i++) {\n+\t\tif (ctx->controllers[i] == intf)\n+\t\t\treturn 0;\n+\t\tif (ctx->controllers[i] > intf)\n+\t\t\tbreak;\n+\t}\n+\ttarget = i;\n+\n+\tctx->nb_controllers += 1;\n+\tnew_size = ctx->nb_controllers * sizeof(ctx->controllers[0]);\n+\n+\tnew_controllers = rte_realloc(ctx->controllers, new_size, 0);\n+\tif (new_controllers == NULL) {\n+\t\trte_free(ctx->controllers);\n+\t\treturn ENOMEM;\n+\t}\n+\tctx->controllers = new_controllers;\n+\n+\tfor (i = target + 1; i < ctx->nb_controllers; i++)\n+\t\tctx->controllers[i] = ctx->controllers[i - 1];\n+\n+\tctx->controllers[target] = intf;\n+\n+\treturn 0;\n+}\n+\n+static efx_rc_t\n+sfc_process_mport_journal_entry(struct sfc_mport_journal_ctx *ctx,\n+\t\t\t\tefx_mport_desc_t *mport)\n+{\n+\tefx_mport_sel_t ethdev_mport;\n+\tint rc;\n+\n+\tsfc_dbg(ctx->sa,\n+\t\t\"processing mport id %u (controller %u pf %u vf %u)\",\n+\t\tmport->emd_id.id, mport->emd_vnic.ev_intf,\n+\t\tmport->emd_vnic.ev_pf, mport->emd_vnic.ev_vf);\n+\tefx_mae_mport_invalid(&ethdev_mport);\n+\n+\tif (!ctx->controllers_assigned) {\n+\t\trc = sfc_journal_ctx_add_controller(ctx,\n+\t\t\t\t\t\t    mport->emd_vnic.ev_intf);\n+\t\tif (rc != 0)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static efx_rc_t\n+sfc_process_mport_journal_cb(void *data, efx_mport_desc_t *mport,\n+\t\t\t     size_t mport_len)\n+{\n+\tstruct sfc_mport_journal_ctx *ctx = data;\n+\n+\tif (ctx == NULL || ctx->sa == NULL) {\n+\t\tsfc_err(ctx->sa, \"received NULL context or SFC adapter\");\n+\t\treturn EINVAL;\n+\t}\n+\n+\tif (mport_len != sizeof(*mport)) {\n+\t\tsfc_err(ctx->sa, \"actual and expected mport buffer sizes differ\");\n+\t\treturn EINVAL;\n+\t}\n+\n+\tSFC_ASSERT(sfc_adapter_is_locked(ctx->sa));\n+\n+\t/*\n+\t * If a zombie flag is set, it means the mport has been marked for\n+\t * deletion and cannot be used for any new operations. The mport will\n+\t * be destroyed completely once all references to it are released.\n+\t */\n+\tif (mport->emd_zombie) {\n+\t\tsfc_dbg(ctx->sa, \"mport is a zombie, skipping\");\n+\t\treturn 0;\n+\t}\n+\tif (mport->emd_type != EFX_MPORT_TYPE_VNIC) {\n+\t\tsfc_dbg(ctx->sa, \"mport is not a VNIC, skipping\");\n+\t\treturn 0;\n+\t}\n+\tif (mport->emd_vnic.ev_client_type != EFX_MPORT_VNIC_CLIENT_FUNCTION) {\n+\t\tsfc_dbg(ctx->sa, \"mport is not a function, skipping\");\n+\t\treturn 0;\n+\t}\n+\tif (mport->emd_vnic.ev_handle == ctx->mcdi_handle) {\n+\t\tsfc_dbg(ctx->sa, \"mport is this driver instance, skipping\");\n+\t\treturn 0;\n+\t}\n+\n+\treturn sfc_process_mport_journal_entry(ctx, mport);\n+}\n+\n+static int\n+sfc_process_mport_journal(struct sfc_adapter *sa)\n+{\n+\tstruct sfc_mport_journal_ctx ctx;\n+\tconst efx_pcie_interface_t *controllers;\n+\tsize_t nb_controllers;\n+\tefx_rc_t efx_rc;\n+\tint rc;\n+\n+\tmemset(&ctx, 0, sizeof(ctx));\n+\tctx.sa = sa;\n+\tctx.switch_domain_id = sa->mae.switch_domain_id;\n+\n+\tefx_rc = efx_mcdi_get_own_client_handle(sa->nic, &ctx.mcdi_handle);\n+\tif (efx_rc != 0) {\n+\t\tsfc_err(sa, \"failed to get own MCDI handle\");\n+\t\tSFC_ASSERT(efx_rc > 0);\n+\t\treturn efx_rc;\n+\t}\n+\n+\trc = sfc_mae_switch_domain_controllers(ctx.switch_domain_id,\n+\t\t\t\t\t       &controllers, &nb_controllers);\n+\tif (rc != 0) {\n+\t\tsfc_err(sa, \"failed to get controller mapping\");\n+\t\treturn rc;\n+\t}\n+\n+\tctx.controllers_assigned = controllers != NULL;\n+\tctx.controllers = NULL;\n+\tctx.nb_controllers = 0;\n+\n+\tefx_rc = efx_mae_read_mport_journal(sa->nic,\n+\t\t\t\t\t    sfc_process_mport_journal_cb, &ctx);\n+\tif (efx_rc != 0) {\n+\t\tsfc_err(sa, \"failed to process MAE mport journal\");\n+\t\tSFC_ASSERT(efx_rc > 0);\n+\t\treturn efx_rc;\n+\t}\n+\n+\tif (controllers == NULL) {\n+\t\trc = sfc_mae_switch_domain_map_controllers(ctx.switch_domain_id,\n+\t\t\t\t\t\t\t   ctx.controllers,\n+\t\t\t\t\t\t\t   ctx.nb_controllers);\n+\t\tif (rc != 0)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static const struct eth_dev_ops sfc_eth_dev_ops = {\n \t.dev_configure\t\t\t= sfc_dev_configure,\n \t.dev_start\t\t\t= sfc_dev_start,\n@@ -2494,6 +2666,18 @@ sfc_eth_dev_create_representors(struct rte_eth_dev *dev,\n \t\treturn -ENOTSUP;\n \t}\n \n+\t/*\n+\t * This is needed to construct the DPDK controller -> EFX interface\n+\t * mapping.\n+\t */\n+\tsfc_adapter_lock(sa);\n+\trc = sfc_process_mport_journal(sa);\n+\tsfc_adapter_unlock(sa);\n+\tif (rc != 0) {\n+\t\tSFC_ASSERT(rc > 0);\n+\t\treturn -rc;\n+\t}\n+\n \tfor (i = 0; i < eth_da->nb_representor_ports; ++i) {\n \t\tconst efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);\n \t\tefx_mport_sel_t mport_sel;\ndiff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c\nindex 80c884a599..f72f6648b8 100644\n--- a/drivers/net/sfc/sfc_switch.c\n+++ b/drivers/net/sfc/sfc_switch.c\n@@ -87,6 +87,10 @@ struct sfc_mae_switch_domain {\n \tstruct sfc_mae_switch_ports\t\tports;\n \t/** RTE switch domain ID allocated for a group of devices */\n \tuint16_t\t\t\t\tid;\n+\t/** DPDK controller -> EFX interface mapping */\n+\tefx_pcie_interface_t\t\t\t*controllers;\n+\t/** Number of DPDK controllers and EFX interfaces */\n+\tsize_t\t\t\t\t\tnb_controllers;\n };\n \n TAILQ_HEAD(sfc_mae_switch_domains, sfc_mae_switch_domain);\n@@ -220,6 +224,59 @@ sfc_mae_assign_switch_domain(struct sfc_adapter *sa,\n \treturn rc;\n }\n \n+int\n+sfc_mae_switch_domain_controllers(uint16_t switch_domain_id,\n+\t\t\t\t  const efx_pcie_interface_t **controllers,\n+\t\t\t\t  size_t *nb_controllers)\n+{\n+\tstruct sfc_mae_switch_domain *domain;\n+\n+\tif (controllers == NULL || nb_controllers == NULL)\n+\t\treturn EINVAL;\n+\n+\trte_spinlock_lock(&sfc_mae_switch.lock);\n+\n+\tdomain = sfc_mae_find_switch_domain_by_id(switch_domain_id);\n+\tif (domain == NULL) {\n+\t\trte_spinlock_unlock(&sfc_mae_switch.lock);\n+\t\treturn EINVAL;\n+\t}\n+\n+\t*controllers = domain->controllers;\n+\t*nb_controllers = domain->nb_controllers;\n+\n+\trte_spinlock_unlock(&sfc_mae_switch.lock);\n+\treturn 0;\n+}\n+\n+int\n+sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id,\n+\t\t\t\t      efx_pcie_interface_t *controllers,\n+\t\t\t\t      size_t nb_controllers)\n+{\n+\tstruct sfc_mae_switch_domain *domain;\n+\n+\trte_spinlock_lock(&sfc_mae_switch.lock);\n+\n+\tdomain = sfc_mae_find_switch_domain_by_id(switch_domain_id);\n+\tif (domain == NULL) {\n+\t\trte_spinlock_unlock(&sfc_mae_switch.lock);\n+\t\treturn EINVAL;\n+\t}\n+\n+\t/* Controller mapping may be set only once */\n+\tif (domain->controllers != NULL) {\n+\t\trte_spinlock_unlock(&sfc_mae_switch.lock);\n+\t\treturn EINVAL;\n+\t}\n+\n+\tdomain->controllers = controllers;\n+\tdomain->nb_controllers = nb_controllers;\n+\n+\trte_spinlock_unlock(&sfc_mae_switch.lock);\n+\treturn 0;\n+}\n+\n /* This function expects to be called only when the lock is held */\n static struct sfc_mae_switch_port *\n sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain,\ndiff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h\nindex a1a2ab9848..1eee5fc0b6 100644\n--- a/drivers/net/sfc/sfc_switch.h\n+++ b/drivers/net/sfc/sfc_switch.h\n@@ -44,6 +44,14 @@ struct sfc_mae_switch_port_request {\n int sfc_mae_assign_switch_domain(struct sfc_adapter *sa,\n \t\t\t\t uint16_t *switch_domain_id);\n \n+int sfc_mae_switch_domain_controllers(uint16_t switch_domain_id,\n+\t\t\t\t      const efx_pcie_interface_t **controllers,\n+\t\t\t\t      size_t *nb_controllers);\n+\n+int sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id,\n+\t\t\t\t\t  efx_pcie_interface_t *controllers,\n+\t\t\t\t\t  size_t nb_controllers);\n+\n int sfc_mae_assign_switch_port(uint16_t switch_domain_id,\n \t\t\t       const struct sfc_mae_switch_port_request *req,\n \t\t\t       uint16_t *switch_port_id);\n",
    "prefixes": [
        "32/38"
    ]
}