[PATCH net 8/9] net: qed: reset ILT block sizes before recomputing to fix crashes
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
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
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
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
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
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
From: Doug BergerThe 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
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
Now we in fact don't allow XDP for big packets, remove its codes. Cc: John FastabendSigned-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
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
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
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/