From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80082.outbound.protection.outlook.com [40.107.8.82]) by dpdk.org (Postfix) with ESMTP id B86801B1FC for ; Mon, 9 Jul 2018 13:57:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fGQ0dtp3vp9Ik+q7aVMGISrYbwwJmm8+epBnX7NCtM0=; b=r/SthaUkcfVn78nSKPLVY2r9Bm2HfxvMdSfSSDG5M+ku3WxQPBHinne38cimpICImKRpBHDA4lL4f97w0S9HbY+4f86LslRVZd7VWGX9iShcHjzt3hTmdUAOTbJcNcSP8tL8ZCM84MnNGM+wDrUIpcZZGT3vokqGggrZ1W3E12Q= Received: from DB7PR05MB4426.eurprd05.prod.outlook.com (52.134.109.15) by DB7PR05MB4122.eurprd05.prod.outlook.com (52.134.107.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.930.19; Mon, 9 Jul 2018 11:57:29 +0000 Received: from DB7PR05MB4426.eurprd05.prod.outlook.com ([fe80::d9c6:913c:c361:f7b7]) by DB7PR05MB4426.eurprd05.prod.outlook.com ([fe80::d9c6:913c:c361:f7b7%6]) with mapi id 15.20.0930.016; Mon, 9 Jul 2018 11:57:29 +0000 From: Shahaf Shuler To: Adrien Mazarguil CC: "dev@dpdk.org" , =?iso-8859-1?Q?N=E9lio_Laranjeiro?= , "Xueming(Steven) Li" Thread-Topic: [PATCH v4 07/10] net/mlx5: probe all port representors Thread-Index: AQHUFDyXmJTjSFxLQkmjY/8QEU2vJqSGtPtA Date: Mon, 9 Jul 2018 11:57:29 +0000 Message-ID: References: <20180704172322.22571-1-adrien.mazarguil@6wind.com> <20180705083934.5535-1-adrien.mazarguil@6wind.com> <20180705083934.5535-8-adrien.mazarguil@6wind.com> In-Reply-To: <20180705083934.5535-8-adrien.mazarguil@6wind.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; x-originating-ip: [193.47.165.251] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB7PR05MB4122; 7:hp3kxaC5YX/F1RHMAvGompJmYeHeSFsTTkrnxh6gsvlpqSiIaCoAgUAuuh6IrlSyI7mXizst0yvPSzBH2NE4x7KcLYSqVtYI1+Wh10qsSlMhsX6Q2xO/t+Xlma9eEFpgiPLSBWI9k7PvqoUvE3s4eb3s3FsXrgVOY5PzcIuZyW4w4+jBJiQPy72WI0f54LudAn70TCfjsPelNsnwB8bob8ytWxI4Wm5FS5q3jJ5COtOfkfAyQmIMCWmLOH05ucP7 x-ms-exchange-antispam-srfa-diagnostics: SOS; x-ms-office365-filtering-correlation-id: e7bded2f-683f-44a1-d79a-08d5e593255a x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(5600053)(711020)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(48565401081)(2017052603328)(7153060)(7193020); SRVR:DB7PR05MB4122; x-ms-traffictypediagnostic: DB7PR05MB4122: x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(158342451672863)(218171748494069)(83566789882024); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(10201501046)(3231311)(944501410)(52105095)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011)(7699016); SRVR:DB7PR05MB4122; BCL:0; PCL:0; RULEID:; SRVR:DB7PR05MB4122; x-forefront-prvs: 07283408BE x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(376002)(366004)(39860400002)(136003)(396003)(189003)(199004)(50084003)(8936002)(55016002)(81166006)(4326008)(81156014)(7736002)(25786009)(74316002)(305945005)(5024004)(33656002)(478600001)(2906002)(53946003)(8676002)(3846002)(6916009)(256004)(14454004)(6246003)(5660300001)(9686003)(107886003)(6116002)(14444005)(53936002)(97736004)(476003)(6306002)(486006)(7696005)(76176011)(102836004)(446003)(6506007)(99286004)(26005)(11346002)(186003)(68736007)(2900100001)(5250100002)(229853002)(54906003)(316002)(86362001)(6436002)(106356001)(105586002)(66066001)(559001)(579004)(309714004); DIR:OUT; SFP:1101; SCL:1; SRVR:DB7PR05MB4122; H:DB7PR05MB4426.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: ai40C9qTUHL3S6e9Y0LkJlnICY0KE4OtHqQruD1uLC+KAxxzBnXH9TrGGfzhvEuafpQMdLn4r5LFeKsq+TcyiK7YSWrgOu27tpdRejW/1MEQSW+DYF6wsE2axqaJxKs+RWGe9kQWk4LFRTLpAnTH+dvSZMeqEoHGq53mKoTDjo9MzG3pUr1+gbsGWu8ZRzEgMCbR6YceZfOgd1rsbP8z3UoQTTj6CaJ5p65mEwY4GMGKuQtcNkaYKj1BG2YZaDe2Pve0DXK9I2XR/5UrvPuTl9/8fw+ELfZV3XBi2AaUYtfQv8m+IYnps3V3sJm4RJfyoCtWcSyapKMLhyfjJoVpdgxYugjf4/kXtNktQheG824= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: e7bded2f-683f-44a1-d79a-08d5e593255a X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Jul 2018 11:57:29.0865 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB7PR05MB4122 Subject: Re: [dpdk-dev] [PATCH v4 07/10] net/mlx5: probe all port representors X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jul 2018 11:57:32 -0000 Hi Adrien, Thursday, July 5, 2018 11:46 AM, Adrien Mazarguil: > Subject: [PATCH v4 07/10] net/mlx5: probe all port representors >=20 > Probe existing port representors in addition to their master device and > associate them automatically. >=20 > To avoid collision between Ethernet devices, they are named as follows: >=20 > - "{DBDF}" for master/switch devices. > - "{DBDF}_representor_{rep}" with "rep" starting from 0 for port > representors. >=20 > (Patch based on prior work from Yuanhan Liu) >=20 > Signed-off-by: Adrien Mazarguil > Signed-off-by: Nelio Laranjeiro > Reviewed-by: Xueming Li > Cc: Xueming Li > Cc: Shahaf Shuler > -- > v4 changes: >=20 > - Fixed domain ID release once the last port using it is closed. Closed > devices are not necessarily detached, their presence is not a good > indicator. Code was modified to check if they still use their domain ID= s > before deciding to release it. >=20 > v3 changes: >=20 > - Nelio introduced mlx5_dev_to_port_id() to prevent the master device > from > releasing a domain ID while representors are still bound. It is now > released by the last device closed. > - Reverted to original naming convention as requested by Xueming and > Shahaf; "net_" prefix and "_0" suffix were dropped. > - mlx5_dev_spawn() (previously mlx5_dev_spawn_one()) now decides on > its own > whether underlying device is a representor. > - Devices can now be probed in any order and not necessarily all at once; > representors can exist without a master device. > - mlx5_pci_probe() iterates on the list of devices directly instead of > relying on an intermediate function (previously mlx5_dev_spawn()). > - mlx5_get_ifname() was rewritten to rely on mlx5_nl_ifindex() when faced > with a representor. > - Since it is not necessarily present, master device is now dynamically > retrieved in mlx5_dev_infos_get(). >=20 > v2 changes: >=20 > - Added representor information to dev_infos_get(). DPDK port ID of maste= r > device is now stored in the private structure to retrieve it > conveniently. > - Master device is assigned dummy representor ID value -1 to better > distinguish from the the first actual representor reported by > dev_infos_get() as those are indexed from 0. > - Added RTE_ETH_DEV_REPRESENTOR device flag. > --- > drivers/net/mlx5/mlx5.c | 134 ++++++++++++++++++++++++++++------- > - > drivers/net/mlx5/mlx5.h | 12 +++- > drivers/net/mlx5/mlx5_ethdev.c | 133 > +++++++++++++++++++++++++++++++---- > drivers/net/mlx5/mlx5_mac.c | 2 +- > drivers/net/mlx5/mlx5_stats.c | 6 +- > 5 files changed, 238 insertions(+), 49 deletions(-) >=20 > diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index > d06ba9886..c02afbb82 100644 > --- a/drivers/net/mlx5/mlx5.c > +++ b/drivers/net/mlx5/mlx5.c > @@ -307,7 +307,27 @@ mlx5_dev_close(struct rte_eth_dev *dev) > if (ret) > DRV_LOG(WARNING, "port %u some flows still remain", > dev->data->port_id); > + if (priv->domain_id !=3D > RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) { > + unsigned int c =3D 0; > + unsigned int i =3D mlx5_dev_to_port_id(dev->device, NULL, 0); > + uint16_t port_id[i]; > + > + i =3D RTE_MIN(mlx5_dev_to_port_id(dev->device, port_id, i), > i); > + while (i--) { > + struct priv *opriv =3D > + rte_eth_devices[port_id[i]].data- > >dev_private; > + > + if (!opriv || > + opriv->domain_id !=3D priv->domain_id || > + &rte_eth_devices[port_id[i]] =3D=3D dev) > + continue; > + ++c; > + } > + if (!c) > + claim_zero(rte_eth_switch_domain_free(priv- > >domain_id)); > + } > memset(priv, 0, sizeof(*priv)); > + priv->domain_id =3D RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; > } >=20 > const struct eth_dev_ops mlx5_dev_ops =3D { @@ -647,6 +667,8 @@ > mlx5_uar_init_secondary(struct rte_eth_dev *dev) > * Verbs device. > * @param vf > * If nonzero, enable VF-specific features. > + * @param[in] switch_info > + * Switch properties of Ethernet device. > * > * @return > * A valid Ethernet device object on success, NULL otherwise and rte_e= rrno > @@ -655,7 +677,8 @@ mlx5_uar_init_secondary(struct rte_eth_dev *dev) > static struct rte_eth_dev * mlx5_dev_spawn(struct rte_device *dpdk_dev, > struct ibv_device *ibv_dev, > - int vf) > + int vf, > + const struct mlx5_switch_info *switch_info) > { > struct ibv_context *ctx; > struct ibv_device_attr_ex attr; > @@ -697,6 +720,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > #endif > struct ether_addr mac; > char name[RTE_ETH_NAME_MAX_LEN]; > + int own_domain_id =3D 0; > + unsigned int i; >=20 > /* Prepare shared data between primary and secondary process. */ > mlx5_prepare_shared_data(); > @@ -805,7 +830,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > DEBUG("ibv_query_device_ex() failed"); > goto error; > } > - rte_strlcpy(name, dpdk_dev->name, sizeof(name)); > + if (!switch_info->representor) > + rte_strlcpy(name, dpdk_dev->name, sizeof(name)); > + else > + snprintf(name, sizeof(name), "%s_representor_%u", > + dpdk_dev->name, switch_info->port_name); > + DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name); > if (rte_eal_process_type() =3D=3D RTE_PROC_SECONDARY) { > eth_dev =3D rte_eth_dev_attach_secondary(name); > if (eth_dev =3D=3D NULL) { > @@ -874,6 +904,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > goto error; > } > priv->ctx =3D ctx; > + strncpy(priv->ibdev_name, priv->ctx->device->name, > + sizeof(priv->ibdev_name)); > strncpy(priv->ibdev_path, priv->ctx->device->ibdev_path, > sizeof(priv->ibdev_path)); > priv->device_attr =3D attr; > @@ -883,6 +915,41 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > priv->nl_socket_rdma =3D mlx5_nl_init(0, NETLINK_RDMA); > priv->nl_socket_route =3D mlx5_nl_init(RTMGRP_LINK, > NETLINK_ROUTE); > priv->nl_sn =3D 0; > + priv->representor =3D !!switch_info->representor; > + priv->domain_id =3D RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID; > + priv->representor_id =3D > + switch_info->representor ? switch_info->port_name : -1; > + /* > + * Look for sibling devices in order to reuse their switch domain > + * if any, otherwise allocate one. > + */ > + i =3D mlx5_dev_to_port_id(dpdk_dev, NULL, 0); > + if (i > 0) { > + uint16_t port_id[i]; > + > + i =3D RTE_MIN(mlx5_dev_to_port_id(dpdk_dev, port_id, i), i); > + while (i--) { > + const struct priv *opriv =3D > + rte_eth_devices[port_id[i]].data- > >dev_private; > + > + if (!opriv || > + opriv->domain_id =3D=3D > + RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) > + continue; > + priv->domain_id =3D opriv->domain_id; It looks like for the second port it will use the domain_id of the first po= rt. Is that what you intent?=20 Note - I couldn't test it due to compilation errors: /.autodirect/swgwork/shahafs/workspace/dpdk.org/drivers/net/mlx5/mlx5_nl.c:= In function 'mlx5_nl_switch_info_cb': /.autodirect/swgwork/shahafs/workspace/dpdk.org/drivers/net/mlx5/mlx5_nl.c:= 843:8: error: 'IFLA_PHYS_PORT_NAME' undecl ared (first use in this function) case IFLA_PHYS_PORT_NAME: ^ /.autodirect/swgwork/shahafs/workspace/dpdk.org/drivers/net/mlx5/mlx5_nl.c:= 843:8: note: each undeclared identifier is reported only once for each function it appears in /.autodirect/swgwork/shahafs/workspace/dpdk.org/drivers/net/mlx5/mlx5_nl.c:= 851:8: error: 'IFLA_PHYS_SWITCH_ID' undecl ared (first use in this function) case IFLA_PHYS_SWITCH_ID: ^ My system info: NAME=3D"Red Hat Enterprise Linux Server" VERSION=3D"7.3 (Maipo)" ID=3D"rhel" ID_LIKE=3D"fedora" VERSION_ID=3D"7.3" PRETTY_NAME=3D"Red Hat Enterprise Linux Server 7.3 (Maipo)" ANSI_COLOR=3D"0;31" CPE_NAME=3D"cpe:/o:redhat:enterprise_linux:7.3:GA:server" HOME_URL=3D"https://www.redhat.com/" BUG_REPORT_URL=3D"https://bugzilla.redhat.com/" REDHAT_BUGZILLA_PRODUCT=3D"Red Hat Enterprise Linux 7" REDHAT_BUGZILLA_PRODUCT_VERSION=3D7.3 REDHAT_SUPPORT_PRODUCT=3D"Red Hat Enterprise Linux" REDHAT_SUPPORT_PRODUCT_VERSION=3D"7.3" Red Hat Enterprise Linux Server release 7.3 (Maipo) Red Hat Enterprise Linux Server release 7.3 (Maipo) > + break; > + } > + } > + if (priv->domain_id =3D=3D > RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) { > + err =3D rte_eth_switch_domain_alloc(&priv->domain_id); > + if (err) { > + err =3D rte_errno; > + DRV_LOG(ERR, "unable to allocate switch domain: > %s", > + strerror(rte_errno)); > + goto error; > + } > + own_domain_id =3D 1; > + } > err =3D mlx5_args(&config, dpdk_dev->devargs); > if (err) { > err =3D rte_errno; > @@ -966,6 +1033,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > err =3D ENOMEM; > goto error; > } > + if (priv->representor) > + eth_dev->data->dev_flags |=3D RTE_ETH_DEV_REPRESENTOR; > eth_dev->data->dev_private =3D priv; > priv->dev_data =3D eth_dev->data; > eth_dev->data->mac_addrs =3D priv->mac; > @@ -1084,6 +1153,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > close(priv->nl_socket_route); > if (priv->nl_socket_rdma >=3D 0) > close(priv->nl_socket_rdma); > + if (own_domain_id) > + claim_zero(rte_eth_switch_domain_free(priv- > >domain_id)); > rte_free(priv); > } > if (pd) > @@ -1100,7 +1171,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, > /** > * DPDK callback to register a PCI device. > * > - * This function spawns an Ethernet device out of a given PCI device. > + * This function spawns Ethernet devices out of a given PCI device. > * > * @param[in] pci_drv > * PCI driver structure (mlx5_driver). > @@ -1115,7 +1186,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, > struct rte_pci_device *pci_dev) { > struct ibv_device **ibv_list; > - struct rte_eth_dev *eth_dev =3D NULL; > unsigned int n =3D 0; > int vf; > int ret; > @@ -1150,9 +1220,11 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, >=20 > unsigned int ifindex[n]; > struct mlx5_switch_info info[n]; > + struct rte_eth_dev *eth_list[n]; > int nl_route =3D n ? mlx5_nl_init(0, NETLINK_ROUTE) : -1; > int nl_rdma =3D n ? mlx5_nl_init(0, NETLINK_RDMA) : -1; > unsigned int i; > + unsigned int u; >=20 > /* > * The existence of several matching entries (n > 1) means port @@ - > 1187,28 +1259,14 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, > close(nl_rdma); > if (nl_route >=3D 0) > close(nl_route); > - /* Look for master device. */ > - for (i =3D 0; i !=3D n; ++i) { > - if (!info[i].master) > - continue; > - /* Make it the first entry. */ > - if (i =3D=3D 0) > - break; > - ibv_match[n] =3D ibv_match[0]; > - ibv_match[0] =3D ibv_match[i]; > - ibv_match[n] =3D NULL; > - break; > - } > - if (n && i =3D=3D n) { > - if (n =3D=3D 1 && !info[0].representor) { > + /* Count unidentified devices. */ > + for (u =3D 0, i =3D 0; i !=3D n; ++i) > + if (!info[i].master && !info[i].representor) > + ++u; > + if (u) { > + if (n =3D=3D 1 && u =3D=3D 1) { > /* Case #2. */ > DRV_LOG(INFO, "no switch support detected"); > - } else if (n =3D=3D 1) { > - /* Case #3. */ > - DRV_LOG(ERR, > - "device looks like a port representor, this is" > - " not supported yet"); > - n =3D 0; > } else { > /* Case #3. */ > DRV_LOG(ERR, > @@ -1227,8 +1285,19 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, > default: > vf =3D 0; > } > - if (n) > - eth_dev =3D mlx5_dev_spawn(&pci_dev->device, > ibv_match[0], vf); > + for (i =3D 0; i !=3D n; ++i) { > + uint32_t restore; > + > + eth_list[i] =3D mlx5_dev_spawn(&pci_dev->device, > ibv_match[i], > + vf, &info[i]); > + if (!eth_list[i]) > + break; > + restore =3D eth_list[i]->data->dev_flags; > + rte_eth_copy_pci_info(eth_list[i], pci_dev); > + /* Restore non-PCI flags cleared by the above call. */ > + eth_list[i]->data->dev_flags |=3D restore; > + rte_eth_dev_probing_finish(eth_list[i]); > + } > mlx5_glue->free_device_list(ibv_list); > if (!n) { > DRV_LOG(WARNING, > @@ -1238,7 +1307,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, > pci_dev->addr.devid, pci_dev->addr.function); > rte_errno =3D ENOENT; > ret =3D -rte_errno; > - } else if (!eth_dev) { > + } else if (i !=3D n) { > DRV_LOG(ERR, > "probe of PCI device " PCI_PRI_FMT " aborted after" > " encountering an error: %s", > @@ -1246,9 +1315,16 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv > __rte_unused, > pci_dev->addr.devid, pci_dev->addr.function, > strerror(rte_errno)); > ret =3D -rte_errno; > + /* Roll back. */ > + while (i--) { > + mlx5_dev_close(eth_list[i]); > + if (rte_eal_process_type() =3D=3D RTE_PROC_PRIMARY) > + rte_free(eth_list[i]->data->dev_private); > + claim_zero(rte_eth_dev_release_port(eth_list[i])); > + } > + /* Restore original error. */ > + rte_errno =3D -ret; > } else { > - rte_eth_copy_pci_info(eth_dev, pci_dev); > - rte_eth_dev_probing_finish(eth_dev); > ret =3D 0; > } > return ret; > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index > 704046270..cc01310e0 100644 > --- a/drivers/net/mlx5/mlx5.h > +++ b/drivers/net/mlx5/mlx5.h > @@ -159,6 +159,7 @@ struct priv { > struct ibv_context *ctx; /* Verbs context. */ > struct ibv_device_attr_ex device_attr; /* Device properties. */ > struct ibv_pd *pd; /* Protection Domain. */ > + char ibdev_name[IBV_SYSFS_NAME_MAX]; /* IB device name. */ Why we need a dedicated entry for the ibdev_name? it is already part of pri= v->ctx->device->name.=20 > char ibdev_path[IBV_SYSFS_PATH_MAX]; /* IB device path for > secondary */ > struct ether_addr mac[MLX5_MAX_MAC_ADDRESSES]; /* MAC > addresses. */ > BITFIELD_DECLARE(mac_own, uint64_t, > MLX5_MAX_MAC_ADDRESSES); @@ -168,6 +169,9 @@ struct priv { > /* Device properties. */ > uint16_t mtu; /* Configured MTU. */ > unsigned int isolated:1; /* Whether isolated mode is enabled. */ > + unsigned int representor:1; /* Device is a port representor. */ > + uint16_t domain_id; /* Switch domain identifier. */ > + int32_t representor_id; /* Port representor identifier. */ > /* RX/TX queues. */ > unsigned int rxqs_n; /* RX queues array size. */ > unsigned int txqs_n; /* TX queues array size. */ @@ -217,9 +221,12 > @@ int mlx5_getenv_int(const char *); >=20 > /* mlx5_ethdev.c */ >=20 > +int mlx5_get_master_ifname(const struct rte_eth_dev *dev, > + char (*ifname)[IF_NAMESIZE]); > int mlx5_get_ifname(const struct rte_eth_dev *dev, char > (*ifname)[IF_NAMESIZE]); int mlx5_ifindex(const struct rte_eth_dev *dev)= ; > -int mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr= ); > +int mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr= , > + int master); > int mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu); int > mlx5_set_flags(struct rte_eth_dev *dev, unsigned int keep, > unsigned int flags); > @@ -244,6 +251,9 @@ int mlx5_set_link_up(struct rte_eth_dev *dev); int > mlx5_is_removed(struct rte_eth_dev *dev); eth_tx_burst_t > mlx5_select_tx_function(struct rte_eth_dev *dev); eth_rx_burst_t > mlx5_select_rx_function(struct rte_eth_dev *dev); > +unsigned int mlx5_dev_to_port_id(const struct rte_device *dev, > + uint16_t *port_list, > + unsigned int port_list_n); >=20 > /* mlx5_mac.c */ >=20 > diff --git a/drivers/net/mlx5/mlx5_ethdev.c > b/drivers/net/mlx5/mlx5_ethdev.c index 819f5baad..05f66f7b6 100644 > --- a/drivers/net/mlx5/mlx5_ethdev.c > +++ b/drivers/net/mlx5/mlx5_ethdev.c > @@ -27,6 +27,7 @@ > #include >=20 > #include > +#include > #include > #include > #include > @@ -93,7 +94,7 @@ struct ethtool_link_settings { #endif >=20 > /** > - * Get interface name from private structure. > + * Get master interface name from private structure. > * > * @param[in] dev > * Pointer to Ethernet device. > @@ -104,7 +105,8 @@ struct ethtool_link_settings { > * 0 on success, a negative errno value otherwise and rte_errno is set= . > */ > int > -mlx5_get_ifname(const struct rte_eth_dev *dev, char > (*ifname)[IF_NAMESIZE]) > +mlx5_get_master_ifname(const struct rte_eth_dev *dev, > + char (*ifname)[IF_NAMESIZE]) > { > struct priv *priv =3D dev->data->dev_private; > DIR *dir; > @@ -179,6 +181,39 @@ mlx5_get_ifname(const struct rte_eth_dev *dev, > char (*ifname)[IF_NAMESIZE]) } >=20 > /** > + * Get interface name from private structure. > + * > + * This is a port representor-aware version of mlx5_get_master_ifname(). > + * > + * @param[in] dev > + * Pointer to Ethernet device. > + * @param[out] ifname > + * Interface name output buffer. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set= . > + */ > +int > +mlx5_get_ifname(const struct rte_eth_dev *dev, char > +(*ifname)[IF_NAMESIZE]) { > + struct priv *priv =3D dev->data->dev_private; > + unsigned int ifindex =3D > + priv->nl_socket_rdma >=3D 0 ? > + mlx5_nl_ifindex(priv->nl_socket_rdma, priv->ibdev_name) : > 0; > + > + if (!ifindex) { > + if (!priv->representor) > + return mlx5_get_master_ifname(dev, ifname); > + rte_errno =3D ENXIO; > + return -rte_errno; > + } > + if (if_indextoname(ifindex, &(*ifname)[0])) > + return 0; > + rte_errno =3D errno; > + return -rte_errno; > +} > + > +/** > * Get the interface index from device name. > * > * @param[in] dev > @@ -214,12 +249,16 @@ mlx5_ifindex(const struct rte_eth_dev *dev) > * Request number to pass to ioctl(). > * @param[out] ifr > * Interface request structure output buffer. > + * @param master > + * When device is a port representor, perform request on master device > + * instead. > * > * @return > * 0 on success, a negative errno value otherwise and rte_errno is set= . > */ > int > -mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr) > +mlx5_ifreq(const struct rte_eth_dev *dev, int req, struct ifreq *ifr, > + int master) > { > int sock =3D socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); > int ret =3D 0; > @@ -228,7 +267,10 @@ mlx5_ifreq(const struct rte_eth_dev *dev, int req, > struct ifreq *ifr) > rte_errno =3D errno; > return -rte_errno; > } > - ret =3D mlx5_get_ifname(dev, &ifr->ifr_name); > + if (master) > + ret =3D mlx5_get_master_ifname(dev, &ifr->ifr_name); > + else > + ret =3D mlx5_get_ifname(dev, &ifr->ifr_name); > if (ret) > goto error; > ret =3D ioctl(sock, req, ifr); > @@ -258,7 +300,7 @@ int > mlx5_get_mtu(struct rte_eth_dev *dev, uint16_t *mtu) { > struct ifreq request; > - int ret =3D mlx5_ifreq(dev, SIOCGIFMTU, &request); > + int ret =3D mlx5_ifreq(dev, SIOCGIFMTU, &request, 0); >=20 > if (ret) > return ret; > @@ -282,7 +324,7 @@ mlx5_set_mtu(struct rte_eth_dev *dev, uint16_t > mtu) { > struct ifreq request =3D { .ifr_mtu =3D mtu, }; >=20 > - return mlx5_ifreq(dev, SIOCSIFMTU, &request); > + return mlx5_ifreq(dev, SIOCSIFMTU, &request, 0); > } >=20 > /** > @@ -302,13 +344,13 @@ int > mlx5_set_flags(struct rte_eth_dev *dev, unsigned int keep, unsigned int > flags) { > struct ifreq request; > - int ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &request); > + int ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &request, 0); >=20 > if (ret) > return ret; > request.ifr_flags &=3D keep; > request.ifr_flags |=3D flags & ~keep; > - return mlx5_ifreq(dev, SIOCSIFFLAGS, &request); > + return mlx5_ifreq(dev, SIOCSIFFLAGS, &request, 0); > } >=20 > /** > @@ -477,6 +519,30 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, > struct rte_eth_dev_info *info) > info->speed_capa =3D priv->link_speed_capa; > info->flow_type_rss_offloads =3D ~MLX5_RSS_HF_MASK; > mlx5_set_default_params(dev, info); > + info->switch_info.name =3D dev->data->name; > + info->switch_info.domain_id =3D priv->domain_id; > + info->switch_info.port_id =3D priv->representor_id; > + if (priv->representor) { > + unsigned int i =3D mlx5_dev_to_port_id(dev->device, NULL, 0); > + uint16_t port_id[i]; > + > + i =3D RTE_MIN(mlx5_dev_to_port_id(dev->device, port_id, i), > i); > + while (i--) { > + struct priv *opriv =3D > + rte_eth_devices[port_id[i]].data- > >dev_private; > + > + if (!opriv || > + opriv->representor || > + opriv->domain_id !=3D priv->domain_id) > + continue; > + /* > + * Override switch name with that of the master > + * device. > + */ > + info->switch_info.name =3D opriv->dev_data->name; > + break; According to this logic it means once the master device is closed, all the = representors are no longer belong to the same switch (switch name of each i= s different) which is not correct. According to your notes it is possible to close master w/o closing the repr= esentor.=20 Why not just storing the master switch name when probing the representor an= d to use it as is on the dev_info?=20 > + } > + } > } >=20 > /** > @@ -540,7 +606,7 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev > *dev, > int link_speed =3D 0; > int ret; >=20 > - ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: > %s", > dev->data->port_id, strerror(rte_errno)); @@ -550,7 > +616,7 @@ mlx5_link_update_unlocked_gset(struct rte_eth_dev *dev, > dev_link.link_status =3D ((ifr.ifr_flags & IFF_UP) && > (ifr.ifr_flags & IFF_RUNNING)); > ifr.ifr_data =3D (void *)&edata; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, > "port %u ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: > %s", @@ -611,7 +677,7 @@ mlx5_link_update_unlocked_gs(struct > rte_eth_dev *dev, > uint64_t sc; > int ret; >=20 > - ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCGIFFLAGS, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, "port %u ioctl(SIOCGIFFLAGS) failed: > %s", > dev->data->port_id, strerror(rte_errno)); @@ -621,7 > +687,7 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, > dev_link.link_status =3D ((ifr.ifr_flags & IFF_UP) && > (ifr.ifr_flags & IFF_RUNNING)); > ifr.ifr_data =3D (void *)&gcmd; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(DEBUG, > "port %u ioctl(SIOCETHTOOL, > ETHTOOL_GLINKSETTINGS)" > @@ -638,7 +704,7 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev > *dev, >=20 > *ecmd =3D gcmd; > ifr.ifr_data =3D (void *)ecmd; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(DEBUG, > "port %u ioctl(SIOCETHTOOL, > ETHTOOL_GLINKSETTINGS)" > @@ -801,7 +867,7 @@ mlx5_dev_get_flow_ctrl(struct rte_eth_dev *dev, > struct rte_eth_fc_conf *fc_conf) > int ret; >=20 > ifr.ifr_data =3D (void *)ðpause; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, > "port %u ioctl(SIOCETHTOOL, > ETHTOOL_GPAUSEPARAM) failed:" > @@ -854,7 +920,7 @@ mlx5_dev_set_flow_ctrl(struct rte_eth_dev *dev, > struct rte_eth_fc_conf *fc_conf) > ethpause.tx_pause =3D 1; > else > ethpause.tx_pause =3D 0; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 0); > if (ret) { > DRV_LOG(WARNING, > "port %u ioctl(SIOCETHTOOL, > ETHTOOL_SPAUSEPARAM)" > @@ -1193,3 +1259,40 @@ mlx5_is_removed(struct rte_eth_dev *dev) > return 1; > return 0; > } > + > +/** > + * Get port ID list of mlx5 instances sharing a common device. > + * > + * @param[in] dev > + * Device to look for. > + * @param[out] port_list > + * Result buffer for collected port IDs. > + * @param port_list_n > + * Maximum number of entries in result buffer. If 0, @p port_list can = be > + * NULL. > + * > + * @return > + * Number of matching instances regardless of the @p port_list_n > + * parameter, 0 if none were found. > + */ > +unsigned int > +mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list, > + unsigned int port_list_n) > +{ > + uint16_t id; > + unsigned int n =3D 0; > + > + RTE_ETH_FOREACH_DEV(id) { > + struct rte_eth_dev *ldev =3D &rte_eth_devices[id]; > + > + if (!ldev->device || > + !ldev->device->driver || > + strcmp(ldev->device->driver->name, > MLX5_DRIVER_NAME) || > + ldev->device !=3D dev) > + continue; > + if (n < port_list_n) > + port_list[n] =3D id; > + n++; > + } > + return n; > +} > diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c > index 672a47619..12ee37f55 100644 > --- a/drivers/net/mlx5/mlx5_mac.c > +++ b/drivers/net/mlx5/mlx5_mac.c > @@ -49,7 +49,7 @@ mlx5_get_mac(struct rte_eth_dev *dev, uint8_t > (*mac)[ETHER_ADDR_LEN]) > struct ifreq request; > int ret; >=20 > - ret =3D mlx5_ifreq(dev, SIOCGIFHWADDR, &request); > + ret =3D mlx5_ifreq(dev, SIOCGIFHWADDR, &request, 0); > if (ret) > return ret; > memcpy(mac, request.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); diff - > -git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c inde= x > 875dd1027..91f3d474a 100644 > --- a/drivers/net/mlx5/mlx5_stats.c > +++ b/drivers/net/mlx5/mlx5_stats.c > @@ -146,7 +146,7 @@ mlx5_read_dev_counters(struct rte_eth_dev *dev, > uint64_t *stats) > et_stats->cmd =3D ETHTOOL_GSTATS; > et_stats->n_stats =3D xstats_ctrl->stats_n; > ifr.ifr_data =3D (caddr_t)et_stats; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, > "port %u unable to read statistic values from device", > @@ -194,7 +194,7 @@ mlx5_ethtool_get_stats_n(struct rte_eth_dev *dev) > { >=20 > drvinfo.cmd =3D ETHTOOL_GDRVINFO; > ifr.ifr_data =3D (caddr_t)&drvinfo; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, "port %u unable to query number of > statistics", > dev->data->port_id); > @@ -244,7 +244,7 @@ mlx5_xstats_init(struct rte_eth_dev *dev) > strings->string_set =3D ETH_SS_STATS; > strings->len =3D dev_stats_n; > ifr.ifr_data =3D (caddr_t)strings; > - ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr); > + ret =3D mlx5_ifreq(dev, SIOCETHTOOL, &ifr, 1); > if (ret) { > DRV_LOG(WARNING, "port %u unable to get statistic > names", > dev->data->port_id); > -- > 2.11.0