From: Salil Mehta <salil.mehta@huawei.com>
To: <davem@davemloft.net>
Cc: <salil.mehta@huawei.com>, <yisen.zhuang@huawei.com>,
<lipeng321@huawei.com>, <mehta.salil@opnsrc.net>,
<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linuxarm@huawei.com>, Xi Wang <wangxi11@huawei.com>
Subject: [PATCH net-next 10/11] net: hns3: Optimize the PF's process of updating multicast MAC
Date: Fri, 1 Jun 2018 17:52:10 +0100 [thread overview]
Message-ID: <20180601165211.46372-11-salil.mehta@huawei.com> (raw)
In-Reply-To: <20180601165211.46372-1-salil.mehta@huawei.com>
From: Xi Wang <wangxi11@huawei.com>
In the current process, the multicast MAC is added to both MAC_VLAN
table and MTA table, this will reduce the utilization of the resource.
This patch improves the process of adding multicast MAC address, the
new process starts using the MTA table to add multicast MAC after the
MAC_VLAN table is full, and the MTA is disable if it is no longer used.
Signed-off-by: Xi Wang <wangxi11@huawei.com>
Reviewed-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 +
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 138 ++++++++++++++++++---
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 12 +-
4 files changed, 136 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index e8244a5..8acb1d1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -353,6 +353,7 @@ struct hnae3_ae_ops {
const unsigned char *addr);
int (*rm_mc_addr)(struct hnae3_handle *handle,
const unsigned char *addr);
+ int (*update_mta_status)(struct hnae3_handle *handle);
void (*set_tso_stats)(struct hnae3_handle *handle, int enable);
void (*update_stats)(struct hnae3_handle *handle,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index e572804..f2b31d2 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -423,9 +423,13 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
}
if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
netdev_err(netdev, "sync uc address fail\n");
- if (netdev->flags & IFF_MULTICAST)
+ if (netdev->flags & IFF_MULTICAST) {
if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync))
netdev_err(netdev, "sync mc address fail\n");
+
+ if (h->ae_algo->ops->update_mta_status)
+ h->ae_algo->ops->update_mta_status(h);
+ }
}
static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 19e5689..2a80134 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2288,8 +2288,10 @@ static int hclge_mac_init(struct hclge_dev *hdev)
struct net_device *netdev = handle->kinfo.netdev;
struct hclge_mac *mac = &hdev->hw.mac;
u8 mac_mask[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ struct hclge_vport *vport;
int mtu;
int ret;
+ int i;
ret = hclge_cfg_mac_speed_dup(hdev, hdev->hw.mac.speed, HCLGE_MAC_FULL);
if (ret) {
@@ -2301,7 +2303,6 @@ static int hclge_mac_init(struct hclge_dev *hdev)
mac->link = 0;
/* Initialize the MTA table work mode */
- hdev->accept_mta_mc = true;
hdev->enable_mta = true;
hdev->mta_mac_sel_type = HCLGE_MAC_ADDR_47_36;
@@ -2314,11 +2315,17 @@ static int hclge_mac_init(struct hclge_dev *hdev)
return ret;
}
- ret = hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc);
- if (ret) {
- dev_err(&hdev->pdev->dev,
- "set mta filter mode fail ret=%d\n", ret);
- return ret;
+ for (i = 0; i < hdev->num_alloc_vport; i++) {
+ vport = &hdev->vport[i];
+ vport->accept_mta_mc = false;
+
+ memset(vport->mta_shadow, 0, sizeof(vport->mta_shadow));
+ ret = hclge_cfg_func_mta_filter(hdev, vport->vport_id, false);
+ if (ret) {
+ dev_err(&hdev->pdev->dev,
+ "set mta filter mode fail ret=%d\n", ret);
+ return ret;
+ }
}
ret = hclge_set_default_mac_vlan_mask(hdev, true, mac_mask);
@@ -4005,9 +4012,88 @@ static int hclge_set_mta_table_item(struct hclge_vport *vport,
return ret;
}
+ if (enable)
+ set_bit(idx, vport->mta_shadow);
+ else
+ clear_bit(idx, vport->mta_shadow);
+
return 0;
}
+static int hclge_update_mta_status(struct hnae3_handle *handle)
+{
+ unsigned long mta_status[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)];
+ struct hclge_vport *vport = hclge_get_vport(handle);
+ struct net_device *netdev = handle->kinfo.netdev;
+ struct netdev_hw_addr *ha;
+ u16 tbl_idx;
+
+ memset(mta_status, 0, sizeof(mta_status));
+
+ /* update mta_status from mc addr list */
+ netdev_for_each_mc_addr(ha, netdev) {
+ tbl_idx = hclge_get_mac_addr_to_mta_index(vport, ha->addr);
+ set_bit(tbl_idx, mta_status);
+ }
+
+ return hclge_update_mta_status_common(vport, mta_status,
+ 0, HCLGE_MTA_TBL_SIZE, true);
+}
+
+int hclge_update_mta_status_common(struct hclge_vport *vport,
+ unsigned long *status,
+ u16 idx,
+ u16 count,
+ bool update_filter)
+{
+ struct hclge_dev *hdev = vport->back;
+ u16 update_max = idx + count;
+ u16 check_max;
+ int ret = 0;
+ bool used;
+ u16 i;
+
+ /* setup mta check range */
+ if (update_filter) {
+ i = 0;
+ check_max = HCLGE_MTA_TBL_SIZE;
+ } else {
+ i = idx;
+ check_max = update_max;
+ }
+
+ used = false;
+ /* check and update all mta item */
+ for (; i < check_max; i++) {
+ /* ignore unused item */
+ if (!test_bit(i, vport->mta_shadow))
+ continue;
+
+ /* if i in update range then update it */
+ if (i >= idx && i < update_max)
+ if (!test_bit(i - idx, status))
+ hclge_set_mta_table_item(vport, i, false);
+
+ if (!used && test_bit(i, vport->mta_shadow))
+ used = true;
+ }
+
+ /* no longer use mta, disable it */
+ if (vport->accept_mta_mc && update_filter && !used) {
+ ret = hclge_cfg_func_mta_filter(hdev,
+ vport->vport_id,
+ false);
+ if (ret)
+ dev_err(&hdev->pdev->dev,
+ "disable func mta filter fail ret=%d\n",
+ ret);
+ else
+ vport->accept_mta_mc = false;
+ }
+
+ return ret;
+}
+
static int hclge_remove_mac_vlan_tbl(struct hclge_vport *vport,
struct hclge_mac_vlan_tbl_entry_cmd *req)
{
@@ -4275,9 +4361,25 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
status = hclge_add_mac_vlan_tbl(vport, &req, desc);
}
- /* Set MTA table for this MAC address */
- tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr);
- status = hclge_set_mta_table_item(vport, tbl_idx, true);
+ /* If mc mac vlan table is full, use MTA table */
+ if (status == -ENOSPC) {
+ if (!vport->accept_mta_mc) {
+ status = hclge_cfg_func_mta_filter(hdev,
+ vport->vport_id,
+ true);
+ if (status) {
+ dev_err(&hdev->pdev->dev,
+ "set mta filter mode fail ret=%d\n",
+ status);
+ return status;
+ }
+ vport->accept_mta_mc = true;
+ }
+
+ /* Set MTA table for this MAC address */
+ tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr);
+ status = hclge_set_mta_table_item(vport, tbl_idx, true);
+ }
return status;
}
@@ -4297,7 +4399,6 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
struct hclge_mac_vlan_tbl_entry_cmd req;
enum hclge_cmd_status status;
struct hclge_desc desc[3];
- u16 tbl_idx;
/* mac addr check */
if (!is_multicast_ether_addr(addr)) {
@@ -4326,17 +4427,15 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
status = hclge_add_mac_vlan_tbl(vport, &req, desc);
} else {
- /* This mac addr do not exist, can't delete it */
- dev_err(&hdev->pdev->dev,
- "Rm multicast mac addr failed, ret = %d.\n",
- status);
- return -EIO;
+ /* Maybe this mac address is in mta table, but it cannot be
+ * deleted here because an entry of mta represents an address
+ * range rather than a specific address. the delete action to
+ * all entries will take effect in update_mta_status called by
+ * hns3_nic_set_rx_mode.
+ */
+ status = 0;
}
- /* Set MTB table for this MAC address */
- tbl_idx = hclge_get_mac_addr_to_mta_index(vport, addr);
- status = hclge_set_mta_table_item(vport, tbl_idx, false);
-
return status;
}
@@ -6137,6 +6236,7 @@ static const struct hnae3_ae_ops hclge_ops = {
.rm_uc_addr = hclge_rm_uc_addr,
.add_mc_addr = hclge_add_mc_addr,
.rm_mc_addr = hclge_rm_mc_addr,
+ .update_mta_status = hclge_update_mta_status,
.set_autoneg = hclge_set_autoneg,
.get_autoneg = hclge_get_autoneg,
.get_pauseparam = hclge_get_pauseparam,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 7fcabde..7488534 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -61,6 +61,8 @@
#define HCLGE_RSS_TC_SIZE_6 64
#define HCLGE_RSS_TC_SIZE_7 128
+#define HCLGE_MTA_TBL_SIZE 4096
+
#define HCLGE_TQP_RESET_TRY_TIMES 10
#define HCLGE_PHY_PAGE_MDIX 0
@@ -559,7 +561,6 @@ struct hclge_dev {
enum hclge_mta_dmac_sel_type mta_mac_sel_type;
bool enable_mta; /* Mutilcast filter enable */
- bool accept_mta_mc; /* Whether accept mta filter multicast */
struct hclge_vlan_type_cfg vlan_type_cfg;
@@ -620,6 +621,9 @@ struct hclge_vport {
struct hclge_dev *back; /* Back reference to associated dev */
struct hnae3_handle nic;
struct hnae3_handle roce;
+
+ bool accept_mta_mc; /* whether to accept mta filter multicast */
+ unsigned long mta_shadow[BITS_TO_LONGS(HCLGE_MTA_TBL_SIZE)];
};
void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
@@ -637,6 +641,12 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
int hclge_cfg_func_mta_filter(struct hclge_dev *hdev,
u8 func_id,
bool enable);
+int hclge_update_mta_status_common(struct hclge_vport *vport,
+ unsigned long *status,
+ u16 idx,
+ u16 count,
+ bool update_filter);
+
struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle);
int hclge_bind_ring_with_vector(struct hclge_vport *vport,
int vector_id, bool en,
--
2.7.4
next prev parent reply other threads:[~2018-06-01 16:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-01 16:52 [PATCH net-next 00/11] Misc. bug fixes & optimizations for HNS3 driver Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 01/11] net: hns3: Disable vf vlan filter when vf vlan table is full Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 02/11] net: hns3: Add support for IFF_ALLMULTI flag Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 03/11] net: hns3: Add repeat address checking for setting mac address Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 04/11] net: hns3: Fix setting mac address error Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 05/11] net: hns3: Fix for service_task not running problem after resetting Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 06/11] net: hns3: Fix for hclge_reset running repeatly problem Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 07/11] net: hns3: Fix for phy not link up problem after resetting Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 08/11] net: hns3: Add missing break in misc_irq_handle Salil Mehta
2018-06-01 16:52 ` [PATCH net-next 09/11] net: hns3: Fix for vxlan tx checksum bug Salil Mehta
2018-06-01 16:52 ` Salil Mehta [this message]
2018-06-01 16:52 ` [PATCH net-next 11/11] net: hns3: Optimize the VF's process of updating multicast MAC Salil Mehta
2018-06-01 18:24 ` [PATCH net-next 00/11] Misc. bug fixes & optimizations for HNS3 driver David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180601165211.46372-11-salil.mehta@huawei.com \
--to=salil.mehta@huawei.com \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=lipeng321@huawei.com \
--cc=mehta.salil@opnsrc.net \
--cc=netdev@vger.kernel.org \
--cc=wangxi11@huawei.com \
--cc=yisen.zhuang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).