Skip to content

Commit

Permalink
be2net: event queue re-design
Browse files Browse the repository at this point in the history
v2: Fixed up the bad typecasting pointed out by David...

In the current design 8 TXQs are serviced by 1 EQ, while each RSS queue
is serviced by a separate EQ. This is being changed as follows:

- Upto 8 EQs will be used (based on the availabilty of msix vectors).
Each EQ will handle 1 RSS and 1 TX ring. The default non-RSS RX queue and
MCC queue are handled by the last EQ.

- On cards which provide support, upto 8 RSS rings will be used, instead
of the current limit of 4.

The new design allows spreading the TX multi-queue completion processing
across multiple CPUs unlike the previous design.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sathya Perla authored and David S. Miller committed Feb 13, 2012
1 parent 23677ce commit 10ef9ab
Show file tree
Hide file tree
Showing 5 changed files with 434 additions and 578 deletions.
65 changes: 38 additions & 27 deletions drivers/net/ethernet/emulex/benet/be.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static inline char *nic_name(struct pci_dev *pdev)
#define BE_MIN_MTU 256

#define BE_NUM_VLANS_SUPPORTED 64
#define BE_MAX_EQD 96
#define BE_MAX_EQD 96u
#define BE_MAX_TX_FRAG_COUNT 30

#define EVNT_Q_LEN 1024
Expand All @@ -92,12 +92,16 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
#define MCC_CQ_LEN 256

#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
#define BE3_MAX_RSS_QS 8
#define BE2_MAX_RSS_QS 4
#define MAX_RSS_QS BE3_MAX_RSS_QS
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */

#define MAX_TX_QS 8
#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */
#define MAX_MSIX_VECTORS MAX_RSS_QS
#define BE_TX_BUDGET 256
#define BE_NAPI_WEIGHT 64
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)

#define FW_VER_LEN 32
Expand Down Expand Up @@ -165,13 +169,16 @@ struct be_eq_obj {

/* Adaptive interrupt coalescing (AIC) info */
bool enable_aic;
u16 min_eqd; /* in usecs */
u16 max_eqd; /* in usecs */
u16 cur_eqd; /* in usecs */
u8 eq_idx;
u32 min_eqd; /* in usecs */
u32 max_eqd; /* in usecs */
u32 eqd; /* configured val when aic is off */
u32 cur_eqd; /* in usecs */

u8 idx; /* array index */
u16 tx_budget;
struct napi_struct napi;
};
struct be_adapter *adapter;
} ____cacheline_aligned_in_smp;

struct be_mcc_obj {
struct be_queue_info q;
Expand All @@ -197,7 +204,7 @@ struct be_tx_obj {
/* Remember the skbs that were transmitted */
struct sk_buff *sent_skb_list[TX_Q_LEN];
struct be_tx_stats stats;
};
} ____cacheline_aligned_in_smp;

/* Struct to remember the pages posted for rx frags */
struct be_rx_page_info {
Expand All @@ -215,8 +222,6 @@ struct be_rx_stats {
u32 rx_drops_no_skbs; /* skb allocation errors */
u32 rx_drops_no_frags; /* HW has no fetched frags */
u32 rx_post_fail; /* page post alloc failures */
u32 rx_polls; /* NAPI calls */
u32 rx_events;
u32 rx_compl;
u32 rx_mcast_pkts;
u32 rx_compl_err; /* completions with err set */
Expand Down Expand Up @@ -249,16 +254,13 @@ struct be_rx_obj {
struct be_queue_info cq;
struct be_rx_compl_info rxcp;
struct be_rx_page_info page_info_tbl[RX_Q_LEN];
struct be_eq_obj rx_eq;
struct be_rx_stats stats;
u8 rss_id;
bool rx_post_starved; /* Zero rx frags have been posted to BE */
u32 cache_line_barrier[16];
};
} ____cacheline_aligned_in_smp;

struct be_drv_stats {
u32 be_on_die_temperature;
u32 tx_events;
u32 eth_red_drops;
u32 rx_drops_no_pbuf;
u32 rx_drops_no_txpb;
Expand Down Expand Up @@ -320,20 +322,19 @@ struct be_adapter {
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock;

struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
u32 num_msix_vec;
u32 num_evt_qs;
struct be_eq_obj eq_obj[MAX_MSIX_VECTORS];
struct msix_entry msix_entries[MAX_MSIX_VECTORS];
bool isr_registered;

/* TX Rings */
struct be_eq_obj tx_eq;
u32 num_tx_qs;
struct be_tx_obj tx_obj[MAX_TX_QS];
u8 num_tx_qs;

u32 cache_line_break[8];

/* Rx rings */
struct be_rx_obj rx_obj[MAX_RX_QS];
u32 num_rx_qs;
struct be_rx_obj rx_obj[MAX_RX_QS];
u32 big_page_size; /* Compounded page size shared by rx wrbs */

u8 eq_next_idx;
Expand Down Expand Up @@ -404,24 +405,34 @@ struct be_adapter {
extern const struct ethtool_ops be_ethtool_ops;

#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
#define tx_stats(txo) (&txo->stats)
#define rx_stats(rxo) (&rxo->stats)
#define num_irqs(adapter) (msix_enabled(adapter) ? \
adapter->num_msix_vec : 1)
#define tx_stats(txo) (&(txo)->stats)
#define rx_stats(rxo) (&(rxo)->stats)

#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
/* The default RXQ is the last RXQ */
#define default_rxo(adpt) (&adpt->rx_obj[adpt->num_rx_qs - 1])

#define for_all_rx_queues(adapter, rxo, i) \
for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
i++, rxo++)

/* Just skip the first default non-rss queue */
/* Skip the default non-rss queue (last one)*/
#define for_all_rss_queues(adapter, rxo, i) \
for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\
i++, rxo++)

#define for_all_tx_queues(adapter, txo, i) \
for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
i++, txo++)

#define for_all_evt_queues(adapter, eqo, i) \
for (i = 0, eqo = &adapter->eq_obj[i]; i < adapter->num_evt_qs; \
i++, eqo++)

#define is_mcc_eqo(eqo) (eqo->idx == 0)
#define mcc_eqo(adapter) (&adapter->eq_obj[0])

#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)

Expand Down
31 changes: 13 additions & 18 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ void be_async_mcc_disable(struct be_adapter *adapter)
adapter->mcc_obj.rearm_cq = false;
}

int be_process_mcc(struct be_adapter *adapter, int *status)
int be_process_mcc(struct be_adapter *adapter)
{
struct be_mcc_compl *compl;
int num = 0;
int num = 0, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;

spin_lock_bh(&adapter->mcc_cq_lock);
Expand All @@ -252,32 +252,32 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
be_async_grp5_evt_process(adapter,
compl->flags, compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
*status = be_mcc_compl_process(adapter, compl);
status = be_mcc_compl_process(adapter, compl);
atomic_dec(&mcc_obj->q.used);
}
be_mcc_compl_use(compl);
num++;
}

if (num)
be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);

spin_unlock_bh(&adapter->mcc_cq_lock);
return num;
return status;
}

/* Wait till no more pending mcc requests are present */
static int be_mcc_wait_compl(struct be_adapter *adapter)
{
#define mcc_timeout 120000 /* 12s timeout */
int i, num, status = 0;
int i, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;

for (i = 0; i < mcc_timeout; i++) {
if (be_error(adapter))
return -EIO;

num = be_process_mcc(adapter, &status);
if (num)
be_cq_notify(adapter, mcc_obj->cq.id,
mcc_obj->rearm_cq, num);
status = be_process_mcc(adapter);

if (atomic_read(&mcc_obj->q.used) == 0)
break;
Expand Down Expand Up @@ -726,9 +726,8 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
}

/* Uses Mbox */
int be_cmd_cq_create(struct be_adapter *adapter,
struct be_queue_info *cq, struct be_queue_info *eq,
bool sol_evts, bool no_delay, int coalesce_wm)
int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
struct be_queue_info *eq, bool no_delay, int coalesce_wm)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_cq_create *req;
Expand Down Expand Up @@ -759,7 +758,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context_lancer, eqid,
ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1);
} else {
AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
coalesce_wm);
Expand All @@ -768,11 +766,8 @@ int be_cmd_cq_create(struct be_adapter *adapter,
AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
__ilog2_u32(cq->len/256));
AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context_be, solevent,
ctxt, sol_evts);
AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1);
}

be_dws_cpu_to_le(ctxt, sizeof(req->context));
Expand Down Expand Up @@ -973,7 +968,7 @@ int be_cmd_txq_create(struct be_adapter *adapter,
/* Uses MCC */
int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id)
u32 if_id, u32 rss, u8 *rss_id)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_eth_rx_create *req;
Expand All @@ -997,7 +992,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
req->num_pages = 2;
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
req->interface_id = cpu_to_le32(if_id);
req->max_frame_size = cpu_to_le16(max_frame_size);
req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
req->rss_queue = cpu_to_le32(rss);

status = be_mcc_notify_wait(adapter);
Expand Down
8 changes: 3 additions & 5 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1506,8 +1506,7 @@ extern int be_cmd_eq_create(struct be_adapter *adapter,
struct be_queue_info *eq, int eq_delay);
extern int be_cmd_cq_create(struct be_adapter *adapter,
struct be_queue_info *cq, struct be_queue_info *eq,
bool sol_evts, bool no_delay,
int num_cqe_dma_coalesce);
bool no_delay, int num_cqe_dma_coalesce);
extern int be_cmd_mccq_create(struct be_adapter *adapter,
struct be_queue_info *mccq,
struct be_queue_info *cq);
Expand All @@ -1516,8 +1515,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter,
struct be_queue_info *cq);
extern int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_queue_info *rxq, u16 cq_id,
u16 frag_size, u16 max_frame_size, u32 if_id,
u32 rss, u8 *rss_id);
u16 frag_size, u32 if_id, u32 rss, u8 *rss_id);
extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
int type);
extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
Expand Down Expand Up @@ -1546,7 +1544,7 @@ extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
extern int be_cmd_reset_function(struct be_adapter *adapter);
extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
u16 table_size);
extern int be_process_mcc(struct be_adapter *adapter, int *status);
extern int be_process_mcc(struct be_adapter *adapter);
extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
u8 port_num, u8 beacon, u8 status, u8 state);
extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
Expand Down
Loading

0 comments on commit 10ef9ab

Please sign in to comment.