Skip to content

Commit

Permalink
ixgbe: add a state flags to ring
Browse files Browse the repository at this point in the history
This change adds a set of state flags to the rings that allow them to
independently function allowing for features like RSC, packet split, and
TX hang detection to be done per ring instead of for the entire device.

This is accomplished by re-purposing the flow director reinit_state member
and making it a global state instead since a long for a single bit flag is
a bit wasteful.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Nov 17, 2010
1 parent 33cf09c commit 7d637bc
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 39 deletions.
44 changes: 33 additions & 11 deletions drivers/net/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,31 @@ struct ixgbe_rx_queue_stats {
u64 alloc_rx_buff_failed;
};

enum ixbge_ring_state_t {
__IXGBE_TX_FDIR_INIT_DONE,
__IXGBE_TX_DETECT_HANG,
__IXGBE_RX_PS_ENABLED,
__IXGBE_RX_RSC_ENABLED,
};

#define ring_is_ps_enabled(ring) \
test_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
#define set_ring_ps_enabled(ring) \
set_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
#define clear_ring_ps_enabled(ring) \
clear_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state)
#define check_for_tx_hang(ring) \
test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
#define set_check_for_tx_hang(ring) \
set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
#define clear_check_for_tx_hang(ring) \
clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state)
#define ring_is_rsc_enabled(ring) \
test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
#define set_ring_rsc_enabled(ring) \
set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
#define clear_ring_rsc_enabled(ring) \
clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
struct ixgbe_ring {
void *desc; /* descriptor ring memory */
struct device *dev; /* device for DMA mapping */
Expand All @@ -167,6 +192,7 @@ struct ixgbe_ring {
struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info;
};
unsigned long state;
u8 atr_sample_rate;
u8 atr_count;
u16 count; /* amount of descriptors */
Expand All @@ -175,28 +201,25 @@ struct ixgbe_ring {
u16 next_to_clean;

u8 queue_index; /* needed for multiqueue queue management */
u8 reg_idx; /* holds the special value that gets
* the hardware register offset
* associated with this ring, which is
* different for DCB and RSS modes
*/

u16 work_limit; /* max work per interrupt */

#define IXGBE_RING_RX_PS_ENABLED (u8)(1)
u8 flags; /* per ring feature flags */
u8 __iomem *tail;

unsigned int total_bytes;
unsigned int total_packets;

u16 work_limit; /* max work per interrupt */
u16 reg_idx; /* holds the special value that gets
* the hardware register offset
* associated with this ring, which is
* different for DCB and RSS modes
*/

struct ixgbe_queue_stats stats;
struct u64_stats_sync syncp;
union {
struct ixgbe_tx_queue_stats tx_stats;
struct ixgbe_rx_queue_stats rx_stats;
};
unsigned long reinit_state;
int numa_node;
unsigned int size; /* length in bytes */
dma_addr_t dma; /* phys. address of descriptor ring */
Expand Down Expand Up @@ -441,7 +464,6 @@ enum ixbge_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
__IXGBE_FDIR_INIT_DONE,
__IXGBE_SFP_MODULE_NOT_FOUND
};

Expand Down
67 changes: 39 additions & 28 deletions drivers/net/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,

/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of eop */
adapter->detect_tx_hung = false;
clear_check_for_tx_hang(tx_ring);
if (tx_ring->tx_buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
ixgbe_tx_xon_state(adapter, tx_ring)) {
Expand Down Expand Up @@ -786,13 +786,12 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
}
}

if (adapter->detect_tx_hung) {
if (ixgbe_check_tx_hang(adapter, tx_ring, i)) {
/* schedule immediate reset if we believe we hung */
e_info(probe, "tx hang %d detected, resetting "
"adapter\n", adapter->tx_timeout_count + 1);
ixgbe_tx_timeout(adapter->netdev);
}
if (check_for_tx_hang(tx_ring) &&
ixgbe_check_tx_hang(adapter, tx_ring, i)) {
/* schedule immediate reset if we believe we hung */
e_info(probe, "tx hang %d detected, resetting "
"adapter\n", adapter->tx_timeout_count + 1);
ixgbe_tx_timeout(adapter->netdev);
}

/* re-arm the interrupt */
Expand Down Expand Up @@ -1084,7 +1083,7 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
}
}

if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
if (ring_is_ps_enabled(rx_ring)) {
if (!bi->page) {
bi->page = netdev_alloc_page(rx_ring->netdev);
if (!bi->page) {
Expand Down Expand Up @@ -1214,7 +1213,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
(*work_done)++;

rmb(); /* read descriptor and rx_buffer_info after status DD */
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
if (ring_is_ps_enabled(rx_ring)) {
hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
IXGBE_RXDADV_HDRBUFLEN_SHIFT;
Expand Down Expand Up @@ -1284,7 +1283,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
prefetch(next_rxd);
cleaned_count++;

if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
if (ring_is_rsc_enabled(rx_ring))
rsc_count = ixgbe_get_rsc_count(rx_desc);

if (rsc_count) {
Expand All @@ -1299,7 +1298,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (skb->prev)
skb = ixgbe_transform_rsc_queue(skb,
&(rx_ring->rx_stats.rsc_count));
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
if (ring_is_rsc_enabled(rx_ring)) {
if (IXGBE_RSC_CB(skb)->delay_unmap) {
dma_unmap_single(rx_ring->dev,
IXGBE_RSC_CB(skb)->dma,
Expand All @@ -1308,7 +1307,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
IXGBE_RSC_CB(skb)->dma = 0;
IXGBE_RSC_CB(skb)->delay_unmap = false;
}
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)
if (ring_is_ps_enabled(rx_ring))
rx_ring->rx_stats.rsc_count +=
skb_shinfo(skb)->nr_frags;
else
Expand All @@ -1320,7 +1319,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
rx_ring->stats.bytes += skb->len;
u64_stats_update_end(&rx_ring->syncp);
} else {
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
if (ring_is_ps_enabled(rx_ring)) {
rx_buffer_info->skb = next_buffer->skb;
rx_buffer_info->dma = next_buffer->dma;
next_buffer->skb = skb;
Expand Down Expand Up @@ -1782,8 +1781,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
for (i = 0; i < adapter->num_tx_queues; i++) {
struct ixgbe_ring *tx_ring =
adapter->tx_ring[i];
if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
&tx_ring->reinit_state))
if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
&tx_ring->state))
schedule_work(&adapter->fdir_reinit_task);
}
}
Expand Down Expand Up @@ -2522,7 +2521,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
}

/* reinitialize flowdirector state */
set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state);
set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state);

/* enable queue */
txdctl |= IXGBE_TXDCTL_ENABLE;
Expand Down Expand Up @@ -2632,7 +2631,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
IXGBE_SRRCTL_BSIZEHDR_MASK;

if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
if (ring_is_ps_enabled(rx_ring)) {
#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
#else
Expand Down Expand Up @@ -2727,7 +2726,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
int rx_buf_len;
u16 reg_idx = ring->reg_idx;

if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
if (!ring_is_rsc_enabled(ring))
return;

rx_buf_len = ring->rx_buf_len;
Expand All @@ -2738,7 +2737,7 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
* total size of max desc * buf_len is not greater
* than 65535
*/
if (ring->flags & IXGBE_RING_RX_PS_ENABLED) {
if (ring_is_ps_enabled(ring)) {
#if (MAX_SKB_FRAGS > 16)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
#elif (MAX_SKB_FRAGS > 8)
Expand Down Expand Up @@ -2976,19 +2975,28 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)
rx_ring->rx_buf_len = rx_buf_len;

if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED;
set_ring_ps_enabled(rx_ring);
else
clear_ring_ps_enabled(rx_ring);

if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
set_ring_rsc_enabled(rx_ring);
else
rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
clear_ring_rsc_enabled(rx_ring);

#ifdef IXGBE_FCOE
if (netdev->features & NETIF_F_FCOE_MTU) {
struct ixgbe_ring_feature *f;
f = &adapter->ring_feature[RING_F_FCOE];
if ((i >= f->mask) && (i < f->mask + f->indices)) {
rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
clear_ring_ps_enabled(rx_ring);
if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)
rx_ring->rx_buf_len =
IXGBE_FCOE_JUMBO_FRAME_SIZE;
} else if (!ring_is_rsc_enabled(rx_ring) &&
!ring_is_ps_enabled(rx_ring)) {
rx_ring->rx_buf_len =
IXGBE_FCOE_JUMBO_FRAME_SIZE;
}
}
#endif /* IXGBE_FCOE */
Expand Down Expand Up @@ -5729,8 +5737,8 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work)

if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
for (i = 0; i < adapter->num_tx_queues; i++)
set_bit(__IXGBE_FDIR_INIT_DONE,
&(adapter->tx_ring[i]->reinit_state));
set_bit(__IXGBE_TX_FDIR_INIT_DONE,
&(adapter->tx_ring[i]->state));
} else {
e_err(probe, "failed to finish FDIR re-initialization, "
"ignored adding FDIR ATR filters\n");
Expand Down Expand Up @@ -5816,7 +5824,10 @@ static void ixgbe_watchdog_task(struct work_struct *work)
netif_carrier_on(netdev);
} else {
/* Force detection of hung controller */
adapter->detect_tx_hung = true;
for (i = 0; i < adapter->num_tx_queues; i++) {
tx_ring = adapter->tx_ring[i];
set_check_for_tx_hang(tx_ring);
}
}
} else {
adapter->link_up = false;
Expand Down Expand Up @@ -6434,8 +6445,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
if (tx_ring->atr_sample_rate) {
++tx_ring->atr_count;
if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
test_bit(__IXGBE_FDIR_INIT_DONE,
&tx_ring->reinit_state)) {
test_bit(__IXGBE_TX_FDIR_INIT_DONE,
&tx_ring->state)) {
ixgbe_atr(adapter, skb, tx_ring->queue_index,
tx_flags, protocol);
tx_ring->atr_count = 0;
Expand Down

0 comments on commit 7d637bc

Please sign in to comment.