Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 1 | From e89ea2a038987102d9eb0a7ea217d7a301b484cb Mon Sep 17 00:00:00 2001 |
| 2 | From: John Daley <johndale@cisco.com> |
| 3 | Date: Thu, 24 Mar 2016 14:00:39 -0700 |
| 4 | Subject: [PATCH 21/22] enic: fix TX hang when number of packets > queue |
| 5 | size |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 6 | |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 7 | If the nb_pkts parameter to rte_eth_tx_burst() was greater than |
| 8 | the TX descriptor count, a completion was not being requested |
| 9 | from the NIC, so descriptors would not be released back to the |
| 10 | host causing a lock-up. |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 11 | |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 12 | Introduce a limit of how many TX descriptors can be used in a single |
| 13 | call to the enic PMD burst TX function before requesting a completion. |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 14 | |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 15 | Fixes: d739ba4c6abf ("enic: improve Tx packet rate") |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 16 | |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 17 | Signed-off-by: John Daley <johndale@cisco.com> |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 18 | --- |
| 19 | drivers/net/enic/enic_ethdev.c | 20 ++++++++++++++++---- |
| 20 | drivers/net/enic/enic_res.h | 1 + |
| 21 | 2 files changed, 17 insertions(+), 4 deletions(-) |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 22 | |
| 23 | diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 24 | index 6c3c734..61bb83c 100644 |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 25 | --- a/drivers/net/enic/enic_ethdev.c |
| 26 | +++ b/drivers/net/enic/enic_ethdev.c |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 27 | @@ -510,7 +510,7 @@ static void enicpmd_remove_mac_addr(struct rte_eth_dev *eth_dev, __rte_unused ui |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 28 | static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, |
| 29 | uint16_t nb_pkts) |
| 30 | { |
| 31 | - unsigned int index; |
| 32 | + uint16_t index; |
| 33 | unsigned int frags; |
| 34 | unsigned int pkt_len; |
| 35 | unsigned int seg_len; |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 36 | @@ -522,6 +522,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 37 | unsigned short vlan_id; |
| 38 | unsigned short ol_flags; |
| 39 | uint8_t last_seg, eop; |
| 40 | + unsigned int host_tx_descs = 0; |
| 41 | |
| 42 | for (index = 0; index < nb_pkts; index++) { |
| 43 | tx_pkt = *tx_pkts++; |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 44 | @@ -537,6 +538,7 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 45 | return index; |
| 46 | } |
| 47 | } |
| 48 | + |
| 49 | pkt_len = tx_pkt->pkt_len; |
| 50 | vlan_id = tx_pkt->vlan_tci; |
| 51 | ol_flags = tx_pkt->ol_flags; |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 52 | @@ -546,9 +548,19 @@ static uint16_t enicpmd_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, |
John Lo | 23650e6 | 2016-03-29 16:14:35 -0400 | [diff] [blame] | 53 | next_tx_pkt = tx_pkt->next; |
| 54 | seg_len = tx_pkt->data_len; |
| 55 | inc_len += seg_len; |
| 56 | - eop = (pkt_len == inc_len) || (!next_tx_pkt); |
| 57 | - last_seg = eop && |
| 58 | - (index == ((unsigned int)nb_pkts - 1)); |
| 59 | + |
| 60 | + host_tx_descs++; |
| 61 | + last_seg = 0; |
| 62 | + eop = 0; |
| 63 | + if ((pkt_len == inc_len) || !next_tx_pkt) { |
| 64 | + eop = 1; |
| 65 | + /* post if last packet in batch or > thresh */ |
| 66 | + if ((index == (nb_pkts - 1)) || |
| 67 | + (host_tx_descs > ENIC_TX_POST_THRESH)) { |
| 68 | + last_seg = 1; |
| 69 | + host_tx_descs = 0; |
| 70 | + } |
| 71 | + } |
| 72 | enic_send_pkt(enic, wq, tx_pkt, (unsigned short)seg_len, |
| 73 | !frags, eop, last_seg, ol_flags, vlan_id); |
| 74 | tx_pkt = next_tx_pkt; |
| 75 | diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h |
| 76 | index 33f2e84..00fa71d 100644 |
| 77 | --- a/drivers/net/enic/enic_res.h |
| 78 | +++ b/drivers/net/enic/enic_res.h |
| 79 | @@ -53,6 +53,7 @@ |
| 80 | |
| 81 | #define ENIC_NON_TSO_MAX_DESC 16 |
| 82 | #define ENIC_DEFAULT_RX_FREE_THRESH 32 |
| 83 | +#define ENIC_TX_POST_THRESH (ENIC_MIN_WQ_DESCS / 2) |
| 84 | |
| 85 | #define ENIC_SETTING(enic, f) ((enic->config.flags & VENETF_##f) ? 1 : 0) |
| 86 | |
Todd Foggoa | a292c8c | 2016-04-06 09:57:01 -0400 | [diff] [blame] | 87 | -- |
| 88 | 1.9.1 |
| 89 | |