summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Monjalon <thomas.monjalon@6wind.com>2013-11-15 12:08:10 +0100
committerThomas Monjalon <thomas.monjalon@6wind.com>2014-01-03 17:08:09 +0100
commite8ae856140bce4e470005ecc02dfa5f7c433f2eb (patch)
tree0f1319ae0eabd7ee72e5a99584a470d382d612da
parent06bea48c368b2cd00826931f0f7d5c621e781a89 (diff)
downloaddpdk-e8ae856140bce4e470005ecc02dfa5f7c433f2eb.zip
dpdk-e8ae856140bce4e470005ecc02dfa5f7c433f2eb.tar.gz
dpdk-e8ae856140bce4e470005ecc02dfa5f7c433f2eb.tar.xz
igb/ixgbe: fix index overflow when resetting big queues
Rings are resetted with a loop because memset cannot be used without issuing a warning about volatile casting. The index of the loop was a 16-bit variable which is sufficient for ring entries number but not for the byte size of the whole ring. The overflow happens when rings are configured for 4096 entries (descriptor size is 16 bytes). The result is an endless loop. It is fixed by indexing ring entries and resetting all bytes of the entry with a simple assignment. The descriptor initializer is zeroed thanks to its static declaration. There already was a fix for ixgbe Tx only (commit bcf457f8c0d64a5cb094fd55836b324bddb930b6). It is reverted to use the same fix everywhere (Rx/Tx for igb/ixgbe). Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com> Acked-by: Ivan Boule <ivan.boule@6wind.com>
-rw-r--r--lib/librte_pmd_e1000/igb_rxtx.c14
-rw-r--r--lib/librte_pmd_ixgbe/ixgbe_rxtx.c19
2 files changed, 16 insertions, 17 deletions
diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c
index 7448ecb..c5508c1 100644
--- a/lib/librte_pmd_e1000/igb_rxtx.c
+++ b/lib/librte_pmd_e1000/igb_rxtx.c
@@ -1134,16 +1134,15 @@ igb_reset_tx_queue_stat(struct igb_tx_queue *txq)
static void
igb_reset_tx_queue(struct igb_tx_queue *txq, struct rte_eth_dev *dev)
{
+ static const union e1000_adv_tx_desc zeroed_desc;
struct igb_tx_entry *txe = txq->sw_ring;
- uint32_t size;
uint16_t i, prev;
struct e1000_hw *hw;
hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- size = sizeof(union e1000_adv_tx_desc) * txq->nb_tx_desc;
/* Zero out HW ring memory */
- for (i = 0; i < size; i++) {
- ((volatile char *)txq->tx_ring)[i] = 0;
+ for (i = 0; i < txq->nb_tx_desc; i++) {
+ txq->tx_ring[i] = zeroed_desc;
}
/* Initialize ring entries */
@@ -1295,13 +1294,12 @@ eth_igb_rx_queue_release(void *rxq)
static void
igb_reset_rx_queue(struct igb_rx_queue *rxq)
{
- unsigned size;
+ static const union e1000_adv_rx_desc zeroed_desc;
unsigned i;
/* Zero out HW ring memory */
- size = sizeof(union e1000_adv_rx_desc) * rxq->nb_rx_desc;
- for (i = 0; i < size; i++) {
- ((volatile char *)rxq->rx_ring)[i] = 0;
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ rxq->rx_ring[i] = zeroed_desc;
}
rxq->rx_tail = 0;
diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
index cadc6a8..cf27a24 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c
@@ -1797,13 +1797,13 @@ ixgbe_dev_tx_queue_release(void *txq)
static void
ixgbe_reset_tx_queue(struct igb_tx_queue *txq)
{
+ static const union ixgbe_adv_tx_desc zeroed_desc;
struct igb_tx_entry *txe = txq->sw_ring;
- uint16_t prev;
- uint32_t i;
+ uint16_t prev, i;
/* Zero out HW ring memory */
- for (i = 0; i < sizeof(union ixgbe_adv_tx_desc) * txq->nb_tx_desc; i++) {
- ((volatile char *)txq->tx_ring)[i] = 0;
+ for (i = 0; i < txq->nb_tx_desc; i++) {
+ txq->tx_ring[i] = zeroed_desc;
}
/* Initialize SW ring entries */
@@ -1812,9 +1812,9 @@ ixgbe_reset_tx_queue(struct igb_tx_queue *txq)
volatile union ixgbe_adv_tx_desc *txd = &txq->tx_ring[i];
txd->wb.status = IXGBE_TXD_STAT_DD;
txe[i].mbuf = NULL;
- txe[i].last_id = (uint16_t)i;
- txe[prev].next_id = (uint16_t)i;
- prev = (uint16_t)i;
+ txe[i].last_id = i;
+ txe[prev].next_id = i;
+ prev = i;
}
txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1);
@@ -2092,6 +2092,7 @@ check_rx_burst_bulk_alloc_preconditions(__rte_unused struct igb_rx_queue *rxq)
static void
ixgbe_reset_rx_queue(struct igb_rx_queue *rxq)
{
+ static const union ixgbe_adv_rx_desc zeroed_desc;
unsigned i;
uint16_t len;
@@ -2119,8 +2120,8 @@ ixgbe_reset_rx_queue(struct igb_rx_queue *rxq)
* the H/W ring so look-ahead logic in Rx Burst bulk alloc function
* reads extra memory as zeros.
*/
- for (i = 0; i < len * sizeof(union ixgbe_adv_rx_desc); i++) {
- ((volatile char *)rxq->rx_ring)[i] = 0;
+ for (i = 0; i < len; i++) {
+ rxq->rx_ring[i] = zeroed_desc;
}
#ifdef RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC