[PATCH net 8/9] net: qed: reset ILT block sizes before recomputing to fix crashes

2020-06-22 Thread Alexander Lobakin
Sizes of all ILT blocks must be reset before ILT recomputing when
disabling clients, or memory allocation may exceed ILT shadow array
and provoke system crashes.

Fixes: 1408cc1fa48c ("qed: Introduce VFs")
Signed-off-by: Alexander Lobakin 
Signed-off-by: Igor Russkikh 
Signed-off-by: Michal Kalderon 
---
 drivers/net/ethernet/qlogic/qed/qed_cxt.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c 
b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
index c0a769b5358c..08ba9d54ab63 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
@@ -465,6 +465,20 @@ static struct qed_ilt_cli_blk *qed_cxt_set_blk(struct 
qed_ilt_cli_blk *p_blk)
return p_blk;
 }
 
+static void qed_cxt_ilt_blk_reset(struct qed_hwfn *p_hwfn)
+{
+   struct qed_ilt_client_cfg *clients = p_hwfn->p_cxt_mngr->clients;
+   u32 cli_idx, blk_idx;
+
+   for (cli_idx = 0; cli_idx < MAX_ILT_CLIENTS; cli_idx++) {
+   for (blk_idx = 0; blk_idx < ILT_CLI_PF_BLOCKS; blk_idx++)
+   clients[cli_idx].pf_blks[blk_idx].total_size = 0;
+
+   for (blk_idx = 0; blk_idx < ILT_CLI_VF_BLOCKS; blk_idx++)
+   clients[cli_idx].vf_blks[blk_idx].total_size = 0;
+   }
+}
+
 int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 *line_count)
 {
struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
@@ -484,6 +498,11 @@ int qed_cxt_cfg_ilt_compute(struct qed_hwfn *p_hwfn, u32 
*line_count)
 
p_mngr->pf_start_line = RESC_START(p_hwfn, QED_ILT);
 
+   /* Reset all ILT blocks at the beginning of ILT computing in order
+* to prevent memory allocation for irrelevant blocks afterwards.
+*/
+   qed_cxt_ilt_blk_reset(p_hwfn);
+
DP_VERBOSE(p_hwfn, QED_MSG_ILT,
   "hwfn [%d] - Set context manager starting line to be 
0x%08x\n",
   p_hwfn->my_id, p_hwfn->p_cxt_mngr->pf_start_line);
-- 
2.21.0



Re: [PATCH net 8/8] net: stmmac: xgmac: Fix RSS not writing all Keys to HW

2019-09-27 Thread Nick Desaulniers
On Fri, Sep 27, 2019 at 12:49 AM Jose Abreu  wrote:
>
> The sizeof(cfg->key) is != ARRAY_SIZE(cfg->key). Fix it.

I think the warning was from -Wsizeof-array-div.

>
> Reported-by: kbuild test robot 
> Reported-by: Nick Desaulniers 

I may have reported the kbuild link, but scanning my email, there's
also a report from
Reported-by: Nathan Chancellor 

> Fixes: 76067459c686 ("net: stmmac: Implement RSS and enable it in XGMAC core")
> Signed-off-by: Jose Abreu 
>
> ---
> Cc: Giuseppe Cavallaro 
> Cc: Alexandre Torgue 
> Cc: Jose Abreu 
> Cc: "David S. Miller" 
> Cc: Maxime Coquelin 
> Cc: net...@vger.kernel.org
> Cc: linux-st...@st-md-mailman.stormreply.com
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: Nick Desaulniers 
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> index 6d8ac2ef4fc2..4a1f52474dbc 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
> @@ -533,7 +533,7 @@ static int dwxgmac2_rss_configure(struct mac_device_info 
> *hw,
> return 0;
> }
>
> -   for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
> +   for (i = 0; i < (ARRAY_SIZE(cfg->key) / sizeof(u32)); i++) {

cfg is an instance of struct stmmac_rss, which looks like:
125 struct stmmac_rss {
126   int enable;
127   u8 key[STMMAC_RSS_HASH_KEY_SIZE];
128   u32 table[STMMAC_RSS_MAX_TABLE_SIZE];
129 };

yep, LGTM. Thanks for the patch.
Reviewed-by: Nick Desaulniers 


> ret = dwxgmac2_rss_write_reg(ioaddr, true, i, cfg->key[i]);
> if (ret)
> return ret;
> --
> 2.7.4
>


--
Thanks,
~Nick Desaulniers


[PATCH net 8/8] net: stmmac: xgmac: Fix RSS not writing all Keys to HW

2019-09-27 Thread Jose Abreu
The sizeof(cfg->key) is != ARRAY_SIZE(cfg->key). Fix it.

Reported-by: kbuild test robot 
Reported-by: Nick Desaulniers 
Fixes: 76067459c686 ("net: stmmac: Implement RSS and enable it in XGMAC core")
Signed-off-by: Jose Abreu 

---
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Jose Abreu 
Cc: "David S. Miller" 
Cc: Maxime Coquelin 
Cc: net...@vger.kernel.org
Cc: linux-st...@st-md-mailman.stormreply.com
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: Nick Desaulniers 
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 6d8ac2ef4fc2..4a1f52474dbc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -533,7 +533,7 @@ static int dwxgmac2_rss_configure(struct mac_device_info 
*hw,
return 0;
}
 
-   for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
+   for (i = 0; i < (ARRAY_SIZE(cfg->key) / sizeof(u32)); i++) {
ret = dwxgmac2_rss_write_reg(ioaddr, true, i, cfg->key[i]);
if (ret)
return ret;
-- 
2.7.4



[PATCH net 8/9] rxrpc: Use shadow refcount for packets in the RxTx ring

2019-08-22 Thread David Howells
Use the previously added shadow refcount for packets that are in the Rx/Tx
ring so that the ring itself only ever holds a single ref on the skbuff.

This allows skb_cow_data() to be used by the recvmsg code to make the data
modifyable for in-place decryption without triggering the assertion in
pskb_expand_head:

BUG_ON(skb_shared(skb));

This *should* be okay as:

 (1) Once rxrpc_input_data() starts attaching the sk_buff to the ring, it
 no longer looks inside the packet (all the parsing was done previously
 and notes were taken in struct rxrpc_skb_priv).

 (2) rxrpc_recvmsg_data() may not run in parallel for a particular call.

 (3) rxrpc_recvmsg_data() cow's the sk_buff the first time it sees it and
 then steps through each pointer from the buffer in order, unpinning as
 it goes.

 Each subpacket is individually and sequentially decrypted in place in
 the sk_buff, hence the need for skb_cow_data().

 (4) No one else can be looking in a packet in the Rx ring once it's there.

The problem was occuring because the softirq handler may be holding a ref
or the ring may be holding multiple refs when skb_cow_data() is called in
rxkad_verify_packet(), and so skb_shared() returns true and
__pskb_pull_tail() dislikes that.  If this occurs, something like the
following report will be generated.

kernel BUG at net/core/skbuff.c:1463!
...
RIP: 0010:pskb_expand_head+0x253/0x2b0
...
Call Trace:
 __pskb_pull_tail+0x49/0x460
 skb_cow_data+0x6f/0x300
 rxkad_verify_packet+0x18b/0xb10 [rxrpc]
 rxrpc_recvmsg_data.isra.11+0x4a8/0xa10 [rxrpc]
 rxrpc_kernel_recv_data+0x126/0x240 [rxrpc]
 afs_extract_data+0x51/0x2d0 [kafs]
 afs_deliver_fs_fetch_data+0x188/0x400 [kafs]
 afs_deliver_to_call+0xac/0x430 [kafs]
 afs_wait_for_call_to_complete+0x22f/0x3d0 [kafs]
 afs_make_call+0x282/0x3f0 [kafs]
 afs_fs_fetch_data+0x164/0x300 [kafs]
 afs_fetch_data+0x54/0x130 [kafs]
 afs_readpages+0x20d/0x340 [kafs]
 read_pages+0x66/0x180
 __do_page_cache_readahead+0x188/0x1a0
 ondemand_readahead+0x17d/0x2e0
 generic_file_read_iter+0x740/0xc10
 __vfs_read+0x145/0x1a0
 vfs_read+0x8c/0x140
 ksys_read+0x4a/0xb0
 do_syscall_64+0x43/0xf0
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Reported-by: Julian Wollrath 
Signed-off-by: David Howells 
---

 net/rxrpc/call_object.c |2 +-
 net/rxrpc/input.c   |   22 ++
 net/rxrpc/recvmsg.c |2 +-
 net/rxrpc/sendmsg.c |1 +
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 014548c259ce..830b6152dfa3 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -429,7 +429,7 @@ static void rxrpc_cleanup_ring(struct rxrpc_call *call)
int i;
 
for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
-   rxrpc_free_skb(call->rxtx_buffer[i], rxrpc_skb_cleaned);
+   rxrpc_unpin_skb(call->rxtx_buffer[i], rxrpc_skb_cleaned);
call->rxtx_buffer[i] = NULL;
}
 }
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 31090bdf1fae..660b7eed39b7 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -258,7 +258,7 @@ static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, 
rxrpc_seq_t to,
skb = list;
list = skb->next;
skb_mark_not_on_list(skb);
-   rxrpc_free_skb(skb, rxrpc_skb_freed);
+   rxrpc_unpin_skb(skb, rxrpc_skb_unpin);
}
 
return rot_last;
@@ -447,6 +447,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, 
struct sk_buff *skb)
return;
}
 
+   atomic_set(>nr_ring_pins, 1);
+
if (call->state == RXRPC_CALL_SERVER_RECV_REQUEST) {
unsigned long timo = READ_ONCE(call->next_req_timo);
unsigned long now, expect_req_by;
@@ -550,6 +552,12 @@ static void rxrpc_input_data(struct rxrpc_call *call, 
struct sk_buff *skb)
ack_serial = serial;
}
 
+   /* Each insertion into the rxtx_buffer holds a ring pin.  This
+* allows a single ref on the buffer to be shared, thereby
+* allowing skb_cow_data() to be used.
+*/
+   rxrpc_pin_skb(skb, rxrpc_skb_pin);
+
/* Queue the packet.  We use a couple of memory barriers here 
as need
 * to make sure that rx_top is perceived to be set after the 
buffer
 * pointer and that the buffer pointer is set after the 
annotation and
@@ -558,8 +566,6 @@ static void rxrpc_input_data(struct rxrpc_call *call, 
struct sk_buff *skb)
 * Barriers against rxrpc_recvmsg_data() and 

[PATCH net 8/9] net: hns3: Fix for setting rss_size incorrectly

2017-09-20 Thread Yunsheng Lin
rss_size is 1, 2, 4, 8, 16, 32, 64, 128, but acutal tc queue
size can be any u16 less than 128. If tc queue size is 5, we
set the rss_size to 8, indirection table will be used to limit
the size of actual queue size.
It may cause dropping of receiving packet in hardware if
rss_size is not set correctly.
For now, each TC has the same rss size.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin 
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 76 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  1 +
 3 files changed, 38 insertions(+), 40 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 1e15ce1..d27618b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2606,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
u16 tc_valid[HCLGE_MAX_TC_NUM];
u16 tc_size[HCLGE_MAX_TC_NUM];
u32 *rss_indir = NULL;
+   u16 rss_size = 0, roundup_size;
const u8 *key;
int i, ret, j;
 
@@ -2620,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
vport[j].rss_indirection_tbl[i] =
-   i % hdev->rss_size_max;
+   i % vport[j].alloc_rss_size;
+
+   /* vport 0 is for PF */
+   if (j != 0)
+   continue;
+
+   rss_size = vport[j].alloc_rss_size;
rss_indir[i] = vport[j].rss_indirection_tbl[i];
}
}
@@ -2637,42 +2644,31 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
if (ret)
goto err;
 
+   /* Each TC have the same queue size, and tc_size set to hardware is
+* the log2 of roundup power of two of rss_size, the acutal queue
+* size is limited by indirection table.
+*/
+   if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
+   dev_err(>pdev->dev,
+   "Configure rss tc size failed, invalid TC_SIZE = %d\n",
+   rss_size);
+   return -EINVAL;
+   }
+
+   roundup_size = roundup_pow_of_two(rss_size);
+   roundup_size = ilog2(roundup_size);
+
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   if (hdev->hw_tc_map & BIT(i))
-   tc_valid[i] = 1;
-   else
-   tc_valid[i] = 0;
+   tc_valid[i] = 0;
 
-   switch (hdev->rss_size_max) {
-   case HCLGE_RSS_TC_SIZE_0:
-   tc_size[i] = 0;
-   break;
-   case HCLGE_RSS_TC_SIZE_1:
-   tc_size[i] = 1;
-   break;
-   case HCLGE_RSS_TC_SIZE_2:
-   tc_size[i] = 2;
-   break;
-   case HCLGE_RSS_TC_SIZE_3:
-   tc_size[i] = 3;
-   break;
-   case HCLGE_RSS_TC_SIZE_4:
-   tc_size[i] = 4;
-   break;
-   case HCLGE_RSS_TC_SIZE_5:
-   tc_size[i] = 5;
-   break;
-   case HCLGE_RSS_TC_SIZE_6:
-   tc_size[i] = 6;
-   break;
-   case HCLGE_RSS_TC_SIZE_7:
-   tc_size[i] = 7;
-   break;
-   default:
-   break;
-   }
-   tc_offset[i] = hdev->rss_size_max * i;
+   if (!(hdev->hw_tc_map & BIT(i)))
+   continue;
+
+   tc_valid[i] = 1;
+   tc_size[i] = roundup_size;
+   tc_offset[i] = rss_size * i;
}
+
ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
 
 err:
@@ -4166,12 +4162,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
-   ret = hclge_rss_init_hw(hdev);
-   if (ret) {
-   dev_err(>dev, "Rss init fail, ret =%d\n", ret);
-   return  ret;
-   }
-
ret = hclge_init_vlan_config(hdev);
if (ret) {
dev_err(>dev, "VLAN init fail, ret =%d\n", ret);
@@ -4184,6 +4174,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
+   ret = hclge_rss_init_hw(hdev);
+   if (ret) {
+   dev_err(>dev, "Rss init fail, ret =%d\n", ret);
+   return ret;
+   }
+
setup_timer(>service_timer, 

[PATCH net 8/9] net: hns3: Fix for setting rss_size incorrectly

2017-09-20 Thread Yunsheng Lin
rss_size is 1, 2, 4, 8, 16, 32, 64, 128, but acutal tc queue
size can be any u16 less than 128. If tc queue size is 5, we
set the rss_size to 8, indirection table will be used to limit
the size of actual queue size.
It may cause dropping of receiving packet in hardware if
rss_size is not set correctly.
For now, each TC has the same rss size.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin 
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 76 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  1 +
 3 files changed, 38 insertions(+), 40 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 1e15ce1..d27618b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2606,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
u16 tc_valid[HCLGE_MAX_TC_NUM];
u16 tc_size[HCLGE_MAX_TC_NUM];
u32 *rss_indir = NULL;
+   u16 rss_size = 0, roundup_size;
const u8 *key;
int i, ret, j;
 
@@ -2620,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
vport[j].rss_indirection_tbl[i] =
-   i % hdev->rss_size_max;
+   i % vport[j].alloc_rss_size;
+
+   /* vport 0 is for PF */
+   if (j != 0)
+   continue;
+
+   rss_size = vport[j].alloc_rss_size;
rss_indir[i] = vport[j].rss_indirection_tbl[i];
}
}
@@ -2637,42 +2644,31 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
if (ret)
goto err;
 
+   /* Each TC have the same queue size, and tc_size set to hardware is
+* the log2 of roundup power of two of rss_size, the acutal queue
+* size is limited by indirection table.
+*/
+   if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
+   dev_err(>pdev->dev,
+   "Configure rss tc size failed, invalid TC_SIZE = %d\n",
+   rss_size);
+   return -EINVAL;
+   }
+
+   roundup_size = roundup_pow_of_two(rss_size);
+   roundup_size = ilog2(roundup_size);
+
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   if (hdev->hw_tc_map & BIT(i))
-   tc_valid[i] = 1;
-   else
-   tc_valid[i] = 0;
+   tc_valid[i] = 0;
 
-   switch (hdev->rss_size_max) {
-   case HCLGE_RSS_TC_SIZE_0:
-   tc_size[i] = 0;
-   break;
-   case HCLGE_RSS_TC_SIZE_1:
-   tc_size[i] = 1;
-   break;
-   case HCLGE_RSS_TC_SIZE_2:
-   tc_size[i] = 2;
-   break;
-   case HCLGE_RSS_TC_SIZE_3:
-   tc_size[i] = 3;
-   break;
-   case HCLGE_RSS_TC_SIZE_4:
-   tc_size[i] = 4;
-   break;
-   case HCLGE_RSS_TC_SIZE_5:
-   tc_size[i] = 5;
-   break;
-   case HCLGE_RSS_TC_SIZE_6:
-   tc_size[i] = 6;
-   break;
-   case HCLGE_RSS_TC_SIZE_7:
-   tc_size[i] = 7;
-   break;
-   default:
-   break;
-   }
-   tc_offset[i] = hdev->rss_size_max * i;
+   if (!(hdev->hw_tc_map & BIT(i)))
+   continue;
+
+   tc_valid[i] = 1;
+   tc_size[i] = roundup_size;
+   tc_offset[i] = rss_size * i;
}
+
ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
 
 err:
@@ -4166,12 +4162,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
-   ret = hclge_rss_init_hw(hdev);
-   if (ret) {
-   dev_err(>dev, "Rss init fail, ret =%d\n", ret);
-   return  ret;
-   }
-
ret = hclge_init_vlan_config(hdev);
if (ret) {
dev_err(>dev, "VLAN init fail, ret =%d\n", ret);
@@ -4184,6 +4174,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
+   ret = hclge_rss_init_hw(hdev);
+   if (ret) {
+   dev_err(>dev, "Rss init fail, ret =%d\n", ret);
+   return ret;
+   }
+
setup_timer(>service_timer, hclge_service_timer,
  

[PATCH net 8/8] net: bcmgenet: decouple flow control from bcmgenet_tx_reclaim

2017-03-09 Thread Doug Berger
From: Doug Berger 

The bcmgenet_tx_reclaim() function is used to reclaim transmit
resources in different places within the driver.  Most of them
should not affect the state of the transmit flow control.

This commit relocates the logic for waking tx queues based on
freed resources to the napi polling function where it is more
appropriate.

refs #SWLINUX-4311

Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
Signed-off-by: Doug Berger 
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ec1f3014e410..69015fa50f20 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1234,7 +1234,6 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = >pdev->dev;
struct enet_cb *tx_cb_ptr;
-   struct netdev_queue *txq;
unsigned int pkts_compl = 0;
unsigned int bytes_compl = 0;
unsigned int c_index;
@@ -1286,13 +1285,8 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
dev->stats.tx_packets += pkts_compl;
dev->stats.tx_bytes += bytes_compl;
 
-   txq = netdev_get_tx_queue(dev, ring->queue);
-   netdev_tx_completed_queue(txq, pkts_compl, bytes_compl);
-
-   if (ring->free_bds > (MAX_SKB_FRAGS + 1)) {
-   if (netif_tx_queue_stopped(txq))
-   netif_tx_wake_queue(txq);
-   }
+   netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue),
+ pkts_compl, bytes_compl);
 
return pkts_compl;
 }
@@ -1315,8 +1309,16 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, 
int budget)
struct bcmgenet_tx_ring *ring =
container_of(napi, struct bcmgenet_tx_ring, napi);
unsigned int work_done = 0;
+   struct netdev_queue *txq;
+   unsigned long flags;
 
-   work_done = bcmgenet_tx_reclaim(ring->priv->dev, ring);
+   spin_lock_irqsave(>lock, flags);
+   work_done = __bcmgenet_tx_reclaim(ring->priv->dev, ring);
+   if (ring->free_bds > (MAX_SKB_FRAGS + 1)) {
+   txq = netdev_get_tx_queue(ring->priv->dev, ring->queue);
+   netif_tx_wake_queue(txq);
+   }
+   spin_unlock_irqrestore(>lock, flags);
 
if (work_done == 0) {
napi_complete(napi);
-- 
2.11.1



[PATCH net 8/8] net: bcmgenet: decouple flow control from bcmgenet_tx_reclaim

2017-03-09 Thread Doug Berger
From: Doug Berger 

The bcmgenet_tx_reclaim() function is used to reclaim transmit
resources in different places within the driver.  Most of them
should not affect the state of the transmit flow control.

This commit relocates the logic for waking tx queues based on
freed resources to the napi polling function where it is more
appropriate.

refs #SWLINUX-4311

Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
Signed-off-by: Doug Berger 
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ec1f3014e410..69015fa50f20 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1234,7 +1234,6 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = >pdev->dev;
struct enet_cb *tx_cb_ptr;
-   struct netdev_queue *txq;
unsigned int pkts_compl = 0;
unsigned int bytes_compl = 0;
unsigned int c_index;
@@ -1286,13 +1285,8 @@ static unsigned int __bcmgenet_tx_reclaim(struct 
net_device *dev,
dev->stats.tx_packets += pkts_compl;
dev->stats.tx_bytes += bytes_compl;
 
-   txq = netdev_get_tx_queue(dev, ring->queue);
-   netdev_tx_completed_queue(txq, pkts_compl, bytes_compl);
-
-   if (ring->free_bds > (MAX_SKB_FRAGS + 1)) {
-   if (netif_tx_queue_stopped(txq))
-   netif_tx_wake_queue(txq);
-   }
+   netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue),
+ pkts_compl, bytes_compl);
 
return pkts_compl;
 }
@@ -1315,8 +1309,16 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, 
int budget)
struct bcmgenet_tx_ring *ring =
container_of(napi, struct bcmgenet_tx_ring, napi);
unsigned int work_done = 0;
+   struct netdev_queue *txq;
+   unsigned long flags;
 
-   work_done = bcmgenet_tx_reclaim(ring->priv->dev, ring);
+   spin_lock_irqsave(>lock, flags);
+   work_done = __bcmgenet_tx_reclaim(ring->priv->dev, ring);
+   if (ring->free_bds > (MAX_SKB_FRAGS + 1)) {
+   txq = netdev_get_tx_queue(ring->priv->dev, ring->queue);
+   netif_tx_wake_queue(txq);
+   }
+   spin_unlock_irqrestore(>lock, flags);
 
if (work_done == 0) {
napi_complete(napi);
-- 
2.11.1



[PATCH net 8/9] virtio-net: remove big packet XDP codes

2016-12-23 Thread Jason Wang
Now we in fact don't allow XDP for big packets, remove its codes.

Cc: John Fastabend 
Signed-off-by: Jason Wang 
---
 drivers/net/virtio_net.c | 44 +++-
 1 file changed, 3 insertions(+), 41 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c1f66d8..e53365a8 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -344,11 +344,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
/* Free up any pending old buffers before queueing new ones. */
while ((xdp_sent = virtqueue_get_buf(sq->vq, )) != NULL) {
struct page *sent_page = virt_to_head_page(xdp_sent);
-
-   if (vi->mergeable_rx_bufs)
-   put_page(sent_page);
-   else
-   give_pages(rq, sent_page);
+   put_page(sent_page);
}
 
/* Zero header and leave csum up to XDP layers */
@@ -360,15 +356,8 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
   xdp->data, GFP_ATOMIC);
if (unlikely(err)) {
-   if (vi->mergeable_rx_bufs)
-   put_page(page);
-   else
-   give_pages(rq, page);
+   put_page(page);
return; // On error abort to avoid unnecessary kick
-   } else if (!vi->mergeable_rx_bufs) {
-   /* If not mergeable bufs must be big packets so cleanup pages */
-   give_pages(rq, (struct page *)page->private);
-   page->private = 0;
}
 
virtqueue_kick(sq->vq);
@@ -430,44 +419,17 @@ static struct sk_buff *receive_big(struct net_device *dev,
   void *buf,
   unsigned int len)
 {
-   struct bpf_prog *xdp_prog;
struct page *page = buf;
-   struct sk_buff *skb;
-
-   rcu_read_lock();
-   xdp_prog = rcu_dereference(rq->xdp_prog);
-   if (xdp_prog) {
-   struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
-   u32 act;
-
-   if (unlikely(hdr->hdr.gso_type))
-   goto err_xdp;
-   act = do_xdp_prog(vi, rq, xdp_prog, page, 0, len);
-   switch (act) {
-   case XDP_PASS:
-   break;
-   case XDP_TX:
-   rcu_read_unlock();
-   goto xdp_xmit;
-   case XDP_DROP:
-   default:
-   goto err_xdp;
-   }
-   }
-   rcu_read_unlock();
+   struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
 
-   skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
if (unlikely(!skb))
goto err;
 
return skb;
 
-err_xdp:
-   rcu_read_unlock();
 err:
dev->stats.rx_dropped++;
give_pages(rq, page);
-xdp_xmit:
return NULL;
 }
 
-- 
2.7.4



[PATCH net 8/9] virtio-net: remove big packet XDP codes

2016-12-23 Thread Jason Wang
Now we in fact don't allow XDP for big packets, remove its codes.

Cc: John Fastabend 
Signed-off-by: Jason Wang 
---
 drivers/net/virtio_net.c | 44 +++-
 1 file changed, 3 insertions(+), 41 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c1f66d8..e53365a8 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -344,11 +344,7 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
/* Free up any pending old buffers before queueing new ones. */
while ((xdp_sent = virtqueue_get_buf(sq->vq, )) != NULL) {
struct page *sent_page = virt_to_head_page(xdp_sent);
-
-   if (vi->mergeable_rx_bufs)
-   put_page(sent_page);
-   else
-   give_pages(rq, sent_page);
+   put_page(sent_page);
}
 
/* Zero header and leave csum up to XDP layers */
@@ -360,15 +356,8 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
err = virtqueue_add_outbuf(sq->vq, sq->sg, num_sg,
   xdp->data, GFP_ATOMIC);
if (unlikely(err)) {
-   if (vi->mergeable_rx_bufs)
-   put_page(page);
-   else
-   give_pages(rq, page);
+   put_page(page);
return; // On error abort to avoid unnecessary kick
-   } else if (!vi->mergeable_rx_bufs) {
-   /* If not mergeable bufs must be big packets so cleanup pages */
-   give_pages(rq, (struct page *)page->private);
-   page->private = 0;
}
 
virtqueue_kick(sq->vq);
@@ -430,44 +419,17 @@ static struct sk_buff *receive_big(struct net_device *dev,
   void *buf,
   unsigned int len)
 {
-   struct bpf_prog *xdp_prog;
struct page *page = buf;
-   struct sk_buff *skb;
-
-   rcu_read_lock();
-   xdp_prog = rcu_dereference(rq->xdp_prog);
-   if (xdp_prog) {
-   struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
-   u32 act;
-
-   if (unlikely(hdr->hdr.gso_type))
-   goto err_xdp;
-   act = do_xdp_prog(vi, rq, xdp_prog, page, 0, len);
-   switch (act) {
-   case XDP_PASS:
-   break;
-   case XDP_TX:
-   rcu_read_unlock();
-   goto xdp_xmit;
-   case XDP_DROP:
-   default:
-   goto err_xdp;
-   }
-   }
-   rcu_read_unlock();
+   struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
 
-   skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
if (unlikely(!skb))
goto err;
 
return skb;
 
-err_xdp:
-   rcu_read_unlock();
 err:
dev->stats.rx_dropped++;
give_pages(rq, page);
-xdp_xmit:
return NULL;
 }
 
-- 
2.7.4



[PATCH] net #8

2001-05-29 Thread Andrzej Krzysztofowicz


The following patch fixes some bogus comments in /drivers/net/*.c

Andrzej

*** PATCH 8 *
diff -uNr linux-2.4.5-ac4/drivers/net/3c501.c linux/drivers/net/3c501.c
--- linux-2.4.5-ac4/drivers/net/3c501.c Wed May 30 01:09:52 2001
+++ linux/drivers/net/3c501.c   Wed May 30 01:15:20 2001
@@ -253,7 +253,7 @@
 }
 
 /**
- * el1_probe: 
+ * el1_probe1: 
  * @dev: The device structure to use
  * @ioaddr: An I/O address to probe at.
  *
diff -uNr linux-2.4.5-ac4/drivers/net/aironet4500_proc.c 
linux/drivers/net/aironet4500_proc.c
--- linux-2.4.5-ac4/drivers/net/aironet4500_proc.c  Tue May 29 20:46:26 2001
+++ linux/drivers/net/aironet4500_proc.cWed May 30 01:15:20 2001
@@ -1,5 +1,5 @@
 /*
- *  Aironet 4500 Pcmcia driver
+ *  Aironet 4500 /proc interface
  *
  * Elmer Joandi, Januar 1999
  * Copyright GPL
diff -uNr linux-2.4.5-ac4/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c
--- linux-2.4.5-ac4/drivers/net/bagetlance.cWed May 30 01:08:54 2001
+++ linux/drivers/net/bagetlance.c  Wed May 30 01:15:20 2001
@@ -1,5 +1,5 @@
 /* $Id$
- * vmelance.c: Ethernet driver for VME Lance cards on Baget/MIPS
+ * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS
  *  This code stealed and adopted from linux/drivers/net/atarilance.c
  *  See that for author info
  *
diff -uNr linux-2.4.5-ac4/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- linux-2.4.5-ac4/drivers/net/seeq8005.c  Wed May 30 01:08:55 2001
+++ linux/drivers/net/seeq8005.cWed May 30 01:15:20 2001
@@ -101,8 +101,6 @@
 /* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
If dev->base_addr == 1, always return failure.
-   If dev->base_addr == 2, allocate space for the device and return success
-   (detachable devices only).
*/
 
 int __init 
diff -uNr linux-2.4.5-ac4/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- linux-2.4.5-ac4/drivers/net/sk_g16.cMon May 28 01:34:55 2001
+++ linux/drivers/net/sk_g16.c  Wed May 30 01:15:20 2001
@@ -536,8 +536,6 @@
  * Check for a network adaptor of this type, and return '0' if one exists.
  * If dev->base_addr == 0, probe all likely locations.
  * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
  */
 
 int __init SK_init(struct net_device *dev)
diff -uNr linux-2.4.5-ac4/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- linux-2.4.5-ac4/drivers/net/winbond-840.c   Wed May 30 01:08:56 2001
+++ linux/drivers/net/winbond-840.c Wed May 30 01:15:20 2001
@@ -1,4 +1,4 @@
-/* winbond-840.c: A Linux PCI network adapter skeleton device driver. */
+/* winbond-840.c: A Linux PCI network adapter device driver. */
 /*
Written 1998-2001 by Donald Becker.
 


-- 
===
  Andrzej M. Krzysztofowicz   [EMAIL PROTECTED]
  phone (48)(58) 347 14 61
Faculty of Applied Phys. & Math.,   Technical University of Gdansk
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



[PATCH] net #8

2001-05-29 Thread Andrzej Krzysztofowicz


The following patch fixes some bogus comments in /drivers/net/*.c

Andrzej

*** PATCH 8 *
diff -uNr linux-2.4.5-ac4/drivers/net/3c501.c linux/drivers/net/3c501.c
--- linux-2.4.5-ac4/drivers/net/3c501.c Wed May 30 01:09:52 2001
+++ linux/drivers/net/3c501.c   Wed May 30 01:15:20 2001
@@ -253,7 +253,7 @@
 }
 
 /**
- * el1_probe: 
+ * el1_probe1: 
  * @dev: The device structure to use
  * @ioaddr: An I/O address to probe at.
  *
diff -uNr linux-2.4.5-ac4/drivers/net/aironet4500_proc.c 
linux/drivers/net/aironet4500_proc.c
--- linux-2.4.5-ac4/drivers/net/aironet4500_proc.c  Tue May 29 20:46:26 2001
+++ linux/drivers/net/aironet4500_proc.cWed May 30 01:15:20 2001
@@ -1,5 +1,5 @@
 /*
- *  Aironet 4500 Pcmcia driver
+ *  Aironet 4500 /proc interface
  *
  * Elmer Joandi, Januar 1999
  * Copyright GPL
diff -uNr linux-2.4.5-ac4/drivers/net/bagetlance.c linux/drivers/net/bagetlance.c
--- linux-2.4.5-ac4/drivers/net/bagetlance.cWed May 30 01:08:54 2001
+++ linux/drivers/net/bagetlance.c  Wed May 30 01:15:20 2001
@@ -1,5 +1,5 @@
 /* $Id$
- * vmelance.c: Ethernet driver for VME Lance cards on Baget/MIPS
+ * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS
  *  This code stealed and adopted from linux/drivers/net/atarilance.c
  *  See that for author info
  *
diff -uNr linux-2.4.5-ac4/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- linux-2.4.5-ac4/drivers/net/seeq8005.c  Wed May 30 01:08:55 2001
+++ linux/drivers/net/seeq8005.cWed May 30 01:15:20 2001
@@ -101,8 +101,6 @@
 /* Check for a network adaptor of this type, and return '0' iff one exists.
If dev-base_addr == 0, probe all likely locations.
If dev-base_addr == 1, always return failure.
-   If dev-base_addr == 2, allocate space for the device and return success
-   (detachable devices only).
*/
 
 int __init 
diff -uNr linux-2.4.5-ac4/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- linux-2.4.5-ac4/drivers/net/sk_g16.cMon May 28 01:34:55 2001
+++ linux/drivers/net/sk_g16.c  Wed May 30 01:15:20 2001
@@ -536,8 +536,6 @@
  * Check for a network adaptor of this type, and return '0' if one exists.
  * If dev-base_addr == 0, probe all likely locations.
  * If dev-base_addr == 1, always return failure.
- * If dev-base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
  */
 
 int __init SK_init(struct net_device *dev)
diff -uNr linux-2.4.5-ac4/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- linux-2.4.5-ac4/drivers/net/winbond-840.c   Wed May 30 01:08:56 2001
+++ linux/drivers/net/winbond-840.c Wed May 30 01:15:20 2001
@@ -1,4 +1,4 @@
-/* winbond-840.c: A Linux PCI network adapter skeleton device driver. */
+/* winbond-840.c: A Linux PCI network adapter device driver. */
 /*
Written 1998-2001 by Donald Becker.
 


-- 
===
  Andrzej M. Krzysztofowicz   [EMAIL PROTECTED]
  phone (48)(58) 347 14 61
Faculty of Applied Phys.  Math.,   Technical University of Gdansk
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/