From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3E46643256 for ; Tue, 31 Oct 2023 23:21:48 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 368B740285; Tue, 31 Oct 2023 23:21:48 +0100 (CET) Received: from mail-io1-f99.google.com (mail-io1-f99.google.com [209.85.166.99]) by mails.dpdk.org (Postfix) with ESMTP id 200FD40285 for ; Tue, 31 Oct 2023 23:21:47 +0100 (CET) Received: by mail-io1-f99.google.com with SMTP id ca18e2360f4ac-7a68d1698adso8263039f.1 for ; Tue, 31 Oct 2023 15:21:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1698790906; x=1699395706; darn=dpdk.org; h=cc:to:from:subject:message-id:date:from:to:cc:subject:date :message-id:reply-to; bh=uerj9JbixZlB5vxGS0pz99cJEHtWdpR90vGNmVngOGw=; b=HtzLewtusl4BXfDxamnPPUU533uVi71xiKwogxx7SDKeDnlhoUN6NBnct982qMj3zt CPZoC+tiRTjztfOUO2HhBAFEUTR8L9bFA5NTbvQf3BWDJfEh90Eo42mATyx/pS28R982 55YOfaL0FQfs2FAXAvkuv1C5LTtvLvw5sGWQ0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698790906; x=1699395706; h=cc:to:from:subject:message-id:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uerj9JbixZlB5vxGS0pz99cJEHtWdpR90vGNmVngOGw=; b=Uih8vXeFzV4n/uPIFGLQ5u2AsfE0OLCDoFNl/yjRR7IhNCyq0jzOCqF1DEYHU5B39w 59lIi07b/tHw6aXlZipkQwKnS2piQbyFiEgk385wLb0qr91cmKXvqLojIyX/LVFEBxa5 xjgZziDffu3k8WwWXrm8375iJUv7euw10hJgKIh4/QSf3s5jzjQwkZk2k63qefzw6fc9 y7FRkZ3MzUUxue+GTGkCH3AJATu5M3kuTIRaGrtkGOfowVuhZE8X97ZrhOSqsNwIXIEe 3qQqPYvNVzs6ofjB2ZsUCv+jnjcXzKMDBNQFJE1ZibCge7XStYYDC0/a6gJ1IDpQ25sw ZPEQ== X-Gm-Message-State: AOJu0YzH1pud+wK022sS6n3OlqTMl9F3tTroJmVn3uSOXOOI+lVe2jy5 2lUuoiUQYz1CC8kwMiAuF3W0/F28ASaTc/zdfuhrxQ/Kh0bUj14ZdEVRBA== X-Google-Smtp-Source: AGHT+IFv28E3DjrmELZbFPX51ju5Ni5FxdJLwts0MCMa0JaDFTjJckP+ESCPyyD+eBHj9M2tg7OyxiPyK3F1 X-Received: by 2002:a05:6602:3a06:b0:7ac:ccd9:da93 with SMTP id by6-20020a0566023a0600b007acccd9da93mr1096163iob.0.1698790906447; Tue, 31 Oct 2023 15:21:46 -0700 (PDT) Received: from postal.iol.unh.edu (postal.iol.unh.edu. [132.177.123.84]) by smtp-relay.gmail.com with ESMTPS id ee1-20020a056638292100b0042b2b936ad6sm330230jab.72.2023.10.31.15.21.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Oct 2023 15:21:46 -0700 (PDT) X-Relaying-Domain: iol.unh.edu Date: Tue, 31 Oct 2023 15:21:46 -0700 (PDT) Message-ID: <65417dfa.050a0220.d6eeb.4b1fSMTPIN_ADDED_MISSING@mx.google.com> Received: from [172.21.0.2] (unknown [172.18.0.240]) by postal.iol.unh.edu (Postfix) with ESMTP id E6B886050A61; Tue, 31 Oct 2023 18:21:45 -0400 (EDT) Subject: |WARNING| pw133668-133674 [PATCH] [8/8] net/mlx5: add support for vport match selection From: dpdklab@iol.unh.edu To: test-report@dpdk.org Cc: dpdk-test-reports@iol.unh.edu Content-Type: text/plain X-BeenThere: test-report@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: automatic DPDK test reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: test-report-bounces@dpdk.org Test-Label: iol-testing Test-Status: WARNING http://dpdk.org/patch/133668 _apply patch failure_ Submitter: Dariusz Sosnowski Date: Tuesday, October 31 2023 14:27:33 Applied on: CommitID:6ff1e408e7e5f7c29fa6227d07ec74a7de642c5a Apply patch set 133668-133674 failed: Checking patch drivers/net/mlx5/hws/mlx5dr_matcher.c... error: while searching for: goto remove_from_list; } if (prev) { /* Reset next miss FT to default (drop refcount) */ ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev->end_ft); if (ret) { DR_LOG(ERR, "Failed to reset matcher ft default miss"); goto remove_from_list; } } else { /* Update tables missing to current table */ ret = mlx5dr_table_update_connected_miss_tables(tbl); if (ret) { DR_LOG(ERR, "Fatal error, failed to update connected miss table"); error: patch failed: drivers/net/mlx5/hws/mlx5dr_matcher.c:253 error: while searching for: return ret; } static int mlx5dr_last_matcher_disconnect(struct mlx5dr_table *tbl, struct mlx5dr_devx_obj *prev_ft) { struct mlx5dr_cmd_ft_modify_attr ft_attr = {0}; if (tbl->default_miss.miss_tbl) { /* Connect new last matcher to next miss_tbl if exists */ return mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl); } else { ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID; ft_attr.type = tbl->fw_ft_type; /* Matcher is last, point prev end FT to default miss */ mlx5dr_cmd_set_attr_connect_miss_tbl(tbl->ctx, tbl->fw_ft_type, tbl->type, &ft_attr); return mlx5dr_cmd_flow_table_modify(prev_ft, &ft_attr); } } static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher) { struct mlx5dr_matcher *tmp_matcher, *prev_matcher; error: patch failed: drivers/net/mlx5/hws/mlx5dr_matcher.c:276 error: while searching for: goto matcher_reconnect; } } else { ret = mlx5dr_last_matcher_disconnect(tbl, prev_ft); if (ret) { DR_LOG(ERR, "Failed to disconnect last matcher"); goto matcher_reconnect; error: patch failed: drivers/net/mlx5/hws/mlx5dr_matcher.c:330 Applying patch drivers/net/mlx5/hws/mlx5dr_matcher.c with 3 rejects... Rejected hunk #1. Rejected hunk #2. Rejected hunk #3. hint: Use 'git am --show-current-patch' to see the failed patch diff a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c (rejected hunks) @@ -253,15 +253,15 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher) goto remove_from_list; } - if (prev) { - /* Reset next miss FT to default (drop refcount) */ - ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev->end_ft); - if (ret) { - DR_LOG(ERR, "Failed to reset matcher ft default miss"); - goto remove_from_list; - } - } else { - /* Update tables missing to current table */ + /* Reset next miss FT to default (drop refcount) */ + ret = mlx5dr_table_ft_set_default_next_ft(tbl, prev ? prev->end_ft : tbl->ft); + if (ret) { + DR_LOG(ERR, "Failed to reset matcher ft default miss"); + goto remove_from_list; + } + + if (!prev) { + /* Update tables missing to current matcher in the table */ ret = mlx5dr_table_update_connected_miss_tables(tbl); if (ret) { DR_LOG(ERR, "Fatal error, failed to update connected miss table"); @@ -276,27 +276,6 @@ static int mlx5dr_matcher_connect(struct mlx5dr_matcher *matcher) return ret; } -static int mlx5dr_last_matcher_disconnect(struct mlx5dr_table *tbl, - struct mlx5dr_devx_obj *prev_ft) -{ - struct mlx5dr_cmd_ft_modify_attr ft_attr = {0}; - - if (tbl->default_miss.miss_tbl) { - /* Connect new last matcher to next miss_tbl if exists */ - return mlx5dr_table_connect_to_miss_table(tbl, - tbl->default_miss.miss_tbl); - } else { - ft_attr.modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_RTC_ID; - ft_attr.type = tbl->fw_ft_type; - /* Matcher is last, point prev end FT to default miss */ - mlx5dr_cmd_set_attr_connect_miss_tbl(tbl->ctx, - tbl->fw_ft_type, - tbl->type, - &ft_attr); - return mlx5dr_cmd_flow_table_modify(prev_ft, &ft_attr); - } -} - static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher) { struct mlx5dr_matcher *tmp_matcher, *prev_matcher; @@ -330,7 +309,7 @@ static int mlx5dr_matcher_disconnect(struct mlx5dr_matcher *matcher) goto matcher_reconnect; } } else { - ret = mlx5dr_last_matcher_disconnect(tbl, prev_ft); + ret = mlx5dr_table_connect_to_miss_table(tbl, tbl->default_miss.miss_tbl); if (ret) { DR_LOG(ERR, "Failed to disconnect last matcher"); goto matcher_reconnect; Checking patch drivers/common/mlx5/linux/mlx5_common_os.c... error: while searching for: char ctrl = 0, pf_c1, pf_c2, vf_c1, vf_c2, eol; char *end; int sc_items; sc_items = sscanf(port_name_in, "%c%d", &ctrl, &port_info_out->ctrl_num); if (sc_items == 2 && ctrl == 'c') { port_name_in++; /* 'c' */ port_name_in += snprintf(NULL, 0, "%d", port_info_out->ctrl_num); error: patch failed: drivers/common/mlx5/linux/mlx5_common_os.c:96 Applying patch drivers/common/mlx5/linux/mlx5_common_os.c with 1 reject... Rejected hunk #1. hint: Use 'git am --show-current-patch' to see the failed patch diff a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c (rejected hunks) @@ -96,10 +96,11 @@ mlx5_translate_port_name(const char *port_name_in, char ctrl = 0, pf_c1, pf_c2, vf_c1, vf_c2, eol; char *end; int sc_items; + int32_t ctrl_num = -1; - sc_items = sscanf(port_name_in, "%c%d", - &ctrl, &port_info_out->ctrl_num); + sc_items = sscanf(port_name_in, "%c%d", &ctrl, &ctrl_num); if (sc_items == 2 && ctrl == 'c') { + port_info_out->ctrl_num = ctrl_num; port_name_in++; /* 'c' */ port_name_in += snprintf(NULL, 0, "%d", port_info_out->ctrl_num); Checking patch drivers/common/mlx5/linux/mlx5_nl.c... error: while searching for: } return 0; } error: patch failed: drivers/common/mlx5/linux/mlx5_nl.c:1962 Checking patch drivers/common/mlx5/linux/mlx5_nl.h... error: while searching for: uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex, uint16_t tag); int mlx5_nl_devlink_family_id_get(int nlsk_fd); int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, int *enable); error: patch failed: drivers/common/mlx5/linux/mlx5_nl.h:71 error: while searching for: __rte_internal int mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex); #endif /* RTE_PMD_MLX5_NL_H_ */ error: patch failed: drivers/common/mlx5/linux/mlx5_nl.h:82 Checking patch drivers/common/mlx5/version.map... error: while searching for: mlx5_mr_addr2mr_bh; mlx5_nl_allmulti; # WINDOWS_NO_EXPORT mlx5_nl_ifindex; # WINDOWS_NO_EXPORT mlx5_nl_init; # WINDOWS_NO_EXPORT mlx5_nl_mac_addr_add; # WINDOWS_NO_EXPORT error: patch failed: drivers/common/mlx5/version.map:125 Applying patch drivers/common/mlx5/linux/mlx5_nl.c with 1 reject... Rejected hunk #1. Applying patch drivers/common/mlx5/linux/mlx5_nl.h with 2 rejects... Rejected hunk #1. Rejected hunk #2. Applying patch drivers/common/mlx5/version.map with 1 reject... Rejected hunk #1. hint: Use 'git am --show-current-patch' to see the failed patch diff a/drivers/common/mlx5/linux/mlx5_nl.c b/drivers/common/mlx5/linux/mlx5_nl.c (rejected hunks) @@ -1962,3 +1962,73 @@ mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg) } return 0; } + +static int +mlx5_nl_esw_multiport_cb(struct nlmsghdr *nh, void *arg) +{ + + int ret = -EINVAL; + int *enable = arg; + struct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len); + struct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr))); + + while (nla->nla_len && nla < tail) { + switch (nla->nla_type) { + /* Expected nested attributes case. */ + case DEVLINK_ATTR_PARAM: + case DEVLINK_ATTR_PARAM_VALUES_LIST: + case DEVLINK_ATTR_PARAM_VALUE: + ret = 0; + nla += 1; + break; + case DEVLINK_ATTR_PARAM_VALUE_DATA: + *enable = 1; + return 0; + default: + nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len)); + } + } + *enable = 0; + return ret; +} + +#define NL_ESW_MULTIPORT_PARAM "esw_multiport" + +int +mlx5_nl_devlink_esw_multiport_get(int nlsk_fd, int family_id, const char *pci_addr, int *enable) +{ + struct nlmsghdr *nlh; + struct genlmsghdr *genl; + uint32_t sn = MLX5_NL_SN_GENERATE; + int ret; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct genlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlattr)) * 4 + + NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 4]; + + memset(buf, 0, sizeof(buf)); + nlh = (struct nlmsghdr *)buf; + nlh->nlmsg_len = sizeof(struct nlmsghdr); + nlh->nlmsg_type = family_id; + nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + genl = (struct genlmsghdr *)nl_msg_tail(nlh); + nlh->nlmsg_len += sizeof(struct genlmsghdr); + genl->cmd = DEVLINK_CMD_PARAM_GET; + genl->version = DEVLINK_GENL_VERSION; + nl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, "pci", 4); + nl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1); + nl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, + NL_ESW_MULTIPORT_PARAM, sizeof(NL_ESW_MULTIPORT_PARAM)); + ret = mlx5_nl_send(nlsk_fd, nlh, sn); + if (ret >= 0) + ret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_esw_multiport_cb, enable); + if (ret < 0) { + DRV_LOG(DEBUG, "Failed to get Multiport E-Switch enable on device %s: %d.", + pci_addr, ret); + return ret; + } + DRV_LOG(DEBUG, "Multiport E-Switch is %sabled for device \"%s\".", + *enable ? "en" : "dis", pci_addr); + return ret; +} diff a/drivers/common/mlx5/linux/mlx5_nl.h b/drivers/common/mlx5/linux/mlx5_nl.h (rejected hunks) @@ -71,6 +71,7 @@ __rte_internal uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa, uint32_t ifindex, uint16_t tag); +__rte_internal int mlx5_nl_devlink_family_id_get(int nlsk_fd); int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr, int *enable); @@ -82,4 +83,8 @@ int mlx5_nl_read_events(int nlsk_fd, mlx5_nl_event_cb *cb, void *cb_arg); __rte_internal int mlx5_nl_parse_link_status_update(struct nlmsghdr *hdr, uint32_t *ifindex); +__rte_internal +int mlx5_nl_devlink_esw_multiport_get(int nlsk_fd, int family_id, + const char *pci_addr, int *enable); + #endif /* RTE_PMD_MLX5_NL_H_ */ diff a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map (rejected hunks) @@ -125,6 +125,8 @@ INTERNAL { mlx5_mr_addr2mr_bh; mlx5_nl_allmulti; # WINDOWS_NO_EXPORT + mlx5_nl_devlink_esw_multiport_get; # WINDOWS_NO_EXPORT + mlx5_nl_devlink_family_id_get; # WINDOWS_NO_EXPORT mlx5_nl_ifindex; # WINDOWS_NO_EXPORT mlx5_nl_init; # WINDOWS_NO_EXPORT mlx5_nl_mac_addr_add; # WINDOWS_NO_EXPORT Checking patch drivers/net/mlx5/linux/mlx5_os.c... error: while searching for: return pf; } /** * Register a PCI device within bonding. * error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:1931 Applying patch drivers/net/mlx5/linux/mlx5_os.c with 1 reject... Rejected hunk #1. hint: Use 'git am --show-current-patch' to see the failed patch diff a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c (rejected hunks) @@ -1931,6 +1931,75 @@ mlx5_device_bond_pci_match(const char *ibdev_name, return pf; } +#define SYSFS_MPESW_PARAM_MAX_LEN 16 + +static __rte_unused int +mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_addr, int *enabled) +{ + int nl_rdma; + unsigned int n_ports; + unsigned int i; + int ret; + + /* Provide correct value to have defined enabled state in case of an error. */ + *enabled = 0; + nl_rdma = mlx5_nl_init(NETLINK_RDMA, 0); + if (nl_rdma < 0) + return nl_rdma; + n_ports = mlx5_nl_portnum(nl_rdma, ibv->name); + if (!n_ports) { + ret = -rte_errno; + goto close_nl_rdma; + } + for (i = 1; i <= n_ports; ++i) { + unsigned int ifindex; + char ifname[IF_NAMESIZE + 1]; + struct rte_pci_addr if_pci_addr; + char mpesw[SYSFS_MPESW_PARAM_MAX_LEN + 1]; + FILE *sysfs; + int n; + + ifindex = mlx5_nl_ifindex(nl_rdma, ibv->name, i); + if (!ifindex) + continue; + if (!if_indextoname(ifindex, ifname)) + continue; + MKSTR(sysfs_if_path, "/sys/class/net/%s", ifname); + if (mlx5_get_pci_addr(sysfs_if_path, &if_pci_addr)) + continue; + if (pci_addr->domain != if_pci_addr.domain || + pci_addr->bus != if_pci_addr.bus || + pci_addr->devid != if_pci_addr.devid || + pci_addr->function != if_pci_addr.function) + continue; + MKSTR(sysfs_mpesw_path, + "/sys/class/net/%s/compat/devlink/lag_port_select_mode", ifname); + sysfs = fopen(sysfs_mpesw_path, "r"); + if (!sysfs) + continue; + n = fscanf(sysfs, "%" RTE_STR(SYSFS_MPESW_PARAM_MAX_LEN) "s", mpesw); + fclose(sysfs); + if (n != 1) + continue; + ret = 0; + if (strcmp(mpesw, "multiport_esw") == 0) { + *enabled = 1; + break; + } + *enabled = 0; + break; + } + if (i > n_ports) { + DRV_LOG(DEBUG, "Unable to get Multiport E-Switch state by sysfs."); + rte_errno = ENOENT; + ret = -rte_errno; + } + +close_nl_rdma: + close(nl_rdma); + return ret; +} + /** * Register a PCI device within bonding. * Checking patch drivers/net/mlx5/linux/mlx5_os.c... error: while searching for: return pf; } #define SYSFS_MPESW_PARAM_MAX_LEN 16 static __rte_unused int mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_addr, int *enabled) { int nl_rdma; error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:1931 error: while searching for: return ret; } /** * Register a PCI device within bonding. * error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2000 Applying patch drivers/net/mlx5/linux/mlx5_os.c with 2 rejects... Rejected hunk #1. Rejected hunk #2. hint: Use 'git am --show-current-patch' to see the failed patch diff a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c (rejected hunks) @@ -1931,9 +1931,38 @@ mlx5_device_bond_pci_match(const char *ibdev_name, return pf; } +static int +mlx5_nl_esw_multiport_get(struct rte_pci_addr *pci_addr, int *enabled) +{ + char pci_addr_str[PCI_PRI_STR_SIZE] = { 0 }; + int nlsk_fd; + int devlink_id; + int ret; + + /* Provide correct value to have defined enabled state in case of an error. */ + *enabled = 0; + rte_pci_device_name(pci_addr, pci_addr_str, sizeof(pci_addr_str)); + nlsk_fd = mlx5_nl_init(NETLINK_GENERIC, 0); + if (nlsk_fd < 0) + return nlsk_fd; + devlink_id = mlx5_nl_devlink_family_id_get(nlsk_fd); + if (devlink_id < 0) { + ret = devlink_id; + DRV_LOG(DEBUG, "Unable to get devlink family id for Multiport E-Switch checks " + "by netlink, for PCI device %s", pci_addr_str); + goto close_nlsk_fd; + } + ret = mlx5_nl_devlink_esw_multiport_get(nlsk_fd, devlink_id, pci_addr_str, enabled); + if (ret < 0) + DRV_LOG(DEBUG, "Unable to get Multiport E-Switch state by Netlink."); +close_nlsk_fd: + close(nlsk_fd); + return ret; +} + #define SYSFS_MPESW_PARAM_MAX_LEN 16 -static __rte_unused int +static int mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_addr, int *enabled) { int nl_rdma; @@ -2000,6 +2029,26 @@ mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_ad return ret; } +static __rte_unused int +mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr, int *enabled) +{ + /* + * Try getting Multiport E-Switch state through netlink interface + * If unable, try sysfs interface. If that is unable as well, + * assume that Multiport E-Switch is disabled and return an error. + */ + if (mlx5_nl_esw_multiport_get(ibv_pci_addr, enabled) >= 0 || + mlx5_sysfs_esw_multiport_get(ibv, ibv_pci_addr, enabled) >= 0) + return 0; + DRV_LOG(DEBUG, "Unable to check MPESW state for IB device %s " + "(PCI: " PCI_PRI_FMT ")", + ibv->name, + ibv_pci_addr->domain, ibv_pci_addr->bus, + ibv_pci_addr->devid, ibv_pci_addr->function); + *enabled = 0; + return -rte_errno; +} + /** * Register a PCI device within bonding. * Checking patch doc/guides/nics/mlx5.rst... error: while searching for: > port config all rss all > port start all Usage example ------------- error: patch failed: doc/guides/nics/mlx5.rst:1759 Checking patch doc/guides/rel_notes/release_23_11.rst... error: while searching for: * Added support for ``RTE_FLOW_ACTION_TYPE_INDIRECT_LIST`` flow action. * Added support for ``RTE_FLOW_ITEM_TYPE_PTYPE`` flow item. * Added support for ``RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR`` flow action and mirror. * **Updated Solarflare net driver.** error: patch failed: doc/guides/rel_notes/release_23_11.rst:157 Checking patch drivers/common/mlx5/mlx5_common.h... error: while searching for: int32_t ctrl_num; /**< Controller number (valid for c#pf#vf# format). */ int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ int32_t port_name; /**< Representor port name. */ uint64_t switch_id; /**< Switch identifier. */ }; error: patch failed: drivers/common/mlx5/mlx5_common.h:169 Checking patch drivers/net/mlx5/linux/mlx5_os.c... error: while searching for: uint16_t repr_id = mlx5_representor_id_encode(switch_info, eth_da->type); switch (eth_da->type) { case RTE_ETH_REPRESENTOR_SF: if (!(spawn->info.port_name == -1 && switch_info->name_type == error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:959 error: while searching for: } /* Check representor ID: */ for (p = 0; p < eth_da->nb_ports; ++p) { if (spawn->pf_bond < 0) { /* For non-LAG mode, allow and ignore pf. */ switch_info->pf_num = eth_da->ports[p]; repr_id = mlx5_representor_id_encode(switch_info, error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:989 error: while searching for: !mlx5_representor_match(spawn, eth_da)) return NULL; /* Build device name. */ if (spawn->pf_bond < 0) { /* Single device. */ if (!switch_info->representor) strlcpy(name, dpdk_dev->name, sizeof(name)); else err = snprintf(name, sizeof(name), "%s_representor_%s%u", dpdk_dev->name, switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", switch_info->port_name); } else { /* Bonding device. */ if (!switch_info->representor) { err = snprintf(name, sizeof(name), "%s_%s", error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:1051 error: while searching for: MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", switch_info->port_name); } } if (err >= (int)sizeof(name)) DRV_LOG(WARNING, "device name overflow %s", name); error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:1075 error: while searching for: priv->vport_meta_tag = 0; priv->vport_meta_mask = 0; priv->pf_bond = spawn->pf_bond; DRV_LOG(DEBUG, "dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d\n", priv->dev_port, dpdk_dev->bus->name, priv->pci_dev ? priv->pci_dev->name : "NONE", priv->master, priv->representor, priv->pf_bond); /* * If we have E-Switch we should determine the vport attributes. * E-Switch may use either source vport field or reg_c[0] metadata error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:1202 error: while searching for: return ret; } static __rte_unused int mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr, int *enabled) { /* error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2029 error: while searching for: return -rte_errno; } /** * Register a PCI device within bonding. * error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2049 error: while searching for: * >= 0 - bonding device (value is slave PF index) */ int bd = -1; struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev); struct mlx5_dev_spawn_data *list = NULL; struct rte_eth_devargs eth_da = *req_eth_da; error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2097 error: while searching for: bd, ibv_list[ret]->name); ibv_match[nd++] = ibv_list[ret]; break; } else { /* Bonding device not found. */ if (mlx5_get_pci_addr(ibv_list[ret]->ibdev_path, &pci_addr)) continue; if (rte_pci_addr_cmp(&owner_pci, &pci_addr) != 0) continue; DRV_LOG(INFO, "PCI information matches for device \"%s\"", ibv_list[ret]->name); ibv_match[nd++] = ibv_list[ret]; } } ibv_match[nd] = NULL; if (!nd) { error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2150 Hunk #10 succeeded at 2358 (offset 12 lines). error: while searching for: ret = -rte_errno; goto exit; } if (bd >= 0 || np > 1) { /* * Single IB device with multiple ports found, * it may be E-Switch master device and representors. error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2203 error: while searching for: list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; list[ns].pf_bond = bd; list[ns].ifindex = mlx5_nl_ifindex(nl_rdma, ibv_match[0]->name, i); error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2222 Hunk #13 succeeded at 2491 (offset 52 lines). error: while searching for: list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; list[ns].pf_bond = -1; list[ns].ifindex = 0; if (nl_rdma >= 0) list[ns].ifindex = mlx5_nl_ifindex error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2317 error: while searching for: struct mlx5_kvargs_ctrl *mkvlist) { struct rte_eth_devargs eth_da = { .nb_ports = 0 }; struct mlx5_dev_spawn_data spawn = { .pf_bond = -1 }; struct rte_device *dev = cdev->dev; struct rte_auxiliary_device *adev = RTE_DEV_TO_AUXILIARY(dev); struct rte_eth_dev *eth_dev; error: patch failed: drivers/net/mlx5/linux/mlx5_os.c:2597 Checking patch drivers/net/mlx5/mlx5.h... error: while searching for: char fw_ver[64]; /* Firmware version of this device. */ }; /** Data associated with devices to spawn. */ struct mlx5_dev_spawn_data { uint32_t ifindex; /**< Network interface index. */ uint32_t max_port; /**< Device maximal port index. */ uint32_t phys_port; /**< Device physical port index. */ int pf_bond; /**< bonding device PF index. < 0 - no bonding */ struct mlx5_switch_info info; /**< Switch information. */ const char *phys_dev_name; /**< Name of physical device. */ struct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */ error: patch failed: drivers/net/mlx5/mlx5.h:186 error: while searching for: struct mlx5_bond_info *bond_info; }; /** Data associated with socket messages. */ struct mlx5_flow_dump_req { uint32_t port_id; /**< There are plans in DPDK to extend port_id. */ error: patch failed: drivers/net/mlx5/mlx5.h:200 error: while searching for: uint32_t vport_meta_mask; /* Used for vport index field match mask. */ uint16_t representor_id; /* UINT16_MAX if not a representor. */ int32_t pf_bond; /* >=0, representor owner PF index in bonding. */ unsigned int if_index; /* Associated kernel network device index. */ /* RX/TX queues. */ unsigned int rxqs_n; /* RX queues array size. */ error: patch failed: drivers/net/mlx5/mlx5.h:1768 error: while searching for: sh->dev_cap.dest_tir); } /* mlx5.c */ int mlx5_getenv_int(const char *); error: patch failed: drivers/net/mlx5/mlx5.h:1933 Checking patch drivers/net/mlx5/mlx5_ethdev.c... error: while searching for: mlx5_representor_id_encode(const struct mlx5_switch_info *info, enum rte_eth_representor_type hpf_type) { enum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF; uint16_t repr = info->port_name; if (info->representor == 0) return UINT16_MAX; if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF) type = RTE_ETH_REPRESENTOR_SF; if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) { type = hpf_type; repr = UINT16_MAX; } return MLX5_REPRESENTOR_ID(info->pf_num, type, repr); } /** error: patch failed: drivers/net/mlx5/mlx5_ethdev.c:395 error: while searching for: struct rte_eth_representor_info *info) { struct mlx5_priv *priv = dev->data->dev_private; int n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */ int n_pf = 2; /* Number of PFs. */ int i = 0, pf; int n_entries; error: patch failed: drivers/net/mlx5/mlx5_ethdev.c:430 error: while searching for: n_entries = info->nb_ranges_alloc; info->controller = 0; info->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0; for (pf = 0; pf < n_pf; ++pf) { /* VF range. */ info->ranges[i].type = RTE_ETH_REPRESENTOR_VF; error: patch failed: drivers/net/mlx5/mlx5_ethdev.c:443 Checking patch drivers/net/mlx5/mlx5_flow_hw.c... error: while searching for: if (!priv->master) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "represented_port acton must" " be used on proxy port"); if (m && !!m->port_id) { struct mlx5_priv *port_priv; error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:1331 error: while searching for: info = &mlx5_flow_hw_port_infos[port_id]; info->regc_mask = priv->vport_meta_mask; info->regc_value = priv->vport_meta_tag; info->is_wire = priv->master; } /* Clears vport tag and mask used for HWS rules. */ error: patch failed: drivers/net/mlx5/mlx5_flow_hw.c:9188 Checking patch drivers/net/mlx5/mlx5_mac.c... error: while searching for: /* * Configuring the VF instead of its representor, * need to skip the special case of HPF on BlueField. */ if (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev)) { DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address", dev->data->port_id); if (priv->pf_bond >= 0) { error: patch failed: drivers/net/mlx5/mlx5_mac.c:157 Applying patch doc/guides/nics/mlx5.rst with 1 reject... Rejected hunk #1. Applying patch doc/guides/rel_notes/release_23_11.rst with 1 reject... Rejected hunk #1. Applying patch drivers/common/mlx5/mlx5_common.h with 1 reject... Rejected hunk #1. Applying patch drivers/net/mlx5/linux/mlx5_os.c with 13 rejects... Rejected hunk #1. Rejected hunk #2. Rejected hunk #3. Rejected hunk #4. Rejected hunk #5. Rejected hunk #6. Rejected hunk #7. Rejected hunk #8. Rejected hunk #9. Hunk #10 applied cleanly. Rejected hunk #11. Rejected hunk #12. Hunk #13 applied cleanly. Rejected hunk #14. Rejected hunk #15. Applying patch drivers/net/mlx5/mlx5.h with 4 rejects... Rejected hunk #1. Rejected hunk #2. Rejected hunk #3. Rejected hunk #4. Applying patch drivers/net/mlx5/mlx5_ethdev.c with 3 rejects... Rejected hunk #1. Rejected hunk #2. Rejected hunk #3. Applying patch drivers/net/mlx5/mlx5_flow_hw.c with 2 rejects... Rejected hunk #1. Rejected hunk #2. Applying patch drivers/net/mlx5/mlx5_mac.c with 1 reject... Rejected hunk #1. hint: Use 'git am --show-current-patch' to see the failed patch diff a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst (rejected hunks) @@ -1759,6 +1759,147 @@ behavior as librte_net_mlx4:: > port config all rss all > port start all + +Multiport E-Switch +------------------ + +In standard deployments of NVIDIA ConnectX and BlueField HCAs, where embedded switch is enabled, +each physical port is associated with a single switching domain. +Only PFs, VFs and SFs related to that physical port are connected to this domain +and offloaded flow rules are allowed to steer traffic only between the entities in the given domain. + +The following diagram pictures the high level overview of this architecture: + +:: + + .---. .------. .------. .---. .------. .------. + |PF0| |PF0VFi| |PF0SFi| |PF1| |PF1VFi| |PF1SFi| + .-+-. .--+---. .--+---. .-+-. .--+---. .--+---. + | | | | | | + .---|------|--------|-------|------|--------|---------. + | | | | | | | HCA| + | .-+------+--------+---. .-+------+--------+---. | + | | | | | | + | | E-Switch | | E-Switch | | + | | PF0 | | PF1 | | + | | | | | | + | .---------+-----------. .--------+------------. | + | | | | + .--------+--+---+---------------+--+---+--------------. + | | | | + | PHY0 | | PHY1 | + | | | | + .------. .------. + +Multiport E-Switch is a deployment scenario where: + +- All physical ports, PFs, VFs and SFs share the same switching domain. +- Each physical port gets a separate representor port. +- Traffic can be matched or forwarded explicitly between any of the entities + connected to the domain. + +The following diagram pictures the high level overview of this architecture: + +:: + + + .---. .------. .------. .---. .------. .------. + |PF0| |PF0VFi| |PF0SFi| |PF1| |PF1VFi| |PF1SFi| + .-+-. .--+---. .--+---. .-+-. .--+---. .--+---. + | | | | | | + .---|------|--------|-------|------|--------|---------. + | | | | | | | HCA| + | .-+------+--------+-------+------+--------+---. | + | | | | + | | Shared | | + | | E-Switch | | + | | | | + | .---------+----------------------+------------. | + | | | | + .--------+--+---+---------------+--+---+--------------. + | | | | + | PHY0 | | PHY1 | + | | | | + .------. .------. + + +In this deployment a single application can control the switching and forwarding behavior for all +entities on the HCA. + +With this configuration, mlx5 PMD supports: + +- matching traffic coming from physical port, PF, VF or SF using REPRESENTED_PORT items; +- forwarding traffic to physical port, PF, VF or SF using REPRESENTED_PORT actions; + + +Requirements +~~~~~~~~~~~~ + +Supported HCAs: + +- ConnectX family: ConnectX-6 Dx and above. +- BlueField family: BlueField-2 and above. +- FW version: at least ``XX.37.1014``. + +Supported mlx5 kernel modules versions: + +- Upstream Linux - from version 6.3. +- Modules packaged in MLNX_OFED - from version v23.04-0.5.3.3. + + +Configuration +~~~~~~~~~~~~~ + +#. Apply required FW configuration:: + + sudo mlxconfig -d /dev/mst/mt4125_pciconf0 set LAG_RESOURCE_ALLOCATION=1 + +#. Reset FW or cold reboot the host. +#. Switch E-Switch mode on all of the PFs to ``switchdev`` mode:: + + sudo devlink dev eswitch set pci/0000:08:00.0 mode switchdev + sudo devlink dev eswitch set pci/0000:08:00.1 mode switchdev + +#. Enable Multiport E-Switch on all of the PFs:: + + sudo devlink dev param set pci/0000:08:00.0 name esw_multiport value true cmode runtime + sudo devlink dev param set pci/0000:08:00.1 name esw_multiport value true cmode runtime + +#. Configure required number of VFs/SFs:: + + echo 4 | sudo tee /sys/class/net/eth2/device/sriov_numvfs + echo 4 | sudo tee /sys/class/net/eth3/device/sriov_numvfs + +#. Start testpmd and verify that all ports are visible:: + + $ sudo dpdk-testpmd -a 08:00.0,dv_flow_en=2,representor=pf0-1vf0-3 -- -i + testpmd> show port summary all + Number of available ports: 10 + Port MAC Address Name Driver Status Link + 0 E8:EB:D5:18:22:BC 08:00.0_p0 mlx5_pci up 200 Gbps + 1 E8:EB:D5:18:22:BD 08:00.0_p1 mlx5_pci up 200 Gbps + 2 D2:F6:43:0B:9E:19 08:00.0_representor_c0pf0vf0 mlx5_pci up 200 Gbps + 3 E6:42:27:B7:68:BD 08:00.0_representor_c0pf0vf1 mlx5_pci up 200 Gbps + 4 A6:5B:7F:8B:B8:47 08:00.0_representor_c0pf0vf2 mlx5_pci up 200 Gbps + 5 12:93:50:45:89:02 08:00.0_representor_c0pf0vf3 mlx5_pci up 200 Gbps + 6 06:D3:B2:79:FE:AC 08:00.0_representor_c0pf1vf0 mlx5_pci up 200 Gbps + 7 12:FC:08:E4:C2:CA 08:00.0_representor_c0pf1vf1 mlx5_pci up 200 Gbps + 8 8E:A9:9A:D0:35:4C 08:00.0_representor_c0pf1vf2 mlx5_pci up 200 Gbps + 9 E6:35:83:1F:B0:A9 08:00.0_representor_c0pf1vf3 mlx5_pci up 200 Gbps + + +Limitations +~~~~~~~~~~~ + +- Multiport E-Switch is not supported on Windows. +- Multiport E-Switch is supported only with HW Steering flow engine (``dv_flow_en=2``). +- Matching traffic coming from a physical port and forwarding it to a physical port + (either the same or other one) is not supported. + + In order to achieve such a functionality, an application has to setup hairpin queues between + physical port representors and forward the traffic using hairpin queues. + + Usage example ------------- diff a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst (rejected hunks) @@ -157,6 +157,7 @@ New Features * Added support for ``RTE_FLOW_ACTION_TYPE_INDIRECT_LIST`` flow action. * Added support for ``RTE_FLOW_ITEM_TYPE_PTYPE`` flow item. * Added support for ``RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR`` flow action and mirror. + * Added support for Multiport E-Switch. * **Updated Solarflare net driver.** diff a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h (rejected hunks) @@ -169,6 +169,7 @@ struct mlx5_switch_info { int32_t ctrl_num; /**< Controller number (valid for c#pf#vf# format). */ int32_t pf_num; /**< PF number (valid for pfxvfx format only). */ int32_t port_name; /**< Representor port name. */ + int32_t mpesw_owner; /**< MPESW owner port number. */ uint64_t switch_id; /**< Switch identifier. */ }; diff a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c (rejected hunks) @@ -959,7 +959,30 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn, uint16_t repr_id = mlx5_representor_id_encode(switch_info, eth_da->type); + /* + * Assuming Multiport E-Switch device was detected, + * if spawned port is an uplink, check if the port + * was requested through representor devarg. + */ + if (mlx5_is_probed_port_on_mpesw_device(spawn) && + switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) { + for (p = 0; p < eth_da->nb_ports; ++p) + if (switch_info->port_name == eth_da->ports[p]) + return true; + rte_errno = EBUSY; + return false; + } switch (eth_da->type) { + case RTE_ETH_REPRESENTOR_PF: + /* + * PF representors provided in devargs translate to uplink ports, but + * if and only if the device is a part of MPESW device. + */ + if (!mlx5_is_probed_port_on_mpesw_device(spawn)) { + rte_errno = EBUSY; + return false; + } + break; case RTE_ETH_REPRESENTOR_SF: if (!(spawn->info.port_name == -1 && switch_info->name_type == @@ -989,7 +1012,7 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn, } /* Check representor ID: */ for (p = 0; p < eth_da->nb_ports; ++p) { - if (spawn->pf_bond < 0) { + if (!mlx5_is_probed_port_on_mpesw_device(spawn) && spawn->pf_bond < 0) { /* For non-LAG mode, allow and ignore pf. */ switch_info->pf_num = eth_da->ports[p]; repr_id = mlx5_representor_id_encode(switch_info, @@ -1051,17 +1074,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, !mlx5_representor_match(spawn, eth_da)) return NULL; /* Build device name. */ - if (spawn->pf_bond < 0) { - /* Single device. */ - if (!switch_info->representor) - strlcpy(name, dpdk_dev->name, sizeof(name)); - else - err = snprintf(name, sizeof(name), "%s_representor_%s%u", - dpdk_dev->name, - switch_info->name_type == - MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", - switch_info->port_name); - } else { + if (spawn->pf_bond >= 0) { /* Bonding device. */ if (!switch_info->representor) { err = snprintf(name, sizeof(name), "%s_%s", @@ -1075,6 +1088,30 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", switch_info->port_name); } + } else if (mlx5_is_probed_port_on_mpesw_device(spawn)) { + /* MPESW device. */ + if (switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK) { + err = snprintf(name, sizeof(name), "%s_p%d", + dpdk_dev->name, spawn->mpesw_port); + } else { + err = snprintf(name, sizeof(name), "%s_representor_c%dpf%d%s%u", + dpdk_dev->name, + switch_info->ctrl_num, + switch_info->pf_num, + switch_info->name_type == + MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", + switch_info->port_name); + } + } else { + /* Single device. */ + if (!switch_info->representor) + strlcpy(name, dpdk_dev->name, sizeof(name)); + else + err = snprintf(name, sizeof(name), "%s_representor_%s%u", + dpdk_dev->name, + switch_info->name_type == + MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf", + switch_info->port_name); } if (err >= (int)sizeof(name)) DRV_LOG(WARNING, "device name overflow %s", name); @@ -1202,13 +1239,25 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, priv->vport_meta_tag = 0; priv->vport_meta_mask = 0; priv->pf_bond = spawn->pf_bond; + priv->mpesw_port = spawn->mpesw_port; + priv->mpesw_uplink = false; + priv->mpesw_owner = spawn->info.mpesw_owner; + if (mlx5_is_port_on_mpesw_device(priv)) + priv->mpesw_uplink = (spawn->info.name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK); DRV_LOG(DEBUG, - "dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d\n", + "dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d " + "mpesw_port=%d mpesw_uplink=%d", priv->dev_port, dpdk_dev->bus->name, priv->pci_dev ? priv->pci_dev->name : "NONE", - priv->master, priv->representor, priv->pf_bond); + priv->master, priv->representor, priv->pf_bond, + priv->mpesw_port, priv->mpesw_uplink); + if (mlx5_is_port_on_mpesw_device(priv) && priv->sh->config.dv_flow_en != 2) { + DRV_LOG(ERR, "MPESW device is supported only with HWS"); + err = ENOTSUP; + goto error; + } /* * If we have E-Switch we should determine the vport attributes. * E-Switch may use either source vport field or reg_c[0] metadata @@ -2029,7 +2078,7 @@ mlx5_sysfs_esw_multiport_get(struct ibv_device *ibv, struct rte_pci_addr *pci_ad return ret; } -static __rte_unused int +static int mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr, int *enabled) { /* @@ -2049,6 +2098,84 @@ mlx5_is_mpesw_enabled(struct ibv_device *ibv, struct rte_pci_addr *ibv_pci_addr, return -rte_errno; } +static int +mlx5_device_mpesw_pci_match(struct ibv_device *ibv, + const struct rte_pci_addr *owner_pci, + int nl_rdma) +{ + struct rte_pci_addr ibdev_pci_addr = { 0 }; + char ifname[IF_NAMESIZE + 1] = { 0 }; + unsigned int ifindex; + unsigned int np; + unsigned int i; + int enabled = 0; + int ret; + + /* Check if IB device's PCI address matches the probed PCI address. */ + if (mlx5_get_pci_addr(ibv->ibdev_path, &ibdev_pci_addr)) { + DRV_LOG(DEBUG, "Skipping MPESW check for IB device %s since " + "there is no underlying PCI device", ibv->name); + rte_errno = ENOENT; + return -rte_errno; + } + if (ibdev_pci_addr.domain != owner_pci->domain || + ibdev_pci_addr.bus != owner_pci->bus || + ibdev_pci_addr.devid != owner_pci->devid || + ibdev_pci_addr.function != owner_pci->function) { + return -1; + } + /* Check if IB device has MPESW enabled. */ + if (mlx5_is_mpesw_enabled(ibv, &ibdev_pci_addr, &enabled)) + return -1; + if (!enabled) + return -1; + /* Iterate through IB ports to find MPESW master uplink port. */ + if (nl_rdma < 0) + return -1; + np = mlx5_nl_portnum(nl_rdma, ibv->name); + if (!np) + return -1; + for (i = 1; i <= np; ++i) { + struct rte_pci_addr pci_addr; + FILE *file; + char port_name[IF_NAMESIZE + 1]; + struct mlx5_switch_info info; + + /* Check whether IB port has a corresponding netdev. */ + ifindex = mlx5_nl_ifindex(nl_rdma, ibv->name, i); + if (!ifindex) + continue; + if (!if_indextoname(ifindex, ifname)) + continue; + /* Read port name and determine its type. */ + MKSTR(ifphysportname, "/sys/class/net/%s/phys_port_name", ifname); + file = fopen(ifphysportname, "rb"); + if (!file) + continue; + ret = fscanf(file, "%16s", port_name); + fclose(file); + if (ret != 1) + continue; + memset(&info, 0, sizeof(info)); + mlx5_translate_port_name(port_name, &info); + if (info.name_type != MLX5_PHYS_PORT_NAME_TYPE_UPLINK) + continue; + /* Fetch PCI address of the device to which the netdev is bound. */ + MKSTR(ifpath, "/sys/class/net/%s", ifname); + if (mlx5_get_pci_addr(ifpath, &pci_addr)) + continue; + if (pci_addr.domain == ibdev_pci_addr.domain && + pci_addr.bus == ibdev_pci_addr.bus && + pci_addr.devid == ibdev_pci_addr.devid && + pci_addr.function == ibdev_pci_addr.function) { + MLX5_ASSERT(info.port_name >= 0); + return info.port_name; + } + } + /* No matching MPESW uplink port was found. */ + return -1; +} + /** * Register a PCI device within bonding. * @@ -2097,6 +2224,12 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, * >= 0 - bonding device (value is slave PF index) */ int bd = -1; + /* + * Multiport E-Switch (MPESW) device: + * < 0 - no MPESW device or could not determine if it is MPESW device, + * >= 0 - MPESW device. Value is the port index of the MPESW owner. + */ + int mpesw = MLX5_MPESW_PORT_INVALID; struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev); struct mlx5_dev_spawn_data *list = NULL; struct rte_eth_devargs eth_da = *req_eth_da; @@ -2150,17 +2283,38 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, bd, ibv_list[ret]->name); ibv_match[nd++] = ibv_list[ret]; break; - } else { - /* Bonding device not found. */ - if (mlx5_get_pci_addr(ibv_list[ret]->ibdev_path, - &pci_addr)) - continue; - if (rte_pci_addr_cmp(&owner_pci, &pci_addr) != 0) - continue; - DRV_LOG(INFO, "PCI information matches for device \"%s\"", + } + mpesw = mlx5_device_mpesw_pci_match(ibv_list[ret], &owner_pci, nl_rdma); + if (mpesw >= 0) { + /* + * MPESW device detected. Only one matching IB device is allowed, + * so if any matches were found previously, fail gracefully. + */ + if (nd) { + DRV_LOG(ERR, + "PCI information matches MPESW device \"%s\", " + "but multiple matching PCI devices were found. " + "Probing failed.", + ibv_list[ret]->name); + rte_errno = ENOENT; + ret = -rte_errno; + goto exit; + } + DRV_LOG(INFO, + "PCI information matches MPESW device \"%s\"", ibv_list[ret]->name); ibv_match[nd++] = ibv_list[ret]; + break; } + /* Bonding or MPESW device was not found. */ + if (mlx5_get_pci_addr(ibv_list[ret]->ibdev_path, + &pci_addr)) + continue; + if (rte_pci_addr_cmp(&owner_pci, &pci_addr) != 0) + continue; + DRV_LOG(INFO, "PCI information matches for device \"%s\"", + ibv_list[ret]->name); + ibv_match[nd++] = ibv_list[ret]; } ibv_match[nd] = NULL; if (!nd) { @@ -2203,7 +2363,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, ret = -rte_errno; goto exit; } - if (bd >= 0 || np > 1) { + if (bd >= 0 || mpesw >= 0 || np > 1) { /* * Single IB device with multiple ports found, * it may be E-Switch master device and representors. @@ -2222,6 +2382,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; list[ns].pf_bond = bd; + list[ns].mpesw_port = MLX5_MPESW_PORT_INVALID; list[ns].ifindex = mlx5_nl_ifindex(nl_rdma, ibv_match[0]->name, i); @@ -2317,6 +2518,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev, list[ns].pci_dev = pci_dev; list[ns].cdev = cdev; list[ns].pf_bond = -1; + list[ns].mpesw_port = MLX5_MPESW_PORT_INVALID; list[ns].ifindex = 0; if (nl_rdma >= 0) list[ns].ifindex = mlx5_nl_ifindex @@ -2597,7 +2799,10 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev, struct mlx5_kvargs_ctrl *mkvlist) { struct rte_eth_devargs eth_da = { .nb_ports = 0 }; - struct mlx5_dev_spawn_data spawn = { .pf_bond = -1 }; + struct mlx5_dev_spawn_data spawn = { + .pf_bond = -1, + .mpesw_port = MLX5_MPESW_PORT_INVALID, + }; struct rte_device *dev = cdev->dev; struct rte_auxiliary_device *adev = RTE_DEV_TO_AUXILIARY(dev); struct rte_eth_dev *eth_dev; diff a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h (rejected hunks) @@ -186,12 +186,15 @@ struct mlx5_dev_cap { char fw_ver[64]; /* Firmware version of this device. */ }; +#define MLX5_MPESW_PORT_INVALID (-1) + /** Data associated with devices to spawn. */ struct mlx5_dev_spawn_data { uint32_t ifindex; /**< Network interface index. */ uint32_t max_port; /**< Device maximal port index. */ uint32_t phys_port; /**< Device physical port index. */ int pf_bond; /**< bonding device PF index. < 0 - no bonding */ + int mpesw_port; /**< MPESW uplink index. Valid if mpesw_owner_port >= 0. */ struct mlx5_switch_info info; /**< Switch information. */ const char *phys_dev_name; /**< Name of physical device. */ struct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */ @@ -200,6 +203,23 @@ struct mlx5_dev_spawn_data { struct mlx5_bond_info *bond_info; }; +/** + * Check if the port requested to be probed is MPESW physical device + * or a representor port. + * + * @param spawn + * Parameters of the probed port. + * + * @return + * True if the probed port is a physical device or representor in MPESW setup. + * False otherwise or MPESW was not configured. + */ +static inline bool +mlx5_is_probed_port_on_mpesw_device(struct mlx5_dev_spawn_data *spawn) +{ + return spawn->mpesw_port >= 0; +} + /** Data associated with socket messages. */ struct mlx5_flow_dump_req { uint32_t port_id; /**< There are plans in DPDK to extend port_id. */ @@ -1768,6 +1788,9 @@ struct mlx5_priv { uint32_t vport_meta_mask; /* Used for vport index field match mask. */ uint16_t representor_id; /* UINT16_MAX if not a representor. */ int32_t pf_bond; /* >=0, representor owner PF index in bonding. */ + int32_t mpesw_owner; /* >=0, representor owner PF index in MPESW. */ + int32_t mpesw_port; /* Related port index of MPESW device. < 0 - no MPESW. */ + bool mpesw_uplink; /* If true, port is an uplink port. */ unsigned int if_index; /* Associated kernel network device index. */ /* RX/TX queues. */ unsigned int rxqs_n; /* RX queues array size. */ @@ -1933,6 +1956,22 @@ mlx5_devx_obj_ops_en(struct mlx5_dev_ctx_shared *sh) sh->dev_cap.dest_tir); } +/** + * Check if the port is either MPESW physical device or a representor port. + * + * @param priv + * Pointer to port's private data. + * + * @return + * True if the port is a physical device or representor in MPESW setup. + * False otherwise or MPESW was not configured. + */ +static inline bool +mlx5_is_port_on_mpesw_device(struct mlx5_priv *priv) +{ + return priv->mpesw_port >= 0; +} + /* mlx5.c */ int mlx5_getenv_int(const char *); diff a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c (rejected hunks) @@ -395,18 +395,30 @@ uint16_t mlx5_representor_id_encode(const struct mlx5_switch_info *info, enum rte_eth_representor_type hpf_type) { - enum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF; + enum rte_eth_representor_type type; uint16_t repr = info->port_name; - - if (info->representor == 0) - return UINT16_MAX; - if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF) + int32_t pf = info->pf_num; + + switch (info->name_type) { + case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: + if (!info->representor) + return UINT16_MAX; + type = RTE_ETH_REPRESENTOR_PF; + pf = info->mpesw_owner; + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFSF: type = RTE_ETH_REPRESENTOR_SF; - if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) { + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFHPF: type = hpf_type; repr = UINT16_MAX; + break; + case MLX5_PHYS_PORT_NAME_TYPE_PFVF: + default: + type = RTE_ETH_REPRESENTOR_VF; + break; } - return MLX5_REPRESENTOR_ID(info->pf_num, type, repr); + return MLX5_REPRESENTOR_ID(pf, type, repr); } /** @@ -430,7 +442,7 @@ mlx5_representor_info_get(struct rte_eth_dev *dev, struct rte_eth_representor_info *info) { struct mlx5_priv *priv = dev->data->dev_private; - int n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */ + int n_type = 5; /* Representor types: PF, VF, HPF@VF, SF and HPF@SF. */ int n_pf = 2; /* Number of PFs. */ int i = 0, pf; int n_entries; @@ -443,7 +455,30 @@ mlx5_representor_info_get(struct rte_eth_dev *dev, n_entries = info->nb_ranges_alloc; info->controller = 0; - info->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0; + info->pf = 0; + if (mlx5_is_port_on_mpesw_device(priv)) { + info->pf = priv->mpesw_port; + /* PF range, both ports will show the same information. */ + info->ranges[i].type = RTE_ETH_REPRESENTOR_PF; + info->ranges[i].controller = 0; + info->ranges[i].pf = priv->mpesw_owner + 1; + info->ranges[i].vf = 0; + /* + * The representor indexes should be the values set of "priv->mpesw_port". + * In the real case now, only 1 PF/UPLINK representor is supported. + * The port index will always be the value of "owner + 1". + */ + info->ranges[i].id_base = + MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type, + info->ranges[i].pf); + info->ranges[i].id_end = + MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type, + info->ranges[i].pf); + snprintf(info->ranges[i].name, sizeof(info->ranges[i].name), + "pf%d", info->ranges[i].pf); + i++; + } else if (priv->pf_bond >= 0) + info->pf = priv->pf_bond; for (pf = 0; pf < n_pf; ++pf) { /* VF range. */ info->ranges[i].type = RTE_ETH_REPRESENTOR_VF; diff a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c (rejected hunks) @@ -1331,7 +1331,7 @@ flow_hw_represented_port_compile(struct rte_eth_dev *dev, if (!priv->master) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, - "represented_port acton must" + "represented_port action must" " be used on proxy port"); if (m && !!m->port_id) { struct mlx5_priv *port_priv; @@ -9188,7 +9188,7 @@ flow_hw_set_port_info(struct rte_eth_dev *dev) info = &mlx5_flow_hw_port_infos[port_id]; info->regc_mask = priv->vport_meta_mask; info->regc_value = priv->vport_meta_tag; - info->is_wire = priv->master; + info->is_wire = mlx5_is_port_on_mpesw_device(priv) ? priv->mpesw_uplink : priv->master; } /* Clears vport tag and mask used for HWS rules. */ diff a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c (rejected hunks) @@ -157,9 +157,13 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) /* * Configuring the VF instead of its representor, - * need to skip the special case of HPF on BlueField. + * need to skip the special cases: + * - HPF on BlueField, + * - SF representors, + * - uplink ports when running in MPESW mode. */ - if (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev)) { + if (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev) && + !priv->mpesw_uplink) { DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address", dev->data->port_id); if (priv->pf_bond >= 0) { Checking patch drivers/net/mlx5/linux/mlx5_os.c... error: drivers/net/mlx5/linux/mlx5_os.c: does not match index hint: Use 'git am --show-current-patch' to see the failed patch Checking patch doc/guides/nics/mlx5.rst... error: while searching for: By default, the PMD will set this value to 1. Sub-Function ------------ error: patch failed: doc/guides/nics/mlx5.rst:1369 Checking patch drivers/net/mlx5/mlx5.c... error: while searching for: /* Device parameter to control representor matching in ingress/egress flows with HWS. */ #define MLX5_REPR_MATCHING_EN "repr_matching_en" /* Shared memory between primary and secondary processes. */ struct mlx5_shared_data *mlx5_shared_data; error: patch failed: drivers/net/mlx5/mlx5.c:184 error: while searching for: config->cnt_svc.cycle_time = tmp; } else if (strcmp(MLX5_REPR_MATCHING_EN, key) == 0) { config->repr_matching = !!tmp; } return 0; } error: patch failed: drivers/net/mlx5/mlx5.c:1425 error: while searching for: MLX5_HWS_CNT_SERVICE_CORE, MLX5_HWS_CNT_CYCLE_TIME, MLX5_REPR_MATCHING_EN, NULL, }; int ret = 0; error: patch failed: drivers/net/mlx5/mlx5.c:1464 error: while searching for: rte_errno = ENODEV; return -rte_errno; } if (!config->tx_pp && config->tx_skew && !sh->cdev->config.hca_attr.wait_on_time) { DRV_LOG(WARNING, error: patch failed: drivers/net/mlx5/mlx5.c:1522 error: while searching for: config->allow_duplicate_pattern); DRV_LOG(DEBUG, "\"fdb_def_rule_en\" is %u.", config->fdb_def_rule); DRV_LOG(DEBUG, "\"repr_matching_en\" is %u.", config->repr_matching); return 0; } error: patch failed: drivers/net/mlx5/mlx5.c:1562 Hunk #6 succeeded at 3020 (offset 5 lines). Checking patch drivers/net/mlx5/mlx5.h... error: while searching for: /* Allow/Prevent the duplicate rules pattern. */ uint32_t fdb_def_rule:1; /* Create FDB default jump rule */ uint32_t repr_matching:1; /* Enable implicit vport matching in HWS FDB. */ }; /* Structure for VF VLAN workaround. */ error: patch failed: drivers/net/mlx5/mlx5.h:352 error: while searching for: uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */ uint32_t num_lag_ports:4; /* Number of ports can be bonded. */ uint32_t tunnel_enabled:1; /* If tunnel offloading is enabled on rxqs. */ uint16_t domain_id; /* Switch domain identifier. */ uint16_t vport_id; /* Associated VF vport index (if any). */ uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */ error: patch failed: drivers/net/mlx5/mlx5.h:1782 Checking patch drivers/net/mlx5/mlx5_flow_dv.c... Hunk #1 succeeded at 10493 (offset -101 lines). Checking patch drivers/net/mlx5/mlx5_trigger.c... error: while searching for: goto error; } } else { DRV_LOG(INFO, "port %u FDB default rule is disabled", dev->data->port_id); } if (priv->isolated) return 0; error: patch failed: drivers/net/mlx5/mlx5_trigger.c:1515 Applying patch doc/guides/nics/mlx5.rst with 1 reject... Rejected hunk #1. Applying patch drivers/net/mlx5/mlx5.c with 5 rejects... Rejected hunk #1. Rejected hunk #2. Rejected hunk #3. Rejected hunk #4. Rejected hunk #5. Hunk #6 applied cleanly. Applying patch drivers/net/mlx5/mlx5.h with 2 rejects... Rejected hunk #1. Rejected hunk #2. Applied patch drivers/net/mlx5/mlx5_flow_dv.c cleanly. Applying patch drivers/net/mlx5/mlx5_trigger.c with 1 reject... Rejected hunk #1. hint: Use 'git am --show-current-patch' to see the failed patch diff a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst (rejected hunks) @@ -1369,6 +1369,22 @@ for an additional list of options shared with other mlx5 drivers. By default, the PMD will set this value to 1. +- ``vport_match`` parameter [int] + + Controls the underlying matching mechanism for REPRESENTED_PORT items when they are used for + flow rules in E-Switch root flow table. + + If set to 1, then ``source_vport`` matching is used. This allows applications to match whole + traffic coming from the application by using REPRESENTED_PORT item with ``port_id == UINT16_MAX``. + As a side effect, flow rules in root flow table will not be able match physical ports explicitly, + when running on Multiport E-Switch. + Matching in non-root flow tables (group bigger than 1) is not affected. + + If set to 0, then ``vport_metadata`` matching is used. This is the default mechanism. + + By default, the PMD will set this value to 0. Setting ``vport_match`` to 1 requires that + ``fdb_def_rule_en`` is set to 0, so that E-Switch root flow table is exposed to the application. + Sub-Function ------------ diff a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c (rejected hunks) @@ -184,6 +184,9 @@ /* Device parameter to control representor matching in ingress/egress flows with HWS. */ #define MLX5_REPR_MATCHING_EN "repr_matching_en" +/* Representor matching field selection: 0 - meta_vport, 1 - misc.vport */ +#define MLX5_HWS_ROOT_VPORT_MATCH "vport_match" + /* Shared memory between primary and secondary processes. */ struct mlx5_shared_data *mlx5_shared_data; @@ -1425,6 +1428,8 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque) config->cnt_svc.cycle_time = tmp; } else if (strcmp(MLX5_REPR_MATCHING_EN, key) == 0) { config->repr_matching = !!tmp; + } else if (strcmp(MLX5_HWS_ROOT_VPORT_MATCH, key) == 0) { + config->vport_match = !!tmp; } return 0; } @@ -1464,6 +1469,7 @@ mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh, MLX5_HWS_CNT_SERVICE_CORE, MLX5_HWS_CNT_CYCLE_TIME, MLX5_REPR_MATCHING_EN, + MLX5_HWS_ROOT_VPORT_MATCH, NULL, }; int ret = 0; @@ -1522,6 +1528,11 @@ mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh, rte_errno = ENODEV; return -rte_errno; } + if (config->dv_flow_en == 2 && config->fdb_def_rule && config->vport_match) { + DRV_LOG(DEBUG, "vport_match=1 is incompatible with FDB default rule " + "(fdb_def_rule-en=1). Setting vport_match=0."); + config->vport_match = 0; + } if (!config->tx_pp && config->tx_skew && !sh->cdev->config.hca_attr.wait_on_time) { DRV_LOG(WARNING, @@ -1562,6 +1573,7 @@ mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh, config->allow_duplicate_pattern); DRV_LOG(DEBUG, "\"fdb_def_rule_en\" is %u.", config->fdb_def_rule); DRV_LOG(DEBUG, "\"repr_matching_en\" is %u.", config->repr_matching); + DRV_LOG(DEBUG, "\"vport_match\" is %u.", config->vport_match); return 0; } diff a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h (rejected hunks) @@ -352,6 +352,7 @@ struct mlx5_sh_config { /* Allow/Prevent the duplicate rules pattern. */ uint32_t fdb_def_rule:1; /* Create FDB default jump rule */ uint32_t repr_matching:1; /* Enable implicit vport matching in HWS FDB. */ + uint32_t vport_match:1; /* Root table representor matching field selection. */ }; /* Structure for VF VLAN workaround. */ @@ -1782,6 +1783,7 @@ struct mlx5_priv { uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */ uint32_t num_lag_ports:4; /* Number of ports can be bonded. */ uint32_t tunnel_enabled:1; /* If tunnel offloading is enabled on rxqs. */ + uint32_t vport_match:1; /* vport match field. */ uint16_t domain_id; /* Switch domain identifier. */ uint16_t vport_id; /* Associated VF vport index (if any). */ uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */ diff a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c (rejected hunks) @@ -1515,7 +1515,10 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev) goto error; } } else { - DRV_LOG(INFO, "port %u FDB default rule is disabled", dev->data->port_id); + DRV_LOG(INFO, "port %u FDB default rule is disabled with vport_match %u", + dev->data->port_id, config->vport_match); + /* vport_match is only interesting in no default FDB rule mode. */ + priv->vport_match = config->vport_match; } if (priv->isolated) return 0; https://lab.dpdk.org/results/dashboard/patchsets/28160/ UNH-IOL DPDK Community Lab