net: hns3: Support for dynamically assigning tx buffer to TC

This patch add support of dynamically assigning tx buffer to
TC when the TC is enabled.
It will save buffer for rx direction to avoid packet loss.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Yunsheng Lin 2017-09-27 09:45:23 +08:00 committed by David S. Miller
parent 6ade97da60
commit 9ffe79a9c2
2 changed files with 55 additions and 10 deletions

View File

@ -311,6 +311,7 @@ struct hclge_tc_thrd {
struct hclge_priv_buf {
struct hclge_waterline wl; /* Waterline for low and high*/
u32 buf_size; /* TC private buffer size */
u32 tx_buf_size;
u32 enable; /* Enable TC private buffer or not */
};

View File

@ -1324,7 +1324,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
}
static int hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
static int hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
{
/* TX buffer size is unit by 128 byte */
#define HCLGE_BUF_SIZE_UNIT_SHIFT 7
@ -1337,10 +1337,13 @@ static int hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
req = (struct hclge_tx_buff_alloc *)desc.data;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TX_BUFF_ALLOC, 0);
for (i = 0; i < HCLGE_TC_NUM; i++)
for (i = 0; i < HCLGE_TC_NUM; i++) {
u32 buf_size = hdev->priv_buf[i].tx_buf_size;
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
HCLGE_BUF_SIZE_UPDATE_EN_MSK);
}
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
@ -1352,9 +1355,9 @@ static int hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
return 0;
}
static int hclge_tx_buffer_alloc(struct hclge_dev *hdev, u32 buf_size)
static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
{
int ret = hclge_cmd_alloc_tx_buff(hdev, buf_size);
int ret = hclge_cmd_alloc_tx_buff(hdev);
if (ret) {
dev_err(&hdev->pdev->dev,
@ -1433,6 +1436,16 @@ static u32 hclge_get_rx_priv_buff_alloced(struct hclge_dev *hdev)
return rx_priv;
}
static u32 hclge_get_tx_buff_alloced(struct hclge_dev *hdev)
{
u32 i, total_tx_size = 0;
for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
total_tx_size += hdev->priv_buf[i].tx_buf_size;
return total_tx_size;
}
static bool hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all)
{
u32 shared_buf_min, shared_buf_tc, shared_std;
@ -1477,18 +1490,43 @@ static bool hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all)
return true;
}
static int hclge_tx_buffer_calc(struct hclge_dev *hdev)
{
u32 i, total_size;
total_size = hdev->pkt_buf_size;
/* alloc tx buffer for all enabled tc */
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
struct hclge_priv_buf *priv = &hdev->priv_buf[i];
if (total_size < HCLGE_DEFAULT_TX_BUF)
return -ENOMEM;
if (hdev->hw_tc_map & BIT(i))
priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
else
priv->tx_buf_size = 0;
total_size -= priv->tx_buf_size;
}
return 0;
}
/* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
* @hdev: pointer to struct hclge_dev
* @tx_size: the allocated tx buffer for all TCs
* @return: 0: calculate sucessful, negative: fail
*/
int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size)
int hclge_rx_buffer_calc(struct hclge_dev *hdev)
{
u32 rx_all = hdev->pkt_buf_size - tx_size;
u32 rx_all = hdev->pkt_buf_size;
int no_pfc_priv_num, pfc_priv_num;
struct hclge_priv_buf *priv;
int i;
rx_all -= hclge_get_tx_buff_alloced(hdev);
/* When DCB is not supported, rx private
* buffer is not allocated.
*/
@ -1771,7 +1809,6 @@ static int hclge_common_wl_config(struct hclge_dev *hdev)
int hclge_buffer_alloc(struct hclge_dev *hdev)
{
u32 tx_buf_size = HCLGE_DEFAULT_TX_BUF;
int ret;
hdev->priv_buf = devm_kmalloc_array(&hdev->pdev->dev, HCLGE_MAX_TC_NUM,
@ -1780,14 +1817,21 @@ int hclge_buffer_alloc(struct hclge_dev *hdev)
if (!hdev->priv_buf)
return -ENOMEM;
ret = hclge_tx_buffer_alloc(hdev, tx_buf_size);
ret = hclge_tx_buffer_calc(hdev);
if (ret) {
dev_err(&hdev->pdev->dev,
"could not calc tx buffer size for all TCs %d\n", ret);
return ret;
}
ret = hclge_tx_buffer_alloc(hdev);
if (ret) {
dev_err(&hdev->pdev->dev,
"could not alloc tx buffers %d\n", ret);
return ret;
}
ret = hclge_rx_buffer_calc(hdev, tx_buf_size);
ret = hclge_rx_buffer_calc(hdev);
if (ret) {
dev_err(&hdev->pdev->dev,
"could not calc rx priv buffer size for all TCs %d\n",